1.环境配置
$ conda create -n CONDA_ENV_NAME --clone /share/conda_envs/internlm-base
2.1 模型转换
使用 TurboMind 推理模型需要先将模型转化为 TurboMind 的格式,目前支持在线转换和离线转换两种形式。在线转换可以直接加载 Huggingface 模型,离线转换需需要先保存模型再加载。
2.1.1 在线转换
加载本地的huggingface模型
lmdeploy chat turbomind /share/temp/model_repos/internlm-chat-7b/ --model-name internlm-chat-7b
效果:
2.1.2 离线转换
lmdeploy convert internlm-chat-7b /path/to/internlm-chat-7b
weights
和 tokenizer
目录分别放的是拆分后的参数和 Tokenizer。如果我们进一步查看 weights
的目录,就会发现参数是按层和模块拆开。
其中名称中的.0是表示Tensor并行的索引,如果是多张卡则会出现不同的数字
2.2 TurboMind 推理+命令行本地对话
lmdeploy chat turbomind ./workspace
效果
2.3 TurboMind推理+API服务
我们尝试如何运用 lmdepoy 进行服务化。
xxxxxxxxxx lmdeploy serve api_server ./workspace \ --server_name 0.0.0.0 \ --server_port 23333 \ --instance_num 64 \ --tp 1
新开一个终端
lmdeploy serve api_client http://localhost:23333
直接打开http://{host}:23333
2.4 网页 Demo 演示
3 模型量化(***)
那么,如何优化 LLM 模型推理中的访存密集问题呢? 我们可以使用 KV Cache 量化和 4bit Weight Only 量化(W4A16)。KV Cache 量化是指将逐 Token(Decoding)生成过程中的上下文 K 和 V 中间结果进行 INT8 量化(计算时再反量化),以降低生成过程中的显存占用。4bit Weight 量化,将 FP16 的模型权重量化为 INT4,Kernel 计算时,访存量直接降为 FP16 模型的 1/4,大幅降低了访存成本。Weight Only 是指仅量化权重,数值计算依然采用 FP16(需要将 INT4 权重反量化)。
3.1 KV Cache 量化
3.1.1 量化步骤
KV Cache 量化是将已经生成序列的 KV 变成 Int8,使用过程一共包括三步:
lmdeploy lite calibrate \
--model /root/share/temp/model_repos/internlm-chat-7b/ \
--calib_dataset "c4" \
--calib_samples 128 \
--calib_seqlen 2048 \
--work_dir ./quant_output
第一步:计算 minmax。主要思路是通过计算给定输入样本在每一层不同位置处计算结果的统计情况。
-
对于 Attention 的 K 和 V:取每个 Head 各自维度在所有Token的最大、最小和绝对值最大值。对每一层来说,上面三组值都是
(num_heads, head_dim)
的矩阵。这里的统计结果将用于本小节的 KV Cache。 -
对于模型每层的输入:取对应维度的最大、最小、均值、绝对值最大和绝对值均值。每一层每个位置的输入都有对应的统计值,它们大多是
(hidden_dim, )
的一维向量,当然在 FFN 层由于结构是先变宽后恢复,因此恢复的位置维度并不相同。这里的统计结果用于下个小节的模型参数量化,主要用在缩放环节(回顾PPT内容)。x lmdeploy lite calibrate \ --model /root/share/temp/model_repos/internlm-chat-7b/ \ --calib_dataset "c4" \ --calib_samples 128 \ --calib_seqlen 2048 \ --work_dir ./quant_output
在这个命令行中,会选择 128 条输入样本,每条样本长度为 2048,数据集选择 C4,输入模型后就会得到上面的各种统计值。值得说明的是,如果显存不足,可以适当调小 samples 的数量或 sample 的长度。
第二步:通过 minmax 获取量化参数。主要就是利用下面这个公式,获取每一层的 K V 中心值(zp)和缩放值(scale)。
zp = (min+max) / 2 scale = (max-min) / 255 quant: q = round( (f-zp) / scale) dequant: f = q * scale + zp
有这两个值就可以进行量化和解量化操作了。具体来说,就是对历史的 K 和 V 存储 quant 后的值,使用时在 dequant。
# 通过 minmax 获取量化参数 lmdeploy lite kv_qparams \ --work_dir ./quant_output \ --turbomind_dir workspace/triton_models/weights/ \ --kv_sym False \ --num_tp 1
第三步:修改配置。也就是修改 weights/config.ini
文件,这个我们在《2.6.2 模型配置实践》中已经提到过了(KV int8 开关),只需要把 quant_policy
改为 4 即可。
3.2 W4A16 量化
最后结果