DeepSeek大模型微调实战(超详细实战篇)
DeepSeek是由 深度求索 团队开发的大语言模型,本实验将基于deepseek-llm-7b-chat模型,在EmoLLM数据集进行微调,实现大模型能够以心理医生的口吻来回答我们的问题。
本实验基于transformers和openMind均已实现本次微调,代码均可在github链接上查看。
通过本次实验,你不仅能够完成 多轮对话数据的微调,还能掌握这些方法,并 将其迁移到其他微调实验中,独立进行高效的模型调优。
实际项目代码+结果演示
本次实验同时适配transformers和openMind,由于openMind缺少数据处理的函数,下面实验手动添加即可,其他部分和基于transformers的代码一致。
2.1 基本概念
1、openMind Library—>Huggingface Transformers
openMind Library类似于transformers的大模型封装工具,其中就有AutoModelForSequenceClassification、AutoModelForCausalLM等等模型加载工具以及像TrainingArguments参数配置工具等等,原理基本一样,不过对NPU适配更友好些。
2、魔乐社区—>HuggingFace
魔乐社区类似于huggingface这种模型托管社区,里面除了torch的模型还有使用MindSpore实现的模型。transformers可以直接从huggingface获取模型或者数据集,openMind也是一样的,可以从魔乐社区获取模型和数据集。
2.2 实验环境搭建及实验代码、结果
2.2.1 环境设置
在运行代码前,需要先配置环境,由于本次实验对比各个参数结果比较多,所以对显存要求稍微高点,具体环境配置如下:
GPU:40GB左右
Python:>=3.8
2.2.2 数据预处理
本次微调目的是使得大模型能够以医生的口吻来回答我们的问题,因此需要与心理健康有关的数据集资料。
⭐下载数据
本项目使用一个EmoLLM-心理健康大模型中使用的数据集(该数据集已经进行数据清洗,在保证质量的同时,通过调整阈值减少因错误匹配而丢失重要数据的风险。):EmoLLM-datasets
(https://github.com/SmartFlowAI/EmoLLM/tree/main/datasets)
数据集内容如下:
在训练前,我们需要将数据进行预处理,将数据集的内容进行数据映射,得到input_ids、attention_mask、labels三个映射目标,同时对数据填充到最大长度,并且转换成张量格式。
数据映射
这里可能会根据每个模型的不同做修改,如果不按照每个模型对应的格式训练,而是按照自己编写的格式进行训练,结果可能会出现由于max_length比较大使得回答停不下来,一直生成句子。
那么该如何确定训练文本格式❓其实在每一个模型的tokenizer_config文件中已经给出模板。
比如deepseek的模板如下:
如果模板看的有点抽象的话,可以直接参考Llama-Factory中deepseek模型对应的模板:
https://github.com/hiyouga/LLaMA-Factory/blob/main/src/llamafactory/data/template.py
数据封装
⚠️注意:
由于openMind缺少数据封装的函数,因此这部分代码需要我们手动添加,transformers直接调用即可。
transformers:
openMind:
2.2.3 设置lora参数
2.2.4 设置训练参数
2.2.5 设置可视化工具SwanLab
SwanLab是一款完全开源免费的机器学习日志跟踪与实验管理工具,为人工智能研究者打造。有以下特点:
●基于一个名为swanlab的python库
●可以帮助您在机器学习实验中记录超参数、训练日志和可视化结果
●能够自动记录logging、系统硬件、环境配置(如用了什么型号的显卡、Python版本是多少等等)
●同时可以完全离线运行,在完全内网环境下也可使用
代码如下:
2.2.6 设置训练器参数+训练
在微调Transformer模型时,使用Trainer类来封装数据和训练参数是至关重要的。Trainer不仅简化了训练流程,还允许我们自定义训练参数,包括但不限于学习率、批次大小、训练轮次等。通过Trainer,我们可以轻松地将这些参数和其他训练参数一起配置,以实现高效且定制化的模型微调。
这里我们需要以下这些参数,包括模型、训练参数、训练数据、处理数据批次的工具、还有可视化工具
2.2.7 保存模型
这里保存了模型的权重、配置文件和词汇表,确保你可以在之后重新加载并使用该模型进行推理或继续训练。模型的优化器状态、学习率调度器等其他信息如果需要保存,则需要显式调用其他相关方法,如 trainer.save_state()。
2.2.8 合并模型权重
保存下来的仅仅是模型的权重信息以及配置文件等,是不能直接使用的,需要与原模型进行合并操作,代码如下: