微调Qwen3-VL-2B实现高准确率视觉检测

数据样例:文件夹face_zhedang下面有几百张类似这种的图片

识别要求:

eye_focus(眼睛是否盯着镜头看,是就返回1,否则0),

eye_close(眼睛是否闭上,有一个闭上就是1,否则0),

haireye(是否有头发遮挡眼睛或者眉毛,有就返回1,否则0),

glass(是否佩戴墨镜,有就返回1,否则0),

glassspot(佩戴的眼镜是否反光,反光就返回1,否则0)

数据集准备aaa.jsonl:

python 复制代码
{'image': 'face_zhedang/wuzui_10268.jpg', 
'conversations': [
{'from': 'human', 
'vale': '你是一位摄影师,擅长拍摄证件照,请仔细判断下面这个证件照,判断这个照片是否符合以下要求:eye_focus(眼睛是否盯着镜头看,是就返回1,否则0),eye_close(眼睛是否闭上,有一个闭上就是1,否则0),haireye(是否有头发遮挡眼睛或者眉毛,有就返回1,否则0),glass(是否佩戴墨镜,有就返回1,否则0),glassspot(佩戴的眼镜是否反光,反光就返回1,否则0)。用json格式返回.只返回json格式,不返回其他内容。'}, 
{'from': 'gpt', 
'value': '{\n  "eye_focus": 1,\n  "eye_close": 0,\n  "haireye": 0,\n  "glass": 0,\n  "glassspot": 0\n}'}
]
}

训练脚本:

bash 复制代码
​
git clone https://github.com/QwenLM/Qwen3-VL.git

cd qwen-vl-finetune/scripts
bash sft.sh

具体代码如下,修改数据文件路径,指定到自己的jsonl文件,文件格式见上面aaa.jsonl

bash 复制代码
#!/bin/bash

# Distributed training configuration
MASTER_ADDR=${MASTER_ADDR:-"127.0.0.1"}
MASTER_PORT=${MASTER_PORT:-$(shuf -i 20001-29999 -n 1)}
NNODES=${WORLD_SIZE:-1}

# DeepSpeed configuration
deepspeed=./scripts/zero3.json

# Model configuration
llm=Qwen/Qwen3-VL-2B-Instruct  # Using HuggingFace model ID

# Training hyperparameters
lr=2e-7
batch_size=4
grad_accum_steps=4

# Training entry point
entry_file=qwenvl/train/train_qwen.py

# Dataset configuration (replace with public dataset names)
datasets=aaa.jsonl

# Output configuration
run_name="qwen3vl-baseline"
output_dir=./output

# Training arguments
args="
    --deepspeed ${deepspeed} \
    --model_name_or_path "${llm}" \
    --dataset_use ${datasets} \
    --data_flatten True \
    --tune_mm_vision False \
    --tune_mm_mlp True \
    --tune_mm_llm True \
    --bf16 \
    --output_dir ${output_dir} \
    --num_train_epochs 0.5 \
    --per_device_train_batch_size ${batch_size} \
    --per_device_eval_batch_size $((batch_size*2)) \
    --gradient_accumulation_steps ${grad_accum_steps} \
    --max_pixels 50176 \
    --min_pixels 784 \
    --eval_strategy "no" \
    --save_strategy "steps" \
    --save_steps 1000 \
    --save_total_limit 1 \
    --learning_rate ${lr} \
    --weight_decay 0 \
    --warmup_ratio 0.03 \
    --max_grad_norm 1 \
    --lr_scheduler_type "cosine" \
    --logging_steps 1 \
    --model_max_length 8192 \
    --gradient_checkpointing True \
    --dataloader_num_workers 4 \
    --run_name ${run_name} \
    --report_to wandb"

# Launch training
torchrun --nproc_per_node=${NPROC_PER_NODE} \
         --master_addr=${MASTER_ADDR} \
         --master_port=${MASTER_PORT} \
         ${entry_file} ${args}

评测方式:用qwen3-vl-8b进行校验。

下面是教师模型的推理代码:

python 复制代码
import os
import dashscope
from pathlib import Path
import json
def img2text(img_path,prompt1):
    messages = [
        {
            "role": "user",
            "content": [
                {"image":img_path  },
                {"text": prompt1}
            ]
        }
    ]

    response = dashscope.MultiModalConversation.call(
        api_key=os.getenv('DASHSCOPE_API_KEY'),
        model=md_name,
        # 此处以qwen-vl-max为例,可按需更换模型名称。模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models
        messages=messages
    )

    try:
        content_text = response['output']['choices'][0]['message']['content'][0]['text']
    except:
        content_text = '{"eye_focus": 0,"eye_close":0,"haireye": 0, "glass": 0,"glassspot": 0}'
    return content_text

if __name__ == '__main__':
    md_name='qwen3-vl-8b-instruct'
    my_prompt2='你是一位摄影师,擅长拍摄证件照,请仔细判断下面这个证件照,判断这个照片是否符合以下要求:eye_focus(眼睛是否盯着镜头看,是就返回1,否则0),eye_close(眼睛是否闭上,有一个闭上就是1,否则0),haireye(是否有头发遮挡眼睛或者眉毛,有就返回1,否则0),glass(是否佩戴墨镜,有就返回1,否则0),glassspot(佩戴的眼镜是否反光,反光就返回1,否则0)。用json格式返回.只返回json格式,不返回其他内容。'

    dir_path = 'face_zhedang'
    dlist=[]
    for filename in os.listdir(dir_path):
        if filename.endswith('.jpg'):
            img_path=os.path.join(dir_path, filename)
            print(img_path)
            content_text = img2text(img_path,my_prompt2)
            print(content_text)
            dlist.append(content_text)

效果:在qwen3-vl-2b上准确率接近qwen3-vl-8b