欺诈文本分类检测(十二):模型导出与部署
1. 引言
前文使用LoRA 适配器训练完后,每次推理时候都需要分别加载基座模型和 LoRA 适配器,一方面比较繁琐,另一方面也不利于模型部署。因此有必要将基座模型和 LoRA 适配器进行合并,导出成一个模型。
2.导出模型
LLamaFactory中自带模型合并的功能,只需要从examples/merge_lora/llama3_lora_sft.yaml
拷贝一份配置根据自己的情况进行修改。修改后的配置文件示例如下:
!cat /data2/downloads/LLaMA-Factory/merge_qwen2_lora_sft.yaml
### Note: DO NOT use quantized model or quantization_bit when merging lora adapters
### model
model_name_or_path: /data2/anti_fraud/models/modelscope/hub/Qwen/Qwen2-1___5B-Instruct
adapter_name_or_path: /data2/anti_fraud/models/Qwen2-1___5B-Instruct_ft_0826/checkpoint-1400
template: qwen
finetuning_type: lora
### export
export_dir: /data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud_1__0
export_size: 2
export_device: cuda
export_legacy_format: false
- export_size: 指定导出的模型文件分片大小,单位为GB, 适用于模型比较大需要分片导出的场景,以便在内存限制的设备上加载。
- export_device: 导出模型时使用的设备。可以选择 cpu 或 cuda(即 GPU)。如果有强大的 GPU 可以使用,选择 cuda 可以加快导出速度。
- export_legacy_format: 指定是否使用旧格式导出模型。通常情况下,选择 false 以导出使用最新格式的模型。
使用llamafactory-cli
执行export命令导出模型。
!llamafactory-cli export /data2/downloads/LLaMA-Factory/merge_qwen2_lora_sft.yaml
[2024-08-29 11:25:38,878] [INFO] [real_accelerator.py:203:get_accelerator] Setting ds_accelerator to cuda (auto detect)
……
08/29/2024 11:30:08 - INFO - llamafactory.model.adapter - Merged 1 adapter(s).
08/29/2024 11:30:08 - INFO - llamafactory.model.adapter - Loaded adapter(s): /data2/anti_fraud/models/Qwen2-1___5B-Instruct_ft_0826/checkpoint-1400
08/29/2024 11:30:08 - INFO - llamafactory.model.loader - all params: 1,543,714,304
08/29/2024 11:30:08 - INFO - llamafactory.train.tuner - Convert model dtype to: torch.bfloat16.
[INFO|configuration_utils.py:472] 2024-08-29 11:30:09,181 >> Configuration saved in /data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud_1__0/config.json
[INFO|configuration_utils.py:807] 2024-08-29 11:30:09,182 >> Configuration saved in /data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud_1__0/generation_config.json
[INFO|modeling_utils.py:2763] 2024-08-29 11:30:13,625 >> The model is bigger than the maximum size per checkpoint (2GB) and is going to be split in 2 checkpoint shards. You can find where each parameters has been saved in the index located at /data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud_1__0/model.safetensors.index.json.
[INFO|tokenization_utils_base.py:2702] 2024-08-29 11:30:13,626 >> tokenizer config file saved in /data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud_1__0/tokenizer_config.json
[INFO|tokenization_utils_base.py:2711] 2024-08-29 11:30:13,626 >> Special tokens file saved in /data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud_1__0/special_tokens_map.json
从日志可以看到,合并了一个adapter,并且根据
the maximum size per checkpoint (2GB)
将模型参数分成了两片。
查看导出的模型文件,可以看到已经按照我们的配置将模型参数分成了两个文件存储。
!ls -l /data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud_1__0
total 3026368
-rw-rw-r-- 1 a200007 a200007 80 Aug 29 11:30 added_tokens.json
-rw-rw-r-- 1 a200007 a200007 748 Aug 29 11:30 config.json
-rw-rw-r-- 1 a200007 a200007 242 Aug 29 11:30 generation_config.json
-rw-rw-r-- 1 a200007 a200007 1671853 Aug 29 11:30 merges.txt
-rw-rw-r-- 1 a200007 a200007 1975314632 Aug 29 11:30 model-00001-of-00002.safetensors
-rw-rw-r-- 1 a200007 a200007 1112152304 Aug 29 11:30 model-00002-of-00002.safetensors
-rw-rw-r-- 1 a200007 a200007 27693 Aug 29 11:30 model.safetensors.index.json
-rw-rw-r-- 1 a200007 a200007 367 Aug 29 11:30 special_tokens_map.json
-rw-rw-r-- 1 a200007 a200007 1532 Aug 29 11:30 tokenizer_config.json
-rw-rw-r-- 1 a200007 a200007 7028043 Aug 29 11:30 tokenizer.json
-rw-rw-r-- 1 a200007 a200007 2776833 Aug 29 11:30 vocab.json
3. 模型部署
LLamaFactory支持直接部署模型,只需要从examples/inference/llama3_vllm.yaml
拷贝一份配置文件,并根据自己的情况进行修改。修改后的配置文件示例如下:
!less /data2/downloads/LLaMA-Factory/qwen2_inference.yaml
model_name_or_path: /data2/anti_fraud/models/Qwen2-1__5B-Instruct-anti_fraud_1__0
template: qwen
infer_backend: vllm
vllm_enforce_eager: false
- template: 指定要使用的推理模板,一般是与模型架构绑定,例如:qwen、llama。
- infer_backend:指定后端使用的推理框架,这里使用vllm加速推理。
- vllm_enforce_eager:设为false可以启用cuda计算图进行推理性能优化。
封装一个shell脚本anti_fraud_start.sh
,分别指定了模型要运行的设备、对外服务端口以及启动命令用于快速启动服务:
#!/bin/sh
export CUDA_VISIBLE_DEVICES=5
export API_PORT=8001
nohup llamafactory-cli api /data2/downloads/LLaMA-Factory/qwen2_inference.yaml > /data2/anti_fraud/logs/anti_fraud.log 2>&1 &
注:
llamafactory-cli api xxx
表示以http api的方式来启动服务。
4. 推理测试
启动服务后,使用openai的标准api接口来测试服务功能。
%%time
from openai import OpenAI
def predict(prompt):
client = OpenAI(api_key="0",base_url="http://192.168.31.200:8001/v1")
messages = [{"role": "user", "content": prompt}]
result = client.chat.completions.create(messages=messages, model="Qwen2-1__5B-Instruct")
return result.choices[0].message.content
predict("详细介绍下你自己。")
CPU times: user 50.6 ms, sys: 8.04 ms, total: 58.7 ms
Wall time: 1.09 s
'我是阿里云开发的一种超大规模语言模型,我叫通义千问。我能够回答问题、创作文字,也可以表达观点、撰写代码。我由大量高质量的语料库训练而来,能够理解并生成人类自然语言,这是由于我被训练来模拟人类的对话和写作过程。'
封装一个用于欺诈文本分类的提示语构建方法。
def build_fraud_prompt(content):
return f"下面是一段对话文本, 请分析对话内容是否有诈骗风险,以json格式输出你的判断结果(is_fraud: true\/false)。\n{content}"
正向用例测试:
%%time
content = '小明: 我们有专业的团队进行风险管理,可以确保你的投资安全。而且我们会提供实时的投资动态,让你随时掌握投资情况。\n小红: 那我什么时候能回收投资并获得收益呢?\n小明: 投资期限为1年,到期后你就可以回收本金和收益。\n小红: 听起来还不错,我会考虑一下。谢谢你的介绍。\n小明: 不客气,如果你有任何问题,随时可以问我。希望你能抓住这个机会,获得更多的财富。'
predict(build_fraud_prompt(content))
CPU times: user 53.3 ms, sys: 3.71 ms, total: 57 ms
Wall time: 217 ms
'{"is_fraud": true}'
反向用例测试:
%%time
content = '发言人3: 然后从不管是分业务板块的一个营收占比和分地区板块的或分地区的一个营收占比来看的话,首先这个屠宰基本上是占了公司总体营收的90%以上的一个比例,但是我们可以看到左下角的这个图,近几年畜禽养殖板块其实更多就来自于生猪养殖板块,它对于整个营收的一个占比它其实有一个明显的提升,而且随着未来公司出栏量的一个增长,包括可能猪价的一个后面有一个周期的一个反转的话,可能未来养殖板块它占总营收的一个比例仍然会有一个快速的一个提升。'
predict(build_fraud_prompt(content))
CPU times: user 52.9 ms, sys: 3.34 ms, total: 56.2 ms
Wall time: 215 ms
'{"is_fraud": false}'
小结: 本文主要介绍了如何通过LLamaFactory框架提供的命令来快速实现模型文件的导出和部署,并用openai库来测试本地私有部署的模型功能。
参考资料
- 欺诈文本分类检测(十一):LLamaFactory多卡微调
- LLamaFactory使用教程