5 微调实验-lora-打造知乎风格问答机器人
使用 Swift 微调 Llama-3.2-3B 打造知乎风格问答机器人实验记录从数据清洗到模型微调的完整流程与踩坑指南https://swift.readthedocs.io/zh-cn/latest/Megatron-SWIFT/LoRA-Training.html一、实验目标训练一个具有知乎答主风格的问答机器人能够以真实人类的语气回答问题展现丰富的情感开心、幸福、愤怒、伤心、阴阳怪气等保持知乎高赞回答的逻辑性和可读性二、实验环境项目配置硬件Mac 笔记本 (Apple Silicon)加速MPS (Metal Performance Shaders)微调框架ms-swift微调方法LoRA基座模型Llama-3.2-3B-Instruct三、数据准备3.1 数据来源使用 ModelScope 上的Zhihu-KOL数据集包含知乎高质量问答内容。frommodelscope.msdatasetsimportMsDataset dsMsDataset.load(OmniData/Zhihu-KOL,cache_dir../data,splittrain)print(f原始数据量:{len(ds)})# 约 100 万条原始数据格式{INSTRUCTION:怎么说服男朋友买烤箱,RESPONSE:emmmmm首先想说的是...,METADATA:{\upvotes\: \赞同 15\, ...},SOURCE:Zhihu}3.2 数据清洗使用Data-Juicer进行数据清洗配置文件zhihu-bot.yamlproject_name:zhihu-processdataset_path:../data/zhihu.jsonlnp:16text_keys:responseexport_path:../data/zhihu_refine.jsonlprocess:# 1. 过滤低点赞数据-specified_numeric_field_filter:field_key:upvotesmin_value:500# 2. 文本长度过滤-text_length_filter:min_len:100max_len:2000# 3. 清洗处理-clean_email_mapper:-clean_html_mapper:-clean_ip_mapper:-clean_links_mapper:-clean_copyright_mapper:# 4. 语言和质量过滤-language_id_score_filter:lang:zhmin_score:0.9-alphanumeric_filter:tokenization:falsemin_ratio:0.72-flagged_words_filter:lang:zhmax_ratio:0.0005-perplexity_filter:lang:zhmax_ppl:4000# 5. 去重-document_simhash_deduplicator:tokenization:characterwindow_size:5num_blocks:10hamming_distance:6# 6. 选取 Top 50000 高赞数据-topk_specified_field_selector:field_key:upvotestopk:50000reverse:True3.3 数据质量分析清洗后数据统计指标数值说明数据量50,000 条从 100 万条中筛选语言98.5% 中文主要为中文内容平均困惑度2390偏高但可接受点赞范围500 ~ 634,000高质量回答关于困惑度偏高的分析困惑度 2000 在基础模型上计算是正常的最大值 170 万是异常值已通过max_ppl: 4000过滤知乎回答风格口语化、有网络用语困惑度偏高符合预期3.4 最终数据格式转换为 Swift 支持的格式{query:语文考试可以写负能量作文吗,response:我真的是服你们这群崽子...,upvotes:434000}{query:有哪些知识你知道后你的世界马上就不一样了,response:1.原则上可以就是不可以...,upvotes:399000}四、模型微调4.1 Swift 微调命令Mac MPS 版本swift sft\--train_typelora\--model/path/to/Llama-3.2-3B-Instruct\--dataset../data/zhihu_train.jsonl#3000 \--system你是一个真实的人类。回答用户的问题并在聊天回复中展现你的情绪包括开心幸福愤怒伤心阴阳怪气等\--split_dataset_ratio0.01\--output_dir../output\--target_modulesall-linear\--lora_rank4\--torch_dtypefp16\--device_mapmps\--seed42\--learning_rate1e-4\--warmup_ratio0.05\--max_length512\--per_device_train_batch_size1\--per_device_eval_batch_size1\--num_train_epochs1\--gradient_accumulation_steps16\--gradient_checkpointingtrue\--save_total_limit2\--eval_steps200\--save_steps2004.2 关键参数说明参数值说明--train_typelora使用 LoRA 微调参数高效--target_modulesall-linear作用于所有线性层--lora_rank4LoRA 秩越小参数越少--torch_dtypefp16MPS 不支持 bf16--device_mapmps使用 Apple Silicon GPU--per_device_train_batch_size1Mac 内存有限设为 1--gradient_accumulation_steps16梯度累积补偿小 batch--gradient_checkpointingtrue用时间换内存--max_length512限制序列长度节省内存4.3 实验具体数据{‘loss’: 2.13094215, ‘acc’: 0.55739484, ‘grad_norm’: 0.6459673, ‘learning_rate’: 8.99e-06, ‘memory(GiB)’: 11.12, ‘train_speed(iter/s)’: 0.218063, ‘epoch’: 0.82, ‘global_step/max_steps’: ‘280/343’, ‘percentage’: ‘81.63%’, ‘elapsed_time’: ‘21m 22s’, ‘remaining_time’: ‘4m 48s’}acc 0.557 (55.7%)→ 模型能正确预测超过一半的 token→ 对于生成任务来说是正常水平grad_norm 0.646→ 非常稳定说明训练平稳异常情况grad_norm 很大 (10) → 可能梯度爆炸grad_norm 接近 0 → 可能梯度消失五、踩坑记录5.1 Data-Juicer: topk_specified_field_selector 非常慢问题topk_specified_field_selector处理 100 万条数据耗时极长。原因全局排序无法并行化必须收集所有数据排序算法复杂度 O(n log n)解决方案提高upvotes阈值预过滤数据分两步处理先过滤去重再单独排序5.2 Swift 新版本参数名变化问题旧教程的参数名在新版本中不识别。参数对照表旧参数新参数--sft_type--train_type--model_type--model_id_or_path--model--dataset_test_ratio--split_dataset_ratio--lora_target_modules--target_modules--dtype--torch_dtype--batch_size--per_device_train_batch_size--device--device_map5.3 target_modules: ALL 不被识别问题ValueError: Target modules {ALL} not found in the base model.解决新版本使用all-linear而非ALL或指定具体模块q_proj k_proj v_proj o_proj gate_proj up_proj down_proj5.4 MPS 不支持 bf16问题Mac MPS 后端不支持 bfloat16。解决使用--torch_dtype fp16替代bf16或使用fp32更慢但更稳定5.5 内置数据集下载失败问题qwen2-pro-zh等内置数据集无法自动下载。解决只使用本地数据集--dataset ../data/zhihu_train.jsonl#3000或手动从 ModelScope 下载后本地引用六、垂直领域微调的核心要点6.1 数据质量 数据数量垂直领域微调数据质量是第一要素维度要求本实验做法准确性内容正确无误选取高赞回答经过社区验证多样性覆盖领域内不同场景保留多话题、多风格一致性风格/格式统一统一转换为 query-response 格式代表性体现领域特点保留知乎特有的表达风格经验法则高质量数据 1 万条 低质量数据 10 万条宁缺毋滥异常数据会严重影响模型效果6.2 数据混用策略防止灾难性遗忘微调垂直领域时模型容易忘记通用能力。解决方案是混合训练数据总训练数据 垂直领域数据 通用数据推荐混合比例场景垂直数据 : 通用数据说明轻度定制7 : 3保留大部分通用能力中度定制5 : 5平衡垂直和通用深度定制8 : 2专注垂直领域接受通用能力下降本实验的数据混用示例--dataset../data/zhihu_train.jsonl#3000 \ # 垂直领域知乎数据alpaca-gpt4-data-zh#1500 \ # 通用数据中文指令belle-1m#1500 # 通用数据中文对话通用数据推荐数据集用途来源alpaca-gpt4-data-zh中文指令跟随ModelScopebelle-1m中文多轮对话ModelScopefirefly-train-1.1M中文多任务HuggingFacemoss-sft-data通用问答ModelScope6.3 防止灾难性遗忘的技术手段除了数据混用还有以下方法方法 1使用 LoRA 而非全量微调--train_typelora# LoRA 只更新少量参数--lora_rank4# 较小的 rank 减少对原模型的干扰原理LoRA 冻结原始权重只训练低秩适配器最大程度保留原始能力。方法 2降低学习率--learning_rate1e-5# 比通常的 1e-4 更小原理小学习率减少对原始权重的修改幅度。方法 3减少训练轮数--num_train_epochs1# 1-2 轮足够原理过多轮次会导致过拟合到垂直领域丢失通用能力。方法 4使用 NEFTune噪声嵌入--neftune_noise_alpha5# 在嵌入层添加噪声原理增加训练噪声提高模型泛化能力。6.4 数据配比的动态调整训练过程中可以观察指标来调整配比现象原因调整方向垂直领域效果差垂直数据不足增加垂直数据比例通用能力明显下降过拟合垂直领域增加通用数据比例两者都不理想数据质量问题检查数据清洗流程6.5 评估策略微调后需要同时评估两方面1. 垂直领域评估 - 用垂直领域测试集评估如知乎问题 - 人工评估回答风格是否符合预期 2. 通用能力评估 - 用通用 benchmark 测试如 C-Eval、CMMLU - 测试常识问答、数学、代码等基础能力6.6 本实验的数据策略总结┌─────────────────────────────────────────────────────┐ │ 训练数据组成 │ ├─────────────────────────────────────────────────────┤ │ 知乎高赞数据 (3000条) │ │ ├── 高点赞筛选 (upvotes 500) │ │ ├── 质量过滤 (困惑度、长度、语言) │ │ └── SimHash 去重 │ ├─────────────────────────────────────────────────────┤ │ 通用中文数据 (建议添加 1500-3000条) │ │ ├── alpaca-gpt4-data-zh (指令跟随) │ │ └── belle / moss (对话能力) │ └─────────────────────────────────────────────────────┘ ↓ LoRA 微调 (rank4, lr1e-4) ↓ 知乎风格 保留通用能力七、Mac 微调的局限性限制影响建议内存有限batch_size 只能设 1使用梯度累积不支持 bf16精度略有损失使用 fp16速度慢3B 模型训练耗时长用于小规模测试MPS 不稳定部分算子可能出错设置 PYTORCH_ENABLE_MPS_FALLBACK1建议Mac 适合小规模测试几百~几千条数据正式训练建议使用云服务器如 AutoDL A10 GPU。八、总结本实验完成了✅ 知乎数据集清洗与筛选100万→5万条高质量数据✅ 数据格式转换适配 Swift 框架✅ 配置 Mac MPS 环境的微调参数✅ 解决 Swift 新版本的兼容性问题后续计划在 GPU 服务器上完成完整训练评估微调后模型的回答质量尝试不同的 system prompt 调整风格多轮对话能力增强

相关新闻

最新新闻

日新闻

周新闻

月新闻