swift-3框架使用
前言
【如果发现问题多去官方群里问吧,又踩到了一个bug】
接前面,swift3相比于swift2做了大升级,很多swift2能使用的在3里面error改改改…但是效率确实大升级,推理速度快了很多~~~
- !!!需要注意,swift3和swift2的使用一定要分开!如果用swift2微调后的模型,目前不要使用swift3进行推理,或出现很奇怪的问题,还不会有报错如果输入了model_type,千万不要混着用这两个版本的框架
- 需要注意,swift3很多默认参数没有像swift2那样默认加进去,所以同样默认参数swift2训出来的会比swift3好,需要做设置【注意看打印的log内容】,swift3里面是默认没设置的,默认没设置!!!
swift3安装
安装也是一波三折,和swift2一样需要注意安装顺序,不然可能得删了重装。
# 首先安装conda python3.10
conda create -n swift3 python==3.10
# 然后安装torch和torchvision
pip install torch torchvision
# 安装flash-attn,如果安装失败像前一篇一样安装
pip install flash-attn
# 安装timm
pip install auto_gptq optimum bitsandbytes timm
# 下载仓库安装swift3,网络不好上github官网下载解压,最好拉取最新的
git clone https://github.com/modelscope/ms-swift.git
cd ms-swift
pip install -e .
# 如果有需要,安装vllm
pip install vllm
- 这里需要注意的是,上面pip install -e .安装的方式,ms-swift这个文件夹需要一直存好,删了这个文件夹就需要重新安装swift
swift lora微调
!!!注意,训练数据格式可以和swift2一样不需要改
#jsonl格式的数据
{"query": "<image>55555", "response": "66666", "images": ["image_path"]}
{"query": "eeeee<image>eeeee<image>eeeee", "response": "fffff", "history": [], "images": ["image_path1", "image_path2"]}
{"query": "EEEEE", "response": "FFFFF", "history": [["query1", "response2"], ["query2", "response2"]], "images": []}
但是训练的脚本需要改一下,很多参数swift3和swift2不一样,swift2的不同版本可能也不一样,如果还报错需要去官方git的swift的sft源代码下面去确认【主要是swift2里面的model_id_or_path在3里面就叫model了,flashattention这里参数名字也改了,并且swift3很多参数不会设置默认值,需要自己设置】
CUDA_VISIBLE_DEVICES=0 MAX_PIXELS=1003520 swift sft \
--model_type internvl2_5 \
--model /data/coding/llm_model/OpenGVLab/InternVL2_5-8B \
--dataset /data/coding/mix_img_text_train_1227.jsonl \
--train_type lora \
--attn_impl flash_attn \
--freeze_vit false \
--freeze_aligner false \
--freeze_llm false \
--freeze_parameters_ratio 0. \ # freeze参数的比例,full的时候可以设置
--per_device_train_batch_size 1 \
--per_device_eval_batch_size 2 \
--split_dataset_ratio 0.1 \
--output_dir internvl25_1227 \
--max_steps 1500 \
--save_steps 100 \
--eval_steps 100 \
--save_total_limit 2 \
--logging_steps 10 \
--seed 42 \
--learning_rate 1e-4 \
--init_weights true \
--lora_rank 8 \
--lora_alpha 32 \
--adam_beta1 0.9 \
--adam_beta2 0.95 \
--adam_epsilon 1e-08 \
--weight_decay 0.1 \
--gradient_accumulation_steps 8 \
--max_grad_norm 1 \
--lr_scheduler_type cosine \
--warmup_ratio 0.05 \
--warmup_steps 0 \
--gradient_checkpointing false
- log里面trainable_parameters不需要管,下面后面有trainerble参数量,可以每次都确认一下
- 注意,swift默认freeze_vit=true,freeze_aligner=true,freeze_llm=false,如果有不同需求可以lora和full都进行针对性修改
- 全参数微调修改train_type=full,同时reeze_vit=true,freeze_aligner=true,freeze_llm=false,然后确认一下打印的log里面训练的参数量和占比
- 部分参数微调可以设置freeze_parameters_ratio,表示从下往上冻结的参数比例, 默认为0. 可设置为1将所有参数冻结
swift cli推理
注意:
- 如果是用swift2微调的模型,哪怕merge-lora之后也千万不要用swift3推理,不然会报错,ValueError: Please explicitly pass the model_type. For reference, the available model_types: [‘qwen2_vl’, ‘qvq’],填了model_types以后输出是错的,也不会报错,很迷惑的
- swift3可以使用2里面的数据格式,但是response不能为空,随便填一个字符串到response就行,response为空会报错
#jsonl格式的数据
{"query": "<image>55555", "response": "66666", "images": ["image_path"]}
{"query": "eeeee<image>eeeee<image>eeeee", "response": "fffff", "history": [], "images": ["image_path1", "image_path2"]}
{"query": "EEEEE", "response": "FFFFF", "history": [["query1", "response2"], ["query2", "response2"]], "images": []}
使用swift3推理时选用vllm和flash-attn快很多,A100-80的卡上,纯文本推理,没用的情况下是一个半小时,用了是10分钟,真香~
- 注意,不需要输入model_type,如果要输入model_type,大概率是哪里出错了,可以去找官方群问一下
- 注意,如果图片数量超过1,需要设置limit_mm_per_prompt,控制vllm使用多图, 默认为None. 例如传入–limit_mm_per_prompt '{“image”: 10, “video”: 5}'表示最多10张图,5个视频,否则报错
【有一个swift的3.0.2版本不要在CLI使用vllm,只会存最后1024条数据】
#单卡vllm推理脚本(前面不要有NPROC_PER_NODE参数,否则会挂起)
#如果运行时突然exit,可能是内存炸了,显存没炸(vllm推理时把整个数据集读到内存里面了),这时更新最新的ms-swift版本有修复
CUDA_VISIBLE_DEVICES=0 MAX_PIXELS=1003520 swift infer \
--ckpt_dir /data/coding/checkpoint-3000-merged \
--attn_impl flash_attn \
--max_new_tokens 300 \
--temperature 0 \
--val_dataset /data/coding/content_test.jsonl \
--result_path output_3000.jsonl \
--max_num_seqs 256 \ # 爆显存降低这个值
--gpu_memory_utilization 0.9 \ # 爆显存降低这个值
--infer_backend vllm
- 如果是不使用vllm,只是使用infer_backend为pt,batch inference,使用下面的脚本(需要填NPROC_PER_NODE参数):
# pt推理
NPROC_PER_NODE=1 MAX_PIXELS=1003520 swift infer \
--ckpt_dir /data/coding/checkpoint-3000-merged \
--attn_impl flash_attn \
--max_new_tokens 300 \
--temperature 0 \
--val_dataset /data/coding/content_test.jsonl \
--result_path output_3000.jsonl \
--max_batch_size 16 \ # 爆显存降低这个值
--infer_backend pt
如果需要使用新的数据格式,swift3推荐的是这样的:
{"messages": [{"role": "system", "content": "你是个有用无害的助手"}, {"role": "user", "content": "<image>图片中是什么,<video>视频中是什么"}, {"role": "assistant", "content": "一个大象,一个狮子"}], "images": ["/xxx/x.jpg"], "videos": ["/xxx/x.mp4"]}
swift vllm python推理
!!注意目前版本不要用CLI的VLLM推理数据写入有问题,除非stream模式,可以用下面的方式
注意数据的格式,python推理时需要包成下面类似的格式
{"messages": [{"role": "system", "content": "<system>"}, {"role": "user", "content": "<query1>"}, {"role": "assistant", "content": "<response1>"}, {"role": "user", "content": "<query2>"}, {"role": "assistant", "content": "<response2>"}]}
import os
from swift.llm import InferEngine, InferRequest, PtEngine, RequestConfig, load_dataset
from swift.plugin import InferStats
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
os.environ['MAX_PIXELS']='602112' # 设置最大图片大小,防止爆显存
from swift.llm import VllmEngine
model_name='模型的本地地址'
engine=VllmEngine(model_name,model_type='模型的type',gpu_memory_utilization=0.9)
test_img_path = '本地图片.jpg'
message = [{
'role': 'user',
'content': [
{
"type": "image",
"image": test_img_path
},
{"type": "text", "text": "What can you see in the image?"},
]
}]
data = dict()
data['messages'] = message
request_config = RequestConfig(max_tokens=512, temperature=0)
metric = InferStats()
infer_requests = [InferRequest(**data)]
resp_list = engine.infer(infer_requests, request_config)
query0 = infer_requests[0].messages[0]['content']
response = resp_list[0].choices[0].message.content
print(response)