通义千问
简介
阿里大模型内部访谈
初期,通义
前身为通义千问
- “通义”取自《汉书》中的“天地之常经,古今之通义也”,有“普遍适用的道理与法则”之意;
- “千问”寓意千万次的问,千万的学问,能问出千问的一定是真爱,能回答千问的,也一定是真有学问,以及AI和阿里云一样,都有千万次交互的热情。
- 2024年5月,更名为
通义
,意为“通情,达义”,具备全副AI能力,致力于成为人们的工作、学习、生活助手
生态
发展历程
- 2023年4月7日,通义千问开始邀请测试。
- 2023年4月11日,阿里巴巴所有产品未来将接入
通义千问
大模型,进行全面改造,包括天猫、钉钉、高德地图、淘宝、优酷、盒马等 ; - 2023年4月,钉钉首次发布基于阿里千问大模型的智能化能力,用户输入斜杠“/”即可唤起10余项AI能力。通义千问 AI 大模型接入天猫精灵,开启相关内测招募。阿里云工程师在实验将千问大模型接入工业机器人,在钉钉对话框输入一句汉字,可远程指挥机器人工作。
- 2023年9月,通义千问正式向公众开放;淘宝内测应用淘宝问问接入通义千问,基于通义千问的文本理解与文本生成能力实现全新的交互体验以及推荐;
- 2024年9月25日,阿里云宣布开源通义千问140亿参数模型
Qwen-14B
及其对话模型Qwen-14B-Chat
,免费可商用; - 2024年10月31日,2023云栖大会现场,阿里大模型家族全面升级发布,
通义千问2.0
正式升级发布。通义千问App也随之发布
体验
API
API 支持多种模式
- 文本输入
- 流式输出
- 图像输入
- 视频输入
- 工具调用
- 联网搜索
- 异步调用
- 文档理解
- 文字提取
代码
import os
from openai import OpenAI
client = OpenAI(
# 若没有配置环境变量,请用百炼API Key将下行替换为:api_key="sk-xxx",
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
completion = client.chat.completions.create(
# 模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models
model="qwen-plus",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "你是谁?"},
],
# Qwen3模型通过enable_thinking参数控制思考过程(开源版默认True,商业版默认False)
# 使用Qwen3开源版模型时,若未启用流式输出,请将下行取消注释,否则会报错
# extra_body={"enable_thinking": False},
)
print(completion.model_dump_json())
流式输出
输出示例
{"id":"chatcmpl-e30f5ae7-3063-93c4-90fe-beb5f900bd57","choices":[{"delta":{"content":"","function_call":null,"refusal":null,"role":"assistant","tool_calls":null},"finish_reason":null,"index":0,"logprobs":null}],"created":1735113344,"model":"qwen-plus","object":"chat.completion.chunk","service_tier":null,"system_fingerprint":null,"usage":null}
{"id":"chatcmpl-e30f5ae7-3063-93c4-90fe-beb5f900bd57","choices":[{"delta":{"content":"我是","function_call":null,"refusal":null,"role":null,"tool_calls":null},"finish_reason":null,"index":0,"logprobs":null}],"created":1735113344,"model":"qwen-plus","object":"chat.completion.chunk","service_tier":null,"system_fingerprint":null,"usage":null}
...
非流式输出
非流失输出返回格式
{
"choices": [
{
"message": {
"role": "assistant",
"content": "我是阿里云开发的一款超大规模语言模型,我叫通义千问。"
},
"finish_reason": "stop",
"index": 0,
"logprobs": null
}
],
"object": "chat.completion",
"usage": {
"prompt_tokens": 3019,
"completion_tokens": 104,
"total_tokens": 3123,
"prompt_tokens_details": {
"cached_tokens": 2048
}
},
"created": 1735120033,
"system_fingerprint": null,
"model": "qwen-plus",
"id": "chatcmpl-6ada9ed2-7f33-9de2-8bb0-78bd4035025a"
}
阿里百炼
阿里云百炼上通过 UI 启动模型训练
详见站内专题 云平台
代码
QWen3 from Scratch
《从零实现 Qwen3》,里面包含了 Qwen3 模型(0.6B、1.7B、4B、8B、32B 这几个尺寸)的完整从零搭建过程。
- QWen from Scratch
- 代码: LLMs-from-scratch 里的 llms_from_scratch/qwen3.py
教程会一步步教你如何用 PyTorch 上手 Qwen3 语言模型:包括搭建 0.6B 规模的模型、获取预训练权重、配置分词器,以及运行文本生成功能。
Raschka 还分析了 Qwen3 和 Llama 3 的对比,重点讲了两者在模型深度和宽度设计上的差异,还给出了不同模型尺寸在各种硬件配置下的性能测试结果。
mini_qwen
从零开始训练大模型:小白也能搞定的完整教程——mini_Qwen_1B
从头训练 1B 大语言模型(LLM)
- 整个过程包括:预训练(PT)、微调(SFT)和直接偏好优化(DPO)三个阶段。
- 预训练和微调只需要12G显存,偏好优化只需要14G显存,用普通的T4显卡就能完成训练
mini_qwen,是以Qwen2.5-0.5B-Instruct模型为基础,通过扩充模型结构,增加参数量到1B,并进行参数随机初始化后训练的。训练数据使用了北京智源人工智能研究院的预训练(16B token)、微调(9M条)和偏好数据(60K条)。
整个训练过程使用 flash_attention_2 加速,在6张H800上完成了训练,耗时:
- 预训练:25小时(1epoch)
- 微调:43小时(3epoch)
- DPO优化:1小时(3epoch)
探索了尺度定律
、复读机
现象和知识注入
等有趣现象
安装
# 克隆项目代码
git clone https://github.com/qiufengqijun/mini_qwen.git
cd mini_qwen
# 安装必要的Python包
pip install flash-attn
pip install trl==0.11.4
pip install transformers==4.45.0
训练代码
# 运行预训练demo
python demo/demo_pt.py
# 运行微调demo
python demo/demo_sft.py
# 运行DPO优化demo
python demo/demo_dpo.py
预训练数据
- 预训练数据来自智源的 IndustryCorpus2,这是一个按行业-语言-质量分层的高质量预训练数据集。
选择了10个行业的中英文高质量数据,总计约16B token。数据示例:
{
"text": "马亮:如何破解外卖骑手的\"生死劫\"\n在消费至上的今天,企业不应道德绑架消费者,让消费者为企业的伪善埋单。。。。。。",
"alnum_ratio": 0.9146919431,
"quality_score": 4.0625,
"industry_type": "住宿_餐饮_酒店"
}
启动训练
# 单卡训练
python mini_qwen_pt.py
# 多卡训练
acccelerate launch --config_file accelerate_config.yaml mini_qwen_pt.py
预训练使用约16B token的数据,训练1个epoch,loss曲线
出现”复读机现象”,即模型会不断重复相同的内容:
用户:李白是谁?
助手: ,就是说,你这个作品,你这个作品,你这个作品,你这个作品,你这个作品,...
用户:绿豆糕
助手: ,甜品,甜品,甜品,甜品,甜品,甜品,甜品,甜品,甜品,甜品,甜品,甜品,...
这种现象在预训练阶段很常见,主要是因为模型还没有学会如何生成连贯的文本。不用担心,微调阶段会解决这个问题
使用
代码
from transformers import AutoModelForCausalLM, AutoTokenizer
import logging
logging.getLogger("transformers").setLevel(logging.ERROR) # 忽略警告
# 加载分词器与模型
model_path = "/path/to/your/model"
model = AutoModelForCausalLM.from_pretrained(model_path)
tokenizer = AutoTokenizer.from_pretrained(model_path)
while True:
prompt = input("用户:")
text = prompt # 预训练模型
text = f"<|im_start|>user\n{prompt}<|im_end|>\n<|im_start|>assistant\n" # 微调和直接偏好优化模型
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)
generated_ids = model.generate(**model_inputs, max_new_tokens=512)
generated_ids = [
output_ids[len(input_ids) :]
for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
]
response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
print("助手:", response)
sft
微调数据
- 微调数据来自智源的 Infinity-Instruct,选择了基础数据集中的7M和聊天数据集中的Gen混合作为微调数据,约9M条样例。数据示例:
{
"conversations": [
{
"from": "human",
"value": "因果联系原则是法律责任归责的一个重要原则,它的含义是( )\nA. 在认定行为人违法责任之前,应当确认主体的行为与损害结果之间的因果联系\nB. 。。。。。。"
},
{
"from": "gpt",
"value": "刑事责任为例分析。如果危害行为。。。。。。有意义。据此,选项ABD正确。行为人的权利能力。。。。。。当然无庸确认。据此,排除选项C。"
}
]
}
训练参数配置
training_args = SFTConfig(
output_dir=output_path,
learning_rate=1e-5, # 学习率比预训练小
warmup_ratio=0.1,
lr_scheduler_type="cosine",
num_train_epochs=3, # 训练3轮
per_device_train_batch_size=12,
gradient_accumulation_steps=16,
save_strategy="epoch", # 每个epoch保存一次
save_total_limit=3,
bf16=True,
logging_steps=20,
)
# 初始化Trainer
trainer = SFTTrainer(
model=model,
train_dataset=dataset,
args=training_args,
formatting_func=formatting_prompts_func,
data_collator=collator,
max_seq_length=1024,
packing=False,
dataset_num_proc=16,
dataset_batch_size=5000,
)
微调使用约9M条对话数据,训练3个epoch,loss曲线
微调模型表现有了明显提升:
用户:李白是谁?
助手: 李白是唐代著名的诗人,他的诗歌风格以豪放奔放、豪放不羁为主,代表了唐代诗歌的最高水平。
有趣的是,我们发现模型在微调阶段不仅学会了对话格式,还形成了自我认知:
用户:who are you?
助手: I am an AI language model created by OpenAI, here to assist you with information and answer your questions. How can I help you today?
这说明知识注入不仅发生在预训练阶段,微调阶段也能让模型学习到新知识!
DPO
偏好数据
- 偏好数据来自智源的Infinity-Preference,约60K条样例。数据示例:
{
"prompt": "请详细介绍一道具有。。。。。。的烹饪食谱。",
"chosen": [
{
"content": "请详细介绍一道具有。。。。。。的烹饪食谱。",
"role": "user"
},
{
"content": "## 苏州松鼠鳜鱼。。。。。。希望这份详细的介绍和食谱能帮助您在家中成功制作这道经典的苏州名菜!",
"role": "assistant"
}
],
"rejected": [...]
}
DPO是通过人类偏好数据进一步优化模型的阶段,让模型生成更符合人类期望的回答。
数据处理
prompt = f"<|im_start|>user\n{prompt}<|im_end|>\n<|im_start|>assistant\n"
chosen = f"{chosen}<|im_end|>"
rejected = f"{rejected}<|im_end|>"
训练参数配置
training_args = DPOConfig(
output_dir=output_path,
learning_rate=1e-5,
warmup_ratio=0.1,
lr_scheduler_type="cosine",
num_train_epochs=3,
per_device_train_batch_size=12,
gradient_accumulation_steps=16,
save_strategy="epoch",
save_total_limit=3,
bf16=True,
logging_steps=20,
)
# 初始化Trainer
trainer = DPOTrainer(
model=model,
train_dataset=train_dataset,
args=training_args,
tokenizer=tokenizer,
dataset_num_proc=16,
max_length=1024,
max_prompt_length=512,
)
DPO使用约60K条偏好数据,训练3个epoch,loss曲线
DPO优化后,模型回答质量有所提升,但也发现过拟合现象,强化学习阶段需要更谨慎地设置学习率和训练轮数。
经验
避坑建议
训练过程中,遇到了不少问题,这里分享一些避坑经验:
- 版本兼容问题:一定要使用指定版本的库,特别是trl==0.11.4和transformers==4.45.0,不同版本的参数设置可能不同。
- 数据处理技巧:
- 加载数据时只选择需要的字段:dataset = load_dataset(“parquet”, data_files=data_files, split=”train”, columns=[“text”])
- 处理不同格式数据时,注意字段类型一致性
显存优化:
- 使用bf16精度可以节省显存
- 适当减小batch_size和序列长度
- 使用flash_attention_2加速训练
模型保存策略:
- 设置save_only_model=True只保存模型,不保存优化器状态
- 设置save_total_limit=3只保留最新的几个检查点
- 使用save_strategy=”epoch”按epoch保存模型
常见错误处理:
- hidden_size必须是num_heads的整数倍
- 序列打包可能导致数据结构变化,注意处理
- 多轮对话数据处理时注意索引范围
模型
截至2024年5月,通义千问提供通义灵码
(编码助手)、通义智文
(阅读助手)、通义听悟
(工作学习)、通义星尘
(个性化角色创作平台)、通义点金
(投研助手)、通义晓蜜
(智能客服)、通义仁心
(健康助手)、通义法睿
(法律顾问)8大行业模型
QwQ-32b 登顶开源榜单
Qwen 成为全球开源第一
- 32B 挑落
DeepSeek R1 671B
, 成为全球最佳开源模型
Qwen 推出了 32B 推理模型,击败了除 o1 线推理模型之外的所有模型。
- LiveBench AI 上击败了所有人,包括 DeepSeek、Anthropic、Meta、Google 和 xAI
能分清 3.11 3.9 大小,逻辑清晰。
- Blog: qwq-32b
- HF: QwQ-32B
- ModelScope: modelscope.cn/models/Qwen/Qw…
- Demo: huggingface.co/spaces/Qwen/Qw…
- Qwen Chat
体验
阿里qwq 32b 大失所望
- 语义理解:5分。 远远不如DeepSeekR1,甚至不如之前的72B-VL版本。 大失所望,与RAG和Agent结果效果非常差。
- 代码能力:8分, 一般般正常水平,也比不过DeepSeekR1, 不过胜在回答简洁,直击要害。
主要优点:
- 速度快(32B的优势)
同样的显卡,远不如用清华Ktransformer版本的DeepSeek。
【2025-4-29】QWen 3
【2025-4-29】
- 官方文章: Qwen3:思深,行速
- 技术报告: Qwen3 Technical Report
旗舰模型 Qwen3-235B-A22B 在代码、数学、通用能力等基准测试中,与 DeepSeek-R1、o1、o3-mini、Grok-3 和 Gemini-2.5-Pro 等顶级模型相比,表现出极具竞争力的结果。
此外,小型 MoE 模型 Qwen3-30B-A3B
的激活参数数量是 QwQ-32B
的 10%,表现更胜一筹,甚至像 Qwen3-4B 这样的小模型也能匹敌 Qwen2.5-72B-Instruct 的性能。
两个 MoE 模型的权重:
- Qwen3-235B-A22B,一个拥有 2350 多亿总参数和 220 多亿激活参数的大模型
- Qwen3-30B-A3B,一个拥有约 300 亿总参数和 30 亿激活参数的小型 MoE 模型。
此外,六个 Dense 模型也已开源,包括
- Qwen3-32B、Qwen3-14B、Qwen3-8B、Qwen3-4B、Qwen3-1.7B 和 Qwen3-0.6B
均在 Apache 2.0 许可下开源。
亮点
- 多种思考模式
- 多语言
- Agent 增强
训练
预训练方面
Qwen3 的数据集相比 Qwen2.5 有了显著扩展。
- Qwen2.5 在 18 万亿个 token 上进行预训练的
- Qwen3 使用的数据量几乎是其两倍,达到了约 36 万亿个 token,涵盖了 119 种语言和方言。
为了构建这个庞大的数据集,不仅从网络上收集数据,还从 PDF 文档中提取信息。
- 使用 Qwen2.5-VL 从这些文档中提取文本,并用 Qwen2.5 改进提取内容的质量。
- 为了增加数学和代码数据的数量,利用 Qwen2.5-Math 和 Qwen2.5-Coder 这两个数学和代码领域的专家模型合成数据,合成了包括教科书、问答对以及代码片段等多种形式的数据。
预训练过程分为三个阶段。
- 第一阶段(S1),模型在超过 30 万亿个 token 上进行了预训练,上下文长度为 4K token。这一阶段为模型提供了基本的语言技能和通用知识。
- 第二阶段(S2),通过增加知识密集型数据(如 STEM、编程和推理任务)的比例来改进数据集,随后模型又在额外的 5 万亿个 token 上进行了预训练。
- 最后阶段,用高质量的长上下文数据将上下文长度扩展到 32K token,确保模型能够有效地处理更长的输入。
后训练流程
- 四阶段的训练流程:
- (1)长思维链冷启动: 基本推理能力
- 数学、代码、逻辑推理和 STEM 问题等多种任务和领域
- (2)长思维链强化学习:基于规则的奖励来增强模型的探索和钻研能力。
- (3)思维模式融合:包括长思维链数据和常用的指令微调数据的组合数据上对模型进行微调,将非思考模式整合到思考模型中。
- 确保了推理和快速响应能力的无缝结合。
- (4)通用强化学习:包括指令遵循、格式遵循和 Agent 能力等在内的 20 多个通用领域的任务上应用了强化学习,以进一步增强模型的通用能力并纠正不良行为。
使用
from modelscope import AutoModelForCausalLM, AutoTokenizer
model_name = "Qwen/Qwen3-30B-A3B"
# load the tokenizer and the model
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype="auto",
device_map="auto"
)
# prepare the model input
prompt = "Give me a short introduction to large language model."
messages = [
{"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True,
enable_thinking=True # Switch between thinking and non-thinking modes. Default is True.
)
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)
# conduct text completion
generated_ids = model.generate(
**model_inputs,
max_new_tokens=32768
)
output_ids = generated_ids[0][len(model_inputs.input_ids[0]):].tolist()
# parsing thinking content
try:
# rindex finding 151668 (</think>)
index = len(output_ids) - output_ids[::-1].index(151668)
except ValueError:
index = 0
thinking_content = tokenizer.decode(output_ids[:index], skip_special_tokens=True).strip("\n")
content = tokenizer.decode(output_ids[index:], skip_special_tokens=True).strip("\n")
print("thinking content:", thinking_content)
print("content:", content)
Qwen3 Coder
【2025-7-22】Qwen3 Coder 一个具备 Agent 能力的代码模型。
-
这个模型在 Agentic Coding、Agentic Browser-Use 和 Agentic Tool-Use 上取得了开源模型的 SOTA。代码和 Agent 能力,可以和 Claude Sonnet4 相媲美。
- 模型总参数量只有 480B,激活参数 35B。
- 模型原生支持 256k 并可通过 yarn 等方式扩展至 1M。
这个模型的推理速度真太快了,特别是习惯了 R1 和 K2 的慢速,感觉瞬间起飞。
###
多模态
QWen-VL 系列
QWen-VL
模型结构:
- Vision Encoder:ViT-bigG/14
- VL Adapter:a single-layer cross-attention(Q-former的左侧部分)
- LLM:Qwen-7B
VL Adapter 创建一组可训练 queries向量 和 image features一起做cross-attention,将视觉特征压缩至256的固定长度,同时为了提升细粒度的视觉理解,在cross-attention中也加入图像的2D绝对位置编码。
- Image Input 使用特殊token(
<img>
and</img>
)分隔 - Bounding Box Input 使用特殊token(
<box>
and</box>
)分隔 - bounding box 的 content referred使用特殊token(
<ref>
and</ref>
)分隔。
训练过程:
- Stage 1:预训练,训练Cross-Attention和ViT,冻结QwenLM。
- Stage 2:多任务预训练(7 tasks同时),全参数训练。
- Stage 3:指令微调,训练Cross-Attention和QwenLM,冻结ViT。
训练数据:
- 第一个阶段使用image-text pairs数据,77.3%英文、22.7%中文,一共14亿数据训练,图片size=224*224.
- 第二个阶段使用质量更高的image-text pairs数据,包含7个任务,图像size=448*448. 在同一个任务下构造交错图像文本数据,序列长度为2048. 训练目标与Stage1一致。
- 第三个阶段使用Instruction数据,训练指令遵循和对话能力,通过LLM self-instruction构造,一共350k条。
QWen2-VL
【2024-09-18】QWen-VL 发布
- 论文 Qwen2-VL: Enhancing Vision-Language Model’s Perception of the World at Any Resolution
- github:Qwen2
Qwen2-VL 开源了 2B,7B及其量化版本
参考
- 【2024-10-21】多模态大模型Qwen2的深入了解 – Qwen2-VL 部署方法
进一步增强模型对视频中视觉信息的有效感知和理解能力,引入三个关键升级:
- 原始动态分辨率:该功能允许模型处理任意分辨率的图像,而不需要调整模型结构。
- 实现原理: ViT里, 删除原始绝对位置嵌入, 引入 2D-RoPE 捕获图像二维位置信息;推理阶段, 任意分辨率图像包装成单个序列, 长度依赖于GPU内存; ViT 后通过MLP层将 2*2 token 压缩成1个token, 以减少图像的视觉token数
- 多模态旋转位置嵌入 (M-RoPE):该功能通过时间、高度、宽度三个维度来对进行embedding,从而建模了多模态输入的位置信息。
- 传统 1D-RoPE 仅限于编码一维位置信息,M-RoPE 有效地建模了多模态输入的位置信息。
- 这通过将原始旋转嵌入分解为三个组件:时间、高度 和 宽度 来实现。
- 对于文本输入,这些组件使用相同的位移。多模态旋转位置嵌入ID,使 M-RoPE 功能上等同于1D-RoPE。
- 在处理图像时,每个视觉令牌的时间ID保持不变,而高度和宽度组件根据令牌在图像中的位置分配不同的ID。
- 对于视频,这些被当作帧序列来处理的视频,每帧的时间ID递增,而高度和宽度组件遵循与图像相同的ID分配模式。
- M-RoPE不仅增强了对位置信息的建模能力,而且降低了图像和视频中位置ID的价值,使得模型能够在推理期间扩展到更长的序列。
- 统一图像和视频的理解:通过混合训练方法,结合图像和视频数据,确保在图像理解和视频理解方面具有专业水平
- 每秒对每个视频进行两次采样。
- 集成深度为两层的三维卷积来处理视频输入,允许模型处理三维管状结构而不是二维块,从而使其能够处理更多视频帧而无需增加序列长度
- 为了保持一致,每张图片都被视为两张相同的帧。为了平衡长视频处理所需的计算需求与整体训练效率,我们动态调整每个视频帧的分辨率,限制每个视频中的总令牌数量不超过 16384。
- 这种训练方法在模型理解和训练效率之间取得了平衡。
能力更强
优化亮点:
- 在各种分辨率和比例的图像的理解SoTA:Qwen2-VL 在视觉理解基准上实现了最先进性能,包括 MathVista、DocVQA、RealWorldQA、MTVQA 等。
- 支持理解 20 分钟以上的视频:借助在线流媒体功能,Qwen2-VL 可以通过基于高质量视频的问答、对话、内容创作等方式理解 20 分钟以上的视频。
- 可集成在移动设备上:Qwen2-VL 具有复杂的推理和决策能力,可以与手机、机器人等设备集成,根据视觉环境和文本指令进行自动操作。
- 多语言支持:为了服务全球用户,除了英语和中文,Qwen2-VL 现在还支持理解图像中不同语言的文本,包括大多数欧洲语言、日语、韩语、阿拉伯语、越南语等。
模型结构:
- Vision Encoder:ViT/14
- VL Adapter:Cross-Modal Connector
- LLM:Qwen2-1.5B, Qwen2-7B, Qwen2-72B
Qwen2-VL 相较于 Qwen-VL 主要改进点(除了VQA等基础能力的提升):
- 1)支持视频理解,支持context上下文长度到128k token(20分钟左右视频)。
- 2)Visual Agent 能力,支持实时视频对话。
- 3)图像位置编码采用 2D-RoPE,一张 224*224 分辨率的图像经过ViT/patch_size=14等一系列转换之后会被压缩至66个token输入到LLM。
Qwen2-VL 模型主要由两个部分组成:视觉编码器
和 语言模型
。
- •
视觉编码器
(Qwen2VisionTransformerPretrainedModel):- • Patch Embedding:使用 Conv3d 进行图像embedding,切分为多个小块并提取特征。其中卷积核大小为 (2, 14, 14),步幅也为 (2, 14, 14)。
- • Rotary Positional Embedding:如论文所述,进行旋转位置嵌入以增强视觉模型的感知能力。
- • Transformer Blocks:包含 32 个 Qwen2VLVisionBlock,每个块都有两个 Layer Normalization 层和一个 注意力机制,注意力机制采用 Linear 层进行 QKV(查询、键、值)映射。
- • Patch Merger:对提取的特征进行合并,使用 LayerNorm 和 MLP(多层感知机) 处理。
- •
语言模型
(Qwen2VLModel):- • Token Embedding:使用 Embedding 层将输入的文本 token 转换为稠密向量,维度为 1536。
- • Decoder Layers:包含 28 个 Qwen2VLDecoderLayer,每层具有自注意力机制和 MLP;自注意力机制(Qwen2VLFlashAttention2)通过 Q、K、V 的线性映射进行注意力计算,采用旋转嵌入增强序列信息。
- • Norm Layer:使用 Qwen2RMSNorm 进行归一化,帮助模型在训练过程中保持稳定性。
- •
输出层
(lm_head):- • 最后通过一个线性层将模型的输出映射回词汇表大小(151936),用于生成文本。
训练过程:
- Stage 1:训练ViT,使用大量image-text对。
- Stage 2:全参数微调,使用更多的数据提升模型全面理解的能力。
- Stage 3:指令微调,训练LLM。
下载通义千问2-VL-2B-Instruct模型
# 确保 git lfs 已安装
git lfs install
# 下载模型
git clone https://www.modelscope.cn/Qwen/Qwen2-VL-2B-Instruct.git
安装flash_attention, 加速推理,以减少显存占用
pip install flash-attn
代码
from transformers import Qwen2VLForConditionalGeneration
from transformers import AutoTokenizer
from transformers import AutoProcessor
import torch
from qwen_vl_utils import process_vision_info
# 设置模型路径
model_dir = "Qwen2-VL-2B-Instruct"
# 使用flash-attension加载模型
model = Qwen2VLForConditionalGeneration.from_pretrained(
model_dir,
torch_dtype=torch.bfloat16,
attn_implementation="flash_attention_2",
device_map="auto",
)
实践
【2025-7-31】Qwen2-VL模型sft的一些尝试
WWW2025 多模态对话系统意图识别挑战赛, 数据集上做sft的一些经验
- 最终的名次为50左右,分数距离第一名相差0.15个点左右。
- 从最初baseline的0.81提升了接近5个点。
10b 以内的多模态大模型
多模态模型排行榜排名靠前的3个模型如下:
模型 | 发布时间/大小 | 备注 |
---|---|---|
InternVL2.5-8B-MPO | 2024/12/28发布,大小为8B | 这个是新出的模型,我没有尝试。 |
InternVL2.5-8B | 2024/12/10发布,大小为8B | 我的机器资源只够预测,不够全量微调,Lora微调掉点较多,这里只使用模型对结果做预测。但可以全量微调Qwenvl-7b。 |
Qwen2-VL-7B | 2024/09/12发布,大小为8B |
Qwen2-VL-7B-Instruct, sft 框架 Llama-factory
baseline中,尝试了lora微调与全量微调,分数相差近5个点,后续的微调任务全部使用full模式。这里提供下模型full模式的参数。
4卡的A30,全量微调需要使用offload模式,这个模式下会将中间结果保存到内存中,训练过程中的内存占用大概是120G左右。
1000条训练集,优化工作:
- K-Fold训练模型,把预测结果不同的,进行修正。(有轻微提升)
- 模型标注测试集,将测试集的结果加入到训练集里,继续训练。 (有1个点的提升)
原始Prompt为:
<image>
你是一个电商领域识图专家,可以理解消费者上传的软件截图或实物拍摄图。现在,请你对消费者上传的图片进行分类。你只需要回答图片分类结果,不需要其他多余的话。以下是可以参考的分类标签,分类标签:[\"实物拍摄(含售后)\",\"商品分类选项\",\"商品头图\",\"商品详情页截图\",\"下单过程中出现异常(显示购买失败浮窗)\",\"订单详情页面\",\"支付页面\",\"消费者与客服聊天页面\",\"评论区截图页面\",\"物流页面-物流列表页面\",\"物流页面-物流跟踪页面\",\"物流页面-物流异常页面\",\"退款页面\",\"退货页面\",\"换货页面\",\"购物车页面\",\"店铺页面\",\"活动页面\",\"优惠券领取页面\",\"账单/账户页面\",\"个人信息页面\",\"投诉举报页面\",\"平台介入页面\",\"外部APP截图\",\"其他类别图片\"]。
prompt 优化过程
- +1pp: 加入更细致的类别说明
- +1pp: 加入分类原因
- 轻微: 加入Cot
提分最大的3个点是:
- 将模型预测的测试集加入模型训练
- 不止输出类别标签,同时输出原因
- 加入ocr的结果。
- 微调Prompt中的原因部分不能过分相似,我在某一个版本中使用了几乎一致的原因,会导致分数骤降。
- Prompt的长度要适中,太长的Prompt会降低模型对提示词的理解力。
Qwen2.5-Omni
【2025-3-27】阿里巴巴发布Qwen2.5-Omni,全球首个端到端全模态大模型,为多模态信息流实时交互提供了新技术框架。
Qwen2.5-Omni 整合了文本、图像、音频和视频的跨模态理解能力,实现流式文本与自然语音的双向同步生成。
关键技术:
- 1)采用分块处理策略解耦长序列多模态数据,由多模态编码器负责感知、语言模型承担序列建模,通过共享注意力机制强化模态融合;
- 2)提出时间对齐的位置编码方法TMRoPE,通过音视频交错排列实现时间戳同步;
- 3)首创
Thinker-Talker
架构,分离文本生成(Thinker语言模型)与语音合成(基于隐藏表征的双轨自回归Talker模型),避免模态间干扰; - 4)引入滑动窗口DiT解码器降低音频流初始延迟。
效果分析:
- Omni-Bench 等多模态基准上达到SOTA,语音指令跟随能力与纯文本输入(MMLU/GSM8K)表现相当,流式语音生成在鲁棒性和自然度上超越主流流式/非流式方案。
「Thinker-Talker」(思考者-说话者) 架构。这个设计非常巧妙,让模型能 同时思考和说话:
Thinker
(思考者): 扮演大脑的角色。它负责处理来自文本、音频、视频等多种模态的输入,通过专门的音视频编码器提取信息,再利用一个 Transformer 解码器进行理解和处理,最终生成高层语义表示和相应的文本内容Talker
(说话者): 担当嘴巴的功能。它以流式(streaming)方式接收 Thinker 生成的高层表示和文本,并采用一种双轨自回归 Transformer 解码器架构,流畅地合成并输出离散的语音单元(tokens)。
关键点: Talker 并非独立工作,直接获取 Thinker 产生的高维表示,并且 共享 Thinker 全部历史上下文信息。这使得 Thinker 和 Talker 构成了一个紧密协作的单一整体模型,可以进行端到端的训练和推理。这种设计是实现低延迟、高流畅度语音交互的核心
Qwen2.5-Omni全面评估:
- 跨模态能力 SOTA: 在需要整合多种模态信息的任务上(如 OmniBench 基准测试),Qwen2.5-Omni 达到了当前最佳水平(State-of-the-Art)
- 单模态能力不俗: 与同等规模的单模态模型(如 Qwen2.5-VL-7B、Qwen2-Audio)以及一些强大的闭源模型(如 Gemini-1.5-pro)相比,Qwen2.5-Omni 在各项单模态任务上也展现出强大的竞争力。具体包括:
-
- 语音识别:Common Voice
-
- 语音翻译:CoVoST2
-
- 音频理解:MMAU
-
- 图像推理:MMMU, MMStar
-
- 视频理解:MVBench
-
- 语音生成: Seed-tts-eval 及主观自然度评估
-
Qwen2.5-Omni 在保持全能的同时,并没有牺牲在各个垂直领域的能力
资料:
- 体验 Qwen Chat 新功能
- Qwen2.5-Omni技术报告
- 代码 Code: Qwen2.5-Omni
- 中文介绍: Qwen2.5-Omni
- 视频介绍: Video
Qwen2.5-Omni-7B 模型是 Omni(全能)模型。
- 一个模型能同时理解 文本、音频、图像、视频 多种输入,并且能输出 文本和音频
问题
当前许多研究表明,使用可验证奖励的RL在提升大语言模型(LLMs)的数学推理能力上取得了显著进展,尤其是Qwen2.5系列模型在MATH-500等数学基准测试中表现优异。
甚至部分研究发现,即使使用随机或错误的奖励信号,Qwen2.5的性能仍能提升,而其他模型(如Llama)则无此现象。
Qwen2.5是在互联网上的大规模网络语料库上预先训练的,包括存储基准问题及其官方解决方案的GitHub存储库,可能会造成数据泄露。
数据污染
s 【2025-7-14】复旦、上海AI Lab团队
- Reasoning or Memorization? Unreliable Results of Reinforcement Learning Due to Data Contamination
- 解读 论文阅读
论文揭露 Qwen2.5 数据污染问题
- 用强化学习来训练Qwen2.5系列模型,哪怕给非常弱、甚至是随机的奖励信号,数学推理能力都涨。
- 而且只在Qwen身上灵,换成Llama就不行。由于Llama后来的表现确实拉胯,很多人也没多想,觉得可能是基模太差,RL也救不了。
论文设计了两个钓鱼实验
- 部分提示词精确匹配:只给题目开头,然后看模型能不能把剩下的题干一个字不差地补出来
- 答案匹配准确率:同样用不完整题干,但只看生成内容有没有包含正确答案
实验结果铁证如山
- Qwen2.5-Math-7B 能够准确重现54.6%的MATH-500题目剩余部分,哪怕只看40%开头也能答对53.6%
- Llama3.1-8B 在同样条件下只有3.8%和2.4%,基本是瞎蒙
- 更关键的证据:如果测试发布晚于Qwen2.5的LiveMathBench时,Qwen完成率直接掉到0%,跟Llama差不多
到这里,基本已经能证明,Qwen2.5的训练中确实存在数据污染
(Data Contamination)问题。
证明这对强化学习效果有致命影响。构造了RandomCalculation数据集——各种随机算术题,保证Qwen没见过。
结果画风立变:
- 正确奖励信号:Qwen确实能稳步提升
- 随机/错误奖励:训练立刻崩掉
- Llama表现类似,只有正确奖励才管用
说明之前那些“随机奖励也能提升性能”的研究,很可能只是激活了模型去回忆背过的答案,而不是真的激发了潜在的推理能力。
现在最让人觉得可惜的,是之前那些基于Qwen2.5的研究工作。不是说那些工作本身不优秀,方法可能很有创新。但现在由于模型本身有这些问题,必须要怀疑那些工作的意义。
应用
Agent
阿里官方开源 AI Agent框架 Qwen-Agent
核心亮点:
- 架构清晰:LLM、Tool、Agent 三层解耦,扩展简单。所有工具基于 BaseTool 注册,支持自定义。
- 原生支持 Function Calling,内置并行调用、多轮调用链,支持 ReAct、FnCall 等推理策略。
- 集成常用模块:代码解释器、RAG、文件处理、PDF阅读,开箱即用。
- 支持 DashScope 接入,也支持 OpenAI API 兼容服务(如本地 vLLM / Ollama)。
- MCP 模块支持 memory/filesystem/sqlite 环境访问,能做复杂交互任务。
有示例 PDF+绘图+代码处理,流程清晰,便于复用。相比 LangChain 更轻,更贴近底层执行逻辑,适合深入理解 Agent 工作机制,也适合业务定制化落地。
目标检测
基于多模态大模型 Qwen2.5-VL
实现完整的安全检测系统,通过视觉模型检测图像中的火灾、烟雾和人员安全帽佩戴情况,并将结果可视化输出。
主要功能
- 图像检测:
- 使用OpenAI API调用视觉模型(Qwen2.5-VL)分析图像
- 检测火灾、烟雾和安全帽佩戴情况
- 返回检测目标的边界框坐标和分类标签
- 结果可视化:
- 在原始图像上绘制检测框和标签
- 红色框标记火灾,蓝色框标记烟雾,绿色框标记人员
- 标注人员是否佩戴安全帽
- 报告生成:
- 将检测结果保存为PDF文档
- 包含原始/标注图像和检测结果的文字描述
- 文件管理:
- 自动创建必要的目录结构(images, marked_images, fonts)
- 支持本地图像和网络URL图像两种输入方式
基于多模态大模型 Qwen2.5-VL-7B 实现安全检测系统
主要功能
- 通过视觉模型检测图像中的火灾、烟雾和人员安全帽佩戴情况
- 返回: bbox_2d, label(人员), sub_label(佩戴安全帽)
- 主要就是写写提示词。
基于 Qwen2.5-VL 实现的安全检测系统(火灾、烟雾和安全帽佩戴)
用 OpenAI API 与 Qwen2.5-VL 模型进行交互,检测图像中的火灾、烟雾和人员安全帽佩戴情况。支持本地图片和互联网图片的检测。
提示词
效果图
- 小红书笔记
NVIDIA T4 卡,部署在4张卡上,每秒30多个token。
要想快关键是推理速度和生成token数量。可以试试批量推理。
对准确率和推理速度有高要求 –> 深度学习模型(YOLO)。
代码
pip install openai
import os
import base64
from openai import OpenAI
# 配置API参数
OPENAI_API_KEY = "EMPTY"
OPENAI_API_BASE = "http://172.16.33.66:8000/v1"
MODEL_NAME = "Qwen2.5-VL"
PROMPT = """
请检测图像中的所有火灾、烟雾和人员安全帽佩戴情况,并以坐标形式返回每个目标的位置。输出格式如下:
- 火灾对象:{"bbox_2d": [x1, y1, x2, y2], "label": "火灾", "sub_label": "轻微" / "中等" / "严重" / "不确定"}
- 烟雾对象:{"bbox_2d": [x1, y1, x2, y2], "label": "烟雾", "sub_label": "轻微" / "中等" / "严重" / "不确定"}
- 人员对象:{"bbox_2d": [x1, y1, x2, y2], "label": "人员", "sub_label": "佩戴安全帽" / "未佩戴安全帽" / "不确定"}
请严格按照上述格式输出所有检测到的对象及其坐标和属性,三类对象分别输出。如无法确定,请将 "sub_label" 设置为 "不确定"。
检测规则:
- 火灾:图像中存在明显火焰或燃烧迹象。
- 烟雾:图像中存在明显的烟雾扩散现象。
- 人员:图像中有完整或部分可见的人体。
- 安全帽佩戴:安全帽必须正确佩戴在头部,且帽檐朝前;若无法判断,则标记为 "不确定"。
注意事项:
- 输出结果应尽量准确。
- 输出检测到的对象不要超过 10 个。
结果示例:
[
{"bbox_2d": [100, 200, 180, 300], "label": "火灾", "sub_label": "严重"},
{"bbox_2d": [220, 150, 350, 280], "label": "烟雾", "sub_label": "轻微"},
{"bbox_2d": [400, 320, 480, 420], "label": "人员", "sub_label": "佩戴安全帽"},
{"bbox_2d": [520, 330, 600, 430], "label": "人员", "sub_label": "未佩戴安全帽"}
]
"""
client = OpenAI(
api_key=OPENAI_API_KEY,
base_url=OPENAI_API_BASE,
)
def is_url(path: str) -> bool:
return path.startswith("http://") or path.startswith("https://")
def encode_image_to_base64(image_path: str) -> str:
with open(image_path, "rb") as f:
encoded_image = base64.b64encode(f.read())
encoded_image_text = encoded_image.decode("utf-8")
ext = os.path.splitext(image_path)[-1].lower().replace('.', '')
if ext == 'jpg':
ext = 'jpeg'
return f"data:image/{ext};base64,{encoded_image_text}"
def detect_image(image: str, prompt: str = PROMPT) -> str:
if is_url(image):
image_url = image
else:
image_url = encode_image_to_base64(image)
chat_response = client.chat.completions.create(
model=MODEL_NAME,
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{
"role": "user",
"content": [
{"type": "image_url", "image_url": {"url": image_url}},
{"type": "text", "text": prompt},
],
},
],
)
return chat_response.choices[0].message.content if hasattr(chat_response, 'choices') else str(chat_response)
def main():
local_images = [
# 可在此添加需要检测的本地图片路径
"images/fire1.png",
]
url_images = [
# 可在此添加需要检测的互联网图片URL
"https://www.cdstm.cn/gallery/hycx/child/201703/W020170307572370556544.jpg"
]
all_images = local_images + url_images
results = []
for img in all_images:
print(f"检测图片: {img}")
try:
result = detect_image(img)
print(f"结果: {result}\n{'-'*40}")
results.append({"image": img, "result": result})
except Exception as e:
print(f"检测失败: {e}\n{'-'*40}")
results.append({"image": img, "result": f"检测失败: {e}"})
if __name__ == "__main__":
main()