☰
LLaMA-Factory微调实战:从数据准备到评估部署的完整指南
2026/10/23 10:42:36 网站建设 项目流程

聊到LLaMA-Factory微调,网上的教程其实已经不少,但大多数是“照抄命令跑通一次”的路子,真正把数据、参数、评估串起来讲透的很少。这篇帖子的定位是我自己沉淀后的“个人重制版”:不打算给你一份万能模板命令,而是把LLaMA-Factory微调入门路上最容易出问题的地方掰开揉碎,告诉你每一步背后的原因和我的判断方式。内容比较适合第一次接触SFT的读者,也适合那种已经跑通训练但效果不佳、想回头找症结的人。

我反复折腾过好几版微调方案,踩过数据格式返工、学习率起飞、损失下降但回答崩坏这些典型坑。下面写的都是我可以直接复现的经验,步骤和参数都是实操验证过的,你拿着能省不少试错时间。

1. 为什么我会把微调教程重制成“判断路径”而不是“照抄命令”

1.1 官方文档能让你启动,但不会告诉你什么时候该停

LLaMA-Factory本身的文档和示例写得足够简洁,克隆仓库、装依赖、填数据集配置,一条命令就能把LoRA训练跑起来。但真到了业务落地,你会发现“能启动”和“能完成一次有效训练”之间有一段不小的距离。官方示例默认使用的是通用数据集,参数也是偏向演示性质,它不会告诉你:你手上的业务问答数据该放多少条、类别不平衡会不会导致模型偏科、loss降到多少才算正常、训练多久就应该停。

我最早跑完一次7B规模的LoRA训练,命令执行成功,日志里没有红色报错,看起来一切都很正常。但等我拿真实问题去问微调后的模型,它把训练集里的标准答案复读了一遍,换个问法就露馅。这时候我才意识到,微调不是一个“执行成功”就结束的事,而是一连串需要判断和取舍的过程。

所以我重制这份入门内容的第一个目标,是把那些“文档默认你知道、实际上你根本不了解”的地方补上。比如模型加载路径和tokenizer的一致性、数据集中字段怎么映射到框架里、训练集和验证集的分配方式,这些细节决定着你训练的是个有效模型还是一堆噪声。

1.2 “能跑通”与“能用在项目里”是两回事

很多人入门的标志是“命令不报错”,但这个标准其实很低。我后来复盘,发现跑通和可用之间至少隔了三道门槛。

第一道门槛是数据。训练集的质量直接决定模型的上限。同样是500条数据,有人拿出来模型立刻学会某种说话风格,有人拿出来模型越训越乱。差别往往不在模型参数,而在数据字段是否干净、指令与输入是否拆得合理、输出是否有多余的格式错乱。

第二道门槛是参数。LoRA rank、学习率、epoch、序列长度这些参数没有绝对正确的答案,只有适合当前数据量和硬件条件的组合。很多人习惯照搬教程里的参数,但场景不同,最优参数也不同,硬套会造成过拟合或者训练不足。

第三道门槛是评估。训练结束后大多数人的做法是拿着几个例子问一问,感觉还行就收工。但模型口语化地说“还行”并不意味着任务正确率达到要求。没有评估集、没有对比基线、没有bad case分析,你很难判断这次训练到底是变好了还是变差了,更没法在下一轮优化时找准方向。

这三道门槛是我重点重制的内容。我希望读者看完后,不是只会粘命令,而是能形成一套属于自己的微调判断框架。

1.3 重制版的内容组织逻辑

这版教程我按实际工作流的顺序来组织,而不是按官方手册的功能菜单去排列。

第一部分是环境准备。这部分不啰嗦,但必须覆盖显存估算、依赖安装、模型文件确认等前置项。

第二部分是数据。我会拆解SFT阶段常见的JSON结构,讲清楚instruction和input的区别、history怎么填、system提示词什么时候该用。

第三部分是训练。我会给一条可以直接套用的LoRA训练命令,并逐个参数说明取舍逻辑,重点讲学习率、batch size和max_length之间如何平衡。

