跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

Qwen3-VL 基于 Llama-Factory QLoRA 训练部署全流程:Open-EQA 具身智能数据集

综述由AI生成介绍使用 Qwen3-VL-2B-Instruct 模型配合 Llama-Factory 框架进行 QLoRA 微调的全流程。涵盖环境配置、基于 Open-EQA 数据集的训练、评估指标分析、模型融合导出,以及在 Ollama 和 LMDeploy 下的推理部署。详细展示了在 NVIDIA Tesla T4 显卡上的配置参数、损失曲线分析及 API 调用方法,验证了 16GB 显存环境下多模态具身智能任务的可执行性与效果。

道系青年发布于 2026/4/6更新于 2026/5/2228 浏览
Qwen3-VL 基于 Llama-Factory QLoRA 训练部署全流程:Open-EQA 具身智能数据集

数据来源 Open-EQA 多模态具身智能数据集,经过处理每个样本八张图片,划分为训练 - 验证集和测试集。

1.微调训练

有 cuda 显卡可以执行 pip install unsloth 可以安装 Unsloth 加快训练和推理

执行 pip install tensorboard 安装保存完整训练过程的数据,避免中断只能部分曲线

创建 saves/Qwen3-VL-2B-Instruct/qlora/train_openeqa,并创建文件 training_args.yaml,内容参考,路径根据自己的情况改

### model
model_name_or_path: model/Qwen3-VL-2B-Instruct
trust_remote_code: true

### method
stage: sft
do_train: true
finetuning_type: lora
lora_target: all
lora_rank: 8
lora_alpha: 16
lora_dropout: 0.1

### 是否使用 unsloth 加速
use_unsloth: false
# 不启用 Unsloth 加速
#unsloth_max_seq_length: 2048 # Unsloth 内部优化
flash_attn: auto # T4 自动回退到 FA1 或 sdpa

### quantization (QLoRA)
quantization_bit: 4
quantization_method: bitsandbytes
double_quantization: true #双量化/嵌套量化,进一步节省显存

### dataset
dataset: open_eqa_train_val
template: qwen3_vl_nothink
cutoff_len: 2048
max_samples: 100000
overwrite_cache: true
preprocessing_num_workers: 8

### output
output_dir: saves/Qwen3-VL-2B-Instruct/qlora/train_openeqa
logging_steps: 10
save_steps: 25
resume_from_checkpoint: false #首次用 false,断点训练用 true
overwrite_output_dir: true

### train
per_device_train_batch_size: 2 # 如果是用 Unsloth 省显存,可以加大
gradient_accumulation_steps: 4 # 有效 batch=8
learning_rate: 5.0e-5 # Unsloth 可以用更高 LR
num_train_epochs: 3.0
lr_scheduler_type: cosine
warmup_ratio: 0.05
#warmup_steps: 0
fp16: true
ddp_timeout: 180000000

### optimization
optim: adamw_torch
# group_by_length: true
report_to: tensorboard
plot_loss: true
video_max_pixels: 65536
video_min_pixels: 256
freeze_multi_modal_projector: true
freeze_vision_tower: true
image_max_pixels: 589824
image_min_pixels: 1024

### evaluation
do_eval: true
per_device_eval_batch_size: 2
val_size: 0.125
eval_strategy: steps
eval_steps: 25
eval_delay: 0 # 延迟多少步开始第一次评估
prediction_loss_only: true # 是否需要完整预测(多模态通常需要 false 以计算准确率和生成指标,除非显存不足)

### save & eval 联动(可选但推荐)
load_best_model_at_end: true # 训练结束后加载最佳模型
#metric_for_best_model: eval_loss # 或 eval_accuracy 等,选择监控指标
#greater_is_better: false # eval_loss 越小越好,如果是 accuracy 则设为 true
#save_total_limit: 3 # 保留最新的 3 个检查点,避免磁盘爆满

这次训练设备配置是显存 16GB 的 NVIDIA Tesla T4,执行 llamafactory-cli train saves/Qwen3-VL-2B-Instruct/qlora/train_openeqa/training_args.yaml 开始训练

文章配图

文章配图

若出现中断,将 resume_from_checkpoint 设置为 true 恢复中断训练继续训练

llamafactory-cli train saves/Qwen3-VL-2B-Instruct/qlora/train_openeqa/training_args.yaml

训练结束

文章配图

观察图片

文章配图

文章配图

从训练和验证的损失曲线与指标来看,Qwen3-VL-2B-Instruct 在 Open-EQA 多模态小样本训练 - 验证集上的表现可以这样总结:

