Feature Extraction
Transformers
Safetensors
English
diffretriever
information-retrieval
dense-retrieval
sparse-retrieval
colbert
diffusion-language-model
lora
custom_code
Instructions to use ielabgroup/diffretriever-dream-7b-multi-q4-p16 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use ielabgroup/diffretriever-dream-7b-multi-q4-p16 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("feature-extraction", model="ielabgroup/diffretriever-dream-7b-multi-q4-p16", trust_remote_code=True)# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("ielabgroup/diffretriever-dream-7b-multi-q4-p16", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
Add self-contained DiffRetriever (trust_remote_code: code + config + adapter/)
Browse files- README.md +206 -0
- adapter/adapter_config.json +46 -0
- adapter/adapter_model.safetensors +3 -0
- added_tokens.json +26 -0
- backbone_adapters.py +329 -0
- chat_template.jinja +54 -0
- config.json +15 -0
- configuration_diffretriever.py +36 -0
- diffretriever_trainable.py +0 -0
- merges.txt +0 -0
- modeling_diffretriever.py +104 -0
- retriever_config.json +135 -0
- sparse_utils.py +93 -0
- special_tokens_map.json +34 -0
- tokenization_dream.py +340 -0
- tokenizer_config.json +219 -0
- vocab.json +0 -0
README.md
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
base_model: Dream-org/Dream-v0-Instruct-7B
|
| 3 |
+
library_name: peft
|
| 4 |
+
tags:
|
| 5 |
+
- base_model:adapter:Dream-org/Dream-v0-Instruct-7B
|
| 6 |
+
- lora
|
| 7 |
+
- transformers
|
| 8 |
+
---
|
| 9 |
+
|
| 10 |
+
# Model Card for Model ID
|
| 11 |
+
|
| 12 |
+
<!-- Provide a quick summary of what the model is/does. -->
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
## Model Details
|
| 17 |
+
|
| 18 |
+
### Model Description
|
| 19 |
+
|
| 20 |
+
<!-- Provide a longer summary of what this model is. -->
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
- **Developed by:** [More Information Needed]
|
| 25 |
+
- **Funded by [optional]:** [More Information Needed]
|
| 26 |
+
- **Shared by [optional]:** [More Information Needed]
|
| 27 |
+
- **Model type:** [More Information Needed]
|
| 28 |
+
- **Language(s) (NLP):** [More Information Needed]
|
| 29 |
+
- **License:** [More Information Needed]
|
| 30 |
+
- **Finetuned from model [optional]:** [More Information Needed]
|
| 31 |
+
|
| 32 |
+
### Model Sources [optional]
|
| 33 |
+
|
| 34 |
+
<!-- Provide the basic links for the model. -->
|
| 35 |
+
|
| 36 |
+
- **Repository:** [More Information Needed]
|
| 37 |
+
- **Paper [optional]:** [More Information Needed]
|
| 38 |
+
- **Demo [optional]:** [More Information Needed]
|
| 39 |
+
|
| 40 |
+
## Uses
|
| 41 |
+
|
| 42 |
+
<!-- Address questions around how the model is intended to be used, including the foreseeable users of the model and those affected by the model. -->
|
| 43 |
+
|
| 44 |
+
### Direct Use
|
| 45 |
+
|
| 46 |
+
<!-- This section is for the model use without fine-tuning or plugging into a larger ecosystem/app. -->
|
| 47 |
+
|
| 48 |
+
[More Information Needed]
|
| 49 |
+
|
| 50 |
+
### Downstream Use [optional]
|
| 51 |
+
|
| 52 |
+
<!-- This section is for the model use when fine-tuned for a task, or when plugged into a larger ecosystem/app -->
|
| 53 |
+
|
| 54 |
+
[More Information Needed]
|
| 55 |
+
|
| 56 |
+
### Out-of-Scope Use
|
| 57 |
+
|
| 58 |
+
<!-- This section addresses misuse, malicious use, and uses that the model will not work well for. -->
|
| 59 |
+
|
| 60 |
+
[More Information Needed]
|
| 61 |
+
|
| 62 |
+
## Bias, Risks, and Limitations
|
| 63 |
+
|
| 64 |
+
<!-- This section is meant to convey both technical and sociotechnical limitations. -->
|
| 65 |
+
|
| 66 |
+
[More Information Needed]
|
| 67 |
+
|
| 68 |
+
### Recommendations
|
| 69 |
+
|
| 70 |
+
<!-- This section is meant to convey recommendations with respect to the bias, risk, and technical limitations. -->
|
| 71 |
+
|
| 72 |
+
Users (both direct and downstream) should be made aware of the risks, biases and limitations of the model. More information needed for further recommendations.
|
| 73 |
+
|
| 74 |
+
## How to Get Started with the Model
|
| 75 |
+
|
| 76 |
+
Use the code below to get started with the model.
|
| 77 |
+
|
| 78 |
+
[More Information Needed]
|
| 79 |
+
|
| 80 |
+
## Training Details
|
| 81 |
+
|
| 82 |
+
### Training Data
|
| 83 |
+
|
| 84 |
+
<!-- This should link to a Dataset Card, perhaps with a short stub of information on what the training data is all about as well as documentation related to data pre-processing or additional filtering. -->
|
| 85 |
+
|
| 86 |
+
[More Information Needed]
|
| 87 |
+
|
| 88 |
+
### Training Procedure
|
| 89 |
+
|
| 90 |
+
<!-- This relates heavily to the Technical Specifications. Content here should link to that section when it is relevant to the training procedure. -->
|
| 91 |
+
|
| 92 |
+
#### Preprocessing [optional]
|
| 93 |
+
|
| 94 |
+
[More Information Needed]
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
#### Training Hyperparameters
|
| 98 |
+
|
| 99 |
+
- **Training regime:** [More Information Needed] <!--fp32, fp16 mixed precision, bf16 mixed precision, bf16 non-mixed precision, fp16 non-mixed precision, fp8 mixed precision -->
|
| 100 |
+
|
| 101 |
+
#### Speeds, Sizes, Times [optional]
|
| 102 |
+
|
| 103 |
+
<!-- This section provides information about throughput, start/end time, checkpoint size if relevant, etc. -->
|
| 104 |
+
|
| 105 |
+
[More Information Needed]
|
| 106 |
+
|
| 107 |
+
## Evaluation
|
| 108 |
+
|
| 109 |
+
<!-- This section describes the evaluation protocols and provides the results. -->
|
| 110 |
+
|
| 111 |
+
### Testing Data, Factors & Metrics
|
| 112 |
+
|
| 113 |
+
#### Testing Data
|
| 114 |
+
|
| 115 |
+
<!-- This should link to a Dataset Card if possible. -->
|
| 116 |
+
|
| 117 |
+
[More Information Needed]
|
| 118 |
+
|
| 119 |
+
#### Factors
|
| 120 |
+
|
| 121 |
+
<!-- These are the things the evaluation is disaggregating by, e.g., subpopulations or domains. -->
|
| 122 |
+
|
| 123 |
+
[More Information Needed]
|
| 124 |
+
|
| 125 |
+
#### Metrics
|
| 126 |
+
|
| 127 |
+
<!-- These are the evaluation metrics being used, ideally with a description of why. -->
|
| 128 |
+
|
| 129 |
+
[More Information Needed]
|
| 130 |
+
|
| 131 |
+
### Results
|
| 132 |
+
|
| 133 |
+
[More Information Needed]
|
| 134 |
+
|
| 135 |
+
#### Summary
|
| 136 |
+
|
| 137 |
+
|
| 138 |
+
|
| 139 |
+
## Model Examination [optional]
|
| 140 |
+
|
| 141 |
+
<!-- Relevant interpretability work for the model goes here -->
|
| 142 |
+
|
| 143 |
+
[More Information Needed]
|
| 144 |
+
|
| 145 |
+
## Environmental Impact
|
| 146 |
+
|
| 147 |
+
<!-- Total emissions (in grams of CO2eq) and additional considerations, such as electricity usage, go here. Edit the suggested text below accordingly -->
|
| 148 |
+
|
| 149 |
+
Carbon emissions can be estimated using the [Machine Learning Impact calculator](https://mlco2.github.io/impact#compute) presented in [Lacoste et al. (2019)](https://arxiv.org/abs/1910.09700).
|
| 150 |
+
|
| 151 |
+
- **Hardware Type:** [More Information Needed]
|
| 152 |
+
- **Hours used:** [More Information Needed]
|
| 153 |
+
- **Cloud Provider:** [More Information Needed]
|
| 154 |
+
- **Compute Region:** [More Information Needed]
|
| 155 |
+
- **Carbon Emitted:** [More Information Needed]
|
| 156 |
+
|
| 157 |
+
## Technical Specifications [optional]
|
| 158 |
+
|
| 159 |
+
### Model Architecture and Objective
|
| 160 |
+
|
| 161 |
+
[More Information Needed]
|
| 162 |
+
|
| 163 |
+
### Compute Infrastructure
|
| 164 |
+
|
| 165 |
+
[More Information Needed]
|
| 166 |
+
|
| 167 |
+
#### Hardware
|
| 168 |
+
|
| 169 |
+
[More Information Needed]
|
| 170 |
+
|
| 171 |
+
#### Software
|
| 172 |
+
|
| 173 |
+
[More Information Needed]
|
| 174 |
+
|
| 175 |
+
## Citation [optional]
|
| 176 |
+
|
| 177 |
+
<!-- If there is a paper or blog post introducing the model, the APA and Bibtex information for that should go in this section. -->
|
| 178 |
+
|
| 179 |
+
**BibTeX:**
|
| 180 |
+
|
| 181 |
+
[More Information Needed]
|
| 182 |
+
|
| 183 |
+
**APA:**
|
| 184 |
+
|
| 185 |
+
[More Information Needed]
|
| 186 |
+
|
| 187 |
+
## Glossary [optional]
|
| 188 |
+
|
| 189 |
+
<!-- If relevant, include terms and calculations in this section that can help readers understand the model or model card. -->
|
| 190 |
+
|
| 191 |
+
[More Information Needed]
|
| 192 |
+
|
| 193 |
+
## More Information [optional]
|
| 194 |
+
|
| 195 |
+
[More Information Needed]
|
| 196 |
+
|
| 197 |
+
## Model Card Authors [optional]
|
| 198 |
+
|
| 199 |
+
[More Information Needed]
|
| 200 |
+
|
| 201 |
+
## Model Card Contact
|
| 202 |
+
|
| 203 |
+
[More Information Needed]
|
| 204 |
+
### Framework versions
|
| 205 |
+
|
| 206 |
+
- PEFT 0.18.1
|
adapter/adapter_config.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"alora_invocation_tokens": null,
|
| 3 |
+
"alpha_pattern": {},
|
| 4 |
+
"arrow_config": null,
|
| 5 |
+
"auto_mapping": null,
|
| 6 |
+
"base_model_name_or_path": "Dream-org/Dream-v0-Instruct-7B",
|
| 7 |
+
"bias": "none",
|
| 8 |
+
"corda_config": null,
|
| 9 |
+
"ensure_weight_tying": false,
|
| 10 |
+
"eva_config": null,
|
| 11 |
+
"exclude_modules": null,
|
| 12 |
+
"fan_in_fan_out": false,
|
| 13 |
+
"inference_mode": true,
|
| 14 |
+
"init_lora_weights": true,
|
| 15 |
+
"layer_replication": null,
|
| 16 |
+
"layers_pattern": null,
|
| 17 |
+
"layers_to_transform": null,
|
| 18 |
+
"loftq_config": {},
|
| 19 |
+
"lora_alpha": 64,
|
| 20 |
+
"lora_bias": false,
|
| 21 |
+
"lora_dropout": 0.05,
|
| 22 |
+
"megatron_config": null,
|
| 23 |
+
"megatron_core": "megatron.core",
|
| 24 |
+
"modules_to_save": null,
|
| 25 |
+
"peft_type": "LORA",
|
| 26 |
+
"peft_version": "0.18.1",
|
| 27 |
+
"qalora_group_size": 16,
|
| 28 |
+
"r": 16,
|
| 29 |
+
"rank_pattern": {},
|
| 30 |
+
"revision": null,
|
| 31 |
+
"target_modules": [
|
| 32 |
+
"v_proj",
|
| 33 |
+
"q_proj",
|
| 34 |
+
"k_proj",
|
| 35 |
+
"o_proj",
|
| 36 |
+
"up_proj",
|
| 37 |
+
"gate_proj",
|
| 38 |
+
"down_proj"
|
| 39 |
+
],
|
| 40 |
+
"target_parameters": null,
|
| 41 |
+
"task_type": "FEATURE_EXTRACTION",
|
| 42 |
+
"trainable_token_indices": null,
|
| 43 |
+
"use_dora": false,
|
| 44 |
+
"use_qalora": false,
|
| 45 |
+
"use_rslora": false
|
| 46 |
+
}
|
adapter/adapter_model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:2963a476388a17cf51e47c1141d00ff7c9fb8bd575459862d632cf9749becfac
|
| 3 |
+
size 80792880
|
added_tokens.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"</tool_call>": 151658,
|
| 3 |
+
"<tool_call>": 151657,
|
| 4 |
+
"<|beginoftext|>": 151665,
|
| 5 |
+
"<|box_end|>": 151649,
|
| 6 |
+
"<|box_start|>": 151648,
|
| 7 |
+
"<|endoftext|>": 151643,
|
| 8 |
+
"<|file_sep|>": 151664,
|
| 9 |
+
"<|fim_middle|>": 151660,
|
| 10 |
+
"<|fim_pad|>": 151662,
|
| 11 |
+
"<|fim_prefix|>": 151659,
|
| 12 |
+
"<|fim_suffix|>": 151661,
|
| 13 |
+
"<|im_end|>": 151645,
|
| 14 |
+
"<|im_start|>": 151644,
|
| 15 |
+
"<|image_pad|>": 151655,
|
| 16 |
+
"<|mask|>": 151666,
|
| 17 |
+
"<|object_ref_end|>": 151647,
|
| 18 |
+
"<|object_ref_start|>": 151646,
|
| 19 |
+
"<|quad_end|>": 151651,
|
| 20 |
+
"<|quad_start|>": 151650,
|
| 21 |
+
"<|repo_name|>": 151663,
|
| 22 |
+
"<|video_pad|>": 151656,
|
| 23 |
+
"<|vision_end|>": 151653,
|
| 24 |
+
"<|vision_pad|>": 151654,
|
| 25 |
+
"<|vision_start|>": 151652
|
| 26 |
+
}
|
backbone_adapters.py
ADDED
|
@@ -0,0 +1,329 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Backbone adapters for diffusion retriever training.
|
| 3 |
+
|
| 4 |
+
Each adapter encapsulates ALL model-specific behavior in one place:
|
| 5 |
+
- How to load the backbone (AutoModel vs AutoModelForCausalLM)
|
| 6 |
+
- PEFT/LoRA configuration (target modules, task type)
|
| 7 |
+
- Attention mask format (2D vs 4D)
|
| 8 |
+
- Hidden state extraction (forward hook on output projection)
|
| 9 |
+
- Mask token ID (verified from HuggingFace tokenizer configs)
|
| 10 |
+
- Gradient checkpointing support
|
| 11 |
+
|
| 12 |
+
The TrainableDiffusionRetriever delegates to an adapter and has ZERO
|
| 13 |
+
model-specific branches. Adding a new model = adding one adapter class.
|
| 14 |
+
"""
|
| 15 |
+
|
| 16 |
+
from abc import ABC, abstractmethod
|
| 17 |
+
from typing import Dict, Optional, Tuple
|
| 18 |
+
import logging
|
| 19 |
+
|
| 20 |
+
import torch
|
| 21 |
+
import torch.nn as nn
|
| 22 |
+
|
| 23 |
+
logger = logging.getLogger(__name__)
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
# ---------------------------------------------------------------------------
|
| 27 |
+
# Base adapter
|
| 28 |
+
# ---------------------------------------------------------------------------
|
| 29 |
+
|
| 30 |
+
class BackboneAdapter(ABC):
|
| 31 |
+
"""Abstract interface for model-specific backbone behavior."""
|
| 32 |
+
|
| 33 |
+
model_type: str # e.g. 'dream', 'llada1', 'llada2'
|
| 34 |
+
mask_token_id: int # verified from HuggingFace model cards
|
| 35 |
+
hub_model_name: str # HuggingFace model ID for fallback loading
|
| 36 |
+
|
| 37 |
+
def __init__(self):
|
| 38 |
+
self.flash_attn: bool = False # set by load_backbone
|
| 39 |
+
|
| 40 |
+
# -- loading --------------------------------------------------------
|
| 41 |
+
|
| 42 |
+
def load_backbone(self, source: str, device_map=None) -> nn.Module:
|
| 43 |
+
"""Load backbone from HuggingFace model name or local directory.
|
| 44 |
+
|
| 45 |
+
Tries flash attention variants in order, falls back to eager.
|
| 46 |
+
Sets ``self.flash_attn`` as a side effect.
|
| 47 |
+
"""
|
| 48 |
+
common_kw = dict(trust_remote_code=True, torch_dtype=torch.bfloat16)
|
| 49 |
+
if device_map is not None:
|
| 50 |
+
common_kw['device_map'] = device_map
|
| 51 |
+
|
| 52 |
+
for attn_impl in self._flash_attn_impls:
|
| 53 |
+
try:
|
| 54 |
+
bb = self._auto_class().from_pretrained(
|
| 55 |
+
source, attn_implementation=attn_impl, **common_kw)
|
| 56 |
+
self.flash_attn = True
|
| 57 |
+
logger.info(f"{self.model_type}: {attn_impl} enabled")
|
| 58 |
+
return bb
|
| 59 |
+
except (ValueError, ImportError):
|
| 60 |
+
pass
|
| 61 |
+
|
| 62 |
+
self.flash_attn = False
|
| 63 |
+
return self._auto_class().from_pretrained(source, **common_kw)
|
| 64 |
+
|
| 65 |
+
@staticmethod
|
| 66 |
+
@abstractmethod
|
| 67 |
+
def _auto_class():
|
| 68 |
+
"""Return the AutoModel class to use (AutoModel or AutoModelForCausalLM)."""
|
| 69 |
+
|
| 70 |
+
_flash_attn_impls: Tuple[str, ...] = ('flash_attention_2',)
|
| 71 |
+
|
| 72 |
+
# -- PEFT / LoRA ----------------------------------------------------
|
| 73 |
+
|
| 74 |
+
@abstractmethod
|
| 75 |
+
def get_lora_config(self, lora_rank: int, lora_alpha: int,
|
| 76 |
+
lora_dropout: float = 0.0):
|
| 77 |
+
"""Return a ``peft.LoraConfig`` appropriate for this backbone."""
|
| 78 |
+
|
| 79 |
+
# -- attention mask --------------------------------------------------
|
| 80 |
+
|
| 81 |
+
@abstractmethod
|
| 82 |
+
def needs_4d_mask(self) -> bool:
|
| 83 |
+
"""Whether the backbone expects a 4D ``[B,1,L,L]`` attention mask.
|
| 84 |
+
|
| 85 |
+
If False, the backbone handles bidirectional attention internally
|
| 86 |
+
and expects a standard 2D ``[B,L]`` padding mask.
|
| 87 |
+
"""
|
| 88 |
+
|
| 89 |
+
# -- hidden state extraction -----------------------------------------
|
| 90 |
+
|
| 91 |
+
def register_hidden_hook(self, backbone: nn.Module,
|
| 92 |
+
ref_dict: Dict[str, torch.Tensor]) -> bool:
|
| 93 |
+
"""Register a forward hook on the output projection to capture the
|
| 94 |
+
last hidden state without ``output_hidden_states=True``.
|
| 95 |
+
|
| 96 |
+
Returns True if a hook was registered, False otherwise (in which
|
| 97 |
+
case the caller should fall back to ``output_hidden_states``).
|
| 98 |
+
"""
|
| 99 |
+
return False # default: no hook, use output_hidden_states
|
| 100 |
+
|
| 101 |
+
# -- gradient checkpointing ------------------------------------------
|
| 102 |
+
|
| 103 |
+
def enable_gradient_checkpointing(self, backbone: nn.Module, **kwargs):
|
| 104 |
+
"""Enable gradient checkpointing. Override for models that don't
|
| 105 |
+
support it."""
|
| 106 |
+
backbone.gradient_checkpointing_enable(**kwargs)
|
| 107 |
+
logger.info("Gradient checkpointing enabled")
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
# ---------------------------------------------------------------------------
|
| 111 |
+
# Hook helpers (shared across adapters)
|
| 112 |
+
# ---------------------------------------------------------------------------
|
| 113 |
+
|
| 114 |
+
def _is_linear(mod: nn.Module) -> bool:
|
| 115 |
+
"""Check if a module is a Linear layer (plain or LoRA-wrapped)."""
|
| 116 |
+
if isinstance(mod, nn.Linear):
|
| 117 |
+
return True
|
| 118 |
+
# PEFT LoRA wraps nn.Linear in peft.tuners.lora.layer.Linear which is
|
| 119 |
+
# NOT a subclass of nn.Linear, but has a base_layer that is.
|
| 120 |
+
if hasattr(mod, 'base_layer') and isinstance(mod.base_layer, nn.Linear):
|
| 121 |
+
return True
|
| 122 |
+
return False
|
| 123 |
+
|
| 124 |
+
|
| 125 |
+
def _hook_on_module(backbone: nn.Module, ref_dict: Dict,
|
| 126 |
+
target_name: str, skip_if_contains: Optional[str] = None,
|
| 127 |
+
adapter_name: str = '') -> bool:
|
| 128 |
+
"""Register a forward hook on the first Linear (or LoRA-wrapped Linear)
|
| 129 |
+
whose leaf name matches *target_name*. Optionally skip modules whose
|
| 130 |
+
full path contains *skip_if_contains* (e.g. 'blocks' to skip per-layer
|
| 131 |
+
ff_out).
|
| 132 |
+
"""
|
| 133 |
+
for name, mod in backbone.named_modules():
|
| 134 |
+
leaf = name.split('.')[-1]
|
| 135 |
+
if leaf == target_name and _is_linear(mod):
|
| 136 |
+
if skip_if_contains and skip_if_contains in name:
|
| 137 |
+
continue
|
| 138 |
+
mod.register_forward_hook(
|
| 139 |
+
lambda m, inp, out, r=ref_dict: r.update({'h': inp[0]})
|
| 140 |
+
)
|
| 141 |
+
logger.info(f"{adapter_name}: hook on '{name}'")
|
| 142 |
+
return True
|
| 143 |
+
return False
|
| 144 |
+
|
| 145 |
+
|
| 146 |
+
# ---------------------------------------------------------------------------
|
| 147 |
+
# Dream
|
| 148 |
+
# ---------------------------------------------------------------------------
|
| 149 |
+
|
| 150 |
+
class DreamAdapter(BackboneAdapter):
|
| 151 |
+
model_type = 'dream'
|
| 152 |
+
mask_token_id = 151666 # <|mask|> — Dream-org/Dream-v0-Instruct-7B
|
| 153 |
+
hub_model_name = 'Dream-org/Dream-v0-Instruct-7B'
|
| 154 |
+
|
| 155 |
+
@staticmethod
|
| 156 |
+
def _auto_class():
|
| 157 |
+
from transformers import AutoModel
|
| 158 |
+
return AutoModel
|
| 159 |
+
|
| 160 |
+
def get_lora_config(self, lora_rank, lora_alpha, lora_dropout=0.0):
|
| 161 |
+
from peft import LoraConfig, TaskType
|
| 162 |
+
# Dream is loaded via AutoModel (not AutoModelForCausalLM), so
|
| 163 |
+
# FEATURE_EXTRACTION avoids PeftModelForCausalLM which would
|
| 164 |
+
# require prepare_inputs_for_generation (Dream lacks this).
|
| 165 |
+
return LoraConfig(
|
| 166 |
+
r=lora_rank, lora_alpha=lora_alpha, lora_dropout=lora_dropout,
|
| 167 |
+
target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
|
| 168 |
+
"gate_proj", "up_proj", "down_proj"],
|
| 169 |
+
task_type=TaskType.FEATURE_EXTRACTION,
|
| 170 |
+
bias="none",
|
| 171 |
+
)
|
| 172 |
+
|
| 173 |
+
def needs_4d_mask(self) -> bool:
|
| 174 |
+
# Standard HF Qwen2 attention — needs 4D to enforce bidirectional.
|
| 175 |
+
return True
|
| 176 |
+
|
| 177 |
+
def register_hidden_hook(self, backbone, ref_dict):
|
| 178 |
+
return _hook_on_module(backbone, ref_dict, 'lm_head',
|
| 179 |
+
adapter_name='dream')
|
| 180 |
+
|
| 181 |
+
|
| 182 |
+
# ---------------------------------------------------------------------------
|
| 183 |
+
# LLaDA v1 (GSAI-ML/LLaDA-8B-Instruct)
|
| 184 |
+
# ---------------------------------------------------------------------------
|
| 185 |
+
|
| 186 |
+
class LLaDA1Adapter(BackboneAdapter):
|
| 187 |
+
model_type = 'llada1'
|
| 188 |
+
mask_token_id = 126336 # <|mdm_mask|> — GSAI-ML/LLaDA-8B-Instruct
|
| 189 |
+
hub_model_name = 'GSAI-ML/LLaDA-8B-Instruct'
|
| 190 |
+
_flash_attn_impls = ('flash_attention_3', 'flash_attention_2')
|
| 191 |
+
|
| 192 |
+
@staticmethod
|
| 193 |
+
def _auto_class():
|
| 194 |
+
from transformers import AutoModelForCausalLM
|
| 195 |
+
return AutoModelForCausalLM
|
| 196 |
+
|
| 197 |
+
def get_lora_config(self, lora_rank, lora_alpha, lora_dropout=0.0):
|
| 198 |
+
from peft import LoraConfig, TaskType
|
| 199 |
+
# LLaDA1 custom arch uses different names than standard LLaMA:
|
| 200 |
+
# attn_out (not o_proj), ff_proj (not gate_proj), ff_out (not down_proj)
|
| 201 |
+
return LoraConfig(
|
| 202 |
+
r=lora_rank, lora_alpha=lora_alpha, lora_dropout=lora_dropout,
|
| 203 |
+
target_modules=["q_proj", "k_proj", "v_proj", "attn_out",
|
| 204 |
+
"ff_proj", "up_proj", "ff_out"],
|
| 205 |
+
task_type=TaskType.CAUSAL_LM,
|
| 206 |
+
bias="none",
|
| 207 |
+
)
|
| 208 |
+
|
| 209 |
+
def needs_4d_mask(self) -> bool:
|
| 210 |
+
# Custom code handles bidirectional attention internally — always 2D.
|
| 211 |
+
return False
|
| 212 |
+
|
| 213 |
+
def register_hidden_hook(self, backbone, ref_dict):
|
| 214 |
+
# LLaDA1 has ff_out per-block (blocks.X.ff_out = FFN output) AND at
|
| 215 |
+
# the model level (transformer.ff_out = output projection to vocab).
|
| 216 |
+
# We need the model-level one; skip per-block ones.
|
| 217 |
+
return _hook_on_module(backbone, ref_dict, 'ff_out',
|
| 218 |
+
skip_if_contains='blocks',
|
| 219 |
+
adapter_name='llada1')
|
| 220 |
+
|
| 221 |
+
def enable_gradient_checkpointing(self, backbone, **kwargs):
|
| 222 |
+
# LLaDA1's LLaDAModelLM doesn't support HF gradient_checkpointing_enable.
|
| 223 |
+
# Manually wrap each transformer block with torch checkpoint.
|
| 224 |
+
from torch.utils.checkpoint import checkpoint as ckpt_fn
|
| 225 |
+
|
| 226 |
+
# Find the blocks ModuleList through the PEFT wrapper
|
| 227 |
+
blocks = None
|
| 228 |
+
for name, mod in backbone.named_modules():
|
| 229 |
+
if name.endswith('.blocks') and isinstance(mod, nn.ModuleList):
|
| 230 |
+
blocks = mod
|
| 231 |
+
break
|
| 232 |
+
|
| 233 |
+
if blocks is None:
|
| 234 |
+
logger.warning("LLaDA1: couldn't find transformer blocks — "
|
| 235 |
+
"skipping gradient checkpointing")
|
| 236 |
+
return
|
| 237 |
+
|
| 238 |
+
for block in blocks:
|
| 239 |
+
orig_forward = block.forward
|
| 240 |
+
|
| 241 |
+
def _make_ckpt(fwd):
|
| 242 |
+
def _ckpt_forward(*args, **kwargs):
|
| 243 |
+
if not torch.is_grad_enabled():
|
| 244 |
+
return fwd(*args, **kwargs)
|
| 245 |
+
return ckpt_fn(fwd, *args, use_reentrant=False, **kwargs)
|
| 246 |
+
return _ckpt_forward
|
| 247 |
+
|
| 248 |
+
block.forward = _make_ckpt(orig_forward)
|
| 249 |
+
|
| 250 |
+
logger.info(f"LLaDA1: manual gradient checkpointing on {len(blocks)} blocks")
|
| 251 |
+
|
| 252 |
+
|
| 253 |
+
# ---------------------------------------------------------------------------
|
| 254 |
+
# LLaDA v1.5 (GSAI-ML/LLaDA-1.5) — same architecture as v1
|
| 255 |
+
# ---------------------------------------------------------------------------
|
| 256 |
+
|
| 257 |
+
class LLaDA15Adapter(LLaDA1Adapter):
|
| 258 |
+
model_type = 'llada15'
|
| 259 |
+
mask_token_id = 126336 # <|mdm_mask|> — same tokenizer as v1
|
| 260 |
+
hub_model_name = 'GSAI-ML/LLaDA-1.5'
|
| 261 |
+
|
| 262 |
+
def register_hidden_hook(self, backbone, ref_dict):
|
| 263 |
+
return _hook_on_module(backbone, ref_dict, 'ff_out',
|
| 264 |
+
skip_if_contains='blocks',
|
| 265 |
+
adapter_name='llada15')
|
| 266 |
+
|
| 267 |
+
|
| 268 |
+
|
| 269 |
+
# ---------------------------------------------------------------------------
|
| 270 |
+
# LLaDA v2 (inclusionAI/LLaDA2.0-mini)
|
| 271 |
+
# ---------------------------------------------------------------------------
|
| 272 |
+
|
| 273 |
+
class LLaDA2Adapter(BackboneAdapter):
|
| 274 |
+
model_type = 'llada2'
|
| 275 |
+
mask_token_id = 156895 # <|mask|> — inclusionAI/LLaDA2.0-mini
|
| 276 |
+
hub_model_name = 'inclusionAI/LLaDA2.0-mini'
|
| 277 |
+
_flash_attn_impls = ('flash_attention_3', 'flash_attention_2')
|
| 278 |
+
|
| 279 |
+
@staticmethod
|
| 280 |
+
def _auto_class():
|
| 281 |
+
from transformers import AutoModelForCausalLM
|
| 282 |
+
return AutoModelForCausalLM
|
| 283 |
+
|
| 284 |
+
def get_lora_config(self, lora_rank, lora_alpha, lora_dropout=0.0):
|
| 285 |
+
from peft import LoraConfig, TaskType
|
| 286 |
+
# LLaDA2 uses fused QKV ("query_key_value") and "dense" for attn
|
| 287 |
+
# output. Skip MoE expert FFN layers to avoid multiplying params.
|
| 288 |
+
return LoraConfig(
|
| 289 |
+
r=lora_rank, lora_alpha=lora_alpha, lora_dropout=lora_dropout,
|
| 290 |
+
target_modules=[
|
| 291 |
+
"query_key_value", "dense",
|
| 292 |
+
"mlp.shared_experts.gate_proj",
|
| 293 |
+
"mlp.shared_experts.up_proj",
|
| 294 |
+
"mlp.shared_experts.down_proj",
|
| 295 |
+
],
|
| 296 |
+
task_type=TaskType.CAUSAL_LM,
|
| 297 |
+
bias="none",
|
| 298 |
+
)
|
| 299 |
+
|
| 300 |
+
def needs_4d_mask(self) -> bool:
|
| 301 |
+
# Standard HF causal model — needs 4D to override causal attention,
|
| 302 |
+
# unless flash attention handles masking itself.
|
| 303 |
+
return not self.flash_attn
|
| 304 |
+
|
| 305 |
+
def register_hidden_hook(self, backbone, ref_dict):
|
| 306 |
+
return _hook_on_module(backbone, ref_dict, 'lm_head',
|
| 307 |
+
adapter_name='llada2')
|
| 308 |
+
|
| 309 |
+
|
| 310 |
+
# ---------------------------------------------------------------------------
|
| 311 |
+
# Registry
|
| 312 |
+
# ---------------------------------------------------------------------------
|
| 313 |
+
|
| 314 |
+
ADAPTER_REGISTRY: Dict[str, type] = {
|
| 315 |
+
'dream': DreamAdapter,
|
| 316 |
+
'llada1': LLaDA1Adapter,
|
| 317 |
+
'llada15': LLaDA15Adapter,
|
| 318 |
+
'llada2': LLaDA2Adapter,
|
| 319 |
+
}
|
| 320 |
+
|
| 321 |
+
|
| 322 |
+
def get_adapter(model_type: str) -> BackboneAdapter:
|
| 323 |
+
"""Create a BackboneAdapter for the given model_type."""
|
| 324 |
+
cls = ADAPTER_REGISTRY.get(model_type)
|
| 325 |
+
if cls is None:
|
| 326 |
+
raise ValueError(
|
| 327 |
+
f"Unknown model_type: {model_type!r}. "
|
| 328 |
+
f"Available: {sorted(ADAPTER_REGISTRY.keys())}")
|
| 329 |
+
return cls()
|
chat_template.jinja
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{%- if tools %}
|
| 2 |
+
{{- '<|im_start|>system\n' }}
|
| 3 |
+
{%- if messages[0]['role'] == 'system' %}
|
| 4 |
+
{{- messages[0]['content'] }}
|
| 5 |
+
{%- else %}
|
| 6 |
+
{{- 'You are a helpful assistant.' }}
|
| 7 |
+
{%- endif %}
|
| 8 |
+
{{- "\n\n# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within <tools></tools> XML tags:\n<tools>" }}
|
| 9 |
+
{%- for tool in tools %}
|
| 10 |
+
{{- "\n" }}
|
| 11 |
+
{{- tool | tojson }}
|
| 12 |
+
{%- endfor %}
|
| 13 |
+
{{- "\n</tools>\n\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n<tool_call>\n{\"name\": <function-name>, \"arguments\": <args-json-object>}\n</tool_call><|im_end|>\n" }}
|
| 14 |
+
{%- else %}
|
| 15 |
+
{%- if messages[0]['role'] == 'system' %}
|
| 16 |
+
{{- '<|im_start|>system\n' + messages[0]['content'] + '<|im_end|>\n' }}
|
| 17 |
+
{%- else %}
|
| 18 |
+
{{- '<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n' }}
|
| 19 |
+
{%- endif %}
|
| 20 |
+
{%- endif %}
|
| 21 |
+
{%- for message in messages %}
|
| 22 |
+
{%- if (message.role == "user") or (message.role == "system" and not loop.first) or (message.role == "assistant" and not message.tool_calls) %}
|
| 23 |
+
{{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>' + '\n' }}
|
| 24 |
+
{%- elif message.role == "assistant" %}
|
| 25 |
+
{{- '<|im_start|>' + message.role }}
|
| 26 |
+
{%- if message.content %}
|
| 27 |
+
{{- '\n' + message.content }}
|
| 28 |
+
{%- endif %}
|
| 29 |
+
{%- for tool_call in message.tool_calls %}
|
| 30 |
+
{%- if tool_call.function is defined %}
|
| 31 |
+
{%- set tool_call = tool_call.function %}
|
| 32 |
+
{%- endif %}
|
| 33 |
+
{{- '\n<tool_call>\n{"name": "' }}
|
| 34 |
+
{{- tool_call.name }}
|
| 35 |
+
{{- '", "arguments": ' }}
|
| 36 |
+
{{- tool_call.arguments | tojson }}
|
| 37 |
+
{{- '}\n</tool_call>' }}
|
| 38 |
+
{%- endfor %}
|
| 39 |
+
{{- '<|im_end|>\n' }}
|
| 40 |
+
{%- elif message.role == "tool" %}
|
| 41 |
+
{%- if (loop.index0 == 0) or (messages[loop.index0 - 1].role != "tool") %}
|
| 42 |
+
{{- '<|im_start|>user' }}
|
| 43 |
+
{%- endif %}
|
| 44 |
+
{{- '\n<tool_response>\n' }}
|
| 45 |
+
{{- message.content }}
|
| 46 |
+
{{- '\n</tool_response>' }}
|
| 47 |
+
{%- if loop.last or (messages[loop.index0 + 1].role != "tool") %}
|
| 48 |
+
{{- '<|im_end|>\n' }}
|
| 49 |
+
{%- endif %}
|
| 50 |
+
{%- endif %}
|
| 51 |
+
{%- endfor %}
|
| 52 |
+
{%- if add_generation_prompt %}
|
| 53 |
+
{{- '<|im_start|>assistant\n' }}
|
| 54 |
+
{%- endif %}
|
config.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"model_type": "diffretriever",
|
| 3 |
+
"architectures": [
|
| 4 |
+
"DiffRetrieverModel"
|
| 5 |
+
],
|
| 6 |
+
"auto_map": {
|
| 7 |
+
"AutoConfig": "configuration_diffretriever.DiffRetrieverConfig",
|
| 8 |
+
"AutoModel": "modeling_diffretriever.DiffRetrieverModel"
|
| 9 |
+
},
|
| 10 |
+
"base_model": "Dream-org/Dream-v0-Instruct-7B",
|
| 11 |
+
"backbone_type": "dream",
|
| 12 |
+
"mode": "multi",
|
| 13 |
+
"k_q": 4,
|
| 14 |
+
"k_p": 16
|
| 15 |
+
}
|
configuration_diffretriever.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""HuggingFace config for DiffRetriever `trust_remote_code` loading.
|
| 2 |
+
|
| 3 |
+
A thin `PretrainedConfig` so that
|
| 4 |
+
|
| 5 |
+
AutoModel.from_pretrained("ielabgroup/diffretriever-...", trust_remote_code=True)
|
| 6 |
+
|
| 7 |
+
can route to `DiffRetrieverModel` via the repo's `config.json` `auto_map`.
|
| 8 |
+
|
| 9 |
+
The real retrieval configuration (prompt token ids, K_q/K_p, temperature,
|
| 10 |
+
sparse weight, ...) lives in `retriever_config.json` and is read by
|
| 11 |
+
`TrainableDiffusionRetriever.load()`. The fields here are informational only
|
| 12 |
+
(they show up in the Hub config viewer) and are not required for loading.
|
| 13 |
+
|
| 14 |
+
This file is shipped *inside each model repo* — keep it dependency-light.
|
| 15 |
+
"""
|
| 16 |
+
from transformers import PretrainedConfig
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
class DiffRetrieverConfig(PretrainedConfig):
|
| 20 |
+
model_type = "diffretriever"
|
| 21 |
+
|
| 22 |
+
def __init__(
|
| 23 |
+
self,
|
| 24 |
+
base_model: str | None = None,
|
| 25 |
+
backbone_type: str | None = None,
|
| 26 |
+
mode: str = "single",
|
| 27 |
+
k_q: int = 1,
|
| 28 |
+
k_p: int = 1,
|
| 29 |
+
**kwargs,
|
| 30 |
+
):
|
| 31 |
+
self.base_model = base_model # e.g. "Dream-org/Dream-v0-Instruct-7B"
|
| 32 |
+
self.backbone_type = backbone_type # e.g. "dream" / "llada"
|
| 33 |
+
self.mode = mode # "single" | "multi"
|
| 34 |
+
self.k_q = k_q
|
| 35 |
+
self.k_p = k_p
|
| 36 |
+
super().__init__(**kwargs)
|
diffretriever_trainable.py
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
merges.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
modeling_diffretriever.py
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""HuggingFace `trust_remote_code` wrapper for DiffRetriever.
|
| 2 |
+
|
| 3 |
+
Lets a released checkpoint load with a single call:
|
| 4 |
+
|
| 5 |
+
from transformers import AutoModel
|
| 6 |
+
model = AutoModel.from_pretrained(
|
| 7 |
+
"ielabgroup/diffretriever-dream-7b-single", trust_remote_code=True)
|
| 8 |
+
model.eval()
|
| 9 |
+
ids, mask = model.tokenize(["a query"], is_query=True)
|
| 10 |
+
out = model.encode(ids, mask, is_query=True) # {'repr_hidden', ...}
|
| 11 |
+
|
| 12 |
+
It wraps `TrainableDiffusionRetriever` (shipped in the same repo) and exposes
|
| 13 |
+
`.tokenize()` / `.encode()` / `.backbone`. The base diffusion backbone
|
| 14 |
+
(Dream / LLaDA / ...) is pulled from its own Hub repo at load time; this repo
|
| 15 |
+
carries only the LoRA adapter + tokenizer + retriever_config.json + this code.
|
| 16 |
+
|
| 17 |
+
Shipped inside each model repo, so keep the import surface minimal.
|
| 18 |
+
"""
|
| 19 |
+
from __future__ import annotations
|
| 20 |
+
|
| 21 |
+
import os
|
| 22 |
+
import shutil
|
| 23 |
+
import tempfile
|
| 24 |
+
|
| 25 |
+
import torch # noqa: F401 (used by the wrapped retriever; keep import explicit)
|
| 26 |
+
from transformers import PreTrainedModel
|
| 27 |
+
|
| 28 |
+
from .configuration_diffretriever import DiffRetrieverConfig
|
| 29 |
+
from .diffretriever_trainable import TrainableDiffusionRetriever
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
class DiffRetrieverModel(PreTrainedModel):
|
| 33 |
+
config_class = DiffRetrieverConfig
|
| 34 |
+
|
| 35 |
+
def __init__(self, config: DiffRetrieverConfig, retriever=None):
|
| 36 |
+
super().__init__(config)
|
| 37 |
+
# Registered as a submodule so .to()/.eval()/.parameters() recurse into it.
|
| 38 |
+
self.retriever = retriever
|
| 39 |
+
|
| 40 |
+
# ── Loading ──────────────────────────────────────────────────────────────
|
| 41 |
+
@classmethod
|
| 42 |
+
def from_pretrained(cls, pretrained_model_name_or_path, *model_args, **kwargs):
|
| 43 |
+
# We do NOT call super().from_pretrained: the checkpoint is a LoRA
|
| 44 |
+
# adapter that must be attached on top of a base backbone pulled from a
|
| 45 |
+
# different Hub repo, which TrainableDiffusionRetriever.load() handles.
|
| 46 |
+
kwargs.pop("trust_remote_code", None)
|
| 47 |
+
config = kwargs.pop("config", None)
|
| 48 |
+
|
| 49 |
+
path = str(pretrained_model_name_or_path)
|
| 50 |
+
if not os.path.isdir(path):
|
| 51 |
+
from huggingface_hub import snapshot_download
|
| 52 |
+
dl = {k: kwargs[k] for k in
|
| 53 |
+
("cache_dir", "revision", "token", "local_files_only", "proxies")
|
| 54 |
+
if k in kwargs and kwargs[k] is not None}
|
| 55 |
+
path = snapshot_download(path, **dl)
|
| 56 |
+
|
| 57 |
+
# Build a temp view of the snapshot for TrainableDiffusionRetriever.load:
|
| 58 |
+
# - DROP config.json: load() detects a released adapter repo only when
|
| 59 |
+
# adapter_config.json is present AND config.json is absent; this repo
|
| 60 |
+
# ships a config.json for the auto_map.
|
| 61 |
+
# - FLATTEN the adapter/ subdir into the root: the LoRA adapter is
|
| 62 |
+
# stored under adapter/ (not the repo root) on purpose, so that
|
| 63 |
+
# transformers' PEFT auto-loader does NOT hijack AutoModel and load
|
| 64 |
+
# the base model directly instead of this wrapper. load() still needs
|
| 65 |
+
# adapter_config.json at the top level, so we link it up here.
|
| 66 |
+
tmp = tempfile.mkdtemp(prefix="diffretriever_")
|
| 67 |
+
|
| 68 |
+
def _link(src, dst):
|
| 69 |
+
if os.path.isfile(src) and not os.path.exists(dst):
|
| 70 |
+
os.symlink(os.path.abspath(src), dst)
|
| 71 |
+
|
| 72 |
+
try:
|
| 73 |
+
for fn in os.listdir(path):
|
| 74 |
+
if fn == "config.json":
|
| 75 |
+
continue
|
| 76 |
+
_link(os.path.join(path, fn), os.path.join(tmp, fn))
|
| 77 |
+
adapter_dir = os.path.join(path, "adapter")
|
| 78 |
+
if os.path.isdir(adapter_dir):
|
| 79 |
+
for fn in os.listdir(adapter_dir):
|
| 80 |
+
_link(os.path.join(adapter_dir, fn), os.path.join(tmp, fn))
|
| 81 |
+
retriever = TrainableDiffusionRetriever.load(tmp)
|
| 82 |
+
finally:
|
| 83 |
+
shutil.rmtree(tmp, ignore_errors=True)
|
| 84 |
+
|
| 85 |
+
if config is None:
|
| 86 |
+
config = DiffRetrieverConfig(
|
| 87 |
+
base_model=getattr(retriever, "model_name", None),
|
| 88 |
+
backbone_type=getattr(retriever, "model_type", None),
|
| 89 |
+
)
|
| 90 |
+
return cls(config, retriever=retriever)
|
| 91 |
+
|
| 92 |
+
# ── Retrieval API (delegates to the wrapped retriever) ─────────────────────
|
| 93 |
+
@property
|
| 94 |
+
def backbone(self):
|
| 95 |
+
return self.retriever.backbone
|
| 96 |
+
|
| 97 |
+
def tokenize(self, *args, **kwargs):
|
| 98 |
+
return self.retriever.tokenize(*args, **kwargs)
|
| 99 |
+
|
| 100 |
+
def encode(self, *args, **kwargs):
|
| 101 |
+
return self.retriever.encode(*args, **kwargs)
|
| 102 |
+
|
| 103 |
+
def forward(self, *args, **kwargs):
|
| 104 |
+
return self.retriever(*args, **kwargs)
|
retriever_config.json
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"model_type": "dream",
|
| 3 |
+
"mask_token_id": 151666,
|
| 4 |
+
"hidden_size": 3584,
|
| 5 |
+
"max_length": 156,
|
| 6 |
+
"n_gen_tokens": 4,
|
| 7 |
+
"n_gen_q_tokens": 4,
|
| 8 |
+
"n_gen_p_tokens": 16,
|
| 9 |
+
"temperature": 0.01,
|
| 10 |
+
"flops_weight": 0.0,
|
| 11 |
+
"num_denoise_steps": 1,
|
| 12 |
+
"sparse_weight": 1.0,
|
| 13 |
+
"normalize": true,
|
| 14 |
+
"query_prefix_ids": [
|
| 15 |
+
151644,
|
| 16 |
+
8948,
|
| 17 |
+
198,
|
| 18 |
+
2610,
|
| 19 |
+
525,
|
| 20 |
+
458,
|
| 21 |
+
15235,
|
| 22 |
+
17847,
|
| 23 |
+
429,
|
| 24 |
+
646,
|
| 25 |
+
3535,
|
| 26 |
+
3738,
|
| 27 |
+
4128,
|
| 28 |
+
13,
|
| 29 |
+
151645,
|
| 30 |
+
198,
|
| 31 |
+
151644,
|
| 32 |
+
872,
|
| 33 |
+
198,
|
| 34 |
+
2859,
|
| 35 |
+
25,
|
| 36 |
+
330
|
| 37 |
+
],
|
| 38 |
+
"query_suffix_ids": [
|
| 39 |
+
3263,
|
| 40 |
+
5443,
|
| 41 |
+
264,
|
| 42 |
+
2421,
|
| 43 |
+
4244,
|
| 44 |
+
311,
|
| 45 |
+
4009,
|
| 46 |
+
279,
|
| 47 |
+
3239,
|
| 48 |
+
304,
|
| 49 |
+
264,
|
| 50 |
+
56370,
|
| 51 |
+
3383,
|
| 52 |
+
13,
|
| 53 |
+
7405,
|
| 54 |
+
2704,
|
| 55 |
+
697,
|
| 56 |
+
4244,
|
| 57 |
+
525,
|
| 58 |
+
304,
|
| 59 |
+
42047,
|
| 60 |
+
13,
|
| 61 |
+
151645,
|
| 62 |
+
198,
|
| 63 |
+
151644,
|
| 64 |
+
77091,
|
| 65 |
+
198,
|
| 66 |
+
785,
|
| 67 |
+
4244,
|
| 68 |
+
525,
|
| 69 |
+
25,
|
| 70 |
+
330
|
| 71 |
+
],
|
| 72 |
+
"passage_prefix_ids": [
|
| 73 |
+
151644,
|
| 74 |
+
8948,
|
| 75 |
+
198,
|
| 76 |
+
2610,
|
| 77 |
+
525,
|
| 78 |
+
458,
|
| 79 |
+
15235,
|
| 80 |
+
17847,
|
| 81 |
+
429,
|
| 82 |
+
646,
|
| 83 |
+
3535,
|
| 84 |
+
3738,
|
| 85 |
+
4128,
|
| 86 |
+
13,
|
| 87 |
+
151645,
|
| 88 |
+
198,
|
| 89 |
+
151644,
|
| 90 |
+
872,
|
| 91 |
+
198,
|
| 92 |
+
12187,
|
| 93 |
+
424,
|
| 94 |
+
25,
|
| 95 |
+
330
|
| 96 |
+
],
|
| 97 |
+
"passage_suffix_ids": [
|
| 98 |
+
3263,
|
| 99 |
+
5443,
|
| 100 |
+
264,
|
| 101 |
+
2421,
|
| 102 |
+
4244,
|
| 103 |
+
311,
|
| 104 |
+
4009,
|
| 105 |
+
279,
|
| 106 |
+
21085,
|
| 107 |
+
304,
|
| 108 |
+
264,
|
| 109 |
+
56370,
|
| 110 |
+
3383,
|
| 111 |
+
13,
|
| 112 |
+
7405,
|
| 113 |
+
2704,
|
| 114 |
+
697,
|
| 115 |
+
4244,
|
| 116 |
+
525,
|
| 117 |
+
304,
|
| 118 |
+
42047,
|
| 119 |
+
13,
|
| 120 |
+
151645,
|
| 121 |
+
198,
|
| 122 |
+
151644,
|
| 123 |
+
77091,
|
| 124 |
+
198,
|
| 125 |
+
785,
|
| 126 |
+
4244,
|
| 127 |
+
525,
|
| 128 |
+
25,
|
| 129 |
+
330
|
| 130 |
+
],
|
| 131 |
+
"lora_rank": 16,
|
| 132 |
+
"lora_alpha": 64,
|
| 133 |
+
"use_eos": false,
|
| 134 |
+
"n_tail": 3
|
| 135 |
+
}
|
sparse_utils.py
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Sparse representation utilities matching original PromptReps.
|
| 3 |
+
|
| 4 |
+
Reference: https://github.com/ielab/PromptReps
|
| 5 |
+
The original filters sparse logits by:
|
| 6 |
+
1. Word-tokenizing the text (lowercased) with NLTK
|
| 7 |
+
2. Removing stopwords and punctuation
|
| 8 |
+
3. Re-tokenizing each content word independently to get clean token IDs
|
| 9 |
+
4. Only keeping logits for those token IDs
|
| 10 |
+
"""
|
| 11 |
+
|
| 12 |
+
import torch
|
| 13 |
+
from typing import List, Set, Optional
|
| 14 |
+
import string
|
| 15 |
+
import logging
|
| 16 |
+
|
| 17 |
+
logger = logging.getLogger(__name__)
|
| 18 |
+
|
| 19 |
+
try:
|
| 20 |
+
from nltk import word_tokenize
|
| 21 |
+
from nltk.corpus import stopwords as _sw_corpus
|
| 22 |
+
STOPWORDS = set(_sw_corpus.words('english') + list(string.punctuation))
|
| 23 |
+
except LookupError:
|
| 24 |
+
import nltk
|
| 25 |
+
nltk.download('punkt_tab', quiet=True)
|
| 26 |
+
nltk.download('stopwords', quiet=True)
|
| 27 |
+
from nltk import word_tokenize
|
| 28 |
+
from nltk.corpus import stopwords as _sw_corpus
|
| 29 |
+
STOPWORDS = set(_sw_corpus.words('english') + list(string.punctuation))
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
def get_content_token_ids(texts: List[str], tokenizer) -> List[Set[int]]:
|
| 33 |
+
"""Extract content token IDs from texts (stopwords removed, word-level tokenization).
|
| 34 |
+
|
| 35 |
+
Matches original PromptReps get_valid_tokens_values:
|
| 36 |
+
1. word_tokenize(text.lower())
|
| 37 |
+
2. Remove stopwords + punctuation
|
| 38 |
+
3. tokenizer.encode(word) for each remaining word
|
| 39 |
+
|
| 40 |
+
Args:
|
| 41 |
+
texts: List of raw text strings.
|
| 42 |
+
tokenizer: HuggingFace tokenizer.
|
| 43 |
+
|
| 44 |
+
Returns:
|
| 45 |
+
List of sets of token IDs, one per text.
|
| 46 |
+
"""
|
| 47 |
+
all_token_ids = []
|
| 48 |
+
for text in texts:
|
| 49 |
+
words = [w for w in word_tokenize(text.lower())
|
| 50 |
+
if w not in STOPWORDS]
|
| 51 |
+
if words:
|
| 52 |
+
# Batch encode all words at once (much faster than per-word encode)
|
| 53 |
+
batch_ids = tokenizer(words, add_special_tokens=False)['input_ids']
|
| 54 |
+
token_ids = set()
|
| 55 |
+
for ids in batch_ids:
|
| 56 |
+
token_ids.update(ids)
|
| 57 |
+
else:
|
| 58 |
+
token_ids = set()
|
| 59 |
+
all_token_ids.append(token_ids)
|
| 60 |
+
return all_token_ids
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def filter_sparse(
|
| 64 |
+
sparse: torch.Tensor,
|
| 65 |
+
content_token_ids: List[Set[int]],
|
| 66 |
+
exclude_ids: Optional[List[int]] = None,
|
| 67 |
+
) -> torch.Tensor:
|
| 68 |
+
"""Filter sparse logits to only keep content tokens.
|
| 69 |
+
|
| 70 |
+
Args:
|
| 71 |
+
sparse: [batch, vocab] sparse logit tensor.
|
| 72 |
+
content_token_ids: List of sets of valid token IDs per example.
|
| 73 |
+
exclude_ids: Token IDs to always exclude (e.g., MASK token).
|
| 74 |
+
|
| 75 |
+
Returns:
|
| 76 |
+
Filtered sparse tensor (same shape, non-content entries zeroed).
|
| 77 |
+
"""
|
| 78 |
+
# Build (row, col) index pairs for all content tokens across batch
|
| 79 |
+
rows, cols = [], []
|
| 80 |
+
for i in range(sparse.size(0)):
|
| 81 |
+
if content_token_ids[i]:
|
| 82 |
+
ids = list(content_token_ids[i])
|
| 83 |
+
rows.extend([i] * len(ids))
|
| 84 |
+
cols.extend(ids)
|
| 85 |
+
if rows:
|
| 86 |
+
mask = torch.zeros_like(sparse)
|
| 87 |
+
mask[rows, cols] = 1.0
|
| 88 |
+
else:
|
| 89 |
+
mask = torch.zeros_like(sparse)
|
| 90 |
+
if exclude_ids:
|
| 91 |
+
for eid in exclude_ids:
|
| 92 |
+
mask[:, eid] = 0.0
|
| 93 |
+
return sparse * mask
|
special_tokens_map.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"additional_special_tokens": [
|
| 3 |
+
"<|beginoftext|>",
|
| 4 |
+
"<|mask|>"
|
| 5 |
+
],
|
| 6 |
+
"bos_token": {
|
| 7 |
+
"content": "<|beginoftext|>",
|
| 8 |
+
"lstrip": false,
|
| 9 |
+
"normalized": false,
|
| 10 |
+
"rstrip": false,
|
| 11 |
+
"single_word": false
|
| 12 |
+
},
|
| 13 |
+
"eos_token": {
|
| 14 |
+
"content": "<|endoftext|>",
|
| 15 |
+
"lstrip": false,
|
| 16 |
+
"normalized": false,
|
| 17 |
+
"rstrip": false,
|
| 18 |
+
"single_word": false
|
| 19 |
+
},
|
| 20 |
+
"mask_token": {
|
| 21 |
+
"content": "<|mask|>",
|
| 22 |
+
"lstrip": false,
|
| 23 |
+
"normalized": false,
|
| 24 |
+
"rstrip": false,
|
| 25 |
+
"single_word": false
|
| 26 |
+
},
|
| 27 |
+
"pad_token": {
|
| 28 |
+
"content": "<|endoftext|>",
|
| 29 |
+
"lstrip": false,
|
| 30 |
+
"normalized": false,
|
| 31 |
+
"rstrip": false,
|
| 32 |
+
"single_word": false
|
| 33 |
+
}
|
| 34 |
+
}
|
tokenization_dream.py
ADDED
|
@@ -0,0 +1,340 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# coding=utf-8
|
| 2 |
+
# Copyright 2024 The Dream team, HKUNLP Group and The HuggingFace Inc. team. All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# This code is based on Qwen's implementations in this library.
|
| 5 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 6 |
+
# you may not use this file except in compliance with the License.
|
| 7 |
+
# You may obtain a copy of the License at
|
| 8 |
+
#
|
| 9 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 10 |
+
#
|
| 11 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 12 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 13 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 14 |
+
# See the License for the specific language governing permissions and
|
| 15 |
+
# limitations under the License.
|
| 16 |
+
"""Tokenization classes for Dream."""
|
| 17 |
+
|
| 18 |
+
import json
|
| 19 |
+
import os
|
| 20 |
+
import unicodedata
|
| 21 |
+
from functools import lru_cache
|
| 22 |
+
from typing import Optional, Tuple
|
| 23 |
+
|
| 24 |
+
import regex as re
|
| 25 |
+
|
| 26 |
+
from transformers.tokenization_utils import AddedToken, PreTrainedTokenizer
|
| 27 |
+
from transformers.utils import logging
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
logger = logging.get_logger(__name__)
|
| 31 |
+
|
| 32 |
+
VOCAB_FILES_NAMES = {
|
| 33 |
+
"vocab_file": "vocab.json",
|
| 34 |
+
"merges_file": "merges.txt",
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
MAX_MODEL_INPUT_SIZES = {"dream/dream-tokenizer": 32768}
|
| 39 |
+
|
| 40 |
+
PRETOKENIZE_REGEX = r"""(?i:'s|'t|'re|'ve|'m|'ll|'d)|[^\r\n\p{L}\p{N}]?\p{L}+|\p{N}| ?[^\s\p{L}\p{N}]+[\r\n]*|\s*[\r\n]+|\s+(?!\S)|\s+"""
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
@lru_cache()
|
| 44 |
+
# Copied from transformers.models.gpt2.tokenization_gpt2.bytes_to_unicode
|
| 45 |
+
def bytes_to_unicode():
|
| 46 |
+
"""
|
| 47 |
+
Returns list of utf-8 byte and a mapping to unicode strings. We specifically avoids mapping to whitespace/control
|
| 48 |
+
characters the bpe code barfs on.
|
| 49 |
+
|
| 50 |
+
The reversible bpe codes work on unicode strings. This means you need a large # of unicode characters in your vocab
|
| 51 |
+
if you want to avoid UNKs. When you're at something like a 10B token dataset you end up needing around 5K for
|
| 52 |
+
decent coverage. This is a significant percentage of your normal, say, 32K bpe vocab. To avoid that, we want lookup
|
| 53 |
+
tables between utf-8 bytes and unicode strings.
|
| 54 |
+
"""
|
| 55 |
+
bs = (
|
| 56 |
+
list(range(ord("!"), ord("~") + 1)) + list(range(ord("¡"), ord("¬") + 1)) + list(range(ord("®"), ord("ÿ") + 1))
|
| 57 |
+
)
|
| 58 |
+
cs = bs[:]
|
| 59 |
+
n = 0
|
| 60 |
+
for b in range(2**8):
|
| 61 |
+
if b not in bs:
|
| 62 |
+
bs.append(b)
|
| 63 |
+
cs.append(2**8 + n)
|
| 64 |
+
n += 1
|
| 65 |
+
cs = [chr(n) for n in cs]
|
| 66 |
+
return dict(zip(bs, cs))
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
# Copied from transformers.models.gpt2.tokenization_gpt2.get_pairs
|
| 70 |
+
def get_pairs(word):
|
| 71 |
+
"""
|
| 72 |
+
Return set of symbol pairs in a word.
|
| 73 |
+
|
| 74 |
+
Word is represented as tuple of symbols (symbols being variable-length strings).
|
| 75 |
+
"""
|
| 76 |
+
pairs = set()
|
| 77 |
+
prev_char = word[0]
|
| 78 |
+
for char in word[1:]:
|
| 79 |
+
pairs.add((prev_char, char))
|
| 80 |
+
prev_char = char
|
| 81 |
+
return pairs
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
class DreamTokenizer(PreTrainedTokenizer):
|
| 85 |
+
"""
|
| 86 |
+
Construct a Dream tokenizer. Based on byte-level Byte-Pair-Encoding.
|
| 87 |
+
|
| 88 |
+
Same with GPT2Tokenizer, this tokenizer has been trained to treat spaces like parts of the tokens so a word will
|
| 89 |
+
be encoded differently whether it is at the beginning of the sentence (without space) or not:
|
| 90 |
+
|
| 91 |
+
```python
|
| 92 |
+
>>> from transformers import AutoTokenizer
|
| 93 |
+
|
| 94 |
+
>>> tokenizer = AutoTokenizer.from_pretrained("Dream-org/Dream-v0-Base-7B", trust_remote_code=True)
|
| 95 |
+
>>> tokenizer("Hello world")["input_ids"]
|
| 96 |
+
[9707, 1879]
|
| 97 |
+
|
| 98 |
+
>>> tokenizer(" Hello world")["input_ids"]
|
| 99 |
+
[21927, 1879]
|
| 100 |
+
```
|
| 101 |
+
This is expected.
|
| 102 |
+
|
| 103 |
+
You should not use GPT2Tokenizer instead, because of the different pretokenization rules.
|
| 104 |
+
|
| 105 |
+
This tokenizer inherits from [`PreTrainedTokenizer`] which contains most of the main methods. Users should refer to
|
| 106 |
+
this superclass for more information regarding those methods.
|
| 107 |
+
|
| 108 |
+
Args:
|
| 109 |
+
vocab_file (`str`):
|
| 110 |
+
Path to the vocabulary file.
|
| 111 |
+
merges_file (`str`):
|
| 112 |
+
Path to the merges file.
|
| 113 |
+
errors (`str`, *optional*, defaults to `"replace"`):
|
| 114 |
+
Paradigm to follow when decoding bytes to UTF-8. See
|
| 115 |
+
[bytes.decode](https://docs.python.org/3/library/stdtypes.html#bytes.decode) for more information.
|
| 116 |
+
unk_token (`str`, *optional*, defaults to `"<|endoftext|>"`):
|
| 117 |
+
The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this
|
| 118 |
+
token instead.
|
| 119 |
+
bos_token (`str`, *optional*):
|
| 120 |
+
The beginning of sequence token. Not applicable for this tokenizer.
|
| 121 |
+
eos_token (`str`, *optional*, defaults to `"<|endoftext|>"`):
|
| 122 |
+
The end of sequence token.
|
| 123 |
+
pad_token (`str`, *optional*, defaults to `"<|endoftext|>"`):
|
| 124 |
+
The token used for padding, for example when batching sequences of different lengths.
|
| 125 |
+
clean_up_tokenization_spaces (`bool`, *optional*, defaults to `False`):
|
| 126 |
+
Whether or not the model should cleanup the spaces that were added when splitting the input text during the
|
| 127 |
+
tokenization process. Not applicable to this tokenizer, since tokenization does not add spaces.
|
| 128 |
+
split_special_tokens (`bool`, *optional*, defaults to `False`):
|
| 129 |
+
Whether or not the special tokens should be split during the tokenization process. The default behavior is
|
| 130 |
+
to not split special tokens. This means that if `<|endoftext|>` is the `eos_token`, then `tokenizer.tokenize("<|endoftext|>") =
|
| 131 |
+
['<|endoftext|>`]. Otherwise, if `split_special_tokens=True`, then `tokenizer.tokenize("<|endoftext|>")` will be give `['<',
|
| 132 |
+
'|', 'endo', 'ft', 'ext', '|', '>']`. This argument is only supported for `slow` tokenizers for the moment.
|
| 133 |
+
"""
|
| 134 |
+
|
| 135 |
+
vocab_files_names = VOCAB_FILES_NAMES
|
| 136 |
+
model_input_names = ["input_ids", "attention_mask"]
|
| 137 |
+
|
| 138 |
+
def __init__(
|
| 139 |
+
self,
|
| 140 |
+
vocab_file,
|
| 141 |
+
merges_file,
|
| 142 |
+
errors="replace",
|
| 143 |
+
unk_token="<|endoftext|>",
|
| 144 |
+
bos_token=None,
|
| 145 |
+
eos_token="<|endoftext|>",
|
| 146 |
+
pad_token="<|endoftext|>",
|
| 147 |
+
clean_up_tokenization_spaces=False,
|
| 148 |
+
split_special_tokens=False,
|
| 149 |
+
**kwargs,
|
| 150 |
+
):
|
| 151 |
+
# Dream vocab does not contain control tokens; added tokens need to be special
|
| 152 |
+
bos_token = (
|
| 153 |
+
AddedToken(bos_token, lstrip=False, rstrip=False, special=True, normalized=False)
|
| 154 |
+
if isinstance(bos_token, str)
|
| 155 |
+
else bos_token
|
| 156 |
+
)
|
| 157 |
+
eos_token = (
|
| 158 |
+
AddedToken(eos_token, lstrip=False, rstrip=False, special=True, normalized=False)
|
| 159 |
+
if isinstance(eos_token, str)
|
| 160 |
+
else eos_token
|
| 161 |
+
)
|
| 162 |
+
unk_token = (
|
| 163 |
+
AddedToken(unk_token, lstrip=False, rstrip=False, special=True, normalized=False)
|
| 164 |
+
if isinstance(unk_token, str)
|
| 165 |
+
else unk_token
|
| 166 |
+
)
|
| 167 |
+
pad_token = (
|
| 168 |
+
AddedToken(pad_token, lstrip=False, rstrip=False, special=True, normalized=False)
|
| 169 |
+
if isinstance(pad_token, str)
|
| 170 |
+
else pad_token
|
| 171 |
+
)
|
| 172 |
+
|
| 173 |
+
with open(vocab_file, encoding="utf-8") as vocab_handle:
|
| 174 |
+
self.encoder = json.load(vocab_handle)
|
| 175 |
+
self.decoder = {v: k for k, v in self.encoder.items()}
|
| 176 |
+
self.errors = errors # how to handle errors in decoding
|
| 177 |
+
self.byte_encoder = bytes_to_unicode()
|
| 178 |
+
self.byte_decoder = {v: k for k, v in self.byte_encoder.items()}
|
| 179 |
+
bpe_merges = []
|
| 180 |
+
with open(merges_file, encoding="utf-8") as merges_handle:
|
| 181 |
+
for i, line in enumerate(merges_handle):
|
| 182 |
+
line = line.strip()
|
| 183 |
+
if (i == 0 and line.startswith("#version:")) or not line:
|
| 184 |
+
continue
|
| 185 |
+
bpe_merges.append(tuple(line.split()))
|
| 186 |
+
self.bpe_ranks = dict(zip(bpe_merges, range(len(bpe_merges))))
|
| 187 |
+
# NOTE: the cache can grow without bound and will get really large for long running processes
|
| 188 |
+
# (esp. for texts of language that do not use space between word, e.g. Chinese); technically
|
| 189 |
+
# not a memory leak but appears as one.
|
| 190 |
+
# GPT2Tokenizer has the same problem, so let's be consistent.
|
| 191 |
+
self.cache = {}
|
| 192 |
+
|
| 193 |
+
self.pat = re.compile(PRETOKENIZE_REGEX)
|
| 194 |
+
|
| 195 |
+
if kwargs.get("add_prefix_space", False):
|
| 196 |
+
logger.warning_once(
|
| 197 |
+
f"{self.__class__.__name} does not support `add_prefix_space`, setting it to True has no effect."
|
| 198 |
+
)
|
| 199 |
+
|
| 200 |
+
super().__init__(
|
| 201 |
+
errors=errors,
|
| 202 |
+
bos_token=bos_token,
|
| 203 |
+
eos_token=eos_token,
|
| 204 |
+
pad_token=pad_token,
|
| 205 |
+
unk_token=unk_token,
|
| 206 |
+
clean_up_tokenization_spaces=clean_up_tokenization_spaces,
|
| 207 |
+
split_special_tokens=split_special_tokens,
|
| 208 |
+
**kwargs,
|
| 209 |
+
)
|
| 210 |
+
|
| 211 |
+
@property
|
| 212 |
+
def vocab_size(self) -> int:
|
| 213 |
+
return len(self.encoder)
|
| 214 |
+
|
| 215 |
+
# Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer.get_vocab
|
| 216 |
+
def get_vocab(self):
|
| 217 |
+
return dict(self.encoder, **self.added_tokens_encoder)
|
| 218 |
+
|
| 219 |
+
# Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer.bpe
|
| 220 |
+
def bpe(self, token):
|
| 221 |
+
if token in self.cache:
|
| 222 |
+
return self.cache[token]
|
| 223 |
+
word = tuple(token)
|
| 224 |
+
pairs = get_pairs(word)
|
| 225 |
+
|
| 226 |
+
if not pairs:
|
| 227 |
+
return token
|
| 228 |
+
|
| 229 |
+
while True:
|
| 230 |
+
bigram = min(pairs, key=lambda pair: self.bpe_ranks.get(pair, float("inf")))
|
| 231 |
+
if bigram not in self.bpe_ranks:
|
| 232 |
+
break
|
| 233 |
+
first, second = bigram
|
| 234 |
+
new_word = []
|
| 235 |
+
i = 0
|
| 236 |
+
while i < len(word):
|
| 237 |
+
try:
|
| 238 |
+
j = word.index(first, i)
|
| 239 |
+
except ValueError:
|
| 240 |
+
new_word.extend(word[i:])
|
| 241 |
+
break
|
| 242 |
+
else:
|
| 243 |
+
new_word.extend(word[i:j])
|
| 244 |
+
i = j
|
| 245 |
+
|
| 246 |
+
if word[i] == first and i < len(word) - 1 and word[i + 1] == second:
|
| 247 |
+
new_word.append(first + second)
|
| 248 |
+
i += 2
|
| 249 |
+
else:
|
| 250 |
+
new_word.append(word[i])
|
| 251 |
+
i += 1
|
| 252 |
+
new_word = tuple(new_word)
|
| 253 |
+
word = new_word
|
| 254 |
+
if len(word) == 1:
|
| 255 |
+
break
|
| 256 |
+
else:
|
| 257 |
+
pairs = get_pairs(word)
|
| 258 |
+
word = " ".join(word)
|
| 259 |
+
self.cache[token] = word
|
| 260 |
+
return word
|
| 261 |
+
|
| 262 |
+
# Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer._tokenize
|
| 263 |
+
def _tokenize(self, text):
|
| 264 |
+
"""Tokenize a string."""
|
| 265 |
+
bpe_tokens = []
|
| 266 |
+
for token in re.findall(self.pat, text):
|
| 267 |
+
token = "".join(
|
| 268 |
+
self.byte_encoder[b] for b in token.encode("utf-8")
|
| 269 |
+
) # Maps all our bytes to unicode strings, avoiding control tokens of the BPE (spaces in our case)
|
| 270 |
+
bpe_tokens.extend(bpe_token for bpe_token in self.bpe(token).split(" "))
|
| 271 |
+
return bpe_tokens
|
| 272 |
+
|
| 273 |
+
# Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer._convert_token_to_id
|
| 274 |
+
def _convert_token_to_id(self, token):
|
| 275 |
+
"""Converts a token (str) in an id using the vocab."""
|
| 276 |
+
return self.encoder.get(token, self.encoder.get(self.unk_token))
|
| 277 |
+
|
| 278 |
+
# Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer._convert_id_to_token
|
| 279 |
+
def _convert_id_to_token(self, index):
|
| 280 |
+
"""Converts an index (integer) in a token (str) using the vocab."""
|
| 281 |
+
return self.decoder.get(index)
|
| 282 |
+
|
| 283 |
+
# Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer.convert_tokens_to_string
|
| 284 |
+
def convert_tokens_to_string(self, tokens):
|
| 285 |
+
"""Converts a sequence of tokens (string) in a single string."""
|
| 286 |
+
text = "".join(tokens)
|
| 287 |
+
text = bytearray([self.byte_decoder[c] for c in text]).decode("utf-8", errors=self.errors)
|
| 288 |
+
return text
|
| 289 |
+
|
| 290 |
+
def decode(
|
| 291 |
+
self,
|
| 292 |
+
token_ids,
|
| 293 |
+
skip_special_tokens: bool = False,
|
| 294 |
+
clean_up_tokenization_spaces: Optional[bool] = False,
|
| 295 |
+
spaces_between_special_tokens: bool = False,
|
| 296 |
+
**kwargs,
|
| 297 |
+
) -> str:
|
| 298 |
+
# `spaces_between_special_tokens` defaults to True for _decode in slow tokenizers
|
| 299 |
+
# and cannot be configured elsewhere, but it should default to False for DreamTokenizer
|
| 300 |
+
return super().decode(
|
| 301 |
+
token_ids,
|
| 302 |
+
skip_special_tokens=skip_special_tokens,
|
| 303 |
+
clean_up_tokenization_spaces=clean_up_tokenization_spaces,
|
| 304 |
+
spaces_between_special_tokens=spaces_between_special_tokens,
|
| 305 |
+
**kwargs,
|
| 306 |
+
)
|
| 307 |
+
|
| 308 |
+
# Copied from transformers.models.gpt2.tokenization_gpt2.GPT2Tokenizer.save_vocabulary
|
| 309 |
+
def save_vocabulary(self, save_directory: str, filename_prefix: Optional[str] = None) -> Tuple[str]:
|
| 310 |
+
if not os.path.isdir(save_directory):
|
| 311 |
+
logger.error(f"Vocabulary path ({save_directory}) should be a directory")
|
| 312 |
+
return
|
| 313 |
+
vocab_file = os.path.join(
|
| 314 |
+
save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"]
|
| 315 |
+
)
|
| 316 |
+
merge_file = os.path.join(
|
| 317 |
+
save_directory, (filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["merges_file"]
|
| 318 |
+
)
|
| 319 |
+
|
| 320 |
+
with open(vocab_file, "w", encoding="utf-8") as f:
|
| 321 |
+
f.write(json.dumps(self.encoder, indent=2, sort_keys=True, ensure_ascii=False) + "\n")
|
| 322 |
+
|
| 323 |
+
index = 0
|
| 324 |
+
with open(merge_file, "w", encoding="utf-8") as writer:
|
| 325 |
+
writer.write("#version: 0.2\n")
|
| 326 |
+
for bpe_tokens, token_index in sorted(self.bpe_ranks.items(), key=lambda kv: kv[1]):
|
| 327 |
+
if index != token_index:
|
| 328 |
+
logger.warning(
|
| 329 |
+
f"Saving vocabulary to {merge_file}: BPE merge indices are not consecutive."
|
| 330 |
+
" Please check that the tokenizer is not corrupted!"
|
| 331 |
+
)
|
| 332 |
+
index = token_index
|
| 333 |
+
writer.write(" ".join(bpe_tokens) + "\n")
|
| 334 |
+
index += 1
|
| 335 |
+
|
| 336 |
+
return vocab_file, merge_file
|
| 337 |
+
|
| 338 |
+
def prepare_for_tokenization(self, text, **kwargs):
|
| 339 |
+
text = unicodedata.normalize("NFC", text)
|
| 340 |
+
return (text, kwargs)
|
tokenizer_config.json
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"add_bos_token": false,
|
| 3 |
+
"add_prefix_space": false,
|
| 4 |
+
"added_tokens_decoder": {
|
| 5 |
+
"151643": {
|
| 6 |
+
"content": "<|endoftext|>",
|
| 7 |
+
"lstrip": false,
|
| 8 |
+
"normalized": false,
|
| 9 |
+
"rstrip": false,
|
| 10 |
+
"single_word": false,
|
| 11 |
+
"special": true
|
| 12 |
+
},
|
| 13 |
+
"151644": {
|
| 14 |
+
"content": "<|im_start|>",
|
| 15 |
+
"lstrip": false,
|
| 16 |
+
"normalized": false,
|
| 17 |
+
"rstrip": false,
|
| 18 |
+
"single_word": false,
|
| 19 |
+
"special": true
|
| 20 |
+
},
|
| 21 |
+
"151645": {
|
| 22 |
+
"content": "<|im_end|>",
|
| 23 |
+
"lstrip": false,
|
| 24 |
+
"normalized": false,
|
| 25 |
+
"rstrip": false,
|
| 26 |
+
"single_word": false,
|
| 27 |
+
"special": true
|
| 28 |
+
},
|
| 29 |
+
"151646": {
|
| 30 |
+
"content": "<|object_ref_start|>",
|
| 31 |
+
"lstrip": false,
|
| 32 |
+
"normalized": false,
|
| 33 |
+
"rstrip": false,
|
| 34 |
+
"single_word": false,
|
| 35 |
+
"special": true
|
| 36 |
+
},
|
| 37 |
+
"151647": {
|
| 38 |
+
"content": "<|object_ref_end|>",
|
| 39 |
+
"lstrip": false,
|
| 40 |
+
"normalized": false,
|
| 41 |
+
"rstrip": false,
|
| 42 |
+
"single_word": false,
|
| 43 |
+
"special": true
|
| 44 |
+
},
|
| 45 |
+
"151648": {
|
| 46 |
+
"content": "<|box_start|>",
|
| 47 |
+
"lstrip": false,
|
| 48 |
+
"normalized": false,
|
| 49 |
+
"rstrip": false,
|
| 50 |
+
"single_word": false,
|
| 51 |
+
"special": true
|
| 52 |
+
},
|
| 53 |
+
"151649": {
|
| 54 |
+
"content": "<|box_end|>",
|
| 55 |
+
"lstrip": false,
|
| 56 |
+
"normalized": false,
|
| 57 |
+
"rstrip": false,
|
| 58 |
+
"single_word": false,
|
| 59 |
+
"special": true
|
| 60 |
+
},
|
| 61 |
+
"151650": {
|
| 62 |
+
"content": "<|quad_start|>",
|
| 63 |
+
"lstrip": false,
|
| 64 |
+
"normalized": false,
|
| 65 |
+
"rstrip": false,
|
| 66 |
+
"single_word": false,
|
| 67 |
+
"special": true
|
| 68 |
+
},
|
| 69 |
+
"151651": {
|
| 70 |
+
"content": "<|quad_end|>",
|
| 71 |
+
"lstrip": false,
|
| 72 |
+
"normalized": false,
|
| 73 |
+
"rstrip": false,
|
| 74 |
+
"single_word": false,
|
| 75 |
+
"special": true
|
| 76 |
+
},
|
| 77 |
+
"151652": {
|
| 78 |
+
"content": "<|vision_start|>",
|
| 79 |
+
"lstrip": false,
|
| 80 |
+
"normalized": false,
|
| 81 |
+
"rstrip": false,
|
| 82 |
+
"single_word": false,
|
| 83 |
+
"special": true
|
| 84 |
+
},
|
| 85 |
+
"151653": {
|
| 86 |
+
"content": "<|vision_end|>",
|
| 87 |
+
"lstrip": false,
|
| 88 |
+
"normalized": false,
|
| 89 |
+
"rstrip": false,
|
| 90 |
+
"single_word": false,
|
| 91 |
+
"special": true
|
| 92 |
+
},
|
| 93 |
+
"151654": {
|
| 94 |
+
"content": "<|vision_pad|>",
|
| 95 |
+
"lstrip": false,
|
| 96 |
+
"normalized": false,
|
| 97 |
+
"rstrip": false,
|
| 98 |
+
"single_word": false,
|
| 99 |
+
"special": true
|
| 100 |
+
},
|
| 101 |
+
"151655": {
|
| 102 |
+
"content": "<|image_pad|>",
|
| 103 |
+
"lstrip": false,
|
| 104 |
+
"normalized": false,
|
| 105 |
+
"rstrip": false,
|
| 106 |
+
"single_word": false,
|
| 107 |
+
"special": true
|
| 108 |
+
},
|
| 109 |
+
"151656": {
|
| 110 |
+
"content": "<|video_pad|>",
|
| 111 |
+
"lstrip": false,
|
| 112 |
+
"normalized": false,
|
| 113 |
+
"rstrip": false,
|
| 114 |
+
"single_word": false,
|
| 115 |
+
"special": true
|
| 116 |
+
},
|
| 117 |
+
"151657": {
|
| 118 |
+
"content": "<tool_call>",
|
| 119 |
+
"lstrip": false,
|
| 120 |
+
"normalized": false,
|
| 121 |
+
"rstrip": false,
|
| 122 |
+
"single_word": false,
|
| 123 |
+
"special": false
|
| 124 |
+
},
|
| 125 |
+
"151658": {
|
| 126 |
+
"content": "</tool_call>",
|
| 127 |
+
"lstrip": false,
|
| 128 |
+
"normalized": false,
|
| 129 |
+
"rstrip": false,
|
| 130 |
+
"single_word": false,
|
| 131 |
+
"special": false
|
| 132 |
+
},
|
| 133 |
+
"151659": {
|
| 134 |
+
"content": "<|fim_prefix|>",
|
| 135 |
+
"lstrip": false,
|
| 136 |
+
"normalized": false,
|
| 137 |
+
"rstrip": false,
|
| 138 |
+
"single_word": false,
|
| 139 |
+
"special": false
|
| 140 |
+
},
|
| 141 |
+
"151660": {
|
| 142 |
+
"content": "<|fim_middle|>",
|
| 143 |
+
"lstrip": false,
|
| 144 |
+
"normalized": false,
|
| 145 |
+
"rstrip": false,
|
| 146 |
+
"single_word": false,
|
| 147 |
+
"special": false
|
| 148 |
+
},
|
| 149 |
+
"151661": {
|
| 150 |
+
"content": "<|fim_suffix|>",
|
| 151 |
+
"lstrip": false,
|
| 152 |
+
"normalized": false,
|
| 153 |
+
"rstrip": false,
|
| 154 |
+
"single_word": false,
|
| 155 |
+
"special": false
|
| 156 |
+
},
|
| 157 |
+
"151662": {
|
| 158 |
+
"content": "<|fim_pad|>",
|
| 159 |
+
"lstrip": false,
|
| 160 |
+
"normalized": false,
|
| 161 |
+
"rstrip": false,
|
| 162 |
+
"single_word": false,
|
| 163 |
+
"special": false
|
| 164 |
+
},
|
| 165 |
+
"151663": {
|
| 166 |
+
"content": "<|repo_name|>",
|
| 167 |
+
"lstrip": false,
|
| 168 |
+
"normalized": false,
|
| 169 |
+
"rstrip": false,
|
| 170 |
+
"single_word": false,
|
| 171 |
+
"special": false
|
| 172 |
+
},
|
| 173 |
+
"151664": {
|
| 174 |
+
"content": "<|file_sep|>",
|
| 175 |
+
"lstrip": false,
|
| 176 |
+
"normalized": false,
|
| 177 |
+
"rstrip": false,
|
| 178 |
+
"single_word": false,
|
| 179 |
+
"special": false
|
| 180 |
+
},
|
| 181 |
+
"151665": {
|
| 182 |
+
"content": "<|beginoftext|>",
|
| 183 |
+
"lstrip": false,
|
| 184 |
+
"normalized": false,
|
| 185 |
+
"rstrip": false,
|
| 186 |
+
"single_word": false,
|
| 187 |
+
"special": true
|
| 188 |
+
},
|
| 189 |
+
"151666": {
|
| 190 |
+
"content": "<|mask|>",
|
| 191 |
+
"lstrip": false,
|
| 192 |
+
"normalized": false,
|
| 193 |
+
"rstrip": false,
|
| 194 |
+
"single_word": false,
|
| 195 |
+
"special": true
|
| 196 |
+
}
|
| 197 |
+
},
|
| 198 |
+
"additional_special_tokens": [
|
| 199 |
+
"<|beginoftext|>",
|
| 200 |
+
"<|mask|>"
|
| 201 |
+
],
|
| 202 |
+
"auto_map": {
|
| 203 |
+
"AutoTokenizer": [
|
| 204 |
+
"tokenization_dream.DreamTokenizer",
|
| 205 |
+
null
|
| 206 |
+
]
|
| 207 |
+
},
|
| 208 |
+
"bos_token": "<|beginoftext|>",
|
| 209 |
+
"clean_up_tokenization_spaces": false,
|
| 210 |
+
"eos_token": "<|endoftext|>",
|
| 211 |
+
"errors": "replace",
|
| 212 |
+
"extra_special_tokens": {},
|
| 213 |
+
"mask_token": "<|mask|>",
|
| 214 |
+
"model_max_length": 131072,
|
| 215 |
+
"pad_token": "<|endoftext|>",
|
| 216 |
+
"split_special_tokens": false,
|
| 217 |
+
"tokenizer_class": "DreamTokenizer",
|
| 218 |
+
"unk_token": null
|
| 219 |
+
}
|
vocab.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|