Commit
•
b6ffcf4
0
Parent(s):
first commit
Browse files- .gitattributes +33 -0
- README.md +86 -0
- config.json +175 -0
- preprocessor_config.json +19 -0
- pytorch_model.bin +3 -0
- tokenizer.json +0 -0
.gitattributes
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
5 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
6 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
7 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
8 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
9 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
10 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
11 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
12 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
13 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
14 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
15 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
16 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
17 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
18 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
19 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
20 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
21 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
22 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
23 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
24 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
25 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
26 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
27 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
28 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
29 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
30 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
31 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
32 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
33 |
+
pytorch_model.bin filter=lfs diff=lfs merge=lfs -text
|
README.md
ADDED
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
license: mit
|
3 |
+
pipeline_tag: zero-shot-image-classification
|
4 |
+
tags:
|
5 |
+
- tinyclip
|
6 |
+
---
|
7 |
+
# TinyCLIP: CLIP Distillation via Affinity Mimicking and Weight Inheritance
|
8 |
+
|
9 |
+
**[ICCV 2023]** - [TinyCLIP: CLIP Distillation via Affinity Mimicking and Weight Inheritance](https://openaccess.thecvf.com/content/ICCV2023/html/Wu_TinyCLIP_CLIP_Distillation_via_Affinity_Mimicking_and_Weight_Inheritance_ICCV_2023_paper.html)
|
10 |
+
|
11 |
+
**TinyCLIP** is a novel **cross-modal distillation** method for large-scale language-image pre-trained models. The method introduces two core techniques: **affinity mimicking** and **weight inheritance**. This work unleashes the capacity of small CLIP models, fully leveraging large-scale models as well as pre-training data and striking the best trade-off between speed and accuracy.
|
12 |
+
|
13 |
+
<p align="center">
|
14 |
+
<img src="./figure/TinyCLIP.jpg" width="1000">
|
15 |
+
</p>
|
16 |
+
|
17 |
+
|
18 |
+
## Use with Transformers
|
19 |
+
|
20 |
+
```python
|
21 |
+
from PIL import Image
|
22 |
+
import requests
|
23 |
+
|
24 |
+
from transformers import CLIPProcessor, CLIPModel
|
25 |
+
|
26 |
+
model = CLIPModel.from_pretrained("wkcn/TinyCLIP-ViT-8M-16-Text-3M-YFCC15M")
|
27 |
+
processor = CLIPProcessor.from_pretrained("wkcn/TinyCLIP-ViT-8M-16-Text-3M-YFCC15M")
|
28 |
+
|
29 |
+
url = "http://images.cocodataset.org/val2017/000000039769.jpg"
|
30 |
+
image = Image.open(requests.get(url, stream=True).raw)
|
31 |
+
|
32 |
+
inputs = processor(text=["a photo of a cat", "a photo of a dog"], images=image, return_tensors="pt", padding=True)
|
33 |
+
|
34 |
+
outputs = model(**inputs)
|
35 |
+
logits_per_image = outputs.logits_per_image # this is the image-text similarity score
|
36 |
+
probs = logits_per_image.softmax(dim=1) # we can take the softmax to get the label probabilities
|
37 |
+
```
|
38 |
+
|
39 |
+
## Highlights
|
40 |
+
<p align="center">
|
41 |
+
<img src="./figure/fig1.jpg" width="500">
|
42 |
+
</p>
|
43 |
+
|
44 |
+
* TinyCLIP ViT-45M/32 uses only **half parameters** of ViT-B/32 to achieves **comparable zero-shot performance**.
|
45 |
+
* TinyCLIP ResNet-19M reduces the parameters by **50\%** while getting **2x** inference speedup, and obtains **56.4\%** accuracy on ImageNet.
|
46 |
+
|
47 |
+
## Model Zoo
|
48 |
+
| Model | Weight inheritance | Pretrain | IN-1K Acc@1(%) | MACs(G) | Throughput(pairs/s) | Link |
|
49 |
+
|--------------------|--------------------|---------------|----------------|---------|---------------------|------|
|
50 |
+
[TinyCLIP ViT-39M/16 Text-19M](./src/open_clip/model_configs/TinyCLIP-ViT-39M-16-Text-19M.json) | manual | YFCC-15M | 63.5 | 9.5 | 1,469 | [Model](https://github.com/wkcn/TinyCLIP-model-zoo/releases/download/checkpoints/TinyCLIP-ViT-39M-16-Text-19M-YFCC15M.pt)
|
51 |
+
[TinyCLIP ViT-8M/16 Text-3M](./src/open_clip/model_configs/TinyCLIP-ViT-8M-16-Text-3M.json) | manual | YFCC-15M | 41.1 | 2.0 | 4,150 | [Model](https://github.com/wkcn/TinyCLIP-model-zoo/releases/download/checkpoints/TinyCLIP-ViT-8M-16-Text-3M-YFCC15M.pt)
|
52 |
+
[TinyCLIP ResNet-30M Text-29M](./src/open_clip/model_configs/TinyCLIP-ResNet-30M-Text-29M.json) | manual | LAION-400M | 59.1 | 6.9 | 1,811 | [Model](https://github.com/wkcn/TinyCLIP-model-zoo/releases/download/checkpoints/TinyCLIP-ResNet-30M-Text-29M-LAION400M.pt)
|
53 |
+
[TinyCLIP ResNet-19M Text-19M](./src/open_clip/model_configs/TinyCLIP-ResNet-19M-Text-19M.json) | manual | LAION-400M | 56.4 | 4.4 | 3,024| [Model](https://github.com/wkcn/TinyCLIP-model-zoo/releases/download/checkpoints/TinyCLIP-ResNet-19M-Text-19M-LAION400M.pt)
|
54 |
+
[TinyCLIP ViT-61M/32 Text-29M](./src/open_clip/model_configs/TinyCLIP-ViT-61M-32-Text-29M.json) | manual | LAION-400M | 62.4 | 5.3 | 3,191|[Model](https://github.com/wkcn/TinyCLIP-model-zoo/releases/download/checkpoints/TinyCLIP-ViT-61M-32-Text-29M-LAION400M.pt)
|
55 |
+
[TinyCLIP ViT-40M/32 Text-19M](./src/open_clip/model_configs/TinyCLIP-ViT-40M-32-Text-19M.json) | manual | LAION-400M | 59.8 | 3.5 | 4,641|[Model](https://github.com/wkcn/TinyCLIP-model-zoo/releases/download/checkpoints/TinyCLIP-ViT-40M-32-Text-19M-LAION400M.pt)
|
56 |
+
TinyCLIP ViT-63M/32 Text-31M | auto | LAION-400M | 63.9 | 5.6 | 2,905|[Model](https://github.com/wkcn/TinyCLIP-model-zoo/releases/download/checkpoints/TinyCLIP-auto-ViT-63M-32-Text-31M-LAION400M.pt)
|
57 |
+
TinyCLIP ViT-45M/32 Text-18M | auto | LAION-400M | 61.4 | 3.7 | 3,682|[Model](https://github.com/wkcn/TinyCLIP-model-zoo/releases/download/checkpoints/TinyCLIP-auto-ViT-45M-32-Text-18M-LAION400M.pt)
|
58 |
+
TinyCLIP ViT-22M/32 Text-10M | auto | LAION-400M | 53.7 | 1.9 | 5,504|[Model](https://github.com/wkcn/TinyCLIP-model-zoo/releases/download/checkpoints/TinyCLIP-auto-ViT-22M-32-Text-10M-LAION400M.pt)
|
59 |
+
TinyCLIP ViT-63M/32 Text-31M | auto | LAION+YFCC-400M | 64.5 | 5.6| 2,909 | [Model](https://github.com/wkcn/TinyCLIP-model-zoo/releases/download/checkpoints/TinyCLIP-auto-ViT-63M-32-Text-31M-LAIONYFCC400M.pt)
|
60 |
+
TinyCLIP ViT-45M/32 Text-18M | auto | LAION+YFCC-400M | 62.7 | 1.9 | 3,685 | [Model](https://github.com/wkcn/TinyCLIP-model-zoo/releases/download/checkpoints/TinyCLIP-auto-ViT-45M-32-Text-18M-LAIONYFCC400M.pt)
|
61 |
+
|
62 |
+
Note: The configs of models with auto inheritance are generated automatically.
|
63 |
+
|
64 |
+
## Official PyTorch Implementation
|
65 |
+
https://github.com/microsoft/Cream/tree/main/TinyCLIP
|
66 |
+
|
67 |
+
## Citation
|
68 |
+
If this repo is helpful for you, please consider to cite it. :mega: Thank you! :)
|
69 |
+
|
70 |
+
```bibtex
|
71 |
+
@InProceedings{tinyclip,
|
72 |
+
title = {TinyCLIP: CLIP Distillation via Affinity Mimicking and Weight Inheritance},
|
73 |
+
author = {Wu, Kan and Peng, Houwen and Zhou, Zhenghong and Xiao, Bin and Liu, Mengchen and Yuan, Lu and Xuan, Hong and Valenzuela, Michael and Chen, Xi (Stephen) and Wang, Xinggang and Chao, Hongyang and Hu, Han},
|
74 |
+
booktitle = {Proceedings of the IEEE/CVF International Conference on Computer Vision (ICCV)},
|
75 |
+
month = {October},
|
76 |
+
year = {2023},
|
77 |
+
pages = {21970-21980}
|
78 |
+
}
|
79 |
+
```
|
80 |
+
|
81 |
+
## Acknowledge
|
82 |
+
|
83 |
+
Our code is based on [CLIP](https://github.com/openai/CLIP), [OpenCLIP](https://github.com/mlfoundations/open_clip), [CoFi](https://github.com/princeton-nlp/CoFiPruning) and [PyTorch](https://github.com/pytorch/pytorch). Thank contributors for their awesome contribution!
|
84 |
+
|
85 |
+
## License
|
86 |
+
- [License](https://github.com/microsoft/Cream/blob/main/TinyCLIP/LICENSE)
|
config.json
ADDED
@@ -0,0 +1,175 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"architectures": [
|
3 |
+
"CLIPModel"
|
4 |
+
],
|
5 |
+
"initializer_factor": 1.0,
|
6 |
+
"logit_scale_init_value": 2.6592,
|
7 |
+
"model_type": "clip",
|
8 |
+
"projection_dim": 512,
|
9 |
+
"text_config": {
|
10 |
+
"_name_or_path": "",
|
11 |
+
"add_cross_attention": false,
|
12 |
+
"architectures": null,
|
13 |
+
"attention_dropout": 0.0,
|
14 |
+
"bad_words_ids": null,
|
15 |
+
"bos_token_id": 0,
|
16 |
+
"chunk_size_feed_forward": 0,
|
17 |
+
"cross_attention_hidden_size": null,
|
18 |
+
"decoder_start_token_id": null,
|
19 |
+
"diversity_penalty": 0.0,
|
20 |
+
"do_sample": false,
|
21 |
+
"dropout": 0.0,
|
22 |
+
"early_stopping": false,
|
23 |
+
"encoder_no_repeat_ngram_size": 0,
|
24 |
+
"eos_token_id": 2,
|
25 |
+
"exponential_decay_length_penalty": null,
|
26 |
+
"finetuning_task": null,
|
27 |
+
"forced_bos_token_id": null,
|
28 |
+
"forced_eos_token_id": null,
|
29 |
+
"hidden_act": "gelu",
|
30 |
+
"hidden_size": 256,
|
31 |
+
"id2label": {
|
32 |
+
"0": "LABEL_0",
|
33 |
+
"1": "LABEL_1"
|
34 |
+
},
|
35 |
+
"initializer_factor": 1.0,
|
36 |
+
"initializer_range": 0.02,
|
37 |
+
"intermediate_size": 1024,
|
38 |
+
"is_decoder": false,
|
39 |
+
"is_encoder_decoder": false,
|
40 |
+
"label2id": {
|
41 |
+
"LABEL_0": 0,
|
42 |
+
"LABEL_1": 1
|
43 |
+
},
|
44 |
+
"layer_norm_eps": 1e-05,
|
45 |
+
"length_penalty": 1.0,
|
46 |
+
"max_length": 20,
|
47 |
+
"max_position_embeddings": 77,
|
48 |
+
"min_length": 0,
|
49 |
+
"model_type": "clip_text_model",
|
50 |
+
"no_repeat_ngram_size": 0,
|
51 |
+
"num_attention_heads": 4,
|
52 |
+
"num_beam_groups": 1,
|
53 |
+
"num_beams": 1,
|
54 |
+
"num_hidden_layers": 3,
|
55 |
+
"num_return_sequences": 1,
|
56 |
+
"output_attentions": false,
|
57 |
+
"output_hidden_states": false,
|
58 |
+
"output_scores": false,
|
59 |
+
"pad_token_id": 1,
|
60 |
+
"prefix": null,
|
61 |
+
"problem_type": null,
|
62 |
+
"pruned_heads": {},
|
63 |
+
"remove_invalid_values": false,
|
64 |
+
"repetition_penalty": 1.0,
|
65 |
+
"return_dict": true,
|
66 |
+
"return_dict_in_generate": false,
|
67 |
+
"sep_token_id": null,
|
68 |
+
"task_specific_params": null,
|
69 |
+
"temperature": 1.0,
|
70 |
+
"tf_legacy_loss": false,
|
71 |
+
"tie_encoder_decoder": false,
|
72 |
+
"tie_word_embeddings": true,
|
73 |
+
"tokenizer_class": null,
|
74 |
+
"top_k": 50,
|
75 |
+
"top_p": 1.0,
|
76 |
+
"torch_dtype": null,
|
77 |
+
"torchscript": false,
|
78 |
+
"transformers_version": "4.21.3",
|
79 |
+
"typical_p": 1.0,
|
80 |
+
"use_bfloat16": false,
|
81 |
+
"vocab_size": 49408
|
82 |
+
},
|
83 |
+
"text_config_dict": {
|
84 |
+
"hidden_act": "gelu",
|
85 |
+
"hidden_size": 256,
|
86 |
+
"intermediate_size": 1024,
|
87 |
+
"num_attention_heads": 4,
|
88 |
+
"num_hidden_layers": 3
|
89 |
+
},
|
90 |
+
"torch_dtype": "float32",
|
91 |
+
"transformers_version": null,
|
92 |
+
"vision_config": {
|
93 |
+
"_name_or_path": "",
|
94 |
+
"add_cross_attention": false,
|
95 |
+
"architectures": null,
|
96 |
+
"attention_dropout": 0.0,
|
97 |
+
"bad_words_ids": null,
|
98 |
+
"bos_token_id": null,
|
99 |
+
"chunk_size_feed_forward": 0,
|
100 |
+
"cross_attention_hidden_size": null,
|
101 |
+
"decoder_start_token_id": null,
|
102 |
+
"diversity_penalty": 0.0,
|
103 |
+
"do_sample": false,
|
104 |
+
"dropout": 0.0,
|
105 |
+
"early_stopping": false,
|
106 |
+
"encoder_no_repeat_ngram_size": 0,
|
107 |
+
"eos_token_id": null,
|
108 |
+
"exponential_decay_length_penalty": null,
|
109 |
+
"finetuning_task": null,
|
110 |
+
"forced_bos_token_id": null,
|
111 |
+
"forced_eos_token_id": null,
|
112 |
+
"hidden_act": "gelu",
|
113 |
+
"hidden_size": 256,
|
114 |
+
"id2label": {
|
115 |
+
"0": "LABEL_0",
|
116 |
+
"1": "LABEL_1"
|
117 |
+
},
|
118 |
+
"image_size": 224,
|
119 |
+
"initializer_factor": 1.0,
|
120 |
+
"initializer_range": 0.02,
|
121 |
+
"intermediate_size": 1024,
|
122 |
+
"is_decoder": false,
|
123 |
+
"is_encoder_decoder": false,
|
124 |
+
"label2id": {
|
125 |
+
"LABEL_0": 0,
|
126 |
+
"LABEL_1": 1
|
127 |
+
},
|
128 |
+
"layer_norm_eps": 1e-05,
|
129 |
+
"length_penalty": 1.0,
|
130 |
+
"max_length": 20,
|
131 |
+
"min_length": 0,
|
132 |
+
"model_type": "clip_vision_model",
|
133 |
+
"no_repeat_ngram_size": 0,
|
134 |
+
"num_attention_heads": 4,
|
135 |
+
"num_beam_groups": 1,
|
136 |
+
"num_beams": 1,
|
137 |
+
"num_channels": 3,
|
138 |
+
"num_hidden_layers": 10,
|
139 |
+
"num_return_sequences": 1,
|
140 |
+
"output_attentions": false,
|
141 |
+
"output_hidden_states": false,
|
142 |
+
"output_scores": false,
|
143 |
+
"pad_token_id": null,
|
144 |
+
"patch_size": 16,
|
145 |
+
"prefix": null,
|
146 |
+
"problem_type": null,
|
147 |
+
"pruned_heads": {},
|
148 |
+
"remove_invalid_values": false,
|
149 |
+
"repetition_penalty": 1.0,
|
150 |
+
"return_dict": true,
|
151 |
+
"return_dict_in_generate": false,
|
152 |
+
"sep_token_id": null,
|
153 |
+
"task_specific_params": null,
|
154 |
+
"temperature": 1.0,
|
155 |
+
"tf_legacy_loss": false,
|
156 |
+
"tie_encoder_decoder": false,
|
157 |
+
"tie_word_embeddings": true,
|
158 |
+
"tokenizer_class": null,
|
159 |
+
"top_k": 50,
|
160 |
+
"top_p": 1.0,
|
161 |
+
"torch_dtype": null,
|
162 |
+
"torchscript": false,
|
163 |
+
"transformers_version": "4.21.3",
|
164 |
+
"typical_p": 1.0,
|
165 |
+
"use_bfloat16": false
|
166 |
+
},
|
167 |
+
"vision_config_dict": {
|
168 |
+
"hidden_act": "gelu",
|
169 |
+
"hidden_size": 256,
|
170 |
+
"intermediate_size": 1024,
|
171 |
+
"num_attention_heads": 4,
|
172 |
+
"num_hidden_layers": 10,
|
173 |
+
"patch_size": 16
|
174 |
+
}
|
175 |
+
}
|
preprocessor_config.json
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"crop_size": 224,
|
3 |
+
"do_center_crop": true,
|
4 |
+
"do_normalize": true,
|
5 |
+
"do_resize": true,
|
6 |
+
"feature_extractor_type": "CLIPFeatureExtractor",
|
7 |
+
"image_mean": [
|
8 |
+
0.48145466,
|
9 |
+
0.4578275,
|
10 |
+
0.40821073
|
11 |
+
],
|
12 |
+
"image_std": [
|
13 |
+
0.26862954,
|
14 |
+
0.26130258,
|
15 |
+
0.27577711
|
16 |
+
],
|
17 |
+
"resample": 3,
|
18 |
+
"size": 224
|
19 |
+
}
|
pytorch_model.bin
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:45d832b8c61a631df7b739fecd3fe895a92e57e3a3f318ede459ee0ca6e9c565
|
3 |
+
size 93857857
|
tokenizer.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|