微信扫码
与创始人交个朋友
我要投稿
背景介绍
虽然目前的通用大模型LLM能够在很多任务上取得令人振奋的效果,但是很多私域业务领域由于由于和通用领域差距较大,直接应用开源LLM经常效果不能达到令人满意的程度。例如,电商领域、医学领域、智能制造领域、金融领域等需要专门精通的领域知识和领域内偏好,仅仅基于通用场景下的偏好知识等不能满足这些领域的输出需求。因此为了能够更好的促进LLM技术在这些领域的应用,我们开源发布了一套LLM训练方案,涵盖了领域post-training适配,指令微调(Instruction Tuning),RLHF模型训练(包含reward模型和基于稳定PPO算法的训练)。此外,我们还开源了一套基于fastapi的前后端部署方案,可以方便进行GUI demo展示、支持类openai访问协议,以及langchain[9]集成。
需要注意的是,我们的尝试并不是得到一个能与ChatGPT能力相当的模型,而是通过实践,验证基于有限资源定制领域大模型的可行性。希望我们总结的经验能够帮助大家更好地理解大模型的训练、评估以及应用。
整体流程
LLM的构建流程核心包含三部分:数据层、模型层、训练层、应用层。数据层囊括了业务语料、指令数据、代码数据等,是领域知识的核心来源。模型层主要包含了用于训练指令微调SFT模型和训练reward模型的Bloom 1.1B模型、0.56B模型,还有7B大小的Bloom和LLaMA可选模型。我们主要目的是通过领域适应训练融入大量领域知识,然后通过指令微调完成监督知识融合和模型输出服从指令的训练,最后经过RLHF达到模型偏好对齐人工偏好的目的。为了利用有限的资源去高效训练LLM模型,我们在训练层使用了基于deepspeed ZeRO[2]原理和megatron tensor-parallel的分布式训练方案,经过测试,在A100和V100机器上都可以运行。
我们使用的指令微调数据50%来自领域场景,主要使用基于模板的规则构造[3]和基于self-instruct[4]相结合的方法:首先使用chatgpt生成丰富的instruction文本,然后基于规则模板融合已有业务数据,形成(instruction,prompt,output)三元组。
最终,基于我们训练的模型,我们实现了一套与openai模型协议一致的api服务,从而方便集成langchain等项目,以便快速构建各式各样的上层应用。
代码资源及配置
deepspeed: 微软基于ZeRO原理开发的一款工程实现软件,相比于torch原生的ddp数据并发,ZeRO可以将模型的优化器(例如adamw)的状态切片分布式保存到多个进程上(GPU卡),从而降低每个GPU的优化器显存消耗,是训练LLM的利器。虽然deepspeed也可以把模型进行切片分布式保存到多个GPU上,但是训练效率会大幅度降低。为了使用deepspeed,你需要把gcc编译器升级到7以后的版本。
megatron: 这是Nvidia开发的一个LLM训练工具,可以高效融合很多模型图的op避免了频繁的内存与GPU之间的IO,从而提高运行速度,还支持高效的张量并行(tensor-parallel),有利于过大体积的LLM的并行计算。如果你的模型太大一个卡装不下,我们推荐使用megatron加载训练。
模型加载框架: transformers、modelscope是我们常用的两个模型加载训练框架,他们都具有丰富的生态,其中transformers的生态更加丰富,接口更佳,更友好。
pdsh工具:为了高效地进行多机部署和操作,我们推荐使用pdsh工具,这是谷歌发布的一个ssh运维工具,可以方便在多主机批量执行命令。为了方便在多太机器并行计算,我们推荐所有机器挂载ceph磁盘,或者每台机器的工作环境的文件路径结构一致。
配置方面,我们在训练总结出如下策略:
确保所有显卡算力相当,我们刚开始还额外加入不同型号显卡,结果发现由整体计算速度的瓶颈会卡在性能较低的显卡上。因此,除非模型需要的显存很大,我们建议仅使用同样算力的显卡。
尽可能保证模型可以在一张卡上加载,然后使用deepspeed进行optimizer多进程状态切分加载,因为optimizer占据了训练显存消耗的75%~80%。
如果模型非常大,我们推荐使用megatron做张量并行,这样每个卡的模型层权重会减少为1/N(N是你的tensor-parallel数目)。尽可能在一个机器内部做tensor-parallel,所以我们根据自己的资源设置N=4。
此外,如果模型还是十分大,例如65B这种,我们推荐采用layer-parallel,这种方式会把模型的多个layer平均放到你所有的卡上,例如我们有16卡,所以最大可以放256G内存模型,能加载两个65B的LLaMA,但这个时候训练会很慢。所以在训练前,需要计划选择好自己的基座模型。
对于较大模型,我们推荐组合Megatron的Tensor-parallel和Deepspeed O2优化器显存优化策略,因为一般机器间常见的通信方案都是网线,不是nvlink,甚至很多机器内部也是需要通过CPU来做多个GPU通信,这种低速通信依赖intel的CPU计算,这会让PCIe限制你的显卡速度。令人悲伤的是,目前很多公司都是和我们一样的情况,没有专属的GPU数据云集群。
其他的一些策略,例如lora、adapters等,也是一种降低显存的好方法,这些都是在你已经基于上面的策略确定好你的并行计算基础的前提下,仍需要进一步压缩显存使用时考虑的。
如果大家有需要,后续我们将评估后开源训练代码包含dataset-construction+post-training+STF+reward+RLHF/PPO+部署/demo。项目地址:https://github.com/zhangzhenyu13/llm3s-conatiner
注意:对于非amphere架构的机器例如V100,RLHF阶段不要安装deepspeed>=0.9的版本。
我们调研了丰富的开源基座模型,包含GLM、modelscope开源的GPT-3中文版本、LLaMA、BLOOM等,经过前期的尝试,我们最终选择了Bloom模型作为我们的基座语言模型,因为这个模型使用了ALiBi(attention with linear bias)位置编码,位置外推能力强,且词表很大,拥有多语言能力,重点支持中英文。下面我们列出了一些常见的支持中文的基座语言模型。虽然这些模型各有特色和优势,但是我们需要选择最适合我们内部业务需求的,所以我们的评测并非侧重模型通用得分能力,而是更加契合团队需求。
模型 | 模型大小 | 体验评分(1~5) | 模型信息 |
damo | 0.1B 0.6B 1.3B 2.7B | 2 | 1.Decoder-Only 2.AutoRegressive 3.Pre-LayerNorm 4.Sinusoidal 5.Sparse-attention 6.BPE |
THUDM/GLM | 0.3B 10B | 3 | 1.Encoder-Decoder 2.AutoRegressive-填空 3.Post-LayerNorm 4.RoPE |
BLOOM | 0.6B 1.1B 3B 7B 13B 65B 176B | 4 | 1.Decoder-Only 2.AutoRegressive 3.Pre-LayerNorm 4.ALiBi 5.Embedding Norm 6.bf16 |
LLaMA | 3B 7B 13B 65B | 4 | 1.Decoder-Only 2.AutoRegressive 3.Pre-LayerNorm(RMSNorm) 4.RoPE 5.SwiGLU |
注:体验评分为相似模型参数大小下评估的LLM能力
由于开源的基座模型普遍是在百科、公共网络语料、开源代码库等数据上训练过的,知识分布虽然很全面,但是在一个与公众网络差距较大的领域,这类语言模型并没有包含足够的领域知识。例如,虽然这些开源的模型具有一些通用的问题相关的知识,但是在某些特定领域(医学诊断场景、机械制造业、电商场景等等)却缺乏足够知识,从而会导致模型在垂直领域应用中出现幻视(hallucination)现象。因此,在垂直领域应用大模型前,需要进行相关的领域知识注入的训练。这个过程称为领域适配Post-training,这个问题被学术界广泛关注[1]。
我们重点关注的是电商领域,尤其是家用电器、3C数码、服装、美妆等行业的LLM落地。为了构建一个电商领域特定的知识语料库,我们抽取了电商平台的商品介绍页信息、用户对话日志、商品的品类描述信息,并将其中的文本进行整理,形成了product-kb-corpus。鉴于隐私策略,我们无法公布具体的商品数目和品类描述数目。此外,我们从线上抽取了1个月时间维度的用户对话日志,经过高质量的对话清洗策略,获得了大约600万的对话日志。然后通过对话文本聚类,保留了50%的低相似度且多样性高的对话。这些共同构成了我们的知识库语料。
我们的对话日志语料结构如下:"User: xxxx ChatBot: xxxx User: xxxxx"。商品介绍描述信息被总结为一段纯文本商品介绍。商品品类信息主要以拓扑结构文本表示:“品类结构:一级品类名称,二级品类名称,三级品类名称...。品类商品描述:xxx。品类包含:xxxx。” 最终,我们把这些数据混合到一起,构成了Ecommerce-corpus文本语料库。我们使用这个语料库训练了3个Epoch,具体参数配置如下。
model | lr | max-l | batch-size | lora | 训练结果评级1~5 |
damo/GPT3-2.7B | 1e-6 | 512 | 256 | - | 1 |
THUDM/GLM-10B* | 1e-6 | 384 | 256 | r=8 | 1 |
LLaMA-7B | 3e-6 | 384 | 256 | r=8 | 5 |
bigscience/BLOOM-7B | 1e-6 | 384 | 256 | r=8 | 4 |
bigscience/BLOOM-3B | 1e-5 | 512 | 256 | - | 4 |
bigscience/BLOOM-1.1B | 1e-5 | 512 | 256 | - | 4 |
#修改run_config/Bloom_config.json"train_on_inputs": truebash run.sh
我们前期尝试了damo/GPT-3基座模型,并基于modelscope使用简单数据并行和megatron张量并行,训练了2.7B的模型,发现相比于原始的基座,确实在电商领域的回答性能得到大幅度改进。此外,我们还训练了一个0.1epoch的GLM模型(模型耗时久,仅做0.1epoch做验证),也观察到了电商领域回复能力的大幅度提升。
我们测试了13个内部的领域相关任务数据集(包含NER、分类、QQ匹配、对话改写、答案召回、答案续写等类型的任务),0.1 epoch的GLM模型和0.1 epoch的damo/GPT-3相比,语言模型回复能力并没有显著差异,即使后者只有前者1/4左右的模型体积。由此可见,一个训练良好的基座也是非常重要的,显然damo/GPT-3的基座训练效果是更好的。
随着2023年上半年出现大量更加优秀的开源基座模型,例如LLaMA,BLOOM、Baichuan等,我们也对其进行了post-training。完成post-training后,效果好很多,很多之前LLM中不存在的知识,也能被训练后的模型回复上了,我们在内部的15个任务评测上,给出了模型的评级,其中LLaMA-7B模型效果最好,BLOOM的1.1B和3B的模型效果紧随其后。BLOOM模型主要在流畅度上相比LLaMA-7B存在一些不足,但是相比于可以进行全量微调的BLOOM 3B和1.1B模型,LLaMA-7B训练速/推理度更慢。我们通过人机交互测试,发现通过post-training注入知识的能力,BLOOM能够达到和LLaMA一样的效果。我们最终选择采用训练后的bigscience/BLOOM 1.1B模型作为我们的领域基座LLM。
数据情况
我们收集了500万开源的指令微调数据集,同时构建了300万内部业务数据集。内部数据集主要通过对我们内部的多个通用任务+多个领域任务+对话采样补全任务,使用self-instruct的方案,请求chatgpt获取。不同于目前的一些研究假说,我们希望通过指令微调训练,达到注入监督知识和训练模型服从人工指令的目的。
下面是我们的数据集详情,在包含开源数据基础上,涵盖了主要的业务场景。
序号 | 任务 | 数据集个数(开源+业务) | instruction | 数据数目 |
1 | 文本分类 | 10 | ✅ | 100w |
2 | 情感分类 | 4 | ✅ | 10w |
3 | 代码生成 | 1 | ✅ | 每个dataset 最多10w, 保证丰富多样性 |
4 | 代码修复 | 2 | ✅ | |
5 | 指令(题目)代码生成 | 1 | ✅ | |
6 | 代码带错误修复 | 1 | ✅ | |
7 | 回答生成 | 5 | 采样100w | |
8 | 阅读理解 | 7 | ✅ | 全用61w |
9 | 指代消解 | 1 | ✅ | 全用3k |
10 | cloze | 2 | ✅ | 采样11w |
11 | NER | 4 | ✅ | 采20w |
12 | NL2SQL | 4 | ✅ | 全用10w |
13 | nli/qq匹配 | 9 | ✅ | 全用56w |
14 | 问题生成 | 1 | ✅ | 全用1.5w |
15 | 改写 | 4 | ✅ | 全36w |
16 | CoT | 9 | ✅ | 全用7.4w |
17 | 用户对话补全 | 1 | ✅ | |
18 | 开源group1 | 2 | 全用18w | |
19 | 开源group2 | 指令350w 特色对话145w |
训练细节
我们使用huggingface开源的datasets加载所有数据,并且把数据整理为【prompt, output】格式,只在output部分计算loss损失。训练的最大长max-length=1024,batch-size=64,learning-rate=2e-5,epochs=2,warmup=10%,采用全量精调训练full-finetuning。
#修改run_config/Bloom_config.json"train_on_inputs": falsebash run.sh
Reward模型
我们收集了大量的人类偏好的【prompt,reject,response】三元组的正(response)负(reject)样本数据,10个英文数据集+8个中文数据集+业务用户偏好数据集(inhouse-dialogue)。开源数据中pangu数据都是根据用户的评论打分构建的偏序正负对,其他都是自然收集到人工偏好反馈数据。业务用户偏好数据主要通过抽取用户对客服回复的评价进行构建,我们通过人工过滤+人工编写的形式,构建出单纯针对内容的偏好回复的正负样本。
数据详情如下所示:
数据集 | 语言 | 数量 |
Dahoas/rm-static | en | 76.3k |
Dahoas/full-hh-rlhf | en | 112k |
Dahoas/synthetic-instruct-gptj-pairwise | en | 33.1k |
yitingxie/rlhf-reward-datasets | en | 76.3k |
openai/webgpt_comparisons | en | 19.6k |
stanfordnlp/SHP | en | 349k |
tasksource/oasst1_pairwise_rlhf_reward | en | 18k |
andersonbcdefg/dolly_reward_modeling_pairwise | en | 19.3k |
andersonbcdefg/red_teaming_reward_modeling_pairwise_no_as_an_ai | en | 35k |
Anthropic/hh-rlhf | en | 161k |
inhouse/dialogue | zh | - |
Cohere/miracl-zh-queries-22-12 | zh | 2.6k |
Hello-SimpleAI/HC3-Chinese | zh | 24.3k |
liyucheng/zhihu_rlhf_3k | zh | 3.46k |
pangu/weibo | zh | 16844k |
pangu/couplet | zh | 6195k |
pangu/baike | zh | - |
pangu/zhidao | zh | 1434k |
pangu/chinese-classical | zh | 7738k |
我们使用重要性采样,每个数据集的采样比重如下,保证训练中模型不止看到较大数据集,同时也可以看到较小数据集,满足训练多样性。
run-reward.sh
由于reward模型无需做生成,任务难度不高,只关注模型输出的偏好,我们给采用了较小的0.56B的BLOOM作为LLM基座训练这个reward模型。我们加入了一个线性层做logit 分数预测作为reward-score:
虽然OpenAI的InstructGPT[5]原文使用的是整句的reward结果进行偏序训练,但是我们这里为了提高训练效率和稳定性,采用基于reject和response部分的token的得分进行reward model(公式:r_{\theta })的loss计算,这样我们可以接收到来自正负样本对每个token的偏好监督信号。prompt为输入x,偏好正输出response为y_l,负偏好为y_w。
原始论文 | 生成token计算方法 |
负样本的得分也如上计算,假设生成response长度为n。 |
训练时,我们采用训练的最大长度max-length=512,batch-size=64,learning-rate=2e-5,epochs=5,warmup=10%,采用全量精调训练full-fintuning。
PPO算法
这一步,数据量不是主要影响模型质量的因素,RLHF训练目的主要是希望模型能够在尽可能多的场景和数据分布下,都可以接收到人类的偏好反馈。因此,我们收集了39个中英文数据集共21900样本,并对每个数据集按照需求和大小进行采样,构建了一个RLHF数据集,具体内容如下:
数据集 | 数量 |
inhouse dialogue context | 2000 |
samples-format/andersonbcdefg-dolly_reward_modeling_pairwise | 100 |
samples-format/andersonbcdefg-red_teaming_reward_modeling_pairwise_no_as_an_ai | 100 |
samples-format/Anthropic-hh-rlhf | 100 |
samples-format/baike_qa.json | 1000 |
samples-format/belle_data-0.5m.json | 1000 |
samples-format/belle_data-1m.json | 1000 |
samples-format/belle_data-2m.json | 1000 |
samples-format/belle_data-genchat-0.4m.json | 1000 |
samples-format/belle_data-multiturn-0.8m.json | 1000 |
samples-format/belle_data-schoolmath-0.25m.json | 1000 |
samples-format/chinese_classical.json | 100 |
samples-format/Cohere-miracl-zh-queries-22-12 | 100 |
samples-format/cot.json | 1000 |
samples-format/couplets.json | 100 |
samples-format/Dahoas-full-hh-rlhf | 100 |
samples-format/Dahoas-rm-static | 100 |
samples-format/Dahoas-synthetic-instruct-gptj-pairwise | 100 |
samples-format/liyucheng-zhihu_rlhf_3k | 100 |
samples-format/mrc_seed_c3-dialog.json | 1000 |
samples-format/mrc_seed_c3-m.json | 1000 |
samples-format/mrc_seed_chid.json | 1000 |
samples-format/mrc_seed_cmrc.json | 1000 |
samples-format/mrc_seed_drcd-tw.json | 1000 |
samples-format/mrc_seed_dureader.json | 1000 |
samples-format/mrc_seed_squad-zen.json | 1000 |
samples-format/nl2sql_chase-wdb.json | 100 |
samples-format/nl2sql_cspider-wdb.json | 100 |
samples-format/nl2sql_dusql-wdb.json | 100 |
samples-format/nl2sql_nl2sql-wdb.json | 100 |
samples-format/openai-webgpt_comparisons | 100 |
samples-format/stanfordnlp-SHP | 100 |
samples-format/tasksource-oasst1_pairwise_rlhf_reward | 100 |
samples-format/wangrui6-Zhihu-KOL | 100 |
samples-format/weibo_summary_comments.json | 1000 |
samples-format/yitingxie-rlhf-reward-datasets | 100 |
samples-format/zhidao.json | 1000 |
PPO训练细节:
我们所采用的PPO算法(off-policy)是根据微软的deepspeed团队工程优化的PPO算法(我们做了自己模型的一些行为参数适配),相比原生的PPO算法只包含actor和critic模型+打分方案(RLHF中通常由reward-model替代),这个实现多引入了actor-ref模型和EMA机制,训练十分稳定。
原始PPO | 优化版本PPO |
初始化价值策略函数,价值函数来自SFT模型(actor)和reward模型(critic) | 额外初始化actor-ref和ema(滑动平均模型) |
clip loss value loss | 加入了actor和actor-ref对统一Q(s,a)下的log-pror】b分数分布KL-div损失,阻止actor策略模型变化过大,此外还引入滑动平均,对新迭代下actor更新采用 虽然这样做使得训练中同时存在5个模型,但是稳定性大幅度提升,有利于RLHF过程收敛。 |
这个阶段训练,我们使用lora轻量化训练,lora的秩r=32,针对所有各层QKV都使用lora,因为我们相信RLHF阶段只需要额外微调少量模型参数就可以达到偏好注入的效果。超参的设定上,我们采用batch-size=16,prompt-length=256,response-length=256,actor学习率9.56e-6,critic学习率5e-6,一共学习3个epoch。
下面举一个例子来证明RLHF的效果。可以看到,经过RLHF训练之后,模型会避免输出有害的答案。
SFT模型结果 | |
RLHF模型结果 | |
7B模型结果(无RLHF) |
bash run-rlhf.sh
评估数据集
大模型的评估是一个挑战的问题,在此我们使用的是BELLE提供的1000条数据,通过FastChat框架进行模型自动评估。实际业务中也可以考虑基于业务下游任务来进行人工评估。具体的数据内容和分布可以参考下面链接中的内容:
https://github.com/LianjiaTech/BELLE/blob/main/eval/eval_set.json
评估方案
采用FastChat-Vicuna的评估方式,将两个模型生成的输出进行成对的比较。FastChat的打分模型使用的是GPT-4(这里我们也尝试了使用GPT-3.5-turbo,但是发现3.5生成的评估理由内容较差),默认有 "Math"(75条), "Coding"(38条)和"General"(887条)三种,分别对数学、编程、其他通用问题的能力进行评估,差异体现在不同的prompt设计上(根据FastChat的英文prompt进行调整):
{"prompt_id": 1, "system_prompt": "你是检查答案质量的助手。", "prompt_template": "[问题]\n{question}\n\n[答案1的开始]\n{answer_1}\n\n[答案1的结束]\n\n[答案2的开始]\n{answer_2}\n\n[答案2的结束]\n\n[系统]\n{prompt}\n\n", "defaults": {"prompt": "针对给出的问题,请对两个答案进行打分。\n请从答案对问题的帮助性、相关性、准确性、细节程度进行评价。每个答案都会得到一个1到10分的总分,分数越高表示整体质量越好。\n请首先输出只包含两个值的单行,分别表示答案1和2的总分。这两个分数用一个空格隔开。在随后的一行中,请对您的评价作出全面解释,避免任何潜在的偏见,并确保回答的顺序不会影响您的判断。"}, "description": "Prompt for general questions", "category": "general"} {"prompt_id": 2, "system_prompt": "你是检查代码质量的助手。", "prompt_template": "[问题]\n{question}\n\n[代码1的开始]\n{answer_1}\n\n[代码1的结束]\n\n[代码2的开始]\n{answer_2}\n\n[代码2的结束]\n\n[系统]\n{prompt}\n\n", "defaults": {"prompt": "针对给出的问题,请对两个代码进行打分。\n密切关注代码解决问题的方法、代码结构、可读性以及是否包含有用的注释。\n\n请确保代码:\n\n1.正确地实现给定的问题陈述。\n2.包含准确和有效的代码。\n3.包括清晰简洁的注释,解释代码的逻辑和功能。\n4.坚持正确的代码标准和最佳实践。\n\n每个代码都会得到一个1到10分的总分,分数越高表示整体质量越好。\n请首先输出只包含两个值的单行,分别表示代码1和2的总分。这两个分数用一个空格隔开。然后从下一行开始给出代码的优点和缺点,并提出改进建议和反馈。"}, "description": "Prompt for coding questions", "category": "coding"} {"prompt_id": 3, "system_prompt": "你是检查数学答案质量的助手。", "prompt_template": "[问题]\n{question}\n\n[答案1的开始]\n{answer_1}\n\n[答案1的结束]\n\n[答案2的开始]\n{answer_2}\n\n[答案2的结束]\n\n[系统]\n{prompt}\n\n", "defaults": {"prompt": "针对给出的问题,请对两个数学答案进行打分。\n首先,请独立解决该问题,不要参考答案1和2。\n之后,请逐步检查答案1和2解决问题的过程,以确保其正确性,如果存在任何不正确的步骤,请指出。你的评价不仅要考虑到最终结果,还要考虑到问题解决的步骤。\n最后,请输出一个Python元组,该元组只包含1到10的两个值,分别表示答案1和2的总分,分数越高表示整体质量越好。"}, "description": "Prompt for math questions", "category": "math"}
我们对如下的公开模型和基于自有数据微调后的Bloom模型进行评估:
(由于利用GPT4进行评估的代价比较高,我们首先按照三大类分布从1000条数据中采样了100条进行评估)
100 cases | |||||
General | Math | Coding | Micro | Macro | |
Vicuna-7B | 6.91 | 1.43 | 7.0 | 6.53 | 5.11 |
Vicuna-13B | 7.6 | 1.0 | 7.25 | 7.12 | 5.28 |
ChatGLM-6B | 7.82 | 1.86 | 6.75 | 7.36 | 5.48 |
ChatGLM2-6B | 8.2 | 7.71 | 7.88 | 8.16 | 7.93 |
BLOOM-IFT-7B | 7.38 | 1.71 | 8.0 | 7.01 | 5.70 |
BLOOM-IFT | 7.11 | 3.57 | 6.75 | 6.85 | 5.81 |
BLOOM-IFT-7B | 7.42 | 2.0 | 7.5 | 7.04 | 5.64 |
BLOOM-RLHF | 7.21 | 2.43 | 6.5 | 6.85 | 5.38 |
BLOOM-IFT-7B | 7.18 | 1.57 | 7.5 | 6.8 | 5.42 |
ChatGPT3.5 | 8.96 | 7.43 | 7.5 | 8.8 | 7.96 |
BLOOM-IFT | 7.13 | 2.86 | 6.5 | 6.81 | 5.50 |
ChatGPT3.5 | 8.9 | 7.57 | 7.75 | 8.76 | 8.07 |
1000 cases | |||||
BLOOM-IFT-7B | 6.99 | 2.55 | 5.82 | 6.62 | 5.12 |
ChatGPT3.5 | 8.85 | 8.39 | 8.05 | 8.79 | 8.43 |
BLOOM-IFT | 6.92 | 2.73 | 6.58 | 6.60 | 5.41 |
ChatGPT3.5 | 8.73 | 8.12 | 8.13 | 8.66 | 8.33 |
宏观(Macro):首先分别计算每个类别的评估指标,然后计算这些指标的平均值。这种方法对所有类别赋予了相等的权重,无论类别的样本数多少。因此,如果你的数据集类别分布不均衡,那么宏观平均可以帮助你理解模型在少数类别上的性能。
微观(Micro):首先将所有类别的混淆矩阵合并成一个混淆矩阵,然后在这个大的混淆矩阵上计算评估指标(例如,精确度、召回率等)。这种方法对每个样本赋予了相等的权重,无论这个样本属于哪个类别。因此,如果你的数据集类别分布不均衡,那么微观平均可以帮助你理解模型在多数类别上的性能。
从结果可以看到,虽然模型的参数有限,我们自己训练的模型仍然具备一定的通用生成和代码编写能力。同时也看到,大模型的主要分水岭在于数值计算和推理能力。
大模型的在线推理是工业界的一个重要难题,我们尝试使用了基于FasterTransformer[6,7]的triton服务器来部署在线推理实例,获得了不
错的效果。
FasterTransformer介绍
FasterTransformer重写封装了transforfmer 的很多内部算子,是的原本需要多次调用系统内核的算子数目被大量精简(下降50%),从而提高了模型推理运算中GPU等内核启动时间的消耗。这里有个详细的介绍:https://zhuanlan.zhihu.com/p/626303702。
此外,FasterTransformer project还支持用户根据已封装内核算子组装自己的transformer模型,从而实现个性化模型的优化。
下面给出一个目前优化后的模型速度对比数据(我们采用了官方的提供的5000多个测试样本):
基于单精度权重的BLOOM-IFT模型,FasterTransformer可以获得12倍加速。
pytorch | FasterTransformer | FasterTransforfmer-fp16 | |
time | 238.4028 sec | (elapsed time: 62.4099 sec) | (elapsed time: 20.5483 sec) |
triton服务器并发测试
基于triton服务器的FasterTransformer后端融合了tokenization预处理、FasterTransformer模型计算、decoding后处理,其中tokenization和decoding部分是基于python代码实现的,调用的transformers库的代码(可以采用fast tokenizer,使用的rast语言实现的,速度非常快)。这个后端支持多机多卡部署,服务响应流程如下。
我们在单机单卡的Tesla V100上部署了模型,并做了并发速度测,具体配置:250字输入,20字输出 (可以覆盖大部分语言理解类任务)。
并发达到104时,对应的TP999约800ms
并发60时,TP999约200ms,完全满足线上需求
TP999 | 对应时间下的TPS并发量 |
生成环境服务器部署代码
我们已经准备好了镜像打包方法,使用这个方法可以直接打包好可运行镜像,方便后续部署。
你首先需要将代码仓库拷贝下来,并启动一个本地的模型hub服务,你需要配置configs/model-hub.json来设置模型存放路径$hub_path。
python hub-server.py
其次,你需要使用如下命令,将你的模型转换为FasterTransformer模型并发保存到hub-server的路径下。
python triton-deply/hf-bloom-converter.py -i $PATH/MODEL -o $PATH/fast_C_Model \
-tp 1 -p 32 -v -dt fp16
mv $PATH/fast_C_Model triton-deploy/triton-models/triton-model-store/bloom_1b1/fastertransformer/1/
mv triton-deploy/triton-models/triton-model-store/bloom_1b1/ $hub_path/model
cd $hub_path/
tar -vxf $model_ID.tgzmodel
然后进入代码目录,运行如下命令:
docker build -t trition-server-[your-org]:v2 -f Dockerfile.base ./
启动这个镜像服务后,服务已经自动运行,但是记得暴露服务端口:
nvidia-docker run --shm-size 5g -tid -p 6200:6200
此时你就可以通过如下api访问模型:
openai.api_base = "http://11.70.129.225:7690/v1"openai.base = NonemodelId="chatJD/bloomS2.1-FT"query="hi,test model input prompt"def request_api():response = openai.ChatCompletion.create(temperature=0.95, top_p= 0.7, decoder='sample',max_length = 128, repetition_penalty=1.0,model=modelId,messages=[{"role": "user", "content": query}],stream=False, seed=2020)print(type(response))if hasattr(response.choices[0].message, "content"):print(response.choices[0].message.content)
为了更好的展示模型的效果,我们还提供了一套模型服务api与gui,支持类似OpenAI这种请求方式和streaming快速输出。我们这个服务框架可以广泛支持目前主流的所有LLM models。这个章节,我们将介绍如何快速使用我们训练的模型替换OpenAI的api,构建一个在线web应用,搭建一个文档问答的应用。
你首先需要进入configs/supported.py配置你的模型端口和模型所在服务器ip,然后把项目拷贝到该服务器ip,进而通过start-service.sh启动相关服务,例如配置start-service.sh启动我们训练后的RLHF模型
export CUDA_VISIBLE_DEVICES=2python service_bloom.py --service-model-id "model/bloom1b1-rlhf-v1"
你可以配置多个模型,然后分别在不同GPU/机器上完成启动。
你需要在一台无需GPU的机器上,启动gui和open形式的api。
nohup python api_sever.py > logs/api.log &nohup python gui_web.py > logs/gui.log &
此时,在通过访问这台机器的http://ip:7680,就可以获取gui服务,你还可以选择解码形式sample/contrastive,配置解码参数等。这里你可以询任何开放问题或者领域业务相关的问题。
而且通过配置,你也可以像使用OpenAI服务一样使用你启动模型服务。
import openai
openai.api_base = "http://xxxx"
openai.api_key = "none"
modelId= "chatJD/bloomS2.1" # none rlhf SFT
query = "你好!用关键词:爱情、珍贵、永恒、价值,为周大福写个100字广告。"
def streaming_test():
for chunk in openai.ChatCompletion.create(
temperature=0.95, top_p= 0.7, decoder='sample',
max_length = None, repetition_penalty=1.0,
model= modelId,
messages=[
{"role": "user", "content": query}
],
stream=True
):
if hasattr(chunk.choices[0].delta, "content"):
print(chunk.choices[0].delta.content, end="", flush=True)
print()
def request_api():
response = openai.ChatCompletion.create(
temperature=0.95, top_p= 0.7, decoder='sample',
max_length = 128, repetition_penalty=1.0,
model=modelId,
messages=[
{"role": "user", "content": query}
],
stream=False
)
print(type(response))
if hasattr(response.choices[0].message, "content"):
print(response.choices[0].message.content)
你还可以通过上述api与langchain集成,实现文档问答等应用。如果你没有其他embedding的api可以使用,你可以参考我们的代码部署一个embedding模型服务,我们采用了m3e[8]中文模型,中文效果接近Open AI的ada-002。
export CUDA_VISIBLE_DEVICES=1python service_embedding_m3e.py --service-model-id "moka-ai/m3e-base"
然后你可以启动一个demo形式的文档问答服务,进行效果测试。
streamlit run examples/langchain-docqa.py --server.fileWatcherType none --server.address localhost
在此,我们收集医保领域的领域文档作为测试文档,通过对比ChatGLM2-6B发现我们训练的模型更擅长在一个垂直领域的简洁回复。相比之下,ChatGLM2的回复较为冗长。(下表第二列代表了我们的模型,第三列表了ChatGLM2模型)
问题 | 答案A:我们的模型/1.1B | 答案B:ChatGLM2/6B | 得分A | 得分B |
备案有效期内办理入院手续,出院时过了有效期,如何结算医疗费用? | 备案有效期内已办理入院手续的,不受备案有效期限制,可正常直接结算相应医疗费用。 | 根据已知信息,备案有效期内办理入院手续,出院时过了有效期,可以通过以下方式结算医疗费用:
需要注意的是,在办理入院手续时,需要确认备案有效期是否符合所选医疗机构的要求,以便及时办理结算。 | 2 | 0 |
什么是预付金 | 预付金是按时按量缴纳的医疗费用,用于预警和及时调增医疗费用。 | 预付金是参保地省级经办机构预付给就医地省级经办机构用于支付参保地异地就医人员医疗费用的资金管理。根据《医保目录》规定的医疗费用标准和参保地省级经办机构的预测预算,医保资金将在就医地省级经办机构的账户中支付。预付金的使用可以帮助就医地省级经办机构在医疗费用无法确定的情况下更好地安排资金,确保医疗服务的及时、优质。 | 2 | 1 |
异地就医档案怎么管理 | 异地就医档案由参保地经办机构和就医地经办机构按其办理的业务分别保管。 | 根据已知信息,异地就医业务档案由参保地经办机构和就医地经办机构按其办理的业务分别保管。具体来说,每个地区的异地就医档案会根据不同的业务进行划分和管理。例如,如果某个地区的异地就医业务主要是治疗肿瘤,那么该地区的异地就医档案可能会按照肿瘤相关的医疗记录进行划分和管理。同时,参保地经办机构和就医地经办机构还需要协同工作,确保异地就医档案的管理和查询方便、安全、准确。 | 1 | 1 |
六十条内容是什么 | 六十条内容是各省级医保部门可根据本规程,制定本地、跨省的异地就医直接结算实施细则。 | 根据已知信息无法回答该问题。第六十二条 跨省异地就医医疗费用结算和清算过程中形成的预付款项和暂收款项按相关会计制度规定进行核算。第六十三条 异地就医业务档案由参保地经办机构和就医地经办机构按其办理的业务分别保管。第六十四条 各省级医保部门可根据本规程,制定本地 区异地就医直接结算实施细则。第六十五条 本规程由国家医疗保障局负责解释。第六十六条 本规程自 2023 年 1 月 1 日起实施。国家医保局 财政部 关于进一步做好基本医疗保险跨省异地就医直接结算工作的通知 | 1 | 0 |
问题一般多久可以得到回复 | 答案:5天。回答慢一些。通常情况下,如果超过10个工作日还未回复,则无法得到答复。 | 根据已知信息无法回答该问题。无法了解问题的具体情况,也不知道医保部门在处理问题时的具体时限要求。请提供更具体的问题信息和上下文背景,以便给出更准确的答案。 | 1 | 0 |
53AI,企业落地应用大模型首选服务商
产品:大模型应用平台+智能体定制开发+落地咨询服务
承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2024-05-28
2024-04-26
2024-08-21
2024-04-11
2024-07-09
2024-08-13
2024-07-18
2024-10-25
2024-07-01
2024-06-17