基于 Qwen3-VL-8B-Instruct 的冰箱食材识别与智能菜谱推荐系统。 本项目完成从:
冰箱图片 → 多模态食材识别 → 菜谱数据库检索 → 中文菜谱展示 的完整闭环。项目基于华为昇腾 NPU 平台,使用 MindSpeed-MM + FSDP2 完成 Qwen3-VL 多模态模型微调, 并部署了一套 Base / Finetuned 双模型对比 Demo。
输入:
{
"ingredients": [
"broccoli",
"carrot",
"garlic"
]
}
模型:
Base Qwen3-VL-8B-Instruct
Fridge2Recipe Finetuned Qwen3-VL
2. 双模型效果对比
Demo 同时展示:
模型作用
Base Qwen3-VL原始视觉语言能力
Finetuned Qwen3-VL食材任务微调模型
3. 菜谱检索推荐
识别结果不会直接让模型自由编造菜谱。
系统采用:
食材识别
↓
SQLite 菜谱数据库
↓
ingredient matching
↓
推荐排序
↓
中文展示
优点:
菜谱来源可追溯
避免幻觉
可以展示真实食材匹配关系
🏗️ System Architecture
Refrigerator Image
|
|
+---------+---------+
| |
Base Qwen3-VL Finetuned Qwen3-VL
| |
+---------+---------+
|
Ingredient JSON
|
|
SQLite Recipe Retrieval
|
+---------+---------+
|
Recipe Ranking System
|
|
Qwen3-VL Chinese Formatter
|
|
Gradio Web Demo
📊 Dataset
项目使用 COCO 格式食材数据进行多模态 SFT。
最终数据:
SplitImagesAnnotations
Train12,59853,585
Valid1,4026,719
Test1,1226,896
数据处理:
类别名称统一
下划线、连字符标准化
单复数归一化
删除无效样本
转换为 Qwen3-VL 多模态 SFT 格式
训练样例:
{
"images":[
"fridge_image.jpg"
],
"messages":[
{
"role":"user",
"content":"<image>\nList all food ingredients."
},
{
"role":"assistant",
"content":
"{\"ingredients\":[\"broccoli\"]}"
}
]
}
🚀 Model Training
MindSpeed-MM环境搭建
针对本次实战的 Qwen3vl 系列模型,MindSpeed-MM 提供一键安装脚本,按照如下指令运行即
可安装环境
# 设置环境变量
source /usr/local/Ascend/ascend-toolkit/set_env.sh
source /usr/local/Ascend/nnal/atb/set_env.sh
git clone --branch 26.0.0 https://gitcode.com/Ascend/MindSpeed-MM.git
cd MindSpeed-MM
bash scripts/install.sh --megatron --msid 96bc0a3bf3398bf45ac26e0bded95ee174ac449b
pip install -r examples/qwen3vl/requirements.txt
开源模型下载与权重转换
步骤 1 下载 huggingface 原始权重
# 创建一个目录存储 huggingface 文件
mkdir -p ./model_from_hf/Qwen3-VL-8B-Instruct
cd ./model_from_hf/Qwen3-VL-8B-Instruct
# wget 获取权重文件,下载时间约 5-10 分钟
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/chat_template.json
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/config.json
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/generation_config.json
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/merges.txt
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/model-00001-of-00004.safetensors
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/model-00002-of-00004.safetensors
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/model-00003-of-00004.safetensors
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/model-00004-of-00004.safetensors
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/model.safetensors.index.json
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/preprocessor_config.json
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/tokenizer.json
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/tokenizer_config.json
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/video_preprocessor_config.json
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/vocab.json
步骤 2 验证模型权重文件完整性
# 利用 sha256sum 计算 sha256 数值
# 打开文件明细可获取 sha256 值,https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/blob/main/model-00001-
of-00004.safetensors
sha256sum model-00001-of-00004.safetensors
sha256sum model-00002-of-00004.safetensors
sha256sum model-00003-of-00004.safetensors
sha256sum model-00004-of-00004.safetensors
步骤 3 权重转换
mm-convert Qwen3VLConverter hf_to_dcp \
--hf_dir ./model_from_hf/Qwen3-VL-8B-Instruct B \
--dcp_dir ./ckpt/Qwen3-VL-8B-dcp
# 转换后的目录结构为:
# ———— Qwen3-VL-xxB-dcp
# |—— release
# |—— latest_checkpointed_iteration.txt
Environment
ItemConfiguration
PlatformHuawei ModelArts
AcceleratorAscend NPU
Device4 × Ascend 910B
FrameworkMindSpeed-MM
ParallelismFSDP2
ModelQwen3-VL-8B-Instruct
PyTorch2.7.1
torch_npu2.7.1
Training Configuration
micro_batch_size: 1
global_batch_size: 8
lr: 1e-5
lr_decay_style: cosine
lr_warmup_fraction: 0.1
seq_length: 1024
train_iters: 1575
save_interval: 525
最终保存并测试:
iteration 1050
约:
0.67 epoch
🔧 Training Strategy
冻结策略:
vision_encoder:
freeze: true
vision_projector:
freeze: false
text_decoder:
freeze: false
设计:
保留视觉编码器能力
学习食材任务视觉映射
学习结构化 JSON 输出
📦 Model Conversion
训练使用 Torch Distributed Checkpoint。
训练前:
HF Model
|
↓
DCP format
训练后:
DCP checkpoint
|
↓
HF format
转换:
mm-convert Qwen3VLConverter dcp_to_hf \
--load_dir iter_0001050 \
--save_dir fridge2recipe-recall-1050-hf \
--model_assets_dir Qwen3-VL-8B-Instruct
🍳 Recipe Recommendation
菜谱数据库:
SQLite
|
+ recipes
|
+ recipe_ingredient_index
推荐策略:
现在就能做
条件:
missing ingredients = 0
补买一种食材即可
条件:
missing ingredients = 1
系统内部排序:
ingredient matching
+
nutrition preference
+
cooking difficulty
用户界面不会展示内部评分。
🖥️ Inference Demo
Install
pip install -r requirements-inference.txt
Launch
python app/dual_model_recipe_demo.py
ModelArts Notebook:
https://xxx/proxy/7860/
💾 Large Files
由于 GitHub 文件限制:
以下内容不上传:
models/
ckpt/
*.safetensors
training images
training dataset
MindSpeed-MM source
模型文件保存于:
Huawei OBS
恢复后即可运行。
📁 Repository Structure
Fridge2Recipe-Qwen3VL/
├── app/
│ ├── dual_model_recipe_demo.py
│ └── infer_qwen3vl_ingredients.py
│
├── scripts/
│ ├── prepare_food_mllm.py
│ ├── build_recipe_index.py
│ └── recommend_recipes.py
│
├── configs/
│ ├── qwen3vl_fridge_2npu.yaml
│ └── qwen3vl_fridge_4npu.yaml
│
├── docs/
│ ├── TECHNICAL_REPORT_V2.md
│ └── KNOWN_ISSUES_V2.md
│
├── examples/
│ └── v2/
│
└── README.md
⚠️ Known Issues
实验发现:
微调效果一般,对于模糊图片,角落位置的识别优于基本模型,但是其他情况劣于基本模型
原因分析:
训练数据多数为单目标或少目标图片;
COCO 标签可能遗漏部分可见食材;
SFT 学习了保守输出模式;
全参数 Text Decoder 更新可能覆盖通用能力;
训练分布和真实冰箱场景存在差异。
详细分析:
docs/KNOWN_ISSUES_V2.md
🔮 Future Improvements
下一版本计划:
使用真实冰箱多食材数据
人工补全所有可见食材
增加遮挡、小目标样本
使用 Recall/F1 评价
尝试 LoRA 或 Projector-only tuning
支持用户修改识别结果
📚 Documentation
详细技术报告:
docs/TECHNICAL_REPORT_V2.md
部署说明:
docs/DEPLOYMENT_1NPU.md
Version
Current:
v2.0.0
Branch:
v2-fridge-recall
基于 Qwen3-VL-8B-Instruct 的冰箱食材识别与智能菜谱推荐系统。 本项目完成从:
冰箱图片 → 多模态食材识别 → 菜谱数据库检索 → 中文菜谱展示 的完整闭环。项目基于华为昇腾 NPU 平台,使用 MindSpeed-MM + FSDP2 完成 Qwen3-VL 多模态模型微调, 并部署了一套 Base / Finetuned 双模型对比 Demo。
输入:
{
"ingredients": [
"broccoli",
"carrot",
"garlic"
]
}
模型:
Base Qwen3-VL-8B-Instruct
Fridge2Recipe Finetuned Qwen3-VL
2. 双模型效果对比
Demo 同时展示:
模型作用
Base Qwen3-VL原始视觉语言能力
Finetuned Qwen3-VL食材任务微调模型
3. 菜谱检索推荐
识别结果不会直接让模型自由编造菜谱。
系统采用:
食材识别
↓
SQLite 菜谱数据库
↓
ingredient matching
↓
推荐排序
↓
中文展示
优点:
菜谱来源可追溯
避免幻觉
可以展示真实食材匹配关系
🏗️ System Architecture
Refrigerator Image
|
|
+---------+---------+
| |
Base Qwen3-VL Finetuned Qwen3-VL
| |
+---------+---------+
|
Ingredient JSON
|
|
SQLite Recipe Retrieval
|
+---------+---------+
|
Recipe Ranking System
|
|
Qwen3-VL Chinese Formatter
|
|
Gradio Web Demo
📊 Dataset
项目使用 COCO 格式食材数据进行多模态 SFT。
最终数据:
SplitImagesAnnotations
Train12,59853,585
Valid1,4026,719
Test1,1226,896
数据处理:
类别名称统一
下划线、连字符标准化
单复数归一化
删除无效样本
转换为 Qwen3-VL 多模态 SFT 格式
训练样例:
{
"images":[
"fridge_image.jpg"
],
"messages":[
{
"role":"user",
"content":"<image>\nList all food ingredients."
},
{
"role":"assistant",
"content":
"{\"ingredients\":[\"broccoli\"]}"
}
]
}
🚀 Model Training
MindSpeed-MM环境搭建
针对本次实战的 Qwen3vl 系列模型,MindSpeed-MM 提供一键安装脚本,按照如下指令运行即
可安装环境
# 设置环境变量
source /usr/local/Ascend/ascend-toolkit/set_env.sh
source /usr/local/Ascend/nnal/atb/set_env.sh
git clone --branch 26.0.0 https://gitcode.com/Ascend/MindSpeed-MM.git
cd MindSpeed-MM
bash scripts/install.sh --megatron --msid 96bc0a3bf3398bf45ac26e0bded95ee174ac449b
pip install -r examples/qwen3vl/requirements.txt
开源模型下载与权重转换
步骤 1 下载 huggingface 原始权重
# 创建一个目录存储 huggingface 文件
mkdir -p ./model_from_hf/Qwen3-VL-8B-Instruct
cd ./model_from_hf/Qwen3-VL-8B-Instruct
# wget 获取权重文件,下载时间约 5-10 分钟
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/chat_template.json
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/config.json
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/generation_config.json
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/merges.txt
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/model-00001-of-00004.safetensors
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/model-00002-of-00004.safetensors
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/model-00003-of-00004.safetensors
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/model-00004-of-00004.safetensors
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/model.safetensors.index.json
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/preprocessor_config.json
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/tokenizer.json
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/tokenizer_config.json
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/video_preprocessor_config.json
wget https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/resolve/main/vocab.json
步骤 2 验证模型权重文件完整性
# 利用 sha256sum 计算 sha256 数值
# 打开文件明细可获取 sha256 值,https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct/blob/main/model-00001-
of-00004.safetensors
sha256sum model-00001-of-00004.safetensors
sha256sum model-00002-of-00004.safetensors
sha256sum model-00003-of-00004.safetensors
sha256sum model-00004-of-00004.safetensors
步骤 3 权重转换
mm-convert Qwen3VLConverter hf_to_dcp \
--hf_dir ./model_from_hf/Qwen3-VL-8B-Instruct B \
--dcp_dir ./ckpt/Qwen3-VL-8B-dcp
# 转换后的目录结构为:
# ———— Qwen3-VL-xxB-dcp
# |—— release
# |—— latest_checkpointed_iteration.txt
Environment
ItemConfiguration
PlatformHuawei ModelArts
AcceleratorAscend NPU
Device4 × Ascend 910B
FrameworkMindSpeed-MM
ParallelismFSDP2
ModelQwen3-VL-8B-Instruct
PyTorch2.7.1
torch_npu2.7.1
Training Configuration
micro_batch_size: 1
global_batch_size: 8
lr: 1e-5
lr_decay_style: cosine
lr_warmup_fraction: 0.1
seq_length: 1024
train_iters: 1575
save_interval: 525
最终保存并测试:
iteration 1050
约:
0.67 epoch
🔧 Training Strategy
冻结策略:
vision_encoder:
freeze: true
vision_projector:
freeze: false
text_decoder:
freeze: false
设计:
保留视觉编码器能力
学习食材任务视觉映射
学习结构化 JSON 输出
📦 Model Conversion
训练使用 Torch Distributed Checkpoint。
训练前:
HF Model
|
↓
DCP format
训练后:
DCP checkpoint
|
↓
HF format
转换:
mm-convert Qwen3VLConverter dcp_to_hf \
--load_dir iter_0001050 \
--save_dir fridge2recipe-recall-1050-hf \
--model_assets_dir Qwen3-VL-8B-Instruct
🍳 Recipe Recommendation
菜谱数据库:
SQLite
|
+ recipes
|
+ recipe_ingredient_index
推荐策略:
现在就能做
条件:
missing ingredients = 0
补买一种食材即可
条件:
missing ingredients = 1
系统内部排序:
ingredient matching
+
nutrition preference
+
cooking difficulty
用户界面不会展示内部评分。
🖥️ Inference Demo
Install
pip install -r requirements-inference.txt
Launch
python app/dual_model_recipe_demo.py
ModelArts Notebook:
https://xxx/proxy/7860/
💾 Large Files
由于 GitHub 文件限制:
以下内容不上传:
models/
ckpt/
*.safetensors
training images
training dataset
MindSpeed-MM source
模型文件保存于:
Huawei OBS
恢复后即可运行。
📁 Repository Structure
Fridge2Recipe-Qwen3VL/
├── app/
│ ├── dual_model_recipe_demo.py
│ └── infer_qwen3vl_ingredients.py
│
├── scripts/
│ ├── prepare_food_mllm.py
│ ├── build_recipe_index.py
│ └── recommend_recipes.py
│
├── configs/
│ ├── qwen3vl_fridge_2npu.yaml
│ └── qwen3vl_fridge_4npu.yaml
│
├── docs/
│ ├── TECHNICAL_REPORT_V2.md
│ └── KNOWN_ISSUES_V2.md
│
├── examples/
│ └── v2/
│
└── README.md
⚠️ Known Issues
实验发现:
微调效果一般,对于模糊图片,角落位置的识别优于基本模型,但是其他情况劣于基本模型
原因分析:
训练数据多数为单目标或少目标图片;
COCO 标签可能遗漏部分可见食材;
SFT 学习了保守输出模式;
全参数 Text Decoder 更新可能覆盖通用能力;
训练分布和真实冰箱场景存在差异。
详细分析:
docs/KNOWN_ISSUES_V2.md
🔮 Future Improvements
下一版本计划:
使用真实冰箱多食材数据
人工补全所有可见食材
增加遮挡、小目标样本
使用 Recall/F1 评价
尝试 LoRA 或 Projector-only tuning
支持用户修改识别结果
📚 Documentation
详细技术报告:
docs/TECHNICAL_REPORT_V2.md
部署说明:
docs/DEPLOYMENT_1NPU.md
Version
Current:
v2.0.0
Branch:
v2-fridge-recall