第四部分是评估。这是大多数人最欠缺的一环。我会讲怎么构建小规模评测集、怎么判断过拟合、怎么有效分析bad case。

第五部分是导出和部署。训练产物如何合并回底座模型,导出后如何校验,部署时该保留LoRA adapter还是合并权重。

最后是我实际踩过的一些坑,以及我建议直接绕开的弯路。整体结构就是这条从数据到上线的主线,中间穿插原理和判断方法。

2. 环境准备:显存、依赖和底座模型的下载顺序

2.1 先按显存倒推训练方式,别拿到模型就开训

第一次做LLaMA-Factory微调的人,最容易犯的错是先把底座模型下载到本地,再折腾依赖,最后发现显存不够。我建议反过来,先搞清楚自己手里GPU的显存大小,再决定训练方式和模型规模。

表格里是我个人常用的起步参考:

训练方式7B级模型参考显存实际体验
LoRA + 半精度约16GB24GB用起来更宽裕,16GB要压低batch或序列长度
LoRA + 基座量化约8-12GB消费级显卡可尝试,但精度略受影响
全参数微调40GB以上单卡基本不够,建议多卡或更大显存

我自己的经验是:如果只有单卡16GB,优先选择LoRA配合短序列,max_length设在512到1024之间,batch_size设为1到2,梯度累积别省,这样整体负担小很多。如果显存到了24GB,LoRA训练7B级模型就很轻松了,甚至可以稍微放宽序列长度。

这里的核心逻辑是:微调不只是把模型加载进显存,训练过程中还要保存梯度、优化器状态和中间激活值。显存估算必须留出安全余量,不然跑到一半OOM,前面的时间全白费。所以我建议训练前先跑一条短训练命令,确认峰值显存再上完整数据。

2.2 依赖安装的顺序决定你后面省不省事

LLaMA-Factory的环境依赖不算复杂,但版本错位会引发很多莫名其妙的问题。我最推荐的顺序是:先确认底层计算环境,再装深度学习框架,最后装LLaMA-Factory相关依赖。

第一步,创建独立的环境管理会话,避免污染其他项目环境。第二步,按驱动版本确定CUDA版本,再安装对应版本的PyTorch。这里最怕的是驱动新、PyTorch旧,或者反过来。装完PyTorch后先验证一下GPU计算环境是否可用:

python -c "import torch; print(torch.__version__, torch.cuda.is_available())"

这一步能正常输出模型计算可用性,再继续往下走。第三步安装transformers、datasets、accelerate、peft、trl这些组件。版本上我不建议全装最新版,优先看LLaMA-Factory当前版本要求的依赖范围。装完之后,跑一下仓库自带的启动脚本或简单训练示例,确认环境整体没有冲突。

这类依赖问题有个共性:报错信息往往不直接指向根因。有时报“缺少某个算子”,实际上是对应框架版本不匹配。所以环境准备阶段花十分钟验证计算环境可用性,比训练到一半排查报错划算得多。

2.3 模型文件下载:优先从可访问的镜像渠道获取

底座模型文件通常包含多个分片权重、配置文件和tokenizer文件,单靠浏览器一个个下载很不现实。我用的是LLaMA-Factory里支持的两个主流模型下载渠道:一个偏海外,一个偏国内镜像。国内网络环境下,我更推荐直接用国内镜像站的方式,速度明显更快。

下载完成后,不要直接开训,花两分钟检查文件完整性:

  • 确认模型权重文件的文件名和分片数量与发布说明一致。
  • 确认目录下包含config.json、tokenizer文件等基础文件。
  • 如果下载平台提供了校验值,最好做一次比对。

我遇到过的问题是把完整权重放在了更深的嵌套目录里,启动时路径没写对,框架自动重新下载或者报错。模型的本地路径填到能直接看到config.json那一层,不要多套一层目录。

2.4 开训前的环境自查清单

为了减少无效训练,我每次开新项目都会先过一遍精简检查:

  1. 计算环境可用,GPU驱动和深度学习框架版本匹配。
  2. 底座模型路径正确,能看到config.json。
  3. 内存空间足够,因为训练过程会写临时文件。
  4. 数据集格式已按预期准备完毕,框架读取时没有字段缺失。
  5. 输出目录可以被写入,并且不会和已有训练产物重名覆盖。

这套检查听起来没什么技术含量,但能拦住绝大多数低级失败。尤其是输出目录的处理:不少人反复训练时之前的结果还在,新结果直接覆盖,想对比都找不到历史版本。我建议每次训练都使用独立的输出目录,比如带上日期或实验代号。

3. 数据是微调的唯一真相:格式、清洗和采样

3.1 先看懂SFT数据的组织方式

LLaMA-Factory在SFT阶段读取的数据以JSON格式为主。常见的数据字段包括system、instruction、input和output,部分场景还会用到history来记录多轮历史对话。理解这些字段之间的关系,是准备数据的起点。

system可以理解为全局人格设定或任务背景,比如“你是一个耐心的客服助手”,这条信息会在多轮对话中一直影响模型。instruction是当前这一轮的具体指令,告诉模型要做什么。input是被处理的对象,属于辅助输入内容。output是期望模型生成的答案。history是可选字段,用来承载多轮上下文。

在实际数据里,很多人的困惑是instruction和input如何划分。我个人的处理习惯是:能放进指令里的信息尽量放指令,input只放真正独立的内容。举例子来说,“把下面这段文字总结成三点”是instruction,“文字内容”是input,这样职责清晰,模型也更容易学到正确的输入输出关系。

dataset_info.json里需要把自定义数据集路径注册进去。配置时重点确认数据集的columns映射是否写对,比如instruction对应数据里的哪个字段、output对应哪个字段。字段名不一致会导致训练时把空值当输入,loss也可能照常下降,但模型根本学不到东西。

3.2 从原始业务资料到训练数据的处理流程

我建议所有准备数据的人都建立一个固定流程,不要用临时脚本堆数据。下面是我在实践中反复使用的六步流程,每一步都有明确的产出。

第一步,收集原始语料。把问答记录、文档片段、客服对话等所有潜在数据源放到统一目录。

第二步,清洗噪声。清除乱码、HTML标签、多余的换行符、不可见字符。清洗的目标是把数据变成规整的文本。

第三步,脱敏处理。涉及隐私的信息要替换掉,比如把具体的姓名、手机号、地址等替换成占位符。这不只是合规问题,也是为了避免模型在生成时复述出这些信息。

第四步,整理成问答对。把一段对话、一篇资料拆成instruction、input、output的结构。拆分的核心原则是每一条数据都要有明确的任务目标和标准答案。

第五步,检查字段对齐。所有条目结构应一致,不要出现一部分数据有history、另一部分没有的情况。

第六步,抽样人工检查。随机抽10条至20条,从指令清晰度、答案准确性、格式一致性三个角度打分。人工检查通过后再送入训练。

有的读者可能觉得自己数据量很大,人工检查浪费时间。我的经验是,如果数据质量本身不错,人工检查一轮花不了太久,但能避免模型学到大量脏数据的副作用。

3.3 质量控制的五个观察点

数据清洗完成后,不要急着开训。我会用一套固定的观察点再扫一遍数据。

第一个观察点是重复率。如果数据里存在大量近似重复的句子,模型会对这部分内容过度记忆,降低泛化能力。我一般会先做一遍文本去重,尤其是模板痕迹明显的自动生成数据。

第二个观察点是类别平衡。如果业务任务里85%的样本是“订单查询”,只有15%是“退货处理”,训练出来的模型在退货处理上的表现会明显偏差。我会对类别做统计,必要时通过扩充少数类别或欠采样多数类别来调整比例。

第三个观察点是长度分布。max_length是训练时的重要参数,如果数据里大量条目远超设定长度,截断后会把答案后半截切掉,模型学不到完整输出。我会看训练数据的长度分布,按覆盖大多数条目的长度设置max_length。