训练阶段表现

  • 损失变化:训练损失初始值很高(约 5.5),在训练初期(前 100 步)快速下降,之后下降速度放缓,在 200 步后稳定在 1.0~1.5 区间。
  • 最终指标:最终训练损失为 1.3233,说明模型在训练集上的拟合效果良好,且后期波动很小,收敛稳定。
  • 效率:训练总耗时约 2 小时 27 分钟,共完成 453 步,计算量达 48049026 GFLOPs,显示出多模态训练的计算成本较高。

验证阶段表现

  • 损失变化:验证损失初始值约 1.8,同样在初期快速下降,100 步后趋于平缓,后期稳定在 1.25~1.3 区间。
  • 最终指标:最终验证损失为 1.2683,略低于训练损失,这表明模型在未见过的验证数据上泛化能力较好,没有出现明显的过拟合。
  • 效率:验证集共 173 个样本,耗时约 2 分钟 10 秒,批大小为 2,验证阶段的样本处理速度比训练阶段更快。

整体表现

训练和验证的损失曲线趋势高度一致,且验证损失略低于训练损失,说明模型在训练过程中不仅对训练数据拟合充分,还具备良好的泛化能力,在 Open-EQA 多模态小样本任务上表现稳定。

如果曲线不完整,可以把云服务器的 runs 目录中 tensorboard 日志文件下载到本地电脑,

文章配图

在自己电脑的 python 环境执行 uv pip install tensorboard -i http://mirrors.aliyun.com/pypi/simple 安装 tensorboard,对于纯 python 或 conda 可以直接执行 pip install tensorboard -i http://mirrors.aliyun.com/pypi/simple 安装 tensorboard

文章配图

执行 tensorboard --logdir=/Users/Zhuanz/Downloads --port 6006 查看,--logdir 是你的 tensorboard 日志文件文件的所在目录(不是文件),port 是端口号可自己设置

文章配图

查看网页

文章配图

文章配图

文章配图

2.测试评估

创建 saves/Qwen3-VL-2B-Instruct/qlora/eval_openeqa 目录,并建立 eval_args.yaml,内容如下,其中 do_predict 设置为 true 代表评估测试,注意要改适配器路径 adapter_name_or_path、基座模型路径 model_name_or_path 和是融合模型路径 output_dir

adapter_name_or_path: saves/Qwen3-VL-2B-Instruct/qlora/train_openeqa/ #最佳 checkpoint
cutoff_len: 2048
dataset_dir: data
ddp_timeout: 180000000
do_predict: true
eval_dataset: open_eqa_test
finetuning_type: lora
flash_attn: auto
max_new_tokens: 128
max_samples: 99999
model_name_or_path: model/Qwen3-VL-2B-Instruct
output_dir: saves/Qwen3-VL-2B-Instruct/qlora/eval_openeqa
per_device_eval_batch_size: 2
predict_with_generate: true
preprocessing_num_workers: 4
report_to: none
stage: sft
temperature: 0.2
template: qwen3_vl_nothink
top_p: 1.0
trust_remote_code: true

执行 llamafactory-cli train saves/Qwen3-VL-2B-Instruct/qlora/eval_openeqa/eval_args.yaml

文章配图

测试评估结束

文章配图

结论:Qwen3-VL-2B-Instruct 模型经 QLoRA 轻量化微调 Open-EQA 多模态具身智能数据集后,在 NVIDIA Tesla T4(16GB 显存)硬件环境下完成了全量测试集的推理评估,本次评估共涉及 258 个测试样本,且每个样本包含 8 张关联图片的多模态输入。评估过程中模型采用批大小 2 的推理配置,全程无显存溢出等异常问题,稳定完成所有样本的预测推理,验证了 QLoRA 微调方案对 16GB 显存低算力显卡的良好适配性。从生成指标来看,模型预测 BLEU-4 值达 29.4966,ROUGE 系列指标中 ROUGE-1、ROUGE-2、ROUGE-L 分别为 36.2965、7.9106、35.7659,整体指标表现表明模型经微调后具备了一定的多图关联理解能力和与任务匹配的文本生成能力,其中 ROUGE-1 和 ROUGE-L 的较好表现体现模型能有效捕捉具身智能任务中的核心信息,ROUGE-2 偏低则反映模型在短句语义衔接的细粒度生成上仍有提升空间。从推理效率来看,本次预测全程耗时约 2 小时 55 分钟,样本处理速度为 0.025 个 / 秒、步数处理速度为 0.012 个 / 秒,推理速度整体偏低,核心受单样本 8 张图片的多模态特征提取带来的高计算量影响。整体而言,模型在 16GB 显存的 Tesla T4 显卡上成功实现了 Open-EQA 具身智能多图任务的稳定推理,并取得了具备参考性的生成效果,充分验证了本次 QLoRA 微调的实际有效性,同时也为后续通过优化图片处理策略、调整推理配置来提升模型推理速度,以及针对性优化训练策略改善细粒度生成能力提供了实际参考依据。

