yxdu commited on
Commit
fa1c394
·
verified ·
1 Parent(s): 33393b2

Upload folder using huggingface_hub

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ tokenizer.json filter=lfs diff=lfs merge=lfs -text
added_tokens.json ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "<image_soft_token>": 262144,
3
+ "<unused0>": 262145,
4
+ "<unused100>": 262245,
5
+ "<unused101>": 262246,
6
+ "<unused10>": 262155,
7
+ "<unused11>": 262156,
8
+ "<unused12>": 262157,
9
+ "<unused13>": 262158,
10
+ "<unused14>": 262159,
11
+ "<unused15>": 262160,
12
+ "<unused16>": 262161,
13
+ "<unused17>": 262162,
14
+ "<unused18>": 262163,
15
+ "<unused19>": 262164,
16
+ "<unused1>": 262146,
17
+ "<unused20>": 262165,
18
+ "<unused21>": 262166,
19
+ "<unused22>": 262167,
20
+ "<unused23>": 262168,
21
+ "<unused24>": 262169,
22
+ "<unused25>": 262170,
23
+ "<unused26>": 262171,
24
+ "<unused27>": 262172,
25
+ "<unused28>": 262173,
26
+ "<unused29>": 262174,
27
+ "<unused2>": 262147,
28
+ "<unused30>": 262175,
29
+ "<unused31>": 262176,
30
+ "<unused32>": 262177,
31
+ "<unused33>": 262178,
32
+ "<unused34>": 262179,
33
+ "<unused35>": 262180,
34
+ "<unused36>": 262181,
35
+ "<unused37>": 262182,
36
+ "<unused38>": 262183,
37
+ "<unused39>": 262184,
38
+ "<unused3>": 262148,
39
+ "<unused40>": 262185,
40
+ "<unused41>": 262186,
41
+ "<unused42>": 262187,
42
+ "<unused43>": 262188,
43
+ "<unused44>": 262189,
44
+ "<unused45>": 262190,
45
+ "<unused46>": 262191,
46
+ "<unused47>": 262192,
47
+ "<unused48>": 262193,
48
+ "<unused49>": 262194,
49
+ "<unused4>": 262149,
50
+ "<unused50>": 262195,
51
+ "<unused51>": 262196,
52
+ "<unused52>": 262197,
53
+ "<unused53>": 262198,
54
+ "<unused54>": 262199,
55
+ "<unused55>": 262200,
56
+ "<unused56>": 262201,
57
+ "<unused57>": 262202,
58
+ "<unused58>": 262203,
59
+ "<unused59>": 262204,
60
+ "<unused5>": 262150,
61
+ "<unused60>": 262205,
62
+ "<unused61>": 262206,
63
+ "<unused62>": 262207,
64
+ "<unused63>": 262208,
65
+ "<unused64>": 262209,
66
+ "<unused65>": 262210,
67
+ "<unused66>": 262211,
68
+ "<unused67>": 262212,
69
+ "<unused68>": 262213,
70
+ "<unused69>": 262214,
71
+ "<unused6>": 262151,
72
+ "<unused70>": 262215,
73
+ "<unused71>": 262216,
74
+ "<unused72>": 262217,
75
+ "<unused73>": 262218,
76
+ "<unused74>": 262219,
77
+ "<unused75>": 262220,
78
+ "<unused76>": 262221,
79
+ "<unused77>": 262222,
80
+ "<unused78>": 262223,
81
+ "<unused79>": 262224,
82
+ "<unused7>": 262152,
83
+ "<unused80>": 262225,
84
+ "<unused81>": 262226,
85
+ "<unused82>": 262227,
86
+ "<unused83>": 262228,
87
+ "<unused84>": 262229,
88
+ "<unused85>": 262230,
89
+ "<unused86>": 262231,
90
+ "<unused87>": 262232,
91
+ "<unused88>": 262233,
92
+ "<unused89>": 262234,
93
+ "<unused8>": 262153,
94
+ "<unused90>": 262235,
95
+ "<unused91>": 262236,
96
+ "<unused92>": 262237,
97
+ "<unused93>": 262238,
98
+ "<unused94>": 262239,
99
+ "<unused95>": 262240,
100
+ "<unused96>": 262241,
101
+ "<unused97>": 262242,
102
+ "<unused98>": 262243,
103
+ "<unused99>": 262244,
104
+ "<unused9>": 262154
105
+ }
config.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "CustomSLM"
4
+ ],
5
+ "auto_map": {
6
+ "AutoConfig": "srt_model.CustomSLMConfig",
7
+ "AutoModel": "srt_model.CustomSLM"
8
+ },
9
+ "dtype": "bfloat16",
10
+ "encoder_dim": 1280,
11
+ "encoder_only": false,
12
+ "encoder_path": "yxdu/whisper-large-v3-encoder",
13
+ "llm_dim": 2560,
14
+ "llm_path": "yxdu/ESRT-4B-LLM",
15
+ "model_type": "custom_slm",
16
+ "qformer_layers": 8,
17
+ "query_len": 80,
18
+ "tie_word_embeddings": false,
19
+ "tokenizer_path": "yxdu/ESRT-4B-LLM",
20
+ "transformers_version": "4.57.3",
21
+ "use_vllm": false,
22
+ "vllm_path": "yxdu/ESRT-4B-LLM"
23
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:15a65e30870c7c59bfef38d2fdf97391f97119aadd11737b6d3542abf11d741e
3
+ size 9183572616
special_tokens_map.json ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "boi_token": "<start_of_image>",
3
+ "bos_token": {
4
+ "content": "<bos>",
5
+ "lstrip": false,
6
+ "normalized": false,
7
+ "rstrip": false,
8
+ "single_word": false
9
+ },
10
+ "eoi_token": "<end_of_image>",
11
+ "eos_token": {
12
+ "content": "<eos>",
13
+ "lstrip": false,
14
+ "normalized": false,
15
+ "rstrip": false,
16
+ "single_word": false
17
+ },
18
+ "image_token": "<image_soft_token>",
19
+ "pad_token": {
20
+ "content": "<pad>",
21
+ "lstrip": false,
22
+ "normalized": false,
23
+ "rstrip": false,
24
+ "single_word": false
25
+ },
26
+ "unk_token": {
27
+ "content": "<unk>",
28
+ "lstrip": false,
29
+ "normalized": false,
30
+ "rstrip": false,
31
+ "single_word": false
32
+ }
33
+ }
srt_model.py ADDED
@@ -0,0 +1,369 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+ import asyncio
4
+ import httpx
5
+ import torch
6
+ import torch.nn as nn
7
+ from typing import List, Optional
8
+ from transformers import (
9
+ PretrainedConfig,
10
+ PreTrainedModel,
11
+ WhisperModel,
12
+ AutoModelForCausalLM,
13
+ AutoTokenizer,
14
+ AutoConfig,
15
+ AutoModel,
16
+ Blip2QFormerConfig,
17
+ Blip2QFormerModel
18
+ )
19
+
20
+
21
+ # --- 1. 定义配置类 ---
22
+ class CustomSLMConfig(PretrainedConfig):
23
+ model_type = "custom_slm"
24
+
25
+ def __init__(
26
+ self,
27
+ encoder_path: str = "",
28
+ llm_path: str = "",
29
+ tokenizer_path: str = "",
30
+ llm_dim: int = 3840,
31
+ query_len: int = 80,
32
+ encoder_dim: int = 1280,
33
+ qformer_layers: int = 8,
34
+ vllm_path: str = "",
35
+ use_vllm: bool = False, # 新增传入参数
36
+ encoder_only: bool = False, # 新增传入参数
37
+ **kwargs
38
+ ):
39
+ # 存储所有初始化需要的路径和超参数
40
+ self.encoder_path = encoder_path
41
+ self.llm_path = llm_path
42
+ self.tokenizer_path = tokenizer_path
43
+ self.llm_dim = llm_dim
44
+ self.query_len = query_len
45
+ self.encoder_dim = encoder_dim
46
+ self.qformer_layers = qformer_layers
47
+ self.vllm_path = vllm_path
48
+ self.use_vllm = use_vllm
49
+ self.encoder_only = encoder_only
50
+ super().__init__(**kwargs)
51
+
52
+
53
+ # --- 2. 辅助组件 ---
54
+ def compute_accuracy(pad_outputs, pad_targets, ignore_label):
55
+ mask = pad_targets != ignore_label
56
+ if mask.sum() == 0:
57
+ return torch.tensor(0.0).to(pad_outputs.device)
58
+ numerator = torch.sum(
59
+ pad_outputs.masked_select(mask) == pad_targets.masked_select(mask)
60
+ )
61
+ denominator = torch.sum(mask)
62
+ return (numerator.float() / denominator.float()) * 100
63
+
64
+ class MLPProjector(nn.Module):
65
+ def __init__(self, encoder_dim=1280, llm_dim=3840):
66
+ super().__init__()
67
+ self.llm_dim = llm_dim
68
+
69
+ if self.llm_dim <= 1536:
70
+ self.linear = nn.Linear(encoder_dim, self.llm_dim)
71
+ self.norm = nn.LayerNorm(self.llm_dim, eps=1e-5)
72
+ elif self.llm_dim <= 3072:
73
+ self.linear1 = nn.Linear(encoder_dim, 1536)
74
+ self.relu = nn.ReLU()
75
+ self.linear2 = nn.Linear(1536, self.llm_dim)
76
+ self.norm = nn.LayerNorm(self.llm_dim, eps=1e-5)
77
+ else:
78
+ self.linear1 = nn.Linear(encoder_dim, 2560)
79
+ self.relu = nn.ReLU()
80
+ self.linear2 = nn.Linear(2560, self.llm_dim)
81
+ self.norm = nn.LayerNorm(self.llm_dim, eps=1e-5)
82
+
83
+ def forward(self, x):
84
+ if self.llm_dim <= 1536:
85
+ return self.norm(self.linear(x))
86
+ else:
87
+ x = self.linear1(x)
88
+ x = self.relu(x)
89
+ x = self.linear2(x)
90
+ return self.norm(x)
91
+
92
+
93
+ class QFormerModule(nn.Module):
94
+ def __init__(self, encoder_dim=1280, query_len=80, num_layers=8):
95
+ super().__init__()
96
+ self.query_len = query_len
97
+
98
+ configuration = Blip2QFormerConfig()
99
+ configuration.encoder_hidden_size = encoder_dim
100
+ configuration.num_hidden_layers = num_layers
101
+
102
+ self.query = nn.Parameter(torch.zeros(1, self.query_len, configuration.hidden_size))
103
+ self.query.data.normal_(mean=0.0, std=1.0)
104
+ self.qformer = Blip2QFormerModel(configuration)
105
+
106
+ def forward(self, x, atts):
107
+ query = self.query.expand(x.shape[0], -1, -1)
108
+
109
+ query_output = self.qformer(
110
+ query_embeds=query,
111
+ encoder_hidden_states=x,
112
+ encoder_attention_mask=atts,
113
+ return_dict=True,
114
+ )
115
+
116
+ return query_output.last_hidden_state
117
+
118
+
119
+ # --- 3. 主模型类 ---
120
+ class CustomSLM(PreTrainedModel):
121
+ config_class = CustomSLMConfig
122
+ _auto_class = "AutoModel"
123
+
124
+ def __init__(self, config: CustomSLMConfig, **kwargs):
125
+ super().__init__(config, **kwargs)
126
+
127
+
128
+ # 从 kwargs 或 config 提取 use_vllm 与 vllm_path
129
+ self.vllm_path = kwargs.pop("vllm_path", getattr(config, "vllm_path", None))
130
+ self.use_vllm = kwargs.pop("use_vllm", getattr(config, "use_vllm", False))
131
+ self.encoder_only = kwargs.pop("encoder_only", getattr(config, "encoder_only", False))
132
+
133
+ encoder_config = AutoConfig.from_pretrained(config.encoder_path)
134
+ self.encoder = WhisperModel(encoder_config).encoder
135
+
136
+ # LLM 部分:构造空壳
137
+ llm_config = AutoConfig.from_pretrained(config.llm_path)
138
+
139
+ if self.encoder_only:
140
+ pass
141
+ else:
142
+ self.llm = AutoModelForCausalLM.from_config(
143
+ llm_config,
144
+ dtype=torch.bfloat16,
145
+ attn_implementation="sdpa"
146
+ )
147
+
148
+ if self.use_vllm:
149
+ print("⚠️ [Info] 检测到 use_vllm=True: 正在释放原生 LLM 解码器参数,仅保留 Embedding 层以防止 vLLM OOM!")
150
+ if hasattr(self.llm, "lm_head"):
151
+ self.llm.lm_head = nn.Identity()
152
+ if hasattr(self.llm, "model") and hasattr(self.llm.model, "layers"):
153
+ self.llm.model.layers = nn.ModuleList()
154
+ elif hasattr(self.llm, "transformer") and hasattr(self.llm.transformer, "h"):
155
+ self.llm.transformer.h = nn.ModuleList()
156
+
157
+ if hasattr(self.llm, "model") and hasattr(self.llm.model, "layers"):
158
+ self.llm.model.layers = nn.ModuleList()
159
+ # 兼容老版本 Qwen, ChatGLM 等
160
+ elif hasattr(self.llm, "transformer") and hasattr(self.llm.transformer, "h"):
161
+ self.llm.transformer.h = nn.ModuleList()
162
+
163
+ import gc
164
+ gc.collect()
165
+
166
+ # Q-Former 部分
167
+ self.q_former = QFormerModule(
168
+ encoder_dim=config.encoder_dim,
169
+ query_len=config.query_len,
170
+ num_layers=config.qformer_layers
171
+ )
172
+
173
+
174
+ # MLP 投影部分
175
+ qformer_hidden_size = Blip2QFormerConfig().hidden_size
176
+ self.mlp = MLPProjector(
177
+ encoder_dim=qformer_hidden_size,
178
+ llm_dim=config.llm_dim
179
+ )
180
+
181
+ self.tokenizer = AutoTokenizer.from_pretrained(config.tokenizer_path)
182
+ self.post_init()
183
+
184
+ def get_input_embeddings(self):
185
+ if hasattr(self, 'llm'):
186
+ return self.llm.get_input_embeddings()
187
+ return None
188
+
189
+ def forward(self,
190
+ audio_mel: torch.Tensor = None,
191
+ audio_mel_post_mask: torch.Tensor = None,
192
+ modality_mask: torch.Tensor = None,
193
+ input_ids: torch.LongTensor = None,
194
+ attention_mask: Optional[torch.Tensor] = None,
195
+ labels: Optional[torch.LongTensor] = None,
196
+ inference_mode: bool = False,
197
+ **kwargs):
198
+
199
+ if self.use_vllm and not inference_mode:
200
+ raise RuntimeError("模型初始化开启了 use_vllm,已释放深层参数,无法进行标准 forward 计算。")
201
+
202
+ # 1. 语音特征提取与投影
203
+ encoder_outs = self.encoder(audio_mel.permute(0, 2, 1)).last_hidden_state
204
+ encoder_outs = self.q_former(encoder_outs, audio_mel_post_mask)
205
+ encoder_outs = self.mlp(encoder_outs)
206
+
207
+ # 2. 获取文本 Embeddings
208
+ if input_ids is not None:
209
+ input_ids_cleaned = input_ids.clone()
210
+ input_ids_cleaned[input_ids_cleaned == -1] = 0
211
+ inputs_embeds = self.get_input_embeddings()(input_ids_cleaned)
212
+
213
+ # 3. 多模态融合 (Modality Mask 逻辑)
214
+ if modality_mask is not None:
215
+ modality_mask_start_indices = (modality_mask == True).float().argmax(dim=1)
216
+ modality_lengths = torch.clamp(modality_mask.sum(dim=1), max=encoder_outs.shape[1]).tolist()
217
+
218
+ encoder_outs_pad = torch.zeros_like(inputs_embeds)
219
+ for i in range(encoder_outs.shape[0]):
220
+ length = int(modality_lengths[i])
221
+ start = int(modality_mask_start_indices[i])
222
+ encoder_outs_pad[i, start : start + length] = encoder_outs[i, :length]
223
+
224
+ inputs_embeds = encoder_outs_pad + inputs_embeds * (~modality_mask[:, :, None])
225
+
226
+ if inference_mode:
227
+ return inputs_embeds, attention_mask
228
+
229
+ # 4. LLM 前向传播
230
+ model_outputs = self.llm(
231
+ inputs_embeds=inputs_embeds,
232
+ attention_mask=attention_mask,
233
+ labels=labels
234
+ )
235
+
236
+ # 5. 计算准确率 (仅用于训练/验证)
237
+ with torch.no_grad():
238
+ preds = torch.argmax(model_outputs.logits, dim=-1)
239
+ acc = compute_accuracy(preds[:, :-1], labels[:, 1:], ignore_label=-100)
240
+
241
+ return model_outputs, acc
242
+
243
+ @torch.no_grad()
244
+ def generate(self, *args, **kwargs):
245
+ if getattr(self, "use_vllm", False):
246
+ raise RuntimeError("当前为 use_vllm=True,LLM 解码器未加载,无法执行原生 generate。请调用 translate_batch_* 方法。")
247
+
248
+ kwargs["inference_mode"] = True
249
+ inputs_embeds, attention_mask = self.forward(*args, **kwargs)
250
+
251
+ model_outputs = self.llm.generate(
252
+ inputs_embeds=inputs_embeds,
253
+ max_new_tokens=kwargs.get("max_new_tokens", 400),
254
+ num_beams=kwargs.get("num_beams", 1),
255
+ do_sample=kwargs.get("do_sample", False),
256
+ min_length=kwargs.get("min_length", 1),
257
+ top_p=kwargs.get("top_p", 1.0),
258
+ repetition_penalty=kwargs.get("repetition_penalty", 1.0),
259
+ length_penalty=kwargs.get("length_penalty", 1.0),
260
+ temperature=kwargs.get("temperature", 1.0),
261
+ no_repeat_ngram_size=5,
262
+ attention_mask=attention_mask,
263
+ bos_token_id=self.tokenizer.bos_token_id,
264
+ eos_token_id=self.tokenizer.eos_token_id,
265
+ pad_token_id=self.tokenizer.pad_token_id
266
+ )
267
+ return model_outputs
268
+
269
+
270
+ @torch.no_grad()
271
+ def translate_encode(self, beam_search, mels, prompts, max_new_tokens=300, use_vllm=False):
272
+ device = self.device
273
+ dtype = self.dtype
274
+
275
+ mels = mels.to(device).to(dtype)
276
+ enc_out = self.encoder(mels).last_hidden_state
277
+ adapter_embeds = self.q_former(enc_out, None)
278
+
279
+ return adapter_embeds
280
+
281
+ def translate_batch_embeds(self, beam_search, embeds, prompts, max_new_tokens=300, use_vllm=False):
282
+ use_vllm_flag = use_vllm or getattr(self, "use_vllm", False)
283
+
284
+ if use_vllm_flag and getattr(self, "use_vllm", False) is False:
285
+ print("⚠️ 警告: 您通过参数强制要求 use_vllm,但初始化未设置 use_vllm=True。")
286
+
287
+ if use_vllm_flag:
288
+ import importlib
289
+ vllm_module = importlib.import_module("vllm")
290
+ LLM = vllm_module.LLM
291
+ SamplingParams = vllm_module.SamplingParams
292
+
293
+ def mark():
294
+ if self.device.type == 'mps': torch.mps.synchronize()
295
+ elif self.device.type in ['cuda', 'npu']: torch.cuda.synchronize()
296
+ return time.perf_counter()
297
+
298
+ if (not hasattr(self, '_vllm_llm') or self._vllm_llm is None) and use_vllm_flag:
299
+ self._vllm_llm = LLM(
300
+ self.vllm_path,
301
+ dtype="bfloat16",
302
+ trust_remote_code=True,
303
+ tensor_parallel_size=1,
304
+ gpu_memory_utilization=0.7,
305
+ enable_prompt_embeds=True,
306
+ max_model_len=1024,
307
+ )
308
+
309
+ device = self.device
310
+ dtype = self.dtype
311
+
312
+ t0 = mark()
313
+
314
+
315
+ adapter_embeds = embeds.to(device).to(dtype)
316
+ adapter_embeds = self.mlp(adapter_embeds)
317
+ text_inputs = self.tokenizer(prompts, return_tensors="pt", padding=True).to(device)
318
+ text_embeds = self.get_input_embeddings()(text_inputs.input_ids)
319
+
320
+ inputs_embeds = torch.cat((adapter_embeds, text_embeds), dim=1)
321
+ t1 = mark()
322
+
323
+ if use_vllm_flag:
324
+ sampling_params = SamplingParams(
325
+ max_tokens=max_new_tokens,
326
+ temperature=0.0,
327
+ )
328
+
329
+ prompt_embeds_list = [{"prompt_embeds": inputs_embeds[i]} for i in range(inputs_embeds.size(0))]
330
+ outputs = self._vllm_llm.generate(
331
+ prompt_embeds_list,
332
+ sampling_params=sampling_params,
333
+ )
334
+
335
+ t2 = mark()
336
+ print(f"⏱️ Embeds Prep: {t1-t0:.2f}s | LLM: {t2-t1:.2f}s | Total: {t2-t0:.2f}s")
337
+ return [output.outputs[0].text for output in outputs]
338
+ else:
339
+ output_ids = self.llm.generate(
340
+ inputs_embeds=inputs_embeds,
341
+ attention_mask=None,
342
+ max_new_tokens=max_new_tokens,
343
+ do_sample=False,
344
+ num_beams=beam_search,
345
+ no_repeat_ngram_size=5,
346
+ eos_token_id=self.tokenizer.eos_token_id,
347
+ pad_token_id=self.tokenizer.pad_token_id,
348
+ )
349
+ t2 = mark()
350
+ print(f"⏱️ Embeds Prep: {t1-t0:.2f}s | LLM: {t2-t1:.2f}s | Total: {t2-t0:.2f}s")
351
+ return [self.tokenizer.decode(g, skip_special_tokens=True) for g in output_ids]
352
+
353
+ # --- 4. 注册与保存脚本 ---
354
+ def register_and_save_model(model, tokenizer, args):
355
+ AutoConfig.register("custom_slm", CustomSLMConfig)
356
+ AutoModel.register(CustomSLMConfig, CustomSLM)
357
+
358
+ if hasattr(model, "use_lora") and model.use_lora:
359
+ print("Merging LoRA weights...")
360
+ model.llm = model.llm.merge_and_unload()
361
+
362
+ model.config.auto_map = {
363
+ "AutoConfig": "srt_model.CustomSLMConfig",
364
+ "AutoModel": "srt_model.CustomSLM"
365
+ }
366
+
367
+ model.save_pretrained(args.merge_model)
368
+ tokenizer.save_pretrained(args.merge_model)
369
+ print(f"Model saved to {args.merge_model}")
tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d9a0be69780559df037b0e7118dcfdde29dd75d01a67cc999ef0dc0db5cb1725
3
+ size 33403140
tokenizer.model ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1299c11d7cf632ef3b4e11937501358ada021bbdf7c47638d13c0ee982f2e79c
3
+ size 4689074
tokenizer_config.json ADDED
The diff for this file is too large to render. See raw diff