0 LMDeploy特性

这个视频算是把各种位置编码讲的很清楚的了 对历史生成的token对QKV的计算结果进行缓存

LMDeploy 量化部署实践闯关任务_大模型


量化技术

LMDeploy 量化部署实践闯关任务_大模型_02


观点1

仅有0.1-1%的权重影响大,对其它权重进行低比特量化

基于激活值进行挑选量化,效果会不错

观点2,

量化时对显著权重缩放

LMDeploy 量化部署实践闯关任务_API_03


实现混合精度的计算

LMDeploy 量化部署实践闯关任务_大模型_04


阈值的确定就通过每行的绝对值平均值

LMDeploy 量化部署实践闯关任务_API_05


大模型外推

LMDeploy 量化部署实践闯关任务_权重_06


通过位置编码角度解决:

直接用整数1,2,…,1000作为位置:数值跨度大,对梯度优化不友好

如果缩放到[0,1]

跨度太小,模型和优化器不易分辨

使用向量:

1234用[1,2,3,4]

transformer原作者:训练阶段预留足够的位数。

LMDeploy 量化部署实践闯关任务_API_07


线性内插法:个位数比较拥挤

LMDeploy 量化部署实践闯关任务_权重_08


进制转换法:用10进制转成16进制

NTK-aware

LMDeploy 量化部署实践闯关任务_API_09


因此,原来的sin-cos编码也可以被统一到这个框架下

LMDeploy 量化部署实践闯关任务_API_10

任务一要求

使用结合W4A16量化与kv cache量化的internlm2_5-1_8b-chat模型封装本地API并与大模型进行一次对话,作业截图需包括显存占用情况与大模型回复,参考4.1 API开发(优秀学员必做),请注意2.2.3节与4.1节应使用作业版本命令。

配置LMDeploy环境

1.1InternStudio开发机创建与环境搭建

模型网址 获取模型精度"torch_dtype": “bfloat16”,

LMDeploy 量化部署实践闯关任务_API_11

安装python环境

conda create -n lmdeploy  python=3.10 -y
conda activate lmdeploy
conda install pytorch==2.1.2 torchvision==0.16.2 torchaudio==2.1.2 pytorch-cuda=12.1 -c pytorch -c nvidia -y
pip install timm==1.0.8 openai==1.40.3 lmdeploy[all]==0.5.3

1.2 InternStudio环境获取模型

创建软链接

mkdir /root/models
ln -s /root/share/new_models/Shanghai_AI_Laboratory/internlm2_5-7b-chat /root/models
ln -s /root/share/new_models/Shanghai_AI_Laboratory/internlm2_5-1_8b-chat /root/models
ln -s /root/share/new_models/OpenGVLab/InternVL2-26B /root/models

1.3 LMDeploy验证启动模型文件

先测试一下模型能不能用
注意,这里的模型路径要自己更改

conda activate lmdeploy
lmdeploy chat /root/models/internlm2_5-1_8b-chat

启动界面:

LMDeploy 量化部署实践闯关任务_数据集_12

测试对话:

LMDeploy 量化部署实践闯关任务_权重_13

记住现在的显存占用

LMDeploy与InternLM2.5

1.模型W4A16量化

用c4数据集微调报错,解决方法是pip install datasets2.19.2

LMDeploy 量化部署实践闯关任务_权重_14


用ptb数据集微调也报错,解决方法是pip install datasets2.19.2

LMDeploy 量化部署实践闯关任务_数据集_15


用wikitext2数据集微调通过

conda activate lmdeploy
lmdeploy lite auto_awq \
   /root/models/internlm2_5-1_8b-chat \
  --calib-dataset 'wikitext2' \
  --calib-samples 128 \
  --calib-seqlen 2048 \
  --w-bits 4 \
  --w-group-size 128 \
  --batch-size 1 \
  --search-scale False \
  --work-dir /root/models/internlm2_5-1_8b-chat-w4a16-4bit

微调完成

LMDeploy 量化部署实践闯关任务_数据集_16

LMDeploy 量化部署实践闯关任务_大模型_17

conda activate lmdeploy
lmdeploy lite auto_awq \
   /root/models/internlm2_5-1_8b-chat \
  --calib-dataset 'pileval' \
  --calib-samples 128 \
  --calib-seqlen 2048 \
  --w-bits 4 \
  --w-group-size 128 \
  --batch-size 1 \
  --search-scale False \
  --work-dir /root/models/internlm2_5-1_8b-chat-w4a16-4bit

查看模型目录

cd /root/models/
du -sh *

量化后的是1.5G大小

LMDeploy 量化部署实践闯关任务_数据集_18

cd /root/share/new_models/Shanghai_AI_Laboratory/
du -sh *

原模型是3.6G大小。压缩了一半

LMDeploy 量化部署实践闯关任务_API_19

2.模型效果比对

API调用原模型

conda activate lmdeploy
lmdeploy serve api_server \
    /root/models/internlm2_5-1_8b-chat \
    --model-format hf \
    --quant-policy 0 \
    --server-name 0.0.0.0 \
    --server-port 23333 \
    --tp 1

LMDeploy 量化部署实践闯关任务_权重_20


LMDeploy 量化部署实践闯关任务_数据集_21

结果:

LMDeploy 量化部署实践闯关任务_数据集_22


显存占用

LMDeploy 量化部署实践闯关任务_大模型_23

部署W4A16量化模型
非API调用

lmdeploy chat /root/models/internlm2_5-1_8b-chat-w4a16-4bit

LMDeploy 量化部署实践闯关任务_大模型_24


显存占用

LMDeploy 量化部署实践闯关任务_langchain_25



conda activate lmdeploy
lmdeploy serve api_server \
    /root/models/internlm2_5-1_8b-chat-w4a16-4bit \
    --model-format awq\
    --quant-policy 0 \
    --server-name 0.0.0.0 \
    --server-port 23333 \
    --tp 1

之前使用参数–model-format hf会报错

LMDeploy 量化部署实践闯关任务_langchain_26


部署后显存占用情况:

LMDeploy 量化部署实践闯关任务_大模型_27


问答情况

LMDeploy 量化部署实践闯关任务_langchain_28

部署W4A16量化模型+kv cache

lmdeploy serve api_server \
    /root/models/internlm2_5-1_8b-chat-w4a16-4bit/ \
    --model-format awq \
    --cache-max-entry-count 0.4\
    --server-name 0.0.0.0 \
    --server-port 23333 \
    --tp 1

显存占用

LMDeploy 量化部署实践闯关任务_数据集_29


对话情况

LMDeploy 量化部署实践闯关任务_API_30

部署W4A16量化模型+kv cache int4量化

lmdeploy serve api_server \
    /root/models/internlm2_5-1_8b-chat-w4a16-4bit/ \
    --model-format awq \
    --quant-policy 4 \
    --cache-max-entry-count 0.4\
    --server-name 0.0.0.0 \
    --server-port 23333 \
    --tp 1

显存占用

LMDeploy 量化部署实践闯关任务_数据集_31


实验结果:

LMDeploy 量化部署实践闯关任务_API_32

对于计算问题:1.5*3.6结果是多少

原版模型回答正确

LMDeploy 量化部署实践闯关任务_langchain_33


量化后回答也正确

LMDeploy 量化部署实践闯关任务_API_34

但是把kv cache int4也量化了,结果就错了

LMDeploy 量化部署实践闯关任务_大模型_35

Function call

使用Function call功能让大模型完成一次简单的"加"与"乘"函数调用,作业截图需包括大模型回复的工具调用情况,参考4.2 Function call(选做)
新建internlm2_5_func.py

touch /root/internlm2_5_func.py

编写内容

from openai import OpenAI


def add(a: int, b: int):
    return a + b


def mul(a: int, b: int):
    return a * b


tools = [{
    'type': 'function',
    'function': {
        'name': 'add',
        'description': 'Compute the sum of two numbers',
        'parameters': {
            'type': 'object',
            'properties': {
                'a': {
                    'type': 'int',
                    'description': 'A number',
                },
                'b': {
                    'type': 'int',
                    'description': 'A number',
                },
            },
            'required': ['a', 'b'],
        },
    }
}, {
    'type': 'function',
    'function': {
        'name': 'mul',
        'description': 'Calculate the product of two numbers',
        'parameters': {
            'type': 'object',
            'properties': {
                'a': {
                    'type': 'int',
                    'description': 'A number',
                },
                'b': {
                    'type': 'int',
                    'description': 'A number',
                },
            },
            'required': ['a', 'b'],
        },
    }
}]
messages = [{'role': 'user', 'content': 'Compute (3+5)*2'}]

client = OpenAI(api_key='YOUR_API_KEY', base_url='http://0.0.0.0:23333/v1')
model_name = client.models.list().data[0].id
response = client.chat.completions.create(
    model=model_name,
    messages=messages,
    temperature=0.8,
    top_p=0.8,
    stream=False,
    tools=tools)
print(response)
func1_name = response.choices[0].message.tool_calls[0].function.name
func1_args = response.choices[0].message.tool_calls[0].function.arguments
func1_out = eval(f'{func1_name}(**{func1_args})')
print(func1_out)

messages.append({
    'role': 'assistant',
    'content': response.choices[0].message.content
})
messages.append({
    'role': 'environment',
    'content': f'3+5={func1_out}',
    'name': 'plugin'
})
response = client.chat.completions.create(
    model=model_name,
    messages=messages,
    temperature=0.8,
    top_p=0.8,
    stream=False,
    tools=tools)
print(response)
func2_name = response.choices[0].message.tool_calls[0].function.name
func2_args = response.choices[0].message.tool_calls[0].function.arguments
func2_out = eval(f'{func2_name}(**{func2_args})')
print(func2_out)

启动量化过的模型的API服务器

conda activate lmdeploy
lmdeploy serve api_server \
    /root/models/internlm2_5-1_8b-chat-w4a16-4bit/ \
    --model-format awq \
    --cache-max-entry-count 0.4\
    --server-name 0.0.0.0 \
    --server-port 23333 \
    --tp 1

这个模型比较笨,还不容易调用到tool

换成internlm2_5-7b-chat 后

容易在调用乘法的时候报错

Traceback (most recent call last):

File “/root/internlm2_5_func.py”, line 65, in

func1_name = response.choices[0].message.tool_calls[0].function.name

TypeError: ‘NoneType’ object is not subscriptable

不过多试几次还是可以跑通的

LMDeploy 量化部署实践闯关任务_权重_36