赞
踩
在模型训练过程中,数据及数据处理是最为重要的工作之一。在当前模型训练流程趋于成熟的情况下,数据集的好坏,是决定了该次训练能否成功的最关键因素。
在上一篇中,我们提到了模型训练的基本原理是将文字转换索引再转换为对应的向量,那么文字转为向量的具体过程是什么?
在NLP(自然语言处理)领域中,承担文字转换索引(token)这一过程的组件是tokenizer。每个模型有自己特定的tokenizer,但它们的处理过程是大同小异的。
首先我们安装好魔搭的模型库modelscope和训练框架swift:
#激活conda环境后
pip install modelscope ms-swift -U
我们使用“千问1.8b”模型将“杭州是个好地方”转为tokens的具体方式是在python中调用:
from modelscope import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("qwen/Qwen-1_8B-Chat", trust_remote_code=True)
print(tokenizer('杭州是个好地方'))
#{'input_ids': [104130, 104104, 52801, 100371], 'token_type_ids': [0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1]}
其中的input_ids就是上面我们说的文字的token。可以注意到token的个数少于实际文字的数量,这是因为在转为token的时候,并不是一个汉字一个token的,可能会将部分词语变为一个token,也可能将一个英文转为两部分(如词根和时态),所以token数量和文字数量不一定对得上。
每种模型有其特定的输入格式,在小模型时代,这种输入格式比较简单:
[CLS]杭州是个好地方[SEP]
[CLS]代表了句子的起始,[SEP]代表了句子的终止。在BERT中,[CLS]的索引是101,[SEP]的索引是102,加上中间的句子部分,在BERT模型中整个的token序列是:
101, 100, 1836, 100, 100, 100, 1802, 1863, 102
我们可以看到,这个序列和上面千问的序列是不同的,这是因为这两个模型的词表不同。
在LLM时代,base模型的格式和上述的差不多,但chat模型的格式要复杂的多,比如千问chat模型的template格式是:
<|im_start|>system
You are a helpful assistant!
<|im_end|>
<|im_start|>user
How are you?<|im_end|>
<|im_start|>assistant
其中“You are a helpful assistant!”是system字段,“How are you?”是用户问题,其他的部分都是template的格式。
system字段是chat模型必要的字段,这个字段会以命令方式提示模型在下面的对话中遵循怎么样的范式进行回答,比如:
“You are a helpful assistant!”
“下面你是一个警察,请按照警察的要求来审问我”
“假如你是一个爱哭的女朋友,下面的对话中清扮演好这个角色”
system字段规定了模型行为准则,比如当模型作为Agent使用时,工具集一般也是定义在system中的:
“你是一个流程的执行者,你有如下工具可以使用:
工具1:xxx,输入格式是:xxx,输出格式是:xxx,作用是:xxx
工具2:xxx,输入格式是:xxx,输出格式是:xxx,作用是:xxx”
复杂的template有助于模型识别哪部分是用户输入,哪部分是自己之前的回答,哪部分是给自己的要求。
比较麻烦的是,目前各开源模型还没有一个统一的template标准。在SWIFT中,我们提供了绝大多数模型的template,可以直接使用:
register_template(
TemplateType.default,
Template([], ['### Human:\n', '{{QUERY}}\n\n', '### Assistant:\n'],
['\n\n'], [['eos_token_id']], DEFAULT_SYSTEM, ['{{SYSTEM}}\n\n']))
#ou can set the query as '' to serve as a template for pre-training.
register_template(TemplateType.default_generation,
Template([], ['{{QUERY}}'], None, [['eos_token_id']]))
register_template(
TemplateType.default_generation_bos,
Template([['bos_token_id']], ['{{QUERY}}'], None, [['eos_token_id']]))
qwen_template = Template(
[], ['<|im_start|>user\n{{QUERY}}<|im_end|>\n<|im_start|>assistant\n'],
['<|im_end|>\n'], ['<|im_end|>'], DEFAULT_SYSTEM,
['<|im_start|>system\n{{SYSTEM}}<|im_end|>\n'])
register_template(TemplateType.qwen, qwen_template)
register_template(TemplateType.chatml, deepcopy(qwen_template))
...
有兴趣的小伙伴可以阅读:https://github.com/modelscope/swift/blob/main/swift/llm/utils/template.py 来获得更细节的信息。
template拼接好后,直接传入tokenizer即可。
微调任务是标注数据集,那么必然有指导性的labels(模型真实输出)存在,将这部分也按照template进行拼接,就会得到类似下面的一组tokens:
input_ids: [34, 56, 21, 12, 45, 73, 96, 45, 32, 11]
---------用户输入部分--------- ----模型真实输出----
labels: [-100, -100, -100, -100, -100, 73, 96, 45, 32, 11]
在labels中,我们将用户输入的部分(问题)替换成了-100,保留了模型输入部分。在模型进行运算时,会根据input_ids的前面的tokens去预测下一个token,就比如:
已知token 预测的下一个token
34 ->17
34,56 ->89
...
34,56,21,12,45 ->121
34,56,21,12,45,73 ->99
34,56,21,12,45,73,96 ->45
34,56,21,12,45,73,96,45 ->14
34,56,21,12,45,73,96,45,32->11
可以看到,这个预测不一定每个都预测对了,而且呈现了下三角矩阵的形态。那么训练的时候就可以这样进行对比:
34, 56, 21, 12, 45, 121, 99, 45, 32, 11
-100, -100, -100, -100, -100, 73, 96, 45, 14, 11
-100部分计算loss时会被忽略,因为这是用户输入,不需要考虑预测值是什么。只要对比下对应的位置对不对就可以计算它们的差异了,这个差异值被称为loss或者残差。我们通过计算梯度的方式对参数进行优化,使模型参数一点一点向真实的未知值靠近。使用的残差算法叫做交叉熵。
在SWIFT中提供了根据模型类型构造template并直接转为token的方法,这个方法输出的结构可以直接用于模型训练和推理:
from swift.llm.utils import get_template, Template
from modelscope import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("qwen/Qwen-1_8B-Chat", trust_remote_code=True)
template: Template = get_template(
'qwen',
tokenizer,
max_length=256)
resp = template.encode({'query': 'How are you?', "response": "I am fine"})[0]
print(resp)
#{'input_ids': [151644, 8948, 198, 2610, 525, 264, 10950, 17847, 13, 151645, 198, 151644, 872, 198, 4340, 525, 498, 30, 151645, 198, 151644, 77091, 198, 40, 1079, 6915, 151645], 'labels': [-100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, 40, 1079, 6915, 151645]}
input_ids和labels可以直接输入模型来获取模型的输出:
from modelscope import AutoModelForCausalLM
import torch
model = AutoModelForCausalLM.from_pretrained("qwen/Qwen-1_8B-Chat", trust_remote_code=True).to(0)
resp = {key: torch.tensor(value).to(0) for key, value in resp.items()}
output = model(**resp)
print(output)
判断自己的场景需要什么样的方法是使用LLM的第一步。下面我们会对比直接推理(提示词工程)、训练、RAG、Agent方法的具体场景,讲解这几种方式的特点,并给出适用场景、使用难度、准确性、成本、缺点几个方面的总结。
这种方式特指直接使用现有LLM,利用prompt范式激活模型不同的能力完成特定需求。直接推理方式对开发的要求较低,一般可以完成通用类型的任务,如通用知识问答、角色扮演等。使用方式如下:
用户:你是一个经验丰富的导游,请使用导游的话术回答游客的问题。
模型:当然可以!请问你需要问些什么呢?
用户:我想去杭州旅行,请告诉我哪里比较值得去。
模型:当然可以!作为一个导游,我可以为你讲解杭州的风景和美食...
使用难度
提示词工程无论是直接推理或训练后推理都是需要的。
适用场景
准确性
成本
缺点
全量训练和轻量训练是训练的两种方式,它们的区别在于:
全量训练在给定LLM模型上冻结一定的参数(或不冻结任何参数)进行训练,一般耗费显存较高,训练周期比较长。受限于成本问题,最近出现了轻量微调方式,主要方案是在模型结构上附着一个额外结构,在训练时冻结原模型并训练额外结构,推理时将额外结构加载起来或合并回原来模型(并不是所有的额外结构都支持合并,支持者比如LoRA,不支持者比如Side)。轻量微调目前的最流行结构是LoRA,该结构理解简单,训练成本较低,在部分任务上可以达到全量微调的效果。
轻量微调另一个方式就是量化(请查看另一篇文章),即对模型的float32权重或float16权重进行缩放,使其变成int类型的整形,节省显存或计算时长。
一般来说,预训练或继续训练不建议使用轻量训练,小数据量微调情况下建议优先使用轻量训练。
简单来说,模型的训练是让模型“找规律”的过程。比如告诉模型1+1=2, 2+2=4,那么让模型分析3+3=?
如果数据是带有规律的,比如文字顺序、逻辑关系、图片元素(比如斑马总是带有黑白色的条纹),那么训练就可以将这些规律抽象出来;如果数据是“无规律的知识”,比如用A解决B问题,用C解决D问题,那么这些数据训练后就几乎不具有泛化性,因为模型无法分析出出现了E问题应该用A解决还是B解决,这时候应当选用RAG或者Agent方式,或者训练的目标改为让模型熟悉使用工具来解决问题。
使用难度
准确性
成本
Model Type [LoRA] | Max Length | Training Speed (samples/s) | GPU Memory (GiB) |
---|---|---|---|
qwen-1_8b-chat | 512 | 9.88 | 6.99 |
1024 | 9.90 | 10.71 | |
2048 | 8.77 | 16.35 | |
4096 | 5.92 | 23.80 | |
8192 | 4.19 | 37.03 | |
qwen-7b-chat | 512 | 7.43 | 18.01 |
1024 | 6.51 | 21.73 | |
2048 | 4.31 | 27.74 | |
4096 | 2.05 | 35.31 | |
8192 | 1.34 | 48.41 | |
qwen-14b-chat | 512 | 5.63 | 30.14 |
1024 | 4.36 | 34.43 | |
2048 | 2.60 | 40.14 | |
4096 | 1.17 | 47.95 | |
8192 | 0.79 | 60.74 | |
qwen-72b-chat (2*A100) | 512 | 1.41 | 67.68+73.07 |
1024 | 1.02 | 70.25+77.11 | |
2048 | 0.59 | 73.71+78.54 | |
4096 | - | OOM | |
8192 | - | OOM | |
chatglm3-6b | 512 | 6.72 | 13.94 |
1024 | 6.16 | 12.99 | |
2048 | 4.20 | 17.20 | |
4096 | 1.92 | 29.80 | |
8192 | 1.24 | 66.82 | |
yi-6b-chat | 512 | 5.27 | 13.72 |
1024 | 5.07 | 15.44 | |
2048 | 3.84 | 16.95 | |
4096 | 1.99 | 28.25 | |
8192 | 1.35 | 43.81 | |
yi-34b-chat | 512 | 2.32 | 66.72 |
1024 | 1.76 | 69.10 | |
2048 | 1.05 | 71.34 | |
4096 | 0.47 | 78.72 | |
8192 | 0.31 (2*A100) | 47.01+65.03 | |
openbuddy-zephyr-7b-chat | 512 | 5.17 | 14.99 |
1024 | 3.92 | 16.57 | |
2048 | 3.08 | 19.89 | |
4096 | 1.85 | 23.29 | |
8192 | 0.92 | 52.14 | |
baichuan2-7b-chat | 512 | 6.09 | 18.18 |
1024 | 5.36 | 17.45 | |
2048 | 3.43 | 19.18 | |
4096 | 1.69 | 34.22 | |
8192 | 1.16 | 45.47 | |
baichuan2-13b-chat | 512 | 5.32 | 31.01 |
1024 | 3.91 | 31.58 | |
2048 | 1.77 | 32.40 | |
4096 | 0.65 | 49.63 | |
8192 | 0.36 | 76.17 |
Model Type [FULL] | Max Length | Training Speed (samples/s) | GPU Memory (GiB) |
---|---|---|---|
qwen-1_8b-chat | 512 | 10.77 | 18.16 |
1024 | 10.39 | 18.62 | |
2048 | 8.73 | 35.11 | |
4096 | 5.45 | 31.62 | |
8192 | 3.81 | 38.93 | |
qwen-7b-chat | 512 | 5.96 | 73.37 |
1024 | 5.00 | 73.64 | |
2048 | 3.30 | 74.26 | |
4096 | 1.64 | 78.76 | |
8192 | 1.11 (2*A100) | 61.34+73.00 | |
qwen-14b-chat (2*A100) | 512 | 3.66 | 60.42+72.31 |
1024 | 2.98 | 60.61+74.37 | |
2048 | 1.93 | 60.70+78.22 | |
4096 | 0.92 | 75.59+78.64 | |
8192 | 0.62 | 76.59+77.68 |
缺点
RAG即检索增强生成,也就是通过模型外挂知识库的方式来辅助模型回答。一般来说会将用户问题变为向量,进向量数据库进行查询,并召回符合条件的文档或回答,之后将回答直接返回或输入模型整理后返回。RAG可以查看另一篇教程。
RAG和微调的选型问题一直是被问的较多的问题之一,两种方法的对比可以查看下表:
如果模型本身对专业知识理解不够(比如模型对召回的文档不能进行良好分析的情况),那么使用RAG是不够的,需要进行模型训练,或将模型训练和RAG结合起来使用。
适用场景
使用难度
准确性
成本
缺点
Agent适合于利用模型进行代码编写运行、API调用的复杂场景。Agent的主要思路是利用模型的CoT(思维链)能力进行复杂场景的流程串接。比如“生成一个具有今天天气特征的海报”,模型会先调用天气预报接口获得天气,之后生成海报文案,然后调用文生图模型生成海报。
适用场景
使用难度
准确性
一般来说模型越大准确性越高。比如GPT4(闭源)、Qwen-max(闭源)、Qwen-72b(开源)、ChatGLM4(闭源)等会具有良好的效果,小模型可能需要特殊训练。
在格外复杂的场景下,比如任务复杂、描述含混不清、模型对行业流程不理解的情况下,需要对模型进行额外训练。
成本
缺点
目前国内外开源模型已经超过了几百个,挑选合适的模型是一个比较关键的问题。在这里可以给出一些泛泛的意见:
Agent场景尽量选择较大的模型或者闭源LLM API(如GPT4、Qwen-max)
训练场景中,数据量较大(比如大于10000条)、数据质量较高、专业度较高的训练优先选择base模型,数据量较少优先选择chat模型。在算力允许条件下可以进行对比训练实验
关注国内外的开源可信模型榜单,选择排名较高或口碑较好的模型
具体参考博客:大模型落地实战指南:从选择到训练,深度解析显卡选型、模型训练技、模型选择巧
更多优质内容请关注公号:汀丶人工智能;会提供一些相关的资源和优质文章,免费获取阅读。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。