前言
大模型统治深度学习的趋势不可阻挡,抱着“打不过就加入,多学点东西没坏处”的想法,博主利用下班时间摸索了些大模型相关的技术,蹭了蹭国产之光《黑神话:悟空》的热度,做了个有关黑神话的AI助手,初版功能可以聊天查询游戏内容、攻略、背景故事等,后续会继续加入多模态、Agent等功能。因为是刚入门(大佬们请跳过😂)涉及的技术主要是llm的数据制作、训练、微调、量化、rag部署等。
叠个甲,下面部分绝非广告,本人由衷感谢这个开源社区:
以上结果都离不开书生*浦语以及他们开发的InternLM系列模型和工具的支持,真的是万分感谢!!!不光有免费的课程教程、还有免费算力支持,造福广大平民学者,感谢。
项目简介
悟了悟了的模型使用 xtuner在 InternLM2.5 微调得到, 首先在一些网络数据上进行增量预训练,再基于RAG生成的准确的问答对数据集,基于此数据集进行QLoRA指令微调。部署时集成了RAG和LMDeploy 4bit 加速推理
代码相关
代码数据均已开源,如果对你有帮助请点个Star,感谢⭐:
https://github.com/xzyun2011/wulewule
效果图
wulewulev1_7b_4bit
框架图
初版功能较为简单,收集数据后使用了RAG进行知识提取制作训练数据,再基于xtuner进行QLoRA的微调,再基于LMDeploy进行4bit量化,然后加入基于LangChain的RAG来提升回答准确性。
技术讲解
数据集制作
高质量的数据集是训练和微调模型的关键,数据制作一般会借用一些大模型的API(如InterLM、DeepSeek、Qwen、OpenAI等),可以去对应官网查看或者用第三方的如硅基流动(注册会送一定量token,足够用来做数据)等,一般付费的效果更好。
本模型数据制作包含增量预训练数据和微调数据两部分,最终格式是适配了Xtuner训练格式的数据:
增量预训练数据是从网络上收集到的和《黑神话:悟空》、《西游记》、《悟空传》等相关的文本数据。
微调数据是用来给模型指令微调的问答对数据,制作难点在于知识的实时性和准确性,本模型借助茴香豆RAG功能,从收集的文本资料中提取准确的知识信息。
如果想了解更多和数据制作相关的,可以看代码中 data/readme.md
模型训练
增量预训练(Incremental Pretraining)
增量预训练是指在一个已经预训练过的模型基础上,引入新的数据或特定领域的数据来进一步训练模型,旨在使模型适应新的领域或任务。训练数据不需要标注,模型从中学习通用特征和先验知识。
特点:
- 数据规模大:通常需要大量的新数据,这些数据可能与原始预训练数据分布不同。
- 目标:增强模型的整体能力和适应性,使其能够处理更广泛的任务和数据。
- 应用场景:适用于模型需要覆盖新的领域或任务时。例如,一个通用的语言模型需要适应医疗领域的文本处理。
指令微调(Instruction Fine-tuning)
指令微调通过在特定任务的数据上进一步训练预训练模型,使其在特定任务上表现更好。指令微调特别关注模型对特定指令或任务的理解和执行能力。
特点:
- 数据规模小:通常使用较小的数据集,专注于某个具体任务的数据,如情感分析、文本分类等。
- 目标:优化模型在特定任务上的表现,使其能够更好地理解和执行特定指令。
- 应用场景:适用于模型已经具有足够的通用知识,但需要在特定任务上进行优化时。例如,一个通用的语言模型需要在情感分析任务上表现更好。
一般而言,做"领域知识注入"时,使用指令微调会比增量预训练的效率更高,另外一般大模型泛化性已经比较好了,直接加个RAG也能用,所以如果是基于chat模型做些角色扮演、聊天机器人、学习某种风格等简单任务用微调的方式最好。
但如果你有海量的特定领域数据,或者想让模型学会某个行业深入的知识,可以试试看增量预训练。前提还是得有大量高质量的领域数据,可以是未标注过的,因为模型是去学数据的分布(续写能力)。
本模型是基于xtuner训练,如果想了解更多和模型训练相关的,可以看代码中 xtuner_config/readme.md
模型量化
本项目基于lmdeploy对模型进行了W4A16量化(Activation-aware Weight Quantization - AWQ),推理时使用了KV缓存(KV Cache)
W4A16量化
W4A16量化是一种特定的量化技术,其中权重(weight)被量化为4位整数(INT4),而激活(activation)保持为16位浮点数(FLOAT16)。这种组合在减少模型存储空间和计算复杂度的同时,尽量保留了模型的精度。
-
参数压缩:通过将模型中的浮点数参数转换为低精度的整数参数,可以显著减少模型所需的存储空间,降低模型加载的时间。
-
计算加速:由于低精度整数运算的速度远快于浮点数运算,W4A16量化可以通过降低计算复杂度来实现计算加速。
KV缓存技术
KV缓存(键值缓存)是一种应用于仅解码器Transformer中的工程优化技术,通过增加内存利用率来减少计算量。在Transformer模型中,KV缓存可以缓存过去token的键和值向量,避免在每次生成步骤中重新计算,从而减少FLOPs,实现线性增长。
- 预填充阶段:输入一个prompt序列,为每个Transformer层生成key cache和value cache(KV cache)。
- 解码阶段:给定当前生成词在第i个Transformer层的向量表示,推断计算分两部分:更新KV cache和计算第i个Transformer层的输出。
量化前后速度对比
Model | Toolkit | Speed (words/s) |
---|---|---|
wulewule_v1_1_8b | transformer | 68.0986 |
wulewule_v1_1_8b-w4a16-4bit | LMDeploy (Turbomind) | 667.8319 |
RAG(检索增强生成)
RAG一般流程
- 将原始数据切分后向量化,制作成向量数据库
- 对用户输入的问题进行 embedding
- 基于 embedding 结果在向量数据库中进行检索
- 对召回数据重排序(选择和问题更接近的结果)
- 依据用户问题和召回数据生成最后的结果
悟了悟了默认data
目录为txt数据源目录,开启RAG后,会使用bce-embedding-base_v1自动将data
目录下的txt数据转为换chroma向量库数据,存放在rag/chroma
目录下(如果该目录下已有数据库文件,则跳过数据库创建),然后使用bce-reranker-base_v1对检索到的信息重排序后,将问题和上下文一起给模型得到最终输出。rag/simple_rag.py
里是一个简单的demo,参数配置见configs/rag_cfg.yaml
。
LangChain在这块的工具比较好,各种功能都有,本模型的RAG是基于LangChain进行开发的,如果想了解更多和模型训练相关的,可以看代码中 rag/readme.md
后续计划
目前初版只实现如下功能的chat模型:
-
游戏角色、背景故事、原著关联性等知识问答助手
-
使用RAG支持游戏攻略、菜单、网络梗等新鲜知识的更新
-
基于OpenXLab使用LMDepoly实现初版demo部署
-
增加history记忆,增加标准测试集,opencompass评估模型性能
后续想加入多模态的功能,尤其是图像类的,和自己专业领域更相关点,基座模型也想换成多模态的
-
加入语音多模态,如ASR(用户语音输入)、TTS(猴哥语音回答问题)
-
加入图像生成,接入别人的SD+LoRA模型,判断用户意图生成对应prompt的天命人
-
基于Agent开发一些功能
-
基座模型换成类型
致谢
最后再次由衷感谢上海人工智能实验室推出的书生·浦语大模型实战营及系列工具提供宝贵的技术指导和强大的算力支持!
最后的最后,如果你是对大模型感兴趣又苦于算力,欢迎报名刚刚开启的第四期书生·浦语大模型实战营,课程和算力都是免费的。上InternLM实战营官网或者点击书生实战营第四期报名均可,一起学习,一起进步~