|
3 | 3 | import comfy.text_encoders.sd3_clip |
4 | 4 | import comfy.text_encoders.llama |
5 | 5 | import comfy.model_management |
6 | | -from transformers import T5TokenizerFast, LlamaTokenizerFast |
| 6 | +from transformers import T5TokenizerFast, LlamaTokenizerFast, Qwen2Tokenizer |
7 | 7 | import torch |
8 | 8 | import os |
9 | 9 | import json |
@@ -172,3 +172,60 @@ def __init__(self, device="cpu", dtype=None, model_options={}): |
172 | 172 | model_options["num_layers"] = 30 |
173 | 173 | super().__init__(device=device, dtype=dtype, model_options=model_options) |
174 | 174 | return Flux2TEModel_ |
| 175 | + |
| 176 | +class Qwen3Tokenizer(sd1_clip.SDTokenizer): |
| 177 | + def __init__(self, embedding_directory=None, tokenizer_data={}): |
| 178 | + tokenizer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "qwen25_tokenizer") |
| 179 | + super().__init__(tokenizer_path, pad_with_end=False, embedding_size=2560, embedding_key='qwen3_4b', tokenizer_class=Qwen2Tokenizer, has_start_token=False, has_end_token=False, pad_to_max_length=False, max_length=99999999, min_length=512, pad_token=151643, tokenizer_data=tokenizer_data) |
| 180 | + |
| 181 | +class Qwen3Tokenizer8B(sd1_clip.SDTokenizer): |
| 182 | + def __init__(self, embedding_directory=None, tokenizer_data={}): |
| 183 | + tokenizer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "qwen25_tokenizer") |
| 184 | + super().__init__(tokenizer_path, pad_with_end=False, embedding_size=4096, embedding_key='qwen3_8b', tokenizer_class=Qwen2Tokenizer, has_start_token=False, has_end_token=False, pad_to_max_length=False, max_length=99999999, min_length=512, pad_token=151643, tokenizer_data=tokenizer_data) |
| 185 | + |
| 186 | +class KleinTokenizer(sd1_clip.SD1Tokenizer): |
| 187 | + def __init__(self, embedding_directory=None, tokenizer_data={}, name="qwen3_4b"): |
| 188 | + if name == "qwen3_4b": |
| 189 | + tokenizer = Qwen3Tokenizer |
| 190 | + elif name == "qwen3_8b": |
| 191 | + tokenizer = Qwen3Tokenizer8B |
| 192 | + |
| 193 | + super().__init__(embedding_directory=embedding_directory, tokenizer_data=tokenizer_data, name=name, tokenizer=tokenizer) |
| 194 | + self.llama_template = "<|im_start|>user\n{}<|im_end|>\n<|im_start|>assistant\n<think>\n\n</think>\n\n" |
| 195 | + |
| 196 | + def tokenize_with_weights(self, text, return_word_ids=False, llama_template=None, **kwargs): |
| 197 | + if llama_template is None: |
| 198 | + llama_text = self.llama_template.format(text) |
| 199 | + else: |
| 200 | + llama_text = llama_template.format(text) |
| 201 | + |
| 202 | + tokens = super().tokenize_with_weights(llama_text, return_word_ids=return_word_ids, disable_weights=True, **kwargs) |
| 203 | + return tokens |
| 204 | + |
| 205 | +class KleinTokenizer8B(KleinTokenizer): |
| 206 | + def __init__(self, embedding_directory=None, tokenizer_data={}, name="qwen3_8b"): |
| 207 | + super().__init__(embedding_directory=embedding_directory, tokenizer_data=tokenizer_data, name=name) |
| 208 | + |
| 209 | +class Qwen3_4BModel(sd1_clip.SDClipModel): |
| 210 | + def __init__(self, device="cpu", layer=[9, 18, 27], layer_idx=None, dtype=None, attention_mask=True, model_options={}): |
| 211 | + super().__init__(device=device, layer=layer, layer_idx=layer_idx, textmodel_json_config={}, dtype=dtype, special_tokens={"pad": 151643}, layer_norm_hidden_state=False, model_class=comfy.text_encoders.llama.Qwen3_4B, enable_attention_masks=attention_mask, return_attention_masks=attention_mask, model_options=model_options) |
| 212 | + |
| 213 | +class Qwen3_8BModel(sd1_clip.SDClipModel): |
| 214 | + def __init__(self, device="cpu", layer=[9, 18, 27], layer_idx=None, dtype=None, attention_mask=True, model_options={}): |
| 215 | + super().__init__(device=device, layer=layer, layer_idx=layer_idx, textmodel_json_config={}, dtype=dtype, special_tokens={"pad": 151643}, layer_norm_hidden_state=False, model_class=comfy.text_encoders.llama.Qwen3_8B, enable_attention_masks=attention_mask, return_attention_masks=attention_mask, model_options=model_options) |
| 216 | + |
| 217 | +def klein_te(dtype_llama=None, llama_quantization_metadata=None, model_type="qwen3_4b"): |
| 218 | + if model_type == "qwen3_4b": |
| 219 | + model = Qwen3_4BModel |
| 220 | + elif model_type == "qwen3_8b": |
| 221 | + model = Qwen3_8BModel |
| 222 | + |
| 223 | + class Flux2TEModel_(Flux2TEModel): |
| 224 | + def __init__(self, device="cpu", dtype=None, model_options={}): |
| 225 | + if llama_quantization_metadata is not None: |
| 226 | + model_options = model_options.copy() |
| 227 | + model_options["quantization_metadata"] = llama_quantization_metadata |
| 228 | + if dtype_llama is not None: |
| 229 | + dtype = dtype_llama |
| 230 | + super().__init__(device=device, dtype=dtype, name=model_type, model_options=model_options, clip_model=model) |
| 231 | + return Flux2TEModel_ |
0 commit comments