近年来,人工智能快速发展,成为全球最为前沿的科技领域;与此同时,也诞生了很多优秀的 AI 工具。比如:国外的 AI 工具 PyTorch 、TensorFlow等,国产 AI 工具百度飞浆、Oneflow、MindSpore等。
像百度飞浆提供了AI整个生命周期中各种各样的工具。比如:
开发与训练
- Paddle核心框架:开发便捷的深度学习框架
- FleetAPI:分布式训练API
- PALM:多任务学习
- PaddleCloud:云上任务提交工具
- Paddle Quantum:量子机器学习框架
模型库
- PaddleCV:智能视觉
- PaddleNLP:智能文本处理
- PaddleRec:智能推荐
- PaddleSpeech:智能语音
- PaddleTS:深度时序算法库
压缩
- PaddleSlim:模型压缩工具
部署
- Paddle Inference:原生推理库
- Paddle Serving:服务化部署框架
- Paddle Lite:轻量化推理引擎
- Paddle.js:前端推理引擎
- FastDeploy:推理部署
而本文给大家分享飞浆 PaddleNLP 中大语言模型工具链。
PaddleNLP 简介
PaddleNLP 是一款简单易用 且功能强大 的自然语言处理和大语言模型(LLM)开发库。聚合业界优质预训练模型 并提供开箱即用 的开发体验,覆盖NLP多场景的模型库搭配产业实践范例 可满足开发者灵活定制的需求。
它的核心特性如下所示:
- 开箱即用的NLP工具集:Taskflow提供丰富的📦开箱即用 的产业级NLP预置模型,覆盖自然语言理解与生成两大场景,提供💪产业级的效果 与**⚡️极致的推理性能** 。更多使用方法可参考Taskflow文档。
- 丰富完备的中文模型库:精选 45+ 个网络结构和 500+ 个预训练模型参数,涵盖业界最全的中文预训练模型:既包括文心NLP大模型的ERNIE、PLATO等,也覆盖BERT、GPT、RoBERTa、T5等主流结构。覆盖从学术到产业的NLP应用示例,涵盖NLP基础技术、NLP系统应用以及拓展应用。全面基于飞桨核心框架2.0全新API体系开发,为开发者提供飞桨文本领域的最佳实践。精选预训练模型示例可参考Model Zoo,更多场景示例文档可参考examples目录。更有免费算力支持的AI Studio平台的Notbook交互式教程提供实践。
- 产业级端到端系统范例:PaddleNLP针对信息抽取、语义检索、智能问答、情感分析等 高频NLP场景,提供了端到端系统范例,打通数据标注-模型训练-模型调优-预测部署全流程,持续降低NLP技术产业落地门槛。
- 高性能分布式训练与推理
- FastTokenizer:高性能文本处理库:为了实现更极致的模型部署性能,安装FastTokenizers后只需在
AutoTokenizer
API上打开use_fast=True
选项,即可调用C++实现的高性能分词算子,轻松获得超Python百余倍的文本处理加速,更多使用说明可参考FastTokenizer文档。 - FastGeneration:高性能生成加速库:简单地在
generate()
API上打开use_fast=True
选项,轻松在Transformer、GPT、BART、PLATO、UniLM等生成式预训练模型上获得5倍以上GPU加速,更多使用说明可参考FastGeneration文档。 - Fleet:飞桨4D混合并行分布式训练技术,更多关于千亿级AI模型的分布式训练使用说明可参考GPT-3。
- FastTokenizer:高性能文本处理库:为了实现更极致的模型部署性能,安装FastTokenizers后只需在
ok,牛B吹完,我们来看下他们最近推出的大语言模型工具链。
PaddleNLP 大语言模型工具链
飞桨大语言模型工具链基于飞桨4D分布式并行技术开发,旨在提供高性能、灵活易用大语言模型全流程开发能力,覆盖开发、预训练、精调、压缩、推理、部署的全流程,具体如下所示,图中上半部分为PaddleNLP 2.6的进展,图中下半部分为最终目标。
支持的模型如下:
Model | Pretrain | SFT | LoRA | Prefix Tuning | Generation | Quantization |
---|---|---|---|---|---|---|
LLaMA v1/v2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
ChatGLM-6B | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ |
ChatGLM2-6B | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ |
Bloom | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ |
GPT-3 | ✅ | ✅ | ✅ | 🚧 | ✅ | 🚧 |
OPT | 🚧 | ✅ | ✅ | 🚧 | ✅ | 🚧 |
GLM | ❌ | ✅ | ✅ | 🚧 | ✅ | 🚧 |
Qwen | ❌ | ✅ | ✅ | ✅ | ✅ | 🚧 |
- ✅: Supported
- 🚧: In Progress
- ❌: Not Supported
可以看到,目前国内外主流的开源大模型(如:Bloom、LLaMA、OPT、ChatGLM等)都有进行支持。同时大部分模型支持预训练、全量微调、参数高效微调(LoRA/Prefix Tuning)、模型推理及量化。
LLaMA家族支持模型权重:
Model |
---|
facebook/llama-7b |
facebook/llama-13b |
facebook/llama-30b |
facebook/llama-65b |
meta-llama/Llama-2-7b |
meta-llama/Llama-2-7b-chat |
meta-llama/Llama-2-13b |
meta-llama/Llama-2-13b-chat |
meta-llama/Llama-2-70b |
meta-llama/Llama-2-70b-chat |
ziqingyang/chinese-llama-7b |
ziqingyang/chinese-llama-13b |
ziqingyang/chinese-alpaca-7b |
ziqingyang/chinese-alpaca-13b |
idea-ccnl/ziya-llama-13b-v1 |
linly-ai/chinese-llama-2-7b |
linly-ai/chinese-llama-2-13b |
baichuan-inc/Baichuan-7B |
baichuan-inc/Baichuan-13B-Base |
baichuan-inc/Baichuan-13B-Chat |
baichuan-inc/Baichuan2-7B-Base |
baichuan-inc/Baichuan2-7B-Chat |
baichuan-inc/Baichuan2-13B-Base |
baichuan-inc/Baichuan2-13B-Chat |
FlagAlpha/Llama2-Chinese-7b-Chat |
FlagAlpha/Llama2-Chinese-13b-Chat |
Bloom家族支持模型权重:
BLOOM 是一种自回归大型语言模型(LLM),在大量文本数据上训练从而生生成目标文本,同时它能够支持46种语言和13种编程语言的文本交互。BLOOM 主要基于文本生成任务训练而成,可以很好的完成文本续写任务,此外 BloomZ 系列模型加入了 Instruction Tuning。
Model |
---|
bigscience/bloom-560m |
bigscience/bloom-560m-bf16 |
bigscience/bloom-1b1/ |
bigscience/bloom-3b |
bigscience/bloom-7b1 |
bigscience/bloomz-560m/ |
bigscience/bloomz-1b1 |
bigscience/bloomz-3b |
bigscience/bloomz-7b1-mt |
bigscience/bloomz-7b1-p3 |
bigscience/bloomz-7b1 |
bellegroup/belle-7b-2m |
ChatGLM家族支持模型权重:
ChatGLM-6B 是一个开源的、支持中英双语问答的对话语言模型,基于 General Language Model (GLM) 架构,具有 62 亿参数。ChatGLM-6B 使用了和 ChatGLM 相同的技术,针对中文问答和对话进行了优化。经过约 1T 标识符的中英双语训练,辅以监督微调、反馈自助、人类反馈强化学习等技术的加持,62 亿参数的 ChatGLM-6B 已经能生成相当符合人类偏好的回答。
Model |
---|
THUDM/chatglm-6b |
THUDM/chatglm-6b-v1.1 |
ChatGLM2-6B 是开源中英双语对话模型 ChatGLM-6B 的第二代版本,在保留了初代模型对话流畅、部署门槛较低等众多优秀特性的基础之上,ChatGLM2-6B 引入了FlashAttention和Multi-Query Attention等新特性。更详细的模型介绍见ChatGLM2-6B GitHub
Model |
---|
THUDM/chatglm2-6b |
预训练
PaddleNLP 中提供了LLaMA v1/v2、GPT-3 预训练的支持,对应的目录中提供了模型预训练的数据准备和训练细节,后续将支持更多的模型预训练。
微调
在 PaddleNLP 中,目前精调统一脚本只支持LLaMA v1/v2、ChatGLM-6B、ChatGLM2-6B、Bloom、OPT、Qwen,其他模型精调使用详见对应模型目录。目前支持全量微调和高效微调(目前支持 LoRA、Prefix Tuning)。
模型推理
PaddleNLP 中提供了动态图推理、静态图推理、Inference Model 动态图推理和Inference Model 静态图推理。
模型服务化
PaddleNLP 中提供了Flask 以及 Gradio UI服务化部署。
PaddleSlim
PaddleSlim 是一个专注于深度学习模型压缩的工具库,提供低比特量化、知识蒸馏、稀疏化和模型结构搜索等模型压缩策略,帮助开发者快速实现模型的小型化。
PaddleSlim 量化
由于量化是应用最为广泛和使用的一种方式,因此,本文仅讲述PaddleSlim 量化。
PaddleSlim 主要包含三种量化方法:量化训练(Quant Aware Training, QAT)、动态离线量化(Post Training Quantization Dynamic, PTQ Dynamic)、静态离线量化(Post Training Quantization Static, PTQ Static)。
- 量化训练 量化训练让模型感知量化运算对模型精度带来的影响,通过finetune训练降低量化误差。
- 动态离线量化 动态离线量化仅将模型中特定算子的权重从FP32类型映射成INT8/16类型。
- 静态离线量化 静态离线量化使用少量无标签校准数据,采用KL散度等方法计算量化比例因子。
除此之外,PaddleSlim还有一种对embedding层量化的方法,将网络中embedding层参数从float32类型量化到int8类型。
- Embedding量化 Embedding量化仅将embedding参数从float32类型映射到int8类型,可以降低embedding参数体积。
下表综合对比了模型量化方法的使用条件、易用性、精度损失和预期收益。
量化方法 | API接口 | 功能 | 经典适用场景 |
---|---|---|---|
在线量化 (QAT) | 动态图:paddleslim.QAT ; 静态图:paddleslim.quant.quant_aware |
通过finetune训练将模型量化误差降到最小 | 对量化敏感的场景、模型,例如目标检测、分割, OCR |
静态离线量化 (PTQ Static) | paddleslim.quant.quant_post_static |
通过少量校准数据得到量化模型 | 对量化不敏感的场景,例如图像分类任务 |
动态离线量化 (PTQ Dynamic) | paddleslim.quant.quant_post_dynamic |
仅量化模型的可学习权重 | 模型体积大、访存开销大的模型,例如BERT模型 |
Embedding量化(Quant Embedding) | paddleslim.quant.quant_embedding |
仅量化模型的Embedding参数 | 任何包含Embedding层的模型 |
PaddleSlim LLM 量化
许多研究表明,Transformer模型往往会存在强烈的异常激活值,这使得它们难以量化。为了保持可接受的性能,这些异常值的存在要求激活具有更高的位宽或使用不同的数字格式、额外的微调或其他解决方法。PaddleSlim中提供了自研的PTQ策略进行量化以及GPTQ量化。
PaddleSlim自研的PTQ策略量化,提供了以下功能:
第一,提供了Shift功能 。 Shift算法来源于Outlier Suppression+。通过Layer Norm和Linear的bias进行数学等价的异常值缩放操作,有效将激活值的分布调整对称,有助于离线量化的精度提升。
在PaddleSlim的实现中,
- 对于前面有Layer Norm的Linear将使用数学等价的方式改变bias从而进行缩放操作,
- 对于前面没有Layer Norm的Linear可以采用插入节点的方式实现,可通过参数shift_all_linears来控制是否需要shift前面没有Layer Norm的Linear。
此外,PaddleSlim版本的Shift功能提供传入sample_function,如设置sample_function为None,Shift算法将完全对齐论文Outlier Suppression+.
参数名 | 参数类型 | 参数释义 |
---|---|---|
model | paddle.nn.Layer | 必须传入的动态图模型 |
model_config | dict | 必须传入的模型结构的配置 |
alpha | float | 可选参数,默认为0.5 |
smooth_all_linears | bool | 可选参数,默认为False,若为True,则shift模型中全部Linear;若为False,则只shift模型中Layer Norm之后的Linear |
sample_function | function | 可选参数,默认为None,若为None,采样方式为单batch数据,现可选的sample_function有MultiStepSampler和EMASampler,Smooth时推荐使用MultiStepSampler |
search_function | function | 可选参数,默认为None,若为None,则不进行搜索,smooth方法与原论文保持一致 |
第二,提供了Smooth功能 。Smooth算法来源于SmoothQuant。通过Layer Norm和Linear的weight和bias进行数学等价的异常值缩放操作,有效减少激活值中的异常值,有助于离线量化的精度提升。在PaddleSlim的实现中,与shift相同,
- 对于前面有Layer Norm的Linear将使用数学等价的方式改变weight和bias从而进行缩放操作,
- 对于前面没有Layer Norm的Linear可以采用插入节点的方式实现,可通过参数smooth_all_linears来控制是否需要smooth前面没有Layer Norm的Linear。
此外,PaddleSlim版本的Smooth功能还提供搜索功能,搜索功能见下文。
参数名 | 参数类型 | 参数释义 |
---|---|---|
model | paddle.nn.Layer | 必须传入的动态图模型 |
model_config | dict | 必须传入的模型结构的配置 |
alpha | float | 可选参数,默认为0.5 |
smooth_all_linears | bool | 可选参数,默认为False,若为True,则shift模型中全部Linear;若为False,则只shift模型中Layer Norm之后的Linear |
sample_function | function | 可选参数,默认为None,若为None,采样方式为单batch数据,现可选的sample_function有MultiStepSampler和EMASampler,Smooth时推荐使用MultiStepSampler |
search_function | function | 可选参数,默认为None,若为None,则不进行搜索,smooth方法与原论文保持一致 |
注意:模型shift和smooth前后从理论数学角度应该是等价的,但从工程角度,输出具体数值可能会有稍微不同,所以模型shift/smooth前后的精度是大约一致的。如果精度出现很大差距,说明模型未解析成功。参数中model_config
请按照模型的实际情况填写,此输入会影响模型结构解析,若结构解析出错,会导致模型精度不对,其中包含字段:
fused_qkv
:该模型是否融合了QKV,默认为Truelinear_flag
:该模型判断Linear的名字字段,默认为linear
norm_flag
:该模型判断Layer Norm的名字字段,默认为norm
parallel_ffn
:该模型是否含有并行的FFN,默认为Falseskip_norm_list
:该模型中需要被忽略的Layer Norm的名字字段,默认为空list
若模型中含有PostLayerNorm Shurtcut结构,则不支持对该模型进行smooth和shift。比如PaddleNLP中ChatGLM结构存在PostLayerNorm Shurtcut结构,所以不支持对该模型进行shift/smooth。
第三,提供了PieceWiseSearch功能 ,根据SmoothQuant算法,的确能够有效减少异常值,但我们在大量的实验中发现,在某些情况下,比如权重值较大,尤其是权重和激活的异常值在同一通道时,直接根据SmoothQuant计算smooth scale的公式会导致权重值难量化的情况。并且,对于一个激活值,当异常值较多、数值范围较大,使用同一个alpha去smooth整个激活张量也并不合理。因此,PaddleSlim提出分段搜索功能,根据数值大小将激活分成K段,对于每一段进行alhpa和scale的搜索。
参数名 | 参数类型 | 参数释义 |
---|---|---|
k_piece | int | 可选参数,分段数量,默认为1,1代表不分段 |
bits_length | int | 可选参数,量化比特数,默认为8 |
search_piece | bool | 可选参数,是否搜索分段数k,默认为False,若为True,将会从1到k搜索合适的k |
search_alpha_min | float | 可选参数,搜索alpha最小值,默认为0.2 |
search_alpha_max | float | 可选参数,搜索alpha最大值,默认为0.8 |
search_scale_min | float | 可选参数,搜索scale最小值,默认为1. |
search_scale_max | float | 可选参数,搜索scale最大值,默认为1. |
weight_quant_method | str | 可选参数,权重量化方法,可选abs_max ,abs_max_channel_wise ,avg ,默认为abs_max_channel_wise |
act_quant_method | str | 可选参数,激活量化方法,可选abs_max ,avg ,默认为abs_max |
loss_function | function | 可选参数,搜索时使用的误差函数,默认为mse_loss |
GPTQ量化:
PaddleSlim中提供了对于GPTQ的支持,GPTQ算法来自GPTQ,该算法逐步按照行量化权重,利用海森矩阵来不断更新未量化的权重,在低比特 Weight Only Int4 量化表现良好。GPTQ 默认搭配使用RPTQ,若不想搭配RPTQ,调用fasterquant时设置act_order=False即可。
参数名 | 参数类型 | 参数释义 |
---|---|---|
layer | paddle.nn.Layer | 必须,传入需要量化的层,现仅支持nn.Linear,ColumnParallelLinear和RowParallelLinear类型 |
model_config | dict | 必须,传入模型结构的配置 |
quant_bits | int | 可选参数,量化比特数,默认为4 |
weight_quant_method | str | 可选参数,权重量化方法,可选abs_max ,abs_max_channel_wise ,avg ,默认为abs_max_channel_wise |
总结
看官方文档,飞浆应该是国产AI框架中对开源大模型支持最全的。但是还是存在很多的问题:
- 目前的版本还不稳定,PaddleNLP中提到量化时 PaddlePaddle、PaddleSlim 要求使用 develop 版本。但是这两个项目之间却没有对齐。
- 使用目前官方支持的一些主流大模型时,没有提供相应的模型权重格式转换脚本。要么就是使用官方加载模型时内置的转换,要么自己自己实现。
- 目前针对大模型的 GPTQ 和 PTQ 的量化方案不稳定,奇奇怪怪的错误。
- 提的issue,社区响应时快时慢,估计这些问题也是没解决。
因此,目前使用飞浆用于日常大模型训练推理量化还是有一定难度,目前还了解的比较浅,后续还有做一些进一步的尝试。最后,希望国产 AI 框架越来越好。
参考文档: