96SEO 2026-02-23 11:22 2
上篇文章我们完成了数据集的制作得到了一个拥有近两万条样本的数据集随后进行了模型选型筛选出了

作为我们的基座模型这篇文章我们来完成剩下的工作包括模型的微调与部署。
Xtuner目前Xtuner只能支持Qwen1.5但是没关系我们可以把Qwen2.5的模型路径给配上。
qwen1_5_1_8b_chat_qlora_alpaca_e3.py位置如下图所示
qwen2_5_chat_dialog_style.py接下来我们修改这个配置文件。
这一部分要改的东西是最多的包括模型路径pretrained_model_name_or_path、数据集路径data_files、输入样本最大长度max_length、批次大小batch_size、训练的最大伦次max_epochs、保存的检查点数量save_total_limit还有用于主观评估的问题evaluation_inputs要修改的地方我已经在下面的程序片段中注释出来了evaluation_inputs没有注释出来。
#######################################################################
#######################################################################
/data/coding/model_weights/Qwen/Qwen2.5-1.5B-Instruct
/data/coding/EmotionalDialogue/convert_data.json
老妈非让我嫁给她同事儿子怎么逃啊,男朋友给女主播刷火箭算精神出轨吗,
领导周末发60秒语音矩阵装没看见行吗,被同事追问有没有整容怎么优雅翻白眼,
相亲对象第一次见面就想搂肩油腻,暗恋的人突然问我喜欢什么类型,
这里用于主观评估的问题至少要有5个以上我们本次微调用的数据达到了万这个级别了所以我这里选了10个挑的方式很随机。
如果是其他项目的话用于主观评估的问题需要有代表性必须覆盖所有的目标场景。
#######################################################################
#######################################################################
dict(typeAutoTokenizer.from_pretrained,pretrained_model_name_or_pathpretrained_model_name_or_path,trust_remote_codeTrue,padding_sideright,
dict(typeSupervisedFinetune,use_varlen_attnuse_varlen_attn,llmdict(typeAutoModelForCausalLM.from_pretrained,pretrained_model_name_or_pathpretrained_model_name_or_path,trust_remote_codeTrue,torch_dtypetorch.float16,quantization_configdict(typeBitsAndBytesConfig,load_in_4bitTrue,load_in_8bitFalse,llm_int8_threshold6.0,llm_int8_has_fp16_weightFalse,bnb_4bit_compute_dtypetorch.float16,bnb_4bit_use_double_quantTrue,bnb_4bit_quant_typenf4,),),loradict(typeLoraConfig,r64,lora_alpha128,
修改lora_dropout0.1,biasnone,task_typeCAUSAL_LM,),
#######################################################################
#######################################################################
修改datasetdict(typeload_dataset,
pathjson,data_filesdata_files),
修改tokenizertokenizer,max_lengthmax_length,#
修改template_map_fndict(typetemplate_map_fn_factory,
templateprompt_template),remove_unused_columnsTrue,shuffle_before_packTrue,pack_to_max_lengthpack_to_max_length,use_varlen_attnuse_varlen_attn,
dict(batch_sizebatch_size,num_workersdataloader_num_workers,datasetalpaca_en,samplerdict(typesampler,
shuffleTrue),collate_fndict(typedefault_collate_fn,
use_varlen_attnuse_varlen_attn),
vis_backends[dict(typeTensorboardVisBackend)])至此配置文件修改完毕。
qwen2_5_chat_dialog_style.py显存占用情况如下
deepspeed_zero2因为我没跑所以我也不知道显存占用情况怎么样如果出现显存不足那就把
/data/coding/utils/xtuner/work_dirs/qwen2_5_chat_dialog_style/20250614_193605/vis_data然后在指定窗口http://localhost:6006/远程服务器需要SSH连接或者端口转发查看。
个step就会评估一次下面截图是训练了3500个step后的评估结果
关于训练什么时候停止关键需要看这十个主观评估的问题是否都达到了预期的效果一个都不能少。
每达到预期效果则说明没收敛当然即便这十个问题都达到了预期效果也不能说模型收敛了因为主观评估的问题太少有一定的偶然性。
不过大模型训练到收敛是有难度的而且GPU算力资源有限因此没必要训练到收敛只要主观评估的结果连续若干次都能达到预期训练就可以停止了。
查看主观评估的结果不需要去翻控制台的打印信息也不需要去看日志在工作中
我训练了18000个step大概相当于31个epoch花了超过12小时发现十个主观评估问题都达到要求后就停止训练了。
下面是损失函数下降情况
我们使用模型最后一个检查点因为Xtuner保存的检查点是低秩适配器而且是以
/data/coding/utils/xtuner/work_dirs/qwen2_5_chat_dialog_style/iter_18000.pth
/data/coding/utils/xtuner/adapter_save_dir/qwen2_5/转化成功后控制台会显示
/data/coding/model_weights/Qwen/Qwen2.5-1.5B-Instruct
/data/coding/utils/xtuner/adapter_save_dir/qwen2_5
从上面的回复可以看到模型的回答风格达到了我们的预期说明模型达到想要的效果。
我们还可以把十个主观评估的问题依次输入或者输入其他可用于主观评估的问题。
/data/coding/model_weights/Qwen/Qwen2.5-1.5B-Instruct
/data/coding/utils/xtuner/adapter_save_dir/qwen2_5/
/data/coding/EmotionalDialogue/model_weights/Qwen2.5-1.5B-Dialog-Style/如果看到控制台输出
xtuner/xtuner/utils/templates.py
自带的对话模板是不一样的但是训练框架不会管这么多它训练的时候用的都是
模型名称可以任意但不要和内置对话模板名相同否则会覆盖system:
{system}{meta_instruction}{eosys}{user}{user_content}{eoh}{assistant}{assistant_content}{eoa}{separator}{user}...下面是我根据
|im_start|system\n,meta_instruction:
dialog_style_chat_template.json。
这里separator
/data/coding/EmotionalDialogue/model_weights/Qwen2.5-1.5B-Dialog-Style
/data/coding/utils/xtuner/dialog_style_chat_template.json结果如下
可以看到输出的信息和我们设定的模板一致第二轮因为涉及多轮对话所以第二轮没有系统提示词模型回复的后缀|im_end|会被后台程序自动去掉这个不重要。
/data/coding/model_weights/Qwen/Qwen2.5-1.5B-Instruct使用原始模型时不需要指定对话模板lmdeploy
/data/coding/EmotionalDialogue/model_weights/Qwen2.5-1.5B-Dialog-Style
/data/coding/utils/xtuner/dialog_style_chat_template.json
dialog_style如果控制台出现下面的信息说明推理的服务已经启动
/data/coding/EmotionalDialogue/model_weights/Qwen2.5-1.5B-Dialog-Style
/data/coding/utils/xtuner/dialog_style_chat_template.json
prompt}messages.append(user_message)return
st.cache_resource那么每次在前端界面输入信息时程序就会再次执行导致模型重复导入client
OpenAI(base_urlhttp://0.0.0.0:23333/v1/,api_keysuibianxie)return
如果session_state中没有messages则创建一个包含默认消息的列表
st.session_state:st.session_state[messages]
st.session_state.messages:st.chat_message(msg[role]).write(msg[content])#
在聊天界面上显示用户的输入st.chat_message(user).write(prompt)#
historyNone)#调用模型chat_complition
client.chat.completions.create(messagesmessages,modeldialog_style)#获取回答model_response
chat_complition.choices[0]response_text
model_response.message.content#
将用户问题和模型的输出添加到session_state中的messages列表中st.session_state.messages.append({role:
prompt})st.session_state.messages.append({role:
在聊天界面上显示模型的输出st.chat_message(assistant).write(response_text)
在终端中运行以下命令启动streamlit服务并将端口映射到本地然后在浏览器中打开链接
可以用相同的输入多试几次如果每次生成的答案都一样则说明过拟合。
因为大模型在生成答案的时候是通过softmax对词表中各个单词计算概率如果多次输入同一个问题而每次答案都一样假设生成的序列为“你好幸苦呀”说明在生成第一个
的时候“好”这个字的概率远远高于其他字后面的序列都是如此最后导致生成的答案几乎没有了随机性。
我们训练用的数据接近两万条但只有一千个问题也就是说每个问题对应20种回答所以本项目不太可能出现过拟合因为在生成每个
的官方文档给的对话模板格式有问题可能是版本比较老的官方文档。
下面是我最终的对话模板
}上面的对话模板除了meta_instruction之外其他一个字符都不能改。
因为我尝试了很多该法比如增加
推理服务然后运行下面的统计代码结果都会出现问题包括但不限于生成内容不带风格名称、生成内容全为温柔风格等。
唯一改了基本没影响的只有把
OpenAI(base_urlhttp://0.0.0.0:23333/v1/,api_keysuibianxie)#
client.chat.completions.create(messagesmessages,model/data/coding/EmotionalDialogue/model_weights/Qwen2.5-1.5B-Dialog-Style)except:chat_completion
client.chat.completions.create(messagesmessages,modeldialog_style)#
chat_completion.choices[0].message.content#
keyabnormal_answer.append(line)#
0}我们训练用的数据集两种风格的比例是1:1上面的两次统计结果均严重偏离这个比例原因我也不知道。
总之LMDeploy
模型的对话模板现在是解决了那以后要是微调其他模型推理的时候怎么改对话模板我找到了一份转换代码下面介绍如何使用。
universal_converter(original_template:
Any]:将多种风格的原始模板转换为lmdeploy官方格式#
re.split(r(\|im_start\|assistant\n?),
converted[system].replace({system},
converted[user].replace({input},
isinstance(converted[stop_words],
SYSTEM(|im_start|system\n{system}|im_end|\n),
INSTRUCTION(|im_start|user\n{input}|im_end|\n
dict(SYSTEM|system|\n{system},INSTRUCTION|user|\n{input}|assistant|\n,SEP\n,)#
universal_converter(train_chat)#
f:json.dump(converted_template,
f,indent2,ensure_asciiFalse,separators(,,
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback