LLama_Factory模型微调课程笔记
一、数据集准备
(一)支持数据格式
LLama_Factory支持alpaca和sharegpt两种数据格式,其中alpaca数据集较为常用。其数据结构呈现为json对象列表,包含以下关键信息:
信息类别 | 是否必填 | 描述 | 示例 |
---|---|---|---|
instruction | 是 | 明确模型生成内容的方向,代表用户指令 | 写一篇关于人工智能发展趋势的文章 |
input | 否 | 用于补充更具体的背景或条件,约束模型生成内容范畴 | 侧重于医疗领域的人工智能发展 |
output | 是 | 模型应给出的正确示范回答,用于训练模型给出恰当输出 | 阐述医疗领域人工智能在疾病诊断、药物研发等方面的趋势…… |
system | 否 | 系统提示词 | 无 |
history | 否 | 用于多轮对话,以数组形式记录每轮指令和回答 | [{“instruction”: “我购买的商品如何退货”, “output”: “您可以先联系客服……”}, {“instruction”: “退货后多久能收到退款”, “output”: “通常在收到退货后的7个工作日内……”}] |
(二)示例数据
- 单轮数据示例:
- “instruction”为“写一个有效的比较语句”。
- “input”是“篮球和足球”。
- “output”是“篮球和足球都是受欢迎的运动”。
- 多轮数据示例:
除基本信息外,“history”会记录多轮对话。例如:
第一轮指令“请你给我写一个面试准备计划,我想去面试微软的程序员岗位”及对应的回答。
第二轮指令“面试着装方面有什么建议”及对应的回答,这些对话依次记录在“history”中 。
(三)自带数据集操作
- 查看数据:
数据集存储于LLaMA - Factory/data
目录下。在Linux系统中,可利用head
或tail
命令查看数据的部分内容。
head
命令:默认显示文件的前10行内容。若想显示前20行,使用head -n 20
加上文件名的命令格式。例如,查看data.json
文件的前20行,命令为head -n 20 data.json
。tail
命令:默认显示文件的最后10行。若要显示最后5行,命令为tail -n 5
加上文件名。如查看data.json
文件的最后5行,命令为tail -n 5 data.json
。
通过这些命令能快速预览数据集的格式和质量。
- 替换数据:
数据中若存在关于模型自我认知的对话,可借助sed
命令替换“name”和“author”值。假设数据集文件名为“data.json”,在Linux系统中,替换“name”值的完整sed
命令如下:
sed -i's/"name":"原有名称"/"name":"木木"/g' data.json
这行命令表示在“data.json”文件中,将所有“name”字段后的“原有名称”替换为“木木”。其中-i
参数表示直接在原文件上进行修改,s
表示替换操作,g
表示全局替换(即文件中所有符合条件的都替换)。对于“author”值的替换,只需相应修改命令中的字段和替换值即可。
二、启动界面与微调设置
(一)启动命令与环境变量
- 下载源设置:
在不同系统中,可通过设置环境变量来更改模型下载源:
- Linux/Mac系统:
export USE_MODELSCOPE_HUB = 1
- Windows系统:
set USE_MODELSCOPE_HUB = 1
设置后,模型将从ModelScope社区下载,而非默认的Hugging Face。在网络环境复杂的情况下,国内部分用户从Hugging Face下载模型可能速度慢或无法下载,切换到ModelScope社区可提升下载效率,因为该社区针对国内网络环境做了优化。
- GPU设备指定:
若服务器配备多个GPU,可利用CUDA_VISIBLE_DEVICES
环境变量指定使用的显卡。
例如,CUDA_VISIBLE_DEVICES = 0,1
表示使用编号为0和1的两张显卡。在深度学习训练中,合理分配GPU资源至关重要,通过该环境变量可控制程序可见的GPU设备,避免其他卡被占用,方便对特定GPU资源进行监控和管理。比如,当服务器有4张GPU卡,而当前训练任务只需要使用编号为2和3的两张卡时,设置CUDA_VISIBLE_DEVICES = 2,3
即可。 - 启动命令与日志记录:
启动LLaMA - Factory界面的命令是llamafactory - cli webui
。通常结合nohup
命令让其在后台运行,并将日志输出到指定文件,命令格式为:
nohup llamafactory - cli webui > 20241119.log 2>&1 &
其中,nohup
命令用于在Linux系统中使命令在后台持续运行,即使终端关闭也不受影响;其标准输出(默认是终端显示)会重定向到指定文件(“20241119.log”),2>&1
表示将标准错误输出也重定向到标准输出相同的位置(即该日志文件),最后的“&”符号表示让该命令在后台异步执行。日志文件位于启动命令所在路径,通过查看日志文件可了解程序运行状态。
(二)微调参数设置
-
模型路径设置:
启动进入界面后,需设置模型路径。建议使用绝对路径,若已下载模型则直接指定;未下载则输入名称后会自动下载。- 绝对路径是从文件系统的根目录开始完整描述文件位置的路径。例如在Linux系统中,若模型存放在“/home/user/models/llama - 3 - 8b”目录下,那么绝对路径就明确为“/home/user/models/llama - 3 - 8b”。
- 相对路径则是相对于当前工作目录的路径,其准确性依赖于启动命令时所在的目录。当在
LLaMA - Factory
目录下启动程序,数据文件在其下的“data”目录,所以相对路径填“data”即可;若在上级目录启动,当前工作目录改变,就需要明确写出从当前工作目录到数据文件的相对路径“LLaMA - Factory/data”。
-
微调方法选择:
以LoRA(Low - Rank Adaptation)为例,它的优势显著。在不改变原始模型参数的基础上,通过引入少量可训练的低秩矩阵来适应新的任务,大大减少了训练参数的数量。例如,对于一个拥有大量参数的庞大语言模型,全量参数微调可能需要占用大量的GPU显存,且训练时间漫长。而使用LoRA微调,可能只需占用极少的额外显存,同时能在较短时间内完成训练,并且在一些任务上能达到与全量微调相近的效果。 -
量化参数设置:
量化是将模型参数从较高精度的数据类型转换为较低精度(如从32位浮点数转换为16位浮点数甚至更低精度),以减少内存占用和计算量,提高推理速度。在微调设置中,若选择量化,需要设置量化位数等相关参数。不同的量化位数对模型性能和内存节省效果有不同影响。一般来说,量化位数越低,内存节省越多,但可能对模型精度产生一定影响,需要根据实际应用场景和对模型性能的要求进行权衡选择。例如,在对模型精度要求不是特别高,但对内存占用和推理速度要求较高的移动端应用中,可选择较低的量化位数;而在对精度要求苛刻的科研计算场景中,则需谨慎选择量化位数,以确保模型性能。
-
训练轮数设置:
训练轮数即模型对数据集进行学习的次数。默认3次训练轮数在一些简单任务或数据集较小的情况下可能足够,但对于复杂任务和大规模数据集,适当增加训练轮数能让模型更好地学习数据特征,提升模型性能。例如在一个包含大量文本的情感分析任务中,增加训练轮数可能使模型更精准地识别各种情感倾向的表达模式,从而提高情感分析的准确率。但训练轮数也并非越多越好,过多可能导致过拟合,即模型过度学习了训练数据中的噪声和特殊情况,在新数据上的泛化能力下降。
三、训练过程监控与完成验证
(一)训练监控
- GPU使用监控:
训练时可借助watch -n 1 nvidia - smi
命令每秒刷新监控GPU使用情况。nvidia - smi
(NVIDIA System Management Interface)是NVIDIA提供的一个命令行工具,用于监控GPU的状态,包括GPU的使用率、显存使用情况、温度等信息。watch -n 1 nvidia - smi
命令表示每隔1秒执行一次nvidia - smi
命令并刷新显示结果。在模型训练过程中,密切关注GPU显存使用量能及时发现是否存在显存不足导致的训练中断问题。例如,当训练过程中GPU显存使用量持续上升并接近或达到GPU的显存上限时,可能会出现程序报错或训练突然终止的情况,此时就需要调整训练参数(如减小批量大小)来降低显存需求。 - 训练日志分析:
训练日志会记录模型加载路径、参数等关键信息。训练日志文件记录了模型从何处加载(如加载的模型路径)、使用的训练参数(如学习率、训练轮数、优化器类型等)、每一轮训练的损失值、训练开始和结束时间等。通过分析训练日志,我们可以了解模型训练的进展是否正常。比如,如果发现损失值在多轮训练中没有明显下降,可能意味着模型没有有效学习,需要检查数据集质量、训练参数设置是否合理等;若日志中出现报错信息,也能根据报错内容定位问题所在,如可能是数据格式错误、代码中存在逻辑错误等。
(二)训练完成验证
- 切换验证界面:
训练完成后,切换到“chat”界面验证效果。 - 模型与模板选择:
- 模型选择保持不变,选择微调输出的检查点路径(与训练时输出路径一致 )。
- 确保使用与微调时相同的模板,防止因模板不一致导致模型输出异常。模板在模型对话生成中起着关键作用,它规定了输入和输出的格式以及一些提示信息。不同的模型可能有不同的适用模板,若在微调时使用了特定模板来组织输入数据,在验证时不使用相同模板,模型可能无法正确解析输入内容,从而导致输出异常。例如,微调时模板中要求输入以特定前缀开头(如“用户问题:”),若验证时输入没有这个前缀,模型可能无法识别问题,给出不符合预期的回答。
- 加载模型与验证:
点击“加载模型”后,输入对话内容(如“hello”),模型会给出回答,以此检验微调效果。在“chat”界面进行验证时,保持模型选择与训练时一致,是为了确保验证的是经过微调后的目标模型。微调输出的检查点路径保存了训练过程中模型在不同阶段的参数状态,选择与训练时一致的检查点路径,能加载到正确的微调后模型参数。
四、模型合并导出与再次验证
(一)模型合并导出
- 合并原理与操作:
训练完成且验证效果良好后,进行模型合并导出。在导出界面,检查点和原模型保持不变,另外创建一个绝对路径作为合并权重后的输出路径(若路径不存在会自动创建 )。模型合并的原理是将基础模型的参数与LoRA训练过程中学习到的低秩矩阵权重进行融合,得到一个完整的、可直接用于推理或部署的模型。检查点包含了LoRA训练后的权重信息,原模型则是初始的基础模型。确保检查点和原模型不变,是为了保证合并的准确性。 - 输出路径设置:
新创建的绝对路径用于存储合并后的模型,这样在后续使用模型时,能够方便地从该路径加载完整的模型。例如,在一个实际的应用部署场景中,我们将合并后的模型导出到“/home/user/deployed_models/merged_llama_model”路径下,后续部署推理服务时,就可以直接从这个路径加载模型,为用户提供服务。
(二)再次验证
- 加载微调合并后模型:
返回“chat”界面,加载微调合并后的模型路径(即导出的模型路径 ),关闭检查点缓存,保证只使用微调合并后的模型。关闭检查点缓存是为了确保加载的是完整的微调合并后的模型,而不是依赖之前训练过程中的检查点缓存数据。如果不关闭检查点缓存,可能会出现模型加载的参数混乱,导致使用的不是最终合并后的模型。 - 对话验证:
输入对话内容测试模型回答的准确性、合理性以及与预期效果的匹配度。例如,在一个智能问答应用中,输入一系列常见问题和一些边缘情况问题,观察模型是否能给出准确、清晰的回答,若模型在各种测试问题上都能表现良好,就说明整个微调、合并流程是成功的,合并后的模型可正常投入使用。
五、后续学习与拓展
主要记录了课程中使用LLaMA - Factory自带数据集进行模型微调的基础流程,之后会有自己的实现记录下来,还是踩了很多雷。
下节课将涉及自定义数据集的注册与使用,会有更多代码操作。自定义数据集的注册与使用在实际应用中非常重要,因为自带数据集往往无法完全满足多样化的业务需求。例如,在一个电商客服场景中,企业可能拥有大量与自身产品、客户常见问题相关的对话数据,这些数据具有独特的业务特征和语言风格。通过注册和使用自定义数据集进行模型微调,模型能够更好地理解和回答与该电商业务相关的问题,提高客服效率和客户满意度。在注册自定义数据集时,需要按照LLaMA - Factory规定的数据格式进行整理和转换,可能涉及数据清洗、标注等操作,并且在代码层面需要编写相应的脚本将数据集与LLaMA - Factory的训练流程进行对接,这些都需要学员在后续课程中深入学习和实践。