Skip to content

Latest commit

 

History

History
347 lines (287 loc) · 13 KB

LLM量化与导出文档.md

File metadata and controls

347 lines (287 loc) · 13 KB

LLM量化与导出文档

swift支持使用awq、gptq、bnb、hqq、eetq技术对模型进行量化。其中awq、gptq量化技术支持vllm进行推理加速,需要使用校准数据集,量化性能更好,但量化速度较慢。而bnb、hqq、eetq无需校准数据,量化速度较快。这五种量化方法都支持qlora微调。

awq、gptq需要使用swift export进行量化。而bnb、hqq、eetq可以直接在sft和infer时进行快速量化。

从vllm推理加速支持的角度来看,更推荐使用awq和gptq进行量化。从量化效果的角度来看,更推荐使用awq、hqq和gptq进行量化。而从量化速度的角度来看,更推荐使用hqq进行量化。

目录

环境准备

GPU设备: A10, 3090, V100, A100均可.

# 设置pip全局镜像 (加速下载)
pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
# 安装ms-swift
git clone https://github.com/modelscope/swift.git
cd swift
pip install -e '.[llm]'

# 使用awq量化:
# autoawq和cuda版本有对应关系,请按照`https://github.com/casper-hansen/AutoAWQ`选择版本
pip install autoawq -U

# 使用gptq量化:
# auto_gptq和cuda版本有对应关系,请按照`https://github.com/PanQiWei/AutoGPTQ#quick-installation`选择版本
pip install auto_gptq optimum -U

# 使用bnb量化:
pip install bitsandbytes -U

# 使用hqq量化:
# pip install transformers>=4.41
pip install hqq

# 使用eetq量化:
# pip install transformers>=4.41
# 参考https://github.com/NetEase-FuXi/EETQ
git clone https://github.com/NetEase-FuXi/EETQ.git
cd EETQ/
git submodule update --init --recursive
pip install .

# 环境对齐 (通常不需要运行. 如果你运行错误, 可以跑下面的代码, 仓库使用最新环境测试)
pip install -r requirements/framework.txt  -U
pip install -r requirements/llm.txt  -U

原始模型

awq、gptq

这里展示对qwen1half-7b-chat进行awq, gptq量化.

# awq-int4量化 (使用A100大约需要18分钟, 显存占用: 13GB)
# 如果出现量化的时候OOM, 可以适度降低`--quant_n_samples`(默认256)和`--quant_seqlen`(默认2048).
# gptq-int4量化 (使用A100大约需要20分钟, 显存占用: 7GB)

# awq: 使用`alpaca-zh alpaca-en sharegpt-gpt4:default`作为量化数据集
CUDA_VISIBLE_DEVICES=0 swift export \
    --model_type qwen1half-7b-chat --quant_bits 4 \
    --dataset alpaca-zh alpaca-en sharegpt-gpt4:default --quant_method awq

# gptq: 使用`alpaca-zh alpaca-en sharegpt-gpt4:default`作为量化数据集
# gptq量化请先查看此issue: https://github.com/AutoGPTQ/AutoGPTQ/issues/439
OMP_NUM_THREADS=14 CUDA_VISIBLE_DEVICES=0 swift export \
    --model_type qwen1half-7b-chat --quant_bits 4 \
    --dataset alpaca-zh alpaca-en sharegpt-gpt4:default --quant_method gptq

# awq: 使用自定义量化数据集
# gptq同理
CUDA_VISIBLE_DEVICES=0 swift export \
    --model_type qwen1half-7b-chat --quant_bits 4 \
    --dataset xxx.jsonl \
    --quant_method awq

# 推理 swift量化产生的模型
# awq
CUDA_VISIBLE_DEVICES=0 swift infer \
    --model_type qwen1half-7b-chat \
    --model_id_or_path qwen1half-7b-chat-awq-int4
# gptq
CUDA_VISIBLE_DEVICES=0 swift infer \
    --model_type qwen1half-7b-chat \
    --model_id_or_path qwen1half-7b-chat-gptq-int4

# 推理 原始模型
CUDA_VISIBLE_DEVICES=0 swift infer --model_type qwen1half-7b-chat

量化效果对比:

# swift量化产生的awq-int4模型
"""
<<< 你好
你好!有什么问题我可以帮助你吗?
--------------------------------------------------
<<< 2000年是闰年嘛?
是的,2000年是闰年。闰年规则是:普通年份能被4整除但不能被100整除,或者能被400整除的年份就是闰年。2000年满足后者,所以按照公历是闰年。
--------------------------------------------------
<<< 15869+587=?
15869 + 587 = 16456
--------------------------------------------------
<<< 浙江的省会在哪
浙江省的省会是杭州市。
--------------------------------------------------
<<< 这有什么好吃的
浙江美食非常丰富,以下列举一些具有代表性的:

1. **杭州菜**:如西湖醋鱼、东坡肉、龙井虾仁、叫化童鸡等,清淡而精致。
2. **宁波菜**:如红烧肉、汤圆、水磨年糕、宁波汤包等,口味鲜美。
3. **温州菜**:温州海鲜如蝤蛑、蝤蛑炒年糕、瓯菜,口味偏咸鲜。
4. **绍兴菜**:如东坡肉、霉干菜扣肉、绍兴黄酒等,酒香浓郁。
5. **嘉兴粽子**:如嘉兴肉粽,特别是五芳斋的粽子,口感软糯。
6. **金华火腿**:浙江特产,以金华地区最为著名,口感醇厚。
7. **浙东土菜**:如农家小炒、野菜、腌菜等,原汁原味。

各地还有许多特色小吃,如杭州的知味观、宋城的宋嫂鱼羹,以及各种小吃街如河坊街、西湖醋鱼一条街等,都值得一尝。如果你有具体地方或口味偏好,可以告诉我,我可以给出更具体的建议。
"""

# swift量化产生的gptq-int4模型
"""
<<< 你好
你好!很高兴为你提供帮助。有什么问题或需要咨询的吗?
--------------------------------------------------
<<< 2000年是闰年嘛?
是的,2000年是闰年。根据格里高利历(公历),闰年的规则是:普通年份能被4整除但不能被100整除,或者能被400整除的年份就是闰年。2000年满足后两个条件,所以是闰年。
--------------------------------------------------
<<< 15869+587=?
15869 + 587 = 16456
--------------------------------------------------
<<< 浙江的省会在哪
浙江省的省会是杭州市。
--------------------------------------------------
<<< 这有什么好吃的
浙江美食丰富多样,以下是一些具有代表性的:

1. **杭州菜**:如东坡肉、西湖醋鱼、龙井虾仁、叫化鸡等,注重原汁原味,讲究刀工和火候。
2. **宁波的海鲜**:如宁波汤圆、海鲜大餐,宁波炒肉丝也很有名。
3. **嘉兴粽子**:以嘉兴五芳斋的粽子最为人知,有各种口味如肉粽、豆沙粽等。
4. **绍兴黄酒**:搭配当地特色菜肴,如醉鸡、糟溜鱼片等。
5. **金华火腿**:浙江特产,口感醇厚,常作为节日礼品。
6. **温州瓯菜**:口味偏酸辣,如温州鱼生、白斩鸡等。
7. **浙东佛跳墙**:类似福建的佛跳墙,用多种海鲜和山珍炖制。

如果你对某种具体的食物感兴趣,可以告诉我,我可以提供更详细的推荐。
"""

# 原始模型
"""
<<< 你好
你好!有什么问题我可以帮助你吗?
--------------------------------------------------
<<< 2000年是闰年嘛?
是的,2000年是闰年。根据格里高利历(公历),闰年的规则是:普通年份能被4整除但不能被100整除,或者能被400整除的年份都是闰年。2000年满足后者,所以是闰年。
--------------------------------------------------
<<< 15869+587=?
15869 + 587 = 16456
--------------------------------------------------
<<< 浙江的省会在哪
浙江省的省会是杭州市。
--------------------------------------------------
<<< 这有什么好吃的
浙江的美食非常丰富,以下列举一些具有代表性的:

1. **杭州菜**:如西湖醋鱼、东坡肉、龙井虾仁、叫化童鸡等,清淡鲜美,注重原汁原味。
2. **宁波菜**:如宁波汤圆、红烧肉、海鲜类,如宁波海鲜面、清蒸河鳗等。
3. **绍兴菜**:如霉干菜扣肉、茴香豆、醉排骨,特色是酱香浓郁。
4. **温州菜**:如温州鱼丸、白斩鸡、楠溪江三鲜,口味偏咸鲜。
5. **嘉兴粽子**:特别是嘉兴五芳斋的粽子,闻名全国,甜咸皆有。
6. **金华火腿**:浙江名特产,口感鲜美,营养丰富。
7. **浙东土菜**:如东阳火腿、嵊州菜、台州海鲜等,地方特色鲜明。

当然,浙江各地还有许多特色小吃,如衢州的鸭头、湖州的粽子、舟山的海鲜等,你可以根据自己的口味选择。如果你需要更具体的推荐,可以告诉我你对哪种类型或者哪个地方的美食感兴趣。
"""

bnb、hqq、eetq

对于bnb、hqq、eetq,我们只需要使用swift infer来进行快速量化并推理。

CUDA_VISIBLE_DEVICES=0 swift infer \
    --model_type qwen1half-7b-chat \
    --quant_method bnb \
    --quantization_bit 4

CUDA_VISIBLE_DEVICES=0 swift infer \
    --model_type qwen1half-7b-chat \
    --quant_method hqq \
    --quantization_bit 4

CUDA_VISIBLE_DEVICES=0 swift infer \
    --model_type qwen1half-7b-chat \
    --quant_method eetq \
    --dtype fp16

微调后模型

假设你使用lora微调了qwen1half-4b-chat, 模型权重目录为: output/qwen1half-4b-chat/vx-xxx/checkpoint-xxx.

这里只介绍使用awq技术对微调后模型进行量化, 如果要使用gptq技术量化, 同理.

Merge-LoRA & 量化

# 使用`alpaca-zh alpaca-en sharegpt-gpt4:default`作为量化数据集
CUDA_VISIBLE_DEVICES=0 swift export \
    --ckpt_dir 'output/qwen1half-4b-chat/vx-xxx/checkpoint-xxx' \
    --merge_lora true --quant_bits 4 \
    --dataset alpaca-zh alpaca-en sharegpt-gpt4:default --quant_method awq

# 使用微调时使用的数据集作为量化数据集
CUDA_VISIBLE_DEVICES=0 swift export \
    --ckpt_dir 'output/qwen1half-4b-chat/vx-xxx/checkpoint-xxx' \
    --merge_lora true --quant_bits 4 \
    --load_dataset_config true --quant_method awq

推理量化后模型

# awq/gptq量化模型支持vllm推理加速. 也支持模型部署.
CUDA_VISIBLE_DEVICES=0 swift infer --ckpt_dir 'output/qwen1half-4b-chat/vx-xxx/checkpoint-xxx-merged-awq-int4'

部署量化后模型

服务端:

CUDA_VISIBLE_DEVICES=0 swift deploy --ckpt_dir 'output/qwen1half-4b-chat/vx-xxx/checkpoint-xxx-merged-awq-int4'

测试:

curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen1half-4b-chat",
"messages": [{"role": "user", "content": "晚上睡不着觉怎么办?"}],
"max_tokens": 256,
"temperature": 0
}'

QLoRA微调

awq、gptq

如果想要对awq、gptq量化的模型进行qlora微调,你需要进行提前量化。例如可以对原始模型使用swift export进行量化。然后使用以下命令进行微调,你需要指定--quant_method来指定对应量化的方式:

# awq
CUDA_VISIBLE_DEVICES=0 swift sft \
    --model_type qwen1half-7b-chat \
    --model_id_or_path qwen1half-7b-chat-awq-int4 \
    --quant_method awq \
    --sft_type lora \
    --dataset alpaca-zh#5000 \

# gptq
CUDA_VISIBLE_DEVICES=0 swift sft \
    --model_type qwen1half-7b-chat \
    --model_id_or_path qwen1half-7b-chat-gptq-int4 \
    --quant_method gptq \
    --sft_type lora \
    --dataset alpaca-zh#5000 \

bnb、hqq、eetq

如果想要使用bnb、hqq、eetq进行qlora微调,你需要在训练中指定--quant_method--quantization_bit

# bnb
CUDA_VISIBLE_DEVICES=0 swift sft \
    --model_type qwen1half-7b-chat \
    --sft_type lora \
    --dataset alpaca-zh#5000 \
    --quant_method bnb \
    --quantization_bit 4 \
    --dtype fp16 \

# hqq
CUDA_VISIBLE_DEVICES=0 swift sft \
    --model_type qwen1half-7b-chat \
    --sft_type lora \
    --dataset alpaca-zh#5000 \
    --quant_method hqq \
    --quantization_bit 4 \

# eetq
CUDA_VISIBLE_DEVICES=0 swift sft \
    --model_type qwen1half-7b-chat \
    --sft_type lora \
    --dataset alpaca-zh#5000 \
    --quant_method eetq \
    --dtype fp16 \

注意

  • hqq支持更多自定义参数,比如为不同网络层指定不同量化配置,具体请见命令行参数
  • eetq量化为8bit量化,无需指定quantization_bit。目前不支持bf16,需要指定dtype为fp16
  • eetq目前qlora速度比较慢,推荐使用hqq。参考issue

推送模型

假设你使用lora微调了qwen1half-4b-chat, 模型权重目录为: output/qwen1half-4b-chat/vx-xxx/checkpoint-xxx.

# 推送原始量化模型
CUDA_VISIBLE_DEVICES=0 swift export \
    --model_type qwen1half-7b-chat \
    --model_id_or_path qwen1half-7b-chat-gptq-int4 \
    --push_to_hub true \
    --hub_model_id qwen1half-7b-chat-gptq-int4 \
    --hub_token '<your-sdk-token>'

# 推送lora增量模型
CUDA_VISIBLE_DEVICES=0 swift export \
    --ckpt_dir output/qwen1half-4b-chat/vx-xxx/checkpoint-xxx \
    --push_to_hub true \
    --hub_model_id qwen1half-4b-chat-lora \
    --hub_token '<your-sdk-token>'

# 推送merged模型
CUDA_VISIBLE_DEVICES=0 swift export \
    --ckpt_dir output/qwen1half-4b-chat/vx-xxx/checkpoint-xxx \
    --push_to_hub true \
    --hub_model_id qwen1half-4b-chat-lora \
    --hub_token '<your-sdk-token>' \
    --merge_lora true

# 推送量化后模型
CUDA_VISIBLE_DEVICES=0 swift export \
    --ckpt_dir output/qwen1half-4b-chat/vx-xxx/checkpoint-xxx \
    --push_to_hub true \
    --hub_model_id qwen1half-4b-chat-lora \
    --hub_token '<your-sdk-token>' \
    --merge_lora true \
    --quant_bits 4