第四个观察点是答案质量。有些输出包含“我不知道”这类模糊表达,或者干脆是错误答案。这种数据要人工清理,不能只靠脚本过滤。

第五个观察点是格式一致性。例如所有答案是否统一包含标点、是否统一换行、是否统一保留特定行业术语。格式一致性对模型生成风格的影响比很多人想象的大。

3.4 数据量级:多少条才算够

“微调到底需要多少数据”可能是入门阶段被问最多的问题。我的回答是:取决于你想让模型发生什么变化。

如果目标是改变说话风格、让模型适应某种角色设定,那么几百条高质量数据往往就够了。风格迁移的本质是让模型学分布偏好,不需要覆盖所有知识。如果目标是注入新的业务知识,比如让模型熟悉产品操作手册里的具体流程,那么几千条起步比较合理,并且每条都要有清晰的标准答案。如果是复杂推理任务,对数据质量的要求会更高,数量反而其次,几百条经过精心构造的推导例子能发挥的价值往往大于几万条粗糙数据。

在真正投入全部数据训练之前,我建议先用少量数据跑通整个流程,比如抽50到100条出来做一次短训练。这能提前发现字段映射、参数设置和代码层面的问题,避免等全部数据准备好后再翻车。花少量时间和算力跑一次完整链路,比直接大训练到最后再排查要高效得多。

4. 第一条LoRA训练:命令、参数与日志判断

4.1 为什么第一个实验选LoRA而不是全参数微调

入门阶段,我几乎都建议先做LoRA。训练成本低、实验周期短、迭代速度快,而且不会把底座权重改得面目全非。

我把LoRA理解为在原始权重旁边挂了一组低秩矩阵,训练时只更新这组附加矩阵,原始模型参数保持冻结。这样显存占用比全参数微调小很多,训练速度更快,切换不同任务也方便——不同任务的LoRA可以分别保存,推理时按需加载。

LoRA还有一个隐性优势:它天然带有一定的正则化效果。因为可训练参数很少,模型不容易在小型数据上急速过拟合,容错空间比全参数微调大。对入门阶段的调试来说,这是非常友好的特性。

4.2 一条可以直接跑通的训练命令示例

下面这条命令来自我实际跑过的7B级模型LoRA训练,数据量约3000条,单卡24GB显存,整体开销可控。你可以直接复制后按路径替换。

llamafactory-cli train \ --model_name_or_path /models/your-base-model \ --stage sft \ --finetuning_type lora \ --dataset my_training_data \ --template llama \ --output_dir ./output/lora-demo \ --learning_rate 2e-4 \ --num_train_epochs 3.0 \ --per_device_train_batch_size 2 \ --gradient_accumulation_steps 8 \ --lora_rank 8 \ --lora_target q_proj,v_proj \ --max_length 1024 \ --save_steps 200 \ --logging_steps 20 \ --eval_steps 200 \ --do_train true \ --do_eval true \ --val_size 0.05

这里有几个关键点需要说明。--model_name_or_path要指向包含config.json的完整底座模型路径,不要多包一层目录。--dataset对应的是dataset_info.json里注册的自定义数据集名称,不是文件路径本身。--template要跟底座模型匹配,写错的话对话格式会乱掉,模型输出可能前言不搭后语。

--per_device_train_batch_size设为2是因为24GB显存下更稳妥。如果你显存不足16GB,可以换成1,同时提高梯度累积步数来保持整体批量大小。--val_size是训练集中切出来做验证的比例,这里设5%,一方面够用来观察验证损失,另一方面不至于减少太多训练数据。

4.3 关键参数的取舍逻辑

为什么学习率是2e-4?因为LoRA只更新少量附加参数,它比全参数微调承受得起更大的学习率。全参数微调常用1e-5,而LoRA常用1e-4到2e-4。如果学习率超过5e-4,就很容易出现损失暴增或灾难性遗忘。第一次训练时我建议先保持2e-4,跑完再看效果。

--lora_rank 8是一个性价比很高的选择。rank越大,可训练参数量越多,模型表达能力越强,但显存和过拟合风险也会上升。对大多数业务场景,rank 8到16足够用。有些任务觉得模型学不进去,我一般先检查数据和训练时长,而不是急着调高rank。

--max_length 1024代表输入和输出拼起来的最大长度。长度越长,单条数据占用的显存越高,训练速度越慢。如果数据里大部分是短问答,1024完全够用。如果业务场景需要输出长文本,可以调到2048,但要同步降低batch size。

--gradient_accumulation_steps 8配合--per_device_train_batch_size 2,相当于每8个小步完成一次参数更新,整体批量大小约等于16。批量太小时,噪声大;批量太大时,单次更新计算时间拉长。16是一个比较稳的起步值。

下面用表格总结我常用参数的调整方向:

参数起步值调整信号调整方向
learning_rate2e-4loss震荡或上升降到1e-4
num_train_epochs3.0验证loss回升减少到2
lora_rank8学不进去增加到16
max_length1024长输出被截断增加到1536或2048
per_device_train_batch_size2显存OOM降到1

4.4 训练日志怎么读,才不会被数字骗了

训练过程中每20步打印一次日志,里面有几项需要关注。最关键的是loss。刚开始几百步,loss通常会快速下降,这个阶段说明模型正在快速吸收主要模式。随后下降速度变缓,进入一个平台期,这很正常,不代表训练卡住了。

验证集上的loss如果整体保持下降但末端略微回升,往往是过拟合信号。如果验证loss上升得很明显,我一般会提前终止训练,而不是等它跑完预设轮次。有些读者担心loss没降到某个数值就不算成功,这个想法可以放一放。不同数据、不同任务,loss的合理范围差异很大,重要的是loss与验证集表现组合起来看。

训练日志里还会打印当前步数、学习率和梯度范数。梯度范数偶尔异常不一定要干预,但持续飘忽或出现特别大的数值时,我会优先检查学习率和数据里是否有异常长文本。

5. 训练完不等于完成:评估、过拟合与bad case排查

5.1 一个很常见的怪象:loss很低,回答却很烂

我见过不少人在第一次微调后困惑:训练损失明明降得很低,可模型在实际回答时表现得像失忆。问题往往出在三个方面。

第一个方面是数据泄露。训练集和评测集没有区分好,模型在训练时已经把评测问题背下来了,评测时自然表现得好。这种做法得出的漂亮结果没有说服力。

第二个方面是过拟合训练集。模型记住了训练集的标准答案,但稍微换个问法就不会了。通俗来说,它不是学会了做这道题,而是背下了这道题的答案和它的某个变体。

第三个方面是评测方式本身有偏差。只挑自己觉得模型应该答对的几个问题去问,没有覆盖多轮、长文本、对抗性输入等真实场景,结果自然显得不错。

我后来给自己定了一条规矩:训练完先用训练集样本测试,确认模型能学进去;再用独立验证集或评测集测试,确认泛化能力;最后在没有见过的随机业务样例上做一轮盲测。三层测试都过了,才算达到可以对比版本的门槛。

5.2 小规模评测集与评分维度的搭建

做完整评测不需要投入巨大成本,一个足够好的小评测集,用50到100条数据就能支撑日常迭代。关键是这些数据要独立于训练集,并且覆盖真实业务里的高频场景。

我的评测集来源有两种。一种是从历史对话记录里随机抽出来的真实样例,这些数据必须和训练数据没有重叠。另一种是按照业务场景编写的模拟问题,用来测试特定能力,比如多轮记忆、边界拒绝、格式遵循。

评分维度可以按任务复杂度拉一个简单表格:

维度说明评分
回答准确性是否输出正确内容1-5
指令遵循是否严格按要求的格式输出1-5
多轮一致性上下文多轮时是否保持连贯1-5
语气风格是否符合设定角色或语气1-5
拒答表现遇到无法回答的内容时是否得体1-5

每次训练后,我会对评测集跑一批通用提示词,把所有输出记录下来,按表格评分。不用每轮都精读所有数据,但要保证每一轮都能分维度对比。

5.3 过拟合不好发现?教你三个检测信号

过拟合有一些可以主动检测的信号。第一个信号是验证集loss先降后升。训练日志里如果验证loss在某一轮开始持续升高,基本可以判断后续轮次会让模型越来越偏离理想状态。第二个信号是复读训练数据。你拿一条训练集里的问题去问,模型不是给出近似答案,而是几乎逐字复刻标准答案,这就是记忆力过强、理解力不足的表现。

第三个信号是通用能力衰退。微调前模型能回答的常识问题,微调后反而答不好,说明训练指令冲掉了原有能力分布。检测方式很简单:准备一组和业务无关的通用问题,在微调前和微调后分别回答对比。通用能力降幅过大时,我会降低epoch数、减小学习率,或者检查数据里是否多条数据都偏向同一模式。

5.4 迭代方向:数据优先,再谈参数

当评估结果不理想,第一反应别急着调参。调参确实有用,但很多时候问题的根源在数据。

如果模型回答不准确,先看标准答案是否本身就有错误或歧义。正确答案有问题,模型再怎么练也是错。如果模型风格不对,检查数据集里的输出风格是否统一,或者数据里混杂了大量不符合目标的文本。如果模型在某些类别上明显落后,回到类别平衡统计那里,给少数类别补充数据。

在确认数据层面无大问题后,再考虑调整参数。过拟合优先减少epoch和降低学习率;欠拟合优先增加数据量或适度提高学习率。这样把“数据问题”和“参数问题”分开排查,迭代效率会高很多。

6. 导出合并与落地部署:微调模型真正可用的一步

6.1 LoRA训练实际改了什么

从原理上看,LoRA训练时原始权重没有被修改,训练产物是一组加在特定层上的低秩增量矩阵。推理时如果你不合并,也可以临时把这些增量加载进去,效果一样。合并的意思是把原始权重和增量矩阵相加,生成一个新的融合权重文件。

为什么需要合并?主要是因为部署时越简单越不容易出错。如果推理框架原生支持加载adapter,当然可以保留LoRA形式;但很多部署环境希望的是一个独立完整的模型目录,直接当成普通底座模型来加载。

每次合并前我都会保留原始权重和原始LoRA产物,确认合并路径无误,避免覆盖重要文件。

6.2 导出合并命令与必要校验

LLaMA-Factory提供的导出命令思路很清晰。指定底模路径、LoRA产物路径、模板类型,然后输出到新目录:

llamafactory-cli export \ --model_name_or_path /models/your-base-model \ --adapter_name_or_path ./output/lora-demo \ --template llama \ --finetuning_type lora \ --export_dir ./output/merged-model

导出完成后,我会做三层校验。第一层是文件完整性:新目录里应该有和底座模型一致的文件结构。第二层是加载验证:用加载函数尝试加载新目录,看看能不能正常跑通一次简单推理。第三层是A/B对比:合并模型调用一次典型业务问题,再回头看LoRA训练时输出的该问题答案,确认两者基本一致。

有一次我合并后没有校验,直接部署上线,结果模型输出里混入了奇怪的模板前缀。排查好久才发现是模板参数没有对齐。所以这类校验步骤最好不要跳过。

6.3 部署形式:合并模型与保留adapter的取舍

部署时我会按场景做选择。如果任务比较固定,只有一个微调版本要上线,合并成完整模型最省心。后续直接把它当作普通底座模型,接入常见的推理服务即可。如果同一底座同时有多个任务适配,比如一个负责客服,一个负责内容生成,那保留多个adapter文件更灵活,推理时按需切换。

但保留adapter形式对推理框架有一定要求,它需要支持动态注入LoRA权重。如果团队现有部署链路不支持,就老老实实合并后再上。我个人的习惯是:凡是进入了正式服务流程,尽量用合并后的完整模型;如果是实验验证阶段,才保留adapter形式。

6.4 训练产物的保存习惯

训练过程中输出目录会按save_steps保存多个checkpoint。很多人训练完只保留最后一份,这种做法容易吃亏。我推荐的保存习惯是:

  1. 保留每个关键checkpoint下对应loss最低或验证loss最低的那份。
  2. 记录每一项实验的学习率、epoch、数据版本、备注信息。
  3. 合并模型时,在目录名里带上版本号或日期,方便回滚。

checkpoint文件占空间较大,不需要无限保存。常规做法是保留最优的一个或两个,其余在确认不需要后清理。清理前务必确认最优checkpoint已经导出合并成功。

7. 那些我花过学费的弯路,建议你直接绕开

7.1 数据格式错一个字段,损失函数照样降得很顺

我第一次微调时,把自定义数据的字段映射写错了。结果框架把input字段读成了空值,模型训练时相当于只看了半句话和答案。最迷惑的是训练全程loss正常下降,输出目录里也有checkpoint,一切看起来都“成功”了。直到评估阶段发现模型压根没学会指令,回头查数据映射才发现问题。

这个问题让人防不胜防的原因在于,字段映射错误几乎不会导致训练失败,它会悄悄污染学习信号。我从那以后给自己立了条规矩:正式训练前先读几行数据,用打印方式确认每条记录的字段是否正确落到预期位置,有必要的话先跑一条极短训练,看训练loss曲线是否明显下降。

7.2 学习率从2e-4调到6e-4,模型只会“激动”不会回答

有段时间我觉得模型学得太慢,把LoRA学习率从2e-4直接提到6e-4。结果训练前期损失下降得非常快,我一度以为找到了更优解。等验证阶段测试,模型回答变得碎片化,甚至出现了重复输出和车轱辘话。

这是因为过大学习率让低秩增量矩阵一下跳得太远,破坏了原有模型参数分布的合理性。微调不是越快越好,而是在速度和可靠性之间找平衡点。吃过这次亏后,我再调学习率都按1.5倍以内去微调,并且每次调整都会搭配一次短验证,不直接跑完整训练。

7.3 盲目堆GPU数量不如先检查单卡吞吐

多卡训练能缩短时间,但前提是代码和数据加载逻辑正确。我有一次试图把训练扩展到多卡,结果发现速度并没有随GPU数量线性提升。仔细排查后发现大部分时间花在数据读取和预处理上,GPU资源大量空闲。

对入门项目来说,先用单卡跑通整个流程比盲目分布式更重要。如果确实需要加快速度,可以先把数据预处理的耗时压下去,比如缓存处理结果、减少重复读取、使用更快的磁盘。GPU数量增加不会帮忙解决数据读取瓶颈,只会让瓶颈更加明显。

7.4 调参前先做实验记录,不然等于白调

调参不可怕,可怕的是调完之后不记得之前是怎么调的。我见过很多新手跑完一轮训练,发现效果不好,随机改几个参数再来一轮,最后训练了好几个版本,却分不清哪个是哪个。

我的建议是准备一张简单的Markdown实验表,或者用Excel记录,至少包含实验日期、数据版本、数据集条数、学习率、epoch、rank、max_length、训练loss、验证loss、评测结果和备注。刚开始可能觉得麻烦,但等你要复盘或向别人请教时,这份表格的价值就体现出来了。

我在后续项目里一直坚持这个习惯,后来返工找问题的时间大幅缩短。很多困惑其实不是模型造成的,而是实验缺乏可复现的上下文。

做LLaMA-Factory微调入门,真正的手感不是靠别人一句两句能点透的,得自己走完从数据准备到评估对比的完整闭环。我自己的体会是:先别急着追求复杂技巧,把最基础的LoRA流程反复跑顺几遍,学会读日志、看损失、做评估,再往SFT、多轮数据、分布式训练这些方向扩展,会轻松很多。

如果你一开始只能记住一条建议,那就是先用少量数据跑通再扩量。我到现在依然保持这个习惯,任何新实验都用最小数据集验证可行性,确认链路没问题之后才上完整数据。这条路可能看起来多花了一些时间,但它省下的混乱和返工时间,远比你想的多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询