3.融合模型导出

创建 saves/Qwen3-VL-2B-Instruct/qlora/merge 目录,并建立 merge_openeqa.yaml,路径同样需要修改,内容如下,

### model
model_name_or_path: model/Qwen3-VL-2B-Instruct
adapter_name_or_path: saves/Qwen3-VL-2B-Instruct/qlora/train_openeqa/
template: qwen3_vl_nothink
finetuning_type: lora
trust_remote_code: true

### export
export_dir: saves/Qwen3-VL-2B-Instruct/qlora/merge
export_size: 2 #导出模型分片(shard)的单文件大小上限,单位是 GB
export_device: auto
export_legacy_format: false #true:导出 .bin(旧/legacy)false:导出 .safetensors(默认/推荐)

执行 llamafactory-cli export saves/Qwen3-VL-2B-Instruct/qlora/merge/merge_openeqa.yaml

文章配图

4.推理部署 API 服务

(1) Ollama

将融合模型下载到本地目录,比如/saves/Qwen3-VL-2B-Instruct/qlora/merge,并进入目录,打开 Modelfile 文件,可以根据需要修改

# ollama modelfile auto-generated by llamafactory
FROM .
TEMPLATE """{{ if .System }}<|im_start|>system {{ .System }}<|im_end|> {{ end }}{{ range .Messages }}{{ if eq .Role "user" }}<|im_start|>user {{ .Content }}<|im_end|> <|im_start|>assistant {{ else if eq .Role "assistant" }}{{ .Content }}<|im_end|> {{ end }}{{ end }}"""
# PARAMETER temperature 0.7 #可设置温度
PARAMETER stop "<|im_end|>"
PARAMETER num_ctx 4096

到终端执行创建模型的命令,模型将被转换格式并放入 ollama 的模型空间中,这里是这个 qwen3-vl-2b 是在 ollama 模型空间的模型名称,可以修改

ollama create qwen3-vl-2b -f Modelfile

文章配图

执行 ollama list 查看 ollama 的模型列表

文章配图

调用方法

这里只列举其中三种

1)命令行直接传入

执行 ollama run qwen3-vl-2b "问题" 图片路径,比如

ollama run qwen3-vl-2b "墙上有什么东西" ./data/open_eqa_frames/0a0c0f2b9ba65d1b/000.jpg

文章配图

2)交互式模式

先执行 ollama run qwen3-vl-2b 加载模型,进入交互模式,然后输入问题及图片路径,比如带有斑纹的椅子上有几个枕头 ./data/open_eqa_frames/0a0c0f2b9ba65d1b/000.jpg

文章配图

3)curl 调用

执行 IMG=$(base64 -i data/open_eqa_frames/0a0c0f2b9ba65d1b/000.jpg | tr -d '\n') 转图片为 base64 格式

文章配图

执行命令

curl http://localhost:11434/api/generate -d '{ 
  "model": "模型名称", 
  "system": "系统提示词", 
  "prompt": "用户提示词", 
  "images": ["$图片 base64 变量"], 
  "format": "格式", 
  "stream": "是否流式输出", 
  "options": {参数设置}, 
}'

比如

curl http://localhost:11434/api/generate -d '{ "model": "qwen3-vl-2b", "system": "你是机器人控制 AI。你必须输出可执行的动作序列。scene_analysis 必须包含:目标相对于当前视角的方位(左/右/前)和距离(米)。plan 中的 params 必须使用英文键名(target/type/distance/degrees)。严禁使用中文键名。", "prompt": "观察图片,为指令\"怎么关闭台灯\"输出 JSON:\n{\n \"scene_analysis\": \"目标在 [方位],距离 [X] 米\",\n \"plan\": [\n {\"action\": \"rotate\", \"params\": {\"degrees\": 角度,\"direction\": \"left|right\"}},\n {\"action\": \"navigate\", \"params\": {\"distance\": 米数}},\n {\"action\": \"interact\", \"params\": {\"type\": \"press\", \"target\": \"台灯开关\"}}\n ]\n}", "images": ["'$IMG'"], "format": "json", "stream": false, "options": {"temperature": 0.01, "num_predict": 300} }'

回答得不错,基本符合格式,实际使用最好使用解析器处理格式

文章配图

(2) LMDeploy

