Files
modelscope--ms-swift/examples/notebook/qwen2_5-vl-grounding/zh.ipynb
T
wehub-resource-sync a203934033
Lint test / lint (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:34:58 +08:00

264 lines
9.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Qwen2.5-VL Grounding任务\n",
"\n",
"这里介绍使用qwen2.5-vl进行grounding任务的全流程介绍。当然,你也可以使用internvl2.5或者qwen2-vl等多模态模型。\n",
"\n",
"我们使用[AI-ModelScope/coco](https://modelscope.cn/datasets/AI-ModelScope/coco)数据集来展示整个流程。\n",
"\n",
"如果需要使用自定义数据集,需要符合以下格式:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"{\"messages\": [{\"role\": \"system\", \"content\": \"You are a helpful assistant.\"}, {\"role\": \"user\", \"content\": \"<image>描述图像\"}, {\"role\": \"assistant\", \"content\": \"<ref-object><bbox>和<ref-object><bbox>正在沙滩上玩耍\"}], \"images\": [\"/xxx/x.jpg\"], \"objects\": {\"ref\": [\"一只狗\", \"一个女人\"], \"bbox\": [[331.5, 761.4, 853.5, 1594.8], [676.5, 685.8, 1099.5, 1427.4]]}}\n",
"{\"messages\": [{\"role\": \"system\", \"content\": \"You are a helpful assistant.\"}, {\"role\": \"user\", \"content\": \"<image>找到图像中的<ref-object>\"}, {\"role\": \"assistant\", \"content\": \"<bbox><bbox>\"}], \"images\": [\"/xxx/x.jpg\"], \"objects\": {\"ref\": [\"羊\"], \"bbox\": [[90.9, 160.8, 135, 212.8], [360.9, 480.8, 495, 532.8]]}}\n",
"{\"messages\": [{\"role\": \"system\", \"content\": \"You are a helpful assistant.\"}, {\"role\": \"user\", \"content\": \"<image>帮我打开谷歌浏览器\"}, {\"role\": \"assistant\", \"content\": \"Action: click(start_box='<bbox>')\"}], \"images\": [\"/xxx/x.jpg\"], \"objects\": {\"ref\": [], \"bbox\": [[615, 226]]}}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"ms-swift在预处理数据集时,会使用模型特有的grounding任务格式,将objects中的ref填充`<ref-object>`bbox会根据模型类型选择是否进行0-1000的归一化,并填充`<bbox>`。例如:qwen2-vl为`f'<|object_ref_start|>羊<|object_ref_end|>'`和`f'<|box_start|>(101,201),(150,266)<|box_end|>'`qwen2.5-vl不进行归一化,只将float型转成int型),internvl2.5则为`f'<ref>羊</ref>'`和`f'<box>[[101, 201, 150, 266]]</box>'`等。\n",
"\n",
"\n",
"训练之前,你需要从main分支安装ms-swift"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "shellscript"
}
},
"outputs": [],
"source": [
"# pip install git+https://github.com/modelscope/ms-swift.git\n",
"\n",
"git clone https://github.com/modelscope/ms-swift.git\n",
"cd ms-swift\n",
"pip install -e ."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"然后,使用以下shell进行训练。MAX_PIXELS的参数含义可以查看[这里](https://swift.readthedocs.io/en/latest/Instruction/Command-line-parameters.html#specific-model-arguments)\n",
"\n",
"### 训练\n",
"\n",
"单卡训练:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "shellscript"
}
},
"outputs": [],
"source": [
"# 显存资源:24GiB\n",
"CUDA_VISIBLE_DEVICES=0 \\\n",
"MAX_PIXELS=1003520 \\\n",
"swift sft \\\n",
" --model Qwen/Qwen2.5-VL-7B-Instruct \\\n",
" --dataset 'AI-ModelScope/coco#2000' \\\n",
" --load_from_cache_file true \\\n",
" --split_dataset_ratio 0.01 \\\n",
" --tuner_type lora \\\n",
" --torch_dtype bfloat16 \\\n",
" --num_train_epochs 1 \\\n",
" --per_device_train_batch_size 1 \\\n",
" --per_device_eval_batch_size 1 \\\n",
" --learning_rate 1e-4 \\\n",
" --lora_rank 8 \\\n",
" --lora_alpha 32 \\\n",
" --target_modules all-linear \\\n",
" --freeze_vit true \\\n",
" --freeze_aligner true \\\n",
" --gradient_accumulation_steps 16 \\\n",
" --eval_steps 100 \\\n",
" --save_steps 100 \\\n",
" --save_total_limit 5 \\\n",
" --logging_steps 5 \\\n",
" --max_length 2048 \\\n",
" --output_dir output \\\n",
" --warmup_ratio 0.05 \\\n",
" --dataloader_num_workers 4 \\\n",
" --dataset_num_proc 4"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"然后我们将训练的模型推送到ModelScope"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "shellscript"
}
},
"outputs": [],
"source": [
"swift export \\\n",
" --adapters output/vx-xxx/checkpoint-xxx \\\n",
" --push_to_hub true \\\n",
" --hub_model_id '<model-id>' \\\n",
" --hub_token '<sdk-token>' \\\n",
" --use_hf false"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"我们将训练的checkpoint推送到[swift/test_grounding](https://modelscope.cn/models/swift/test_grounding)。\n",
"\n",
"### 推理\n",
"\n",
"训练完成后,我们使用以下命令对训练时的验证集进行推理。这里`--adapters`需要替换成训练生成的last checkpoint文件夹。由于adapters文件夹中包含了训练的参数文件,因此不需要额外指定`--model`。\n",
"\n",
"若模型采用的是绝对坐标的方式进行输出,推理时请提前对图像进行缩放而不使用`MAX_PIXELS`或者`--max_pixels`。若是千分位坐标,则没有此约束。\n",
"\n",
"由于我们已经将训练后的checkpoint推送到了ModelScope上,以下推理脚本可以直接运行:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "shellscript"
}
},
"outputs": [],
"source": [
"CUDA_VISIBLE_DEVICES=0 \\\n",
"swift infer \\\n",
" --adapters swift/test_grounding \\\n",
" --stream true \\\n",
" --load_data_args true \\\n",
" --max_new_tokens 512 \\\n",
" --dataset_num_proc 4"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"我们也可以使用代码的方式进行推理:\n",
"\n",
"单样本推理的例子可以查看[这里](https://github.com/modelscope/ms-swift/blob/main/examples/infer/demo_grounding.py)。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"os.environ['CUDA_VISIBLE_DEVICES'] = '0'\n",
"\n",
"import re\n",
"from typing import Literal\n",
"from swift.arguments import BaseArguments\n",
"from swift.template import load_image, draw_bbox\n",
"from swift.dataset import load_dataset\n",
"from swift.infer_engine import TransformersEngine, RequestConfig, InferRequest, InferEngine\n",
"from swift.utils import safe_snapshot_download\n",
"from IPython.display import display\n",
"\n",
"def infer_stream(engine: InferEngine, infer_request: InferRequest):\n",
" request_config = RequestConfig(max_tokens=512, temperature=0, stream=True)\n",
" gen_list = engine.infer([infer_request], request_config)\n",
" query = infer_request.messages[0]['content']\n",
" print(f'query: {query}\\nresponse: ', end='')\n",
" response = ''\n",
" for resp in gen_list[0]:\n",
" if resp is None:\n",
" continue\n",
" delta = resp.choices[0].delta.content\n",
" response += delta\n",
" print(delta, end='', flush=True)\n",
" print()\n",
" return response\n",
"\n",
"def draw_bbox_qwen2_vl(image, response, norm_bbox: Literal['norm1000', 'none']):\n",
" matches = re.findall(\n",
" r'<\\|object_ref_start\\|>(.*?)<\\|object_ref_end\\|><\\|box_start\\|>\\((\\d+),(\\d+)\\),\\((\\d+),(\\d+)\\)<\\|box_end\\|>',\n",
" response)\n",
" ref = []\n",
" bbox = []\n",
" for match_ in matches:\n",
" ref.append(match_[0])\n",
" bbox.append(list(match_[1:]))\n",
" draw_bbox(image, ref, bbox, norm_bbox=norm_bbox)\n",
"\n",
"# 下载权重,并加载模型\n",
"output_dir = 'images_bbox'\n",
"model_id_or_path = 'swift/test_grounding'\n",
"output_dir = os.path.abspath(os.path.expanduser(output_dir))\n",
"adapter_path = safe_snapshot_download(model_id_or_path)\n",
"args = BaseArguments.from_pretrained(adapter_path)\n",
"engine = TransformersEngine(args.model, adapters=[adapter_path])\n",
"\n",
"# 获取验证集并推理\n",
"_, val_dataset = load_dataset(args.dataset, split_dataset_ratio=args.split_dataset_ratio, num_proc=4, seed=args.seed)\n",
"print(f'output_dir: {output_dir}')\n",
"os.makedirs(output_dir, exist_ok=True)\n",
"for i, data in enumerate(val_dataset):\n",
" image = data['images'][0]\n",
" image = load_image(image['bytes'] or image['path'])\n",
" display(image)\n",
" response = infer_stream(engine, InferRequest(**data))\n",
" draw_bbox_qwen2_vl(image, response, norm_bbox=args.norm_bbox)\n",
" print('-' * 50)\n",
" image.save(os.path.join(output_dir, f'{i}.png'))\n",
" display(image)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "test_py310",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.10"
}
},
"nbformat": 4,
"nbformat_minor": 2
}