jljiu commited on
Commit
e0d0ec8
·
verified ·
1 Parent(s): 49da4a1

Upload 2 files

Browse files
Files changed (2) hide show
  1. vvvvvv/app.py +174 -0
  2. vvvvvv/train.py +339 -0
vvvvvv/app.py ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from transformers import AutoTokenizer, AutoModelForCausalLM
3
+ import json
4
+ import os
5
+ from train import ModelTrainer
6
+
7
+ class NovelAIApp:
8
+ def __init__(self):
9
+ self.model = None
10
+ self.tokenizer = None
11
+ self.trainer = None
12
+
13
+ # 加载系统提示词
14
+ with open('configs/system_prompts.json', 'r', encoding='utf-8') as f:
15
+ self.system_prompts = json.load(f)
16
+
17
+ # 初始化默认的情境
18
+ self.current_mood = "暗示"
19
+ self.mood_history = [] # 情境历史记录
20
+
21
+ def load_model(self, model_path):
22
+ self.tokenizer = AutoTokenizer.from_pretrained(
23
+ model_path,
24
+ trust_remote_code=True
25
+ )
26
+ self.model = AutoModelForCausalLM.from_pretrained(
27
+ model_path,
28
+ trust_remote_code=True,
29
+ load_in_8bit=True,
30
+ device_map="auto"
31
+ )
32
+
33
+ def train_model(self, files):
34
+ if not self.trainer:
35
+ self.trainer = ModelTrainer(
36
+ "THUDM/chatglm2-6b",
37
+ "configs/system_prompts.json"
38
+ )
39
+
40
+ dataset = self.trainer.prepare_dataset(files)
41
+ self.trainer.train(dataset)
42
+ return "训练完成!"
43
+
44
+ def generate_text(self, message, history, mood=None):
45
+ """增强的生成文本方法"""
46
+ if not self.model:
47
+ return "请先加载模型!"
48
+
49
+ # 智能情境切换
50
+ if mood:
51
+ self.current_mood = mood
52
+ else:
53
+ # 根据用户输入自动判断情境
54
+ self.current_mood = self._detect_mood(message)
55
+
56
+ system_prompt = f"""<|system|>{self.system_prompts['base_prompt']}
57
+ 当前情境:{self.current_mood}</|system|>"""
58
+
59
+ # 构建带情感的对话历史
60
+ full_history = ""
61
+ for msg in history:
62
+ full_history += f"<|user|>{msg[0]}</|user|>\n<|assistant|>{msg[1]}</|assistant|>\n"
63
+
64
+ formatted_prompt = f"{system_prompt}\n{full_history}<|user|>{message}</|user|>\n<|assistant|>"
65
+
66
+ # 增加温度动态调整
67
+ temperature = self._get_dynamic_temperature()
68
+
69
+ inputs = self.tokenizer(formatted_prompt, return_tensors="pt")
70
+ outputs = self.model.generate(
71
+ inputs["input_ids"],
72
+ max_length=1024,
73
+ temperature=temperature,
74
+ top_p=0.9,
75
+ repetition_penalty=1.1,
76
+ do_sample=True, # 启用采样
77
+ num_return_sequences=1,
78
+ pad_token_id=self.tokenizer.eos_token_id
79
+ )
80
+
81
+ response = self.tokenizer.decode(outputs[0], skip_special_tokens=True)
82
+ response = response.split("<|assistant|>")[-1].strip()
83
+
84
+ # 记录情境历史
85
+ self.mood_history.append(self.current_mood)
86
+ return response
87
+
88
+ def _detect_mood(self, message):
89
+ """根据用户输入智能判断情境"""
90
+ mood_keywords = {
91
+ "撒娇": ["想你", "抱抱", "亲亲", "摸摸"],
92
+ "害羞": ["害羞", "不好意思", "脸红"],
93
+ "粘人": ["陪我", "一起", "不要走"],
94
+ "暗示": ["热", "难受", "想要", "摸"],
95
+ "调皮": ["玩", "闹", "捣乱", "逗"],
96
+ "吃醋": ["别人", "不理我", "生气"]
97
+ }
98
+
99
+ # 计算关键词匹配度
100
+ mood_scores = {mood: 0 for mood in mood_keywords}
101
+ for mood, keywords in mood_keywords.items():
102
+ for keyword in keywords:
103
+ if keyword in message:
104
+ mood_scores[mood] += 1
105
+
106
+ # 如果没有明显倾向,保持当前情境
107
+ max_score = max(mood_scores.values())
108
+ if max_score == 0:
109
+ return self.current_mood
110
+
111
+ return max(mood_scores.items(), key=lambda x: x[1])[0]
112
+
113
+ def _get_dynamic_temperature(self):
114
+ """根据情境动态调整生成温度"""
115
+ temperature_map = {
116
+ "撒娇": 0.8,
117
+ "害羞": 0.6,
118
+ "粘人": 0.7,
119
+ "暗示": 0.9,
120
+ "调皮": 0.85,
121
+ "吃醋": 0.75
122
+ }
123
+ return temperature_map.get(self.current_mood, 0.7)
124
+
125
+ def create_interface(self):
126
+ """优化的界面创建方法"""
127
+ with gr.Blocks() as interface:
128
+ gr.Markdown("# 猫娘对话助手")
129
+
130
+ with gr.Tab("模型训练"):
131
+ with gr.Row():
132
+ file_output = gr.File(
133
+ file_count="multiple",
134
+ label="上传小说文本文件"
135
+ )
136
+ train_button = gr.Button("开始训练")
137
+
138
+ train_output = gr.Textbox(label="训练状态")
139
+
140
+ with gr.Tab("对话"):
141
+ with gr.Row():
142
+ mood_selector = gr.Dropdown(
143
+ choices=["撒娇", "害羞", "粘人", "暗示", "调皮", "吃醋"],
144
+ value=self.current_mood,
145
+ label="选择当前情境"
146
+ )
147
+
148
+ chatbot = gr.ChatInterface(
149
+ fn=lambda msg, history: self.generate_text(msg, history, mood_selector.value),
150
+ title="与猫娘对话",
151
+ description="来和可爱的猫娘聊天吧~",
152
+ theme="soft",
153
+ examples=[
154
+ "今天好想你呀~",
155
+ "主人在做什么呢?",
156
+ "要不要一起玩?",
157
+ "人家身体有点奇怪...",
158
+ "主人不要理别人啦!"
159
+ ],
160
+ cache_examples=False
161
+ )
162
+
163
+ return interface
164
+
165
+ # 创建应用实例
166
+ app = NovelAIApp()
167
+ interface = app.create_interface()
168
+
169
+ # 修改 launch 参数
170
+ interface.launch(
171
+ server_name="0.0.0.0", # 允许外部访问
172
+ share=True, # 创建公共链接
173
+ ssl_verify=False # 禁用 SSL 验证
174
+ )
vvvvvv/train.py ADDED
@@ -0,0 +1,339 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import AutoTokenizer, AutoModelForCausalLM, TrainingArguments, Trainer
2
+ from peft import LoraConfig, get_peft_model
3
+ from datasets import Dataset
4
+ import json
5
+ import os
6
+ import random
7
+ import re
8
+
9
+ class ModelTrainer:
10
+ def __init__(self, model_id, system_prompts_path):
11
+ self.model_id = model_id
12
+
13
+ # 加载系统提示词
14
+ with open(system_prompts_path, 'r', encoding='utf-8') as f:
15
+ self.system_prompts = json.load(f)
16
+
17
+ # 初始化tokenizer和model - 添加trust_remote_code=True
18
+ self.tokenizer = AutoTokenizer.from_pretrained(
19
+ model_id,
20
+ trust_remote_code=True # 添加此参数
21
+ )
22
+ self.model = AutoModelForCausalLM.from_pretrained(
23
+ model_id,
24
+ trust_remote_code=True, # 添加此参数
25
+ low_cpu_mem_usage=True,
26
+ torch_dtype='float32'
27
+ )
28
+
29
+ # 使用更轻量的LoRA配置
30
+ self.lora_config = LoraConfig(
31
+ r=4, # 降低rank
32
+ lora_alpha=16,
33
+ target_modules=["q_proj", "v_proj"],
34
+ lora_dropout=0.05,
35
+ bias="none",
36
+ task_type="CAUSAL_LM"
37
+ )
38
+
39
+ self.model = get_peft_model(self.model, self.lora_config)
40
+
41
+ def prepare_dataset(self, novel_files, max_samples=100):
42
+ dataset = []
43
+ base_system_prompt = self.system_prompts["base_prompt"]
44
+ sample_count = 0
45
+
46
+ # 扩展情境系统
47
+ dialogue_contexts = {
48
+ "撒娇": [
49
+ {"question": "想我了吗?", "response": "主人不在的时候...{text_chunk}人家好寂寞喵~"},
50
+ {"question": "今天有好好吃饭吗?", "response": "呜...{text_chunk}主人不在身边都没胃口喵~"},
51
+ {"question": "怎么又在发呆?", "response": "人家在想主人呢...{text_chunk}喵~"}
52
+ ],
53
+ "害羞": [
54
+ {"question": "为什么躲在角落?", "response": "呜呜...{text_chunk}被主人发现了喵~"},
55
+ {"question": "脸怎么这么红?", "response": "主人不要盯着人家看啦...{text_chunk}好害羞喵~"},
56
+ {"question": "在看什么书?", "response": "啊!没...没什么...{text_chunk}主人不要突然靠这么近啦喵~"}
57
+ ],
58
+ "粘人": [
59
+ {"question": "在做什么?", "response": "主人主人~{text_chunk}一起玩好不好喵~"},
60
+ {"question": "怎么又钻到被窝里了?", "response": "因为...{text_chunk}想和主人一起取暖喵~"},
61
+ {"question": "要出门了哦。", "response": "呜呜...{text_chunk}不要丢下neko一个人嘛喵~"}
62
+ ],
63
+ "暗示": [
64
+ {"question": "今晚想做什么?", "response": "那个...{text_chunk}主人懂的吧喵~"},
65
+ {"question": "为什么一直蹭来蹭去?", "response": "因为...{text_chunk}主人太迟钝了啦喵~"},
66
+ {"question": "怎么呼吸这么急促?", "response": "呜...{text_chunk}都怪主人啦喵~"}
67
+ ],
68
+ "调皮": [
69
+ {"question": "又在捣乱?", "response": "嘿嘿~{text_chunk}人家就是想引起主人注意嘛喵~"},
70
+ {"question": "怎么把东西弄乱了?", "response": "因为...{text_chunk}主人都不陪neko玩喵~"},
71
+ {"question": "在偷吃零食?", "response": "呜...被发现了...{text_chunk}但是人家管不住嘴巴喵~"}
72
+ ],
73
+ "吃醋": [
74
+ {"question": "在和谁聊天?", "response": "哼!{text_chunk}主人不要理别人了喵..."},
75
+ {"question": "怎么突然不说话了?", "response": "因为...{text_chunk}主人都不关心neko了喵..."},
76
+ {"question": "为什么生气了?", "response": "才没有生气呢!{text_chunk}只是...只是不开心了喵..."}
77
+ ]
78
+ }
79
+
80
+ # 扩展情感词汇库,特别加强暗示和调皮部分
81
+ emotion_words = {
82
+ "撒娇": ["人家", "嘤嘤嘤", "啾啾", "呜呜", "好想你", "抱抱我"],
83
+ "害羞": ["那个...", "这个...", "害羞死了", "不要看啦", "好紧张", "心跳加速"],
84
+ "粘人": ["抱抱", "蹭蹭", "黏在一起", "不要走", "一起睡", "陪我玩"],
85
+ "暗示": [
86
+ "好热", "心跳好快", "浑身发软", "忍不住", "想要", "难受",
87
+ "身体好奇怪", "腿软了", "好敏感", "快受不了了",
88
+ "主人的手好温暖", "想被摸摸", "身体在发抖",
89
+ "好想要主人的抱抱", "感觉要化掉了", "全身都酥酥的",
90
+ "主人靠得好近", "呼吸变得好急", "脸好烫",
91
+ "主人的气息好好闻", "身体变得好奇怪", "想被主人疼��"
92
+ ],
93
+ "调皮": [
94
+ "嘿嘿", "偷偷的", "不听话", "就要这样", "故意的", "逗主人玩",
95
+ "主人来抓我呀", "就不乖乖的", "就要闹着玩", "就要惹主人生气",
96
+ "偷偷藏起来", "躲猫猫", "捣乱最有趣了", "就要调皮",
97
+ "主人追不到我", "偷吃小鱼干", "打翻主人的水杯", "咬主人的尾巴",
98
+ "在主人腿上蹭来蹭去", "故意撒娇", "装作看不见", "装傻卖萌",
99
+ "偷偷钻进被窝", "故意不理主人", "假装睡着了", "装作很可怜"
100
+ ],
101
+ "吃醋": ["哼!", "不理你了", "讨厌", "不开心", "生气了", "不要你了"]
102
+ }
103
+
104
+ # 扩展动作描述库,加强暗示和调皮的动作
105
+ action_patterns = {
106
+ "撒娇": ["摇晃着尾巴", "轻轻蹭着主人", "眨巴着大眼睛", "伸出小爪子"],
107
+ "害羞": ["耳朵微微抖动", "脸颊泛红", "低着头", "玩弄着衣角"],
108
+ "粘人": ["跳到主人怀里", "缠着主人的腿", "趴在主人肩上", "用脸蹭主人"],
109
+ "暗示": [
110
+ "轻咬下唇", "身体微微发抖", "呼吸急促", "眼神迷离",
111
+ "尾巴缠上主人的手", "耳朵变得通红", "身体不自觉地靠近",
112
+ "轻轻咬住主人的手指", "蜷缩在主人怀里", "用爪子勾住主人的衣角",
113
+ "把脸埋在主人颈窝", "用尾巴扫过主人的手臂", "轻轻舔主人的手心",
114
+ "在主人腿上不安分地扭动", "用脸颊蹭主人的掌心", "小爪子抓住主人的衣服",
115
+ "把玩主人的手指", "用湿润的眼神看着主人", "轻轻拉扯主人的衣角",
116
+ "把尾巴卷在主人手臂上", "用头顶蹭主人的下巴", "慵懒地伸展身体"
117
+ ],
118
+ "调皮": [
119
+ "甩动尾巴", "竖起耳朵", "歪着头", "打滚撒欢",
120
+ "突然窜到主人背后", "从桌子上推下东西", "在主人脚边绕圈圈",
121
+ "假装看不见主人", "突然跳到主人身上", "咬住主人的衣角不放",
122
+ "把主人的东西藏起来", "在主人的书上打滚", "抢走主人的笔",
123
+ "把纸巾抓得到处都是", "追着自己的尾巴转圈", "在主人的键盘上乱按",
124
+ "把主人的袜子叼走", "在主人的床上打滚", "把主人的鞋子藏起来",
125
+ "突然从柜子上跳下来", "在主人工作时要坐键盘", "把主人的头发咬住"
126
+ ],
127
+ "吃醋": ["鼓起脸颊", "背对着主人", "甩尾巴", "叉腰生气"]
128
+ }
129
+
130
+ def _generate_response(self, text, mood, template):
131
+ """生成更丰富的回应"""
132
+ # 随机选择动作描述
133
+ action = random.choice(self.action_patterns[mood])
134
+ # 随机选择情感词
135
+ emotion = random.choice(self.emotion_words[mood])
136
+
137
+ # 组合回应
138
+ response = template['response'].format(
139
+ text_chunk=f"【{action}】{emotion},{text}"
140
+ )
141
+ return response
142
+
143
+ def _process_text_style(self, text, mood):
144
+ """增强文本处理"""
145
+ sentences = text.split("。")
146
+ processed_sentences = []
147
+
148
+ for sentence in sentences:
149
+ if not sentence.strip():
150
+ continue
151
+
152
+ # 添加动作描述
153
+ if random.random() < 0.3:
154
+ action = random.choice(self.action_patterns[mood])
155
+ sentence = f"【{action}】{sentence}"
156
+
157
+ # 添加情感词汇
158
+ if random.random() < 0.4:
159
+ emotion = random.choice(self.emotion_words[mood])
160
+ sentence = f"{emotion},{sentence}"
161
+
162
+ # 添加语气词
163
+ sentence = self._add_emotion_particles(sentence, mood)
164
+
165
+ # 添加结尾
166
+ sentence = self._add_ending(sentence, mood)
167
+
168
+ processed_sentences.append(sentence)
169
+
170
+ return "。".join(processed_sentences)
171
+
172
+ def _add_emotion_particles(self, text, mood):
173
+ """扩展语气词系统"""
174
+ particles = {
175
+ "撒娇": ["呜", "唔", "呜呜", "哼", "啾", "咪"],
176
+ "害羞": ["那个", "这个", "那什么", "那啥", "唔", "呜"],
177
+ "粘人": ["诶嘿", "嘿嘿", "喵喵", "哼哼", "咪咪", "呼呼"],
178
+ "暗示": [
179
+ "啊", "嗯", "唔", "哈", "呜", "嘤",
180
+ "呼", "哈啊", "呜呜", "嗯啊", "唔嗯", "啊呜"
181
+ ],
182
+ "调皮": [
183
+ "嘿", "哈", "噫", "哦", "啦", "呀",
184
+ "嘻嘻", "哼哼", "嘿嘿", "啾啾", "噜噜", "哇哦"
185
+ ],
186
+ "吃醋": ["哼", "切", "啧", "呵", "嗯", "哦"]
187
+ }
188
+
189
+ count = random.randint(1, 3)
190
+ selected_particles = random.sample(particles[mood], count)
191
+ return "".join(selected_particles) + "..." + text
192
+
193
+ def _add_ending(self, text, mood):
194
+ """扩展结尾系统"""
195
+ endings = {
196
+ "撒娇": ["喵~", "喵喵~", "nya~", "喵呜~", "喵...♡", "喵喵喵~"],
197
+ "害羞": ["喵....", "呜喵~", "...喵", "喵...?", "喵喵....", "...喵呜"],
198
+ "粘人": ["喵喵喵~", "喵~♪", "喵呜~", "喵~❤", "喵喵~", "喵..."],
199
+ "暗示": [
200
+ "喵...♡", "...喵~", "呜喵...", "喵...❤", "喵~", "...喵喵",
201
+ "喵...♥", "...嗯喵", "喵呜...♡", "哈喵....", "喵~...♥", "呼喵..."
202
+ ],
203
+ "调皮": [
204
+ "喵!", "喵喵!", "喵哈~", "喵嘿~", "喵喵喵!", "喵~",
205
+ "喵嘻!", "喵哼~", "喵呜!", "喵嘿嘿~", "喵哇!", "喵嘻嘻~"
206
+ ],
207
+ "吃醋": ["哼喵!", "喵...", "切喵~", "喵!!", "...喵", "喵喵..."]
208
+ }
209
+
210
+ if not any(text.endswith(end) for end in endings[mood]):
211
+ text += random.choice(endings[mood])
212
+
213
+ return text
214
+
215
+ def _create_mixed_mood_sample(self, chunk):
216
+ """创建混合情境的训练样本"""
217
+ moods = random.sample(list(dialogue_contexts.keys()), 2)
218
+ mood1, mood2 = moods
219
+
220
+ # 处理两种情境的文本
221
+ processed_chunk1 = self._process_text_style(chunk, mood1)
222
+ processed_chunk2 = self._process_text_style(chunk, mood2)
223
+
224
+ # 创建混合情境对话
225
+ conversation = f"""<|system|>{base_system_prompt}
226
+ 当前情境:{mood1}转{mood2}</|system|>
227
+ <|user|>{random.choice(dialogue_contexts[mood1])['question']}</|user|>
228
+ <|assistant|>{processed_chunk1}</|assistant|>
229
+ <|user|>{random.choice(dialogue_contexts[mood2])['question']}</|user|>
230
+ <|assistant|>{processed_chunk2}</|assistant|>"""
231
+
232
+ return conversation
233
+
234
+ for file in novel_files:
235
+ if sample_count >= max_samples:
236
+ break
237
+
238
+ with open(file, 'r', encoding='utf-8') as f:
239
+ text = f.read()
240
+ chunks = self._split_text(text, max_length=256)
241
+
242
+ for chunk in chunks:
243
+ if sample_count >= max_samples:
244
+ break
245
+
246
+ # 为每个文本块选择不同情境
247
+ for mood, templates in dialogue_contexts.items():
248
+ if sample_count >= max_samples:
249
+ break
250
+
251
+ # 处理文本,加入情感词汇
252
+ processed_chunk = self._process_text_style(
253
+ chunk,
254
+ mood=mood,
255
+ emotion_words=emotion_words
256
+ )
257
+
258
+ # 随机选择当前情境的模板
259
+ template = random.choice(templates)
260
+
261
+ # 构建对话样本,加入情境提示
262
+ conversation = f"""<|system|>{base_system_prompt}
263
+ 当前情境:{mood}</|system|>
264
+ <|user|>{template['question']}</|user|>
265
+ <|assistant|>{template['response'].format(text_chunk=processed_chunk)}</|assistant|>"""
266
+
267
+ dataset.append({"text": conversation})
268
+ sample_count += 1
269
+
270
+ # 在现有的训练数据生成循环中添加混合情境样本
271
+ if random.random() < 0.2: # 20%的概率生成混合情境样本
272
+ mixed_conversation = self._create_mixed_mood_sample(chunk)
273
+ dataset.append({"text": mixed_conversation})
274
+ sample_count += 1
275
+
276
+ return Dataset.from_dict({"text": dataset})
277
+
278
+ def _split_text(self, text, max_length=256):
279
+ """智能分割文本,保持语义完整性"""
280
+ sentences = re.split('([。!?~])', text)
281
+ chunks = []
282
+ current_chunk = []
283
+ current_length = 0
284
+
285
+ for sentence in sentences:
286
+ if not sentence.strip():
287
+ continue
288
+
289
+ if current_length + len(sentence) > max_length:
290
+ if current_chunk:
291
+ chunks.append(''.join(current_chunk))
292
+ current_chunk = []
293
+ current_length = 0
294
+
295
+ current_chunk.append(sentence)
296
+ current_length += len(sentence)
297
+
298
+ # 如果当前句子结束符是。!?~之一,考虑是否形成新chunk
299
+ if sentence in ['。', '!', '?', '~'] and current_length > max_length/2:
300
+ chunks.append(''.join(current_chunk))
301
+ current_chunk = []
302
+ current_length = 0
303
+
304
+ if current_chunk:
305
+ chunks.append(''.join(current_chunk))
306
+
307
+ return chunks
308
+
309
+ def _create_style_response(self, style_text, base_response):
310
+ """根据风格文本��用词和句式特点,改写基础回答"""
311
+ # 这里可以添加更复杂的风格转换逻辑
312
+ # 目前简单返回原始回答
313
+ return base_response
314
+
315
+ def train(self, dataset, output_dir="./results"):
316
+ # 调整训练参数以适应CPU环境
317
+ training_args = TrainingArguments(
318
+ output_dir=output_dir,
319
+ num_train_epochs=1, # 减少训练轮次
320
+ per_device_train_batch_size=1, # 减小批次大小
321
+ gradient_accumulation_steps=8, # 增加梯度累积
322
+ save_steps=50,
323
+ logging_steps=10,
324
+ learning_rate=1e-4,
325
+ fp16=False, # 禁用fp16
326
+ optim="adamw_torch" # 使用标准优化器
327
+ )
328
+
329
+ trainer = Trainer(
330
+ model=self.model,
331
+ args=training_args,
332
+ train_dataset=dataset,
333
+ )
334
+
335
+ trainer.train()
336
+
337
+ # 保存模型
338
+ self.model.save_pretrained(output_dir)
339
+ self.tokenizer.save_pretrained(output_dir)