切换激活环境,执行 pip install --no-cache-dir lmdeploy 安装 LMDeploy 库

文章配图

编写测试脚本 test_offline.py

from lmdeploy import pipeline, TurbomindEngineConfig, PytorchEngineConfig, GenerationConfig
from lmdeploy.vl import load_image
import time

MODEL_PATH = "/workspace/LlamaFactory/saves/Qwen3-VL-2B-Instruct/qlora/merge"
IMAGE_PATH = "/workspace/LlamaFactory/data/open_eqa_frames/0a0c0f2b9ba65d1b/000.jpg"

print("🚀 使用 LMDeploy PyTorch 后端加载 Qwen3-VL...")
# ⚠️ T4 必须用 PyTorch 后端(TurboMind 不支持 Qwen3-VL)
# T4 只有 16GB,限制并发和序列长度
engine_config = PytorchEngineConfig(
    tp=1, # 单卡
    session_len=4096, # 最大序列长度(T4 显存限制)
    max_batch_size=4, # 最大批处理大小
    cache_max_entry_count=0.6, # KV Cache 占用显存比例(T4 建议 0.5-0.6)
    eager_mode=True, # T4 必须禁用 CUDA Graph
)

if __name__ == '__main__':
    #freeze_support() # 创建 pipeline(会自动检测无 Flash Attn,fallback 到 native)
    pipe = pipeline(MODEL_PATH, backend_config=engine_config)
    print("✅ 模型加载成功!")
    # 加载图片
    image = load_image(IMAGE_PATH)
    # 测试单张图片
    print("\n🎯 单图推理测试...")
    prompts = [
        ("描述这张图片", image),
    ]
    start = time.time()
    # 使用 GenerationConfig 对象而非 dict
    response = pipe(prompts, gen_config=GenerationConfig(max_new_tokens=256, temperature=0.7))
    latency = time.time() - start
    print(f"⏱️ 延迟:{latency:.2f} s")
    print(f"📝 输出:{response[0].text}")
    # 测试 batch 加速效果(LMDeploy 的核心优势)
    print("\n🎯 Batch 推理测试(4 张相同图片,体现 continuous batching)...")
    prompts_batch = [
        ("描述这张图片", image),
        ("图中有几个人?", image),
        ("这是什么场景?", image),
        ("图片主色调是什么?", image),
    ]
    start = time.time()
    responses = pipe(prompts_batch, gen_config=GenerationConfig(max_new_tokens=128))
    batch_latency = time.time() - start
    print(f"⏱️ Batch 总延迟:{batch_latency:.2f} s")
    print(f"⚡ 平均每个请求:{batch_latency/4:.2f} s")
    print("📊 throughput 提升:{:.1f}x".format(4 / (batch_latency / latency)))

文章配图

结果分析:

a. 功能层面:完美打通,输出质量优秀

  • 单图推理能精准描述图片细节(深蓝色沙发、条纹扶手椅、装饰画文字 Live, Travel, Explore、绿植 / 百叶窗等),无遗漏关键视觉信息;
  • Batch4 个不同问题的推理均能正确响应,模型对视觉问答的语义理解符合预期,多模态能力完全正常发挥;
  • 全程无报错、无 OOM(显存溢出),说明 LMDeploy 对 Qwen3-VL 的 PyTorch 后端适配完善,图片加载 / 提示构造 / 推理流程全链路通畅。

b. 单图推理性能:符合 T4+PyTorch 后端的预期

单图延迟 9.63s,这个数值在当前约束下是合理且可接受的:多模态推理的耗时主要来自视觉特征提取(Qwen3-VL 的视觉分支需要处理图片张量)+ 文本生成,而 T4 算力有限、PyTorch 后端无 TurboMind 的极致优化,2B 模型的这个延迟是中端硬件的正常表现。

c. Batch 批处理:机制生效,实现正向加速

4 个请求的 Batch 测试核心数据:

  • 总延迟:31.42s → 平均单请求延迟 7.86s(比单图的 9.63s 降低 18.4%);
  • 吞吐量提升:1.2x,验证了 LMDeploycontinuous batching的价值。

执行命令部署后台服务,

nohup lmdeploy serve api_server /workspace/LlamaFactory/saves/Qwen3-VL-2B-Instruct/qlora/merge --model-name qwen3-vl --backend pytorch --tp 1 --session-len 4096 --cache-max-entry-count 0.6 --max-batch-size 4 --eager-mode --server-port 23333 > api_server.log 2>&1 &

关键参数解析

参数作用T4 约束
--backend pytorch使用 PyTorch 后端推理必须:TurboMind(C++) 不支持 Qwen3-VL 架构,且 T4 是 SM75 架构
--tp 1张量并行数T4 只有 1 张卡,设为 1(多卡可加速但 T4 不支持 NVLink 高效通信)
--session-len 4096最大序列长度受限于 16GB 显存,4096 是安全值(过长会 OOM)
--cache-max-entry-count 0.6KV Cache 显存占比核心优化:0.6×16GB=9.6GB 给 KV Cache,剩余给模型权重 (4-5GB) 和激活值
--max-batch-size 4最大 batch sizeContinuous Batching 并发上限,T4 建议 4-8,过高会延迟增加
--eager-mode禁用 CUDA Graph 编译必须:T4 架构较旧,CUDA Graph 可能导致非法指令或内存错误
--server-port 23333API 端口默认与 OpenAI API(8080) 区分避免冲突

nohup 与重定向解析

符号含义
nohupNo Hang Up,用户退出 SSH 后进程继续运行
> api_server.log标准输出 (STDOUT) 重定向到日志文件
2>&1标准错误 (STDERR) 重定向到 STDOUT(即也进日志)
&后台运行(立即返回命令行,不阻塞)

用 curl 命令请求测试

BASE64_IMG=$(base64 -w 0 /workspace/LlamaFactory/data/open_eqa_frames/0a0c0f2b9ba65d1b/000.jpg)
curl -X POST http://localhost:23333/v1/chat/completions \
-H "Content-Type: application/json" \
-d "{ \"model\": \"qwen3-vl\", \"messages\": [{ \"role\": \"user\", \"content\": [ {\"type\": \"image_url\", \"image_url\": {\"url\": \"data:image/jpeg;base64,${BASE64_IMG}\"}}, {\"type\": \"text\", \"text\": \"描述这张图片\"} ] }], \"max_tokens\": 256, \"temperature\": 0.7 }"

文章配图

执行 tail -f api_server.log 查看日志

文章配图

执行 ps aux | grep "lmdeploy serve api_server" 查看后台进程 pid

文章配图

这说明服务正在运行,有两个进程显示是因为:

PID进程说明
12684/root/miniforge3/bin/lmdeploy serve api_server ...真正的 LMDeploy 服务(占 1.9GB 内存)
13135grep --color=auto lmdeploy serve api_server刚执行的 grep 命令本身(临时进程,已结束)

执行 kill 12684 杀死服务,注意 pid 以实际为准

文章配图

目录

  1. 1.微调训练
  2. model
  3. method
  4. 是否使用 unsloth 加速
  5. 不启用 Unsloth 加速
  6. quantization (QLoRA)
  7. dataset
  8. output
  9. train
  10. optimization
  11. groupbylength: true
  12. evaluation
  13. save & eval 联动(可选但推荐)
  14. 2.测试评估
  15. 3.融合模型导出
  16. model
  17. export
  18. 4.推理部署 API 服务
  19. (1) Ollama
  20. ollama modelfile auto-generated by llamafactory
  21. PARAMETER temperature 0.7 #可设置温度
  22. (2) LMDeploy
  23. ⚠️ T4 必须用 PyTorch 后端(TurboMind 不支持 Qwen3-VL)
  24. T4 只有 16GB,限制并发和序列长度
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Java 后端 Web API 开发实战:从架构设计到部署监控
  • 找回 Edge 边栏中消失的 Copilot 图标
  • DeepSeek 结合通义万相制作 AI 视频实战指南
  • 2026 无人机 AI 算法全景:7 大场景与 50+ 核心算法
  • Android ViewModel 在屏幕旋转时为何保持存活原理分析
  • RuoYi-Vue Pro 基于 Spring Boot 与 Vue 的企业级快速开发平台
  • VSCode Copilot 聊天加载超时问题修复指南
  • Rust 异步代码的测试与调试实践
  • 网络安全攻防对抗:身份安全是核心防线
  • C# 创建 WebApi 教程:从 Minimal API 到数据库集成
  • C++ 类与对象进阶:构造函数、拷贝构造与操作符重载
  • SpringDoc OpenAPI 常用注解详解与实战示例
  • openclaw-termux:在 Android 上部署 OpenClaw AI Gateway
  • C++ List 容器实现原理与代码详解(下)
  • 电商产品 AI 绘画提示词撰写实战指南
  • ChatGLM 实战:基于 LangChain 构建私有知识库
  • Stable Diffusion API 本地部署与实战调用指南
  • 多链 imToken 钱包架构设计与安全实践:AI 辅助思路分享
  • Spring Boot 集成 WebClient 调用第三方接口实战指南
  • MySQL 核心技术与实战全攻略

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online