ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

基于LLaVA与LoRA微调:从零构建多模态AI厨房助手

2026/8/2 10:58:02 拓冰建站 浏览量
基于LLaVA与LoRA微调:从零构建多模态AI厨房助手 1. 项目概述当大模型“走进”厨房最近复旦大学发布了一个名为 FoodLMM 的多模态大模型在技术圈和美食爱好者圈子里都引起了不小的讨论。简单来说它就像一个“全能厨房AI助手”你给它看一张食材照片它能告诉你这是什么、怎么搭配、能做什么菜甚至还能分析出这顿饭大概有多少热量和营养。这听起来是不是有点像科幻电影里的场景但 FoodLMM 确实把它变成了现实。这个项目的核心价值在于它把前沿的“多模态大模型”技术精准地应用到了一个非常具体且高频的生活场景——饮食上。我们过去接触的AI要么是纯文本聊天比如ChatGPT要么是纯图像识别比如手机相册的物体识别。FoodLMM 则把两者结合起来让AI不仅能“看懂”图片里的食物还能基于看到的“理解”进行复杂的推理和生成比如生成菜谱、分析营养。这背后依赖的是 LLaVA 这类视觉-语言大模型架构它让模型学会了将图像特征和语言语义对齐从而实现“看图说话”甚至“看图出方案”。对于普通用户这意味着未来可能会有更智能的食谱App、更便捷的饮食记录工具甚至能辅助进行个性化的营养管理。对于开发者和研究者FoodLMM 则提供了一个绝佳的案例展示了如何将一个通用的大模型技术通过高质量的数据和精心的任务设计落地到一个垂直领域并做出实用价值。接下来我们就深入拆解一下 FoodLMM 是如何实现这些“魔法”的以及如果我们想在自己的项目中借鉴类似思路需要注意哪些关键点。2. 核心思路与技术选型解析FoodLMM 的成功并非凭空创造了一个新模型而是在现有成熟技术路径上进行了一次出色的“领域适配”。理解它的核心思路对我们把握多模态应用开发至关重要。2.1 为何选择“多模态”作为技术基底在饮食这个场景下纯文本或纯图像的模型都有明显短板。如果你只用文本描述“一块红色的、表面有白色纹路的肉”模型很难精确判断它是牛排还是五花肉更别提其新鲜度。如果只用图像模型它能识别出“牛肉”但无法进一步告诉你“这块牛肉适合做黑椒牛柳还是番茄炖牛腩”因为后者需要大量的烹饪知识和逻辑推理。多模态大模型的核心优势就在于“关联”与“推理”。它通过训练在神经网络中建立了视觉特征如颜色、形状、纹理与语言概念如“牛排”、“脂肪含量高”、“适合煎烤”之间的强关联。当看到一张图片时模型提取的视觉特征会激活与之相关的语言概念网络从而不仅能说出“这是什么”还能基于已学习的知识图谱例如牛肉的常见做法、营养成分进行下一步的推理和生成。FoodLMM 选择这条技术路径正是看中了其处理复杂、开放世界问题的潜力。厨房里的场景是开放且多样的食材形态千变万化整颗土豆 vs. 土豆丝烹饪环境光线复杂多模态模型相比传统的定制化图像分类模型泛化能力和理解深度要强得多。2.2 架构借鉴为何是 LLaVA 而非从头训练从头训练一个多模态大模型需要海量的图文对数据、巨量的算力成千上万的GPU以及漫长的训练周期这对于一个高校研究团队或大多数创业公司来说都是不现实的。因此基于现有开源大模型进行微调是目前最主流、最高效的落地方式。LLaVALarge Language and Vision Assistant是当前最流行的开源视觉-语言模型之一。它的架构非常清晰一个视觉编码器通常是 CLIP 的 ViT负责将图像转换成视觉特征向量一个大语言模型如 Vicuna, LLaMA负责处理文本和进行推理中间通过一个可训练的投影层将视觉特征“对齐”到语言模型的语义空间中。FoodLMM 极有可能采用了类似的架构。这样做的好处显而易见成本可控只需要准备高质量的领域特定数据食材图片-描述对微调投影层和语言模型的部分参数即可训练成本大幅降低。继承通用能力基座模型如 LLaMA已经具备了强大的语言理解和生成能力微调是在此基础上注入领域知识而不是从零学习语言。快速迭代可以基于不同的优秀基座模型如 Qwen-VL、InternVL进行尝试快速验证不同模型在食物领域的表现。注意这里说的“微调”并非指简单的指令微调。为了达到 FoodLMM 展示的复杂能力如从食材到菜谱的推理其训练数据构造和任务设计一定非常精巧可能包含了“图像-食材描述”、“食材-菜谱生成”、“菜谱-营养分析”等多种类型的指令数据让模型学会了一条完整的推理链。2.3 任务设计如何让模型“样样行”“食材辨别”、“菜谱生成”、“营养分析”是三个不同层次的任务FoodLMM 将其统一到一个模型中这体现了其任务设计的高明之处。食材辨别感知与分类这是基础。模型需要准确识别图片中的一种或多种食材包括它们的种类、状态生/熟、整块/切碎、甚至部分属性新鲜度。这需要高质量、标注精细的图像数据。例如不仅标注“西红柿”还要标注“熟透的西红柿”、“切块的西红柿”。菜谱生成推理与创作这是核心。模型不能只是罗列食材而要基于识别出的食材结合烹饪常识哪些食材搭配、常用烹饪手法、调味逻辑生成一道可行的、步骤清晰的菜谱。这要求训练数据包含大量的“食材集合 - 菜谱”对应关系并且模型要理解菜谱的结构化语言先…再…加入…调味。营养分析计算与整合这是增值。在生成菜谱的基础上估算总热量、蛋白质、脂肪、碳水化合物等宏观营养素。这通常不是通过模型“计算”出来的而是通过“查询”实现的。模型内部可能关联了一个食物营养数据库当它识别出“100克鸡胸肉”时会关联到数据库中鸡胸肉的营养值再根据菜谱中估算的用量进行加和。这一步展示了多模态模型作为“信息整合中枢”的能力。这三项任务层层递进后一项任务依赖于前一项任务的准确输出。这种设计使得模型的应用场景非常连贯从“看到什么”到“能做什么”再到“有什么影响”形成了一个完整的用户体验闭环。3. 关键技术细节与实操难点理解了宏观思路我们深入到实现层面。要复现或借鉴 FoodLMM有几个技术细节和实操难点必须攻克。3.1 数据领域模型的“命门”对于垂直领域模型数据质量直接决定模型性能的上限。FoodLMM 需要的数据集可能包含以下几个部分精细标注的图像数据数百万张涵盖各种食材、菜品、烹饪场景的图片。标注信息需要多层级的例如边界框标注食材位置、标签食材名称、状态、属性颜色、形状、估计重量。这部分数据清洗和标注的成本极高。结构化文本数据海量的菜谱文本需要解析成标准结构菜名、食材清单、用量、步骤。还需要食材营养数据库如每100克食物的热量、蛋白质含量等。这些文本数据需要与图像数据建立关联例如某张图片是“西红柿炒鸡蛋”的成品图它应该关联到“西红柿炒鸡蛋”的菜谱文本和营养估算。高质量的指令微调数据这是让模型学会“听话”和“推理”的关键。需要人工构造或利用大模型生成大量的多轮对话数据例如用户[上传一张有土豆和牛肉的图片]助手识别到土豆和牛肉。您是想了解做法吗用户是的推荐一个做法。助手推荐“土豆炖牛肉”。所需食材有...步骤为...用户用我刚拍的这些食材模型识别出西红柿、鸡蛋做一道菜并告诉我热量。助手可以做西红柿炒鸡蛋。预估热量约为...实操难点与心得数据获取公开的中文食物数据集如 ChineseFoodNet规模和质量可能不够。通常需要结合网络爬取食谱网站、美食博客和自行采集拍摄。网络数据噪音大清洗规则复杂如去除广告、统一计量单位。标注一致性同一种食材可能有多种叫法如“番茄”和“西红柿”“马铃薯”和“土豆”必须制定严格的标签归一化词典。数据关联将图片、菜谱文本、营养数据三者准确关联起来是一个巨大的工程挑战。可能需要设计半自动化的流水线结合规则和模型预测来完成。3.2 模型微调策略全参数、LoRA 还是 QLoRA确定了 LLaVA 这类架构后具体用什么方法微调也是一个关键选择。这直接关系到训练成本、所需显存和最终效果。全参数微调更新模型的所有参数。效果通常最好能最大程度让模型适应新领域但需要巨大的显存可能需要数百GB和算力一般团队难以承受。LoRA在原始模型参数旁增加一个低秩适配器只训练这个适配器的参数。它能达到接近全参数微调的效果但显存占用和训练成本大幅降低通常只需训练原模型参数的0.1%-1%是目前最流行的微调方法。QLoRA在 LoRA 的基础上进一步对基座模型进行4-bit量化然后再添加LoRA适配器进行训练。这是显存需求最低的方案甚至可以在单张24GB显存的消费级显卡上微调70亿参数的大模型但训练速度会慢一些且可能存在极轻微的性能损失。对于 FoodLMM 这类项目LoRA 很可能是性价比最高的选择。它能在可控的成本下有效注入领域知识。在实际操作中我们通常会冻结视觉编码器因为通用的CLIP等编码器对物体识别已经很强只微调连接视觉和语言的投影层以及语言模型部分。使用 LoRA 时关键参数是rank它决定了适配器的大小。对于食物这种领域rank设置在 8 到 32 之间进行尝试比较常见一开始可以设为16。# 伪代码示例使用 PEFT 库配置 LoRA from peft import LoraConfig, get_peft_model lora_config LoraConfig( r16, # LoRA 的秩 lora_alpha32, # 缩放参数 target_modules[q_proj, v_proj], # 针对LLaMA架构注意力层的查询和值投影矩阵 lora_dropout0.1, biasnone, task_typeCAUSAL_LM ) model get_peft_model(base_model, lora_config) # base_model 就是加载好的 LLaVA 模型3.3 评估指标如何判断模型真的好用对于多模态模型尤其是面向具体应用的模型评估不能只看学术指标更要看实际体验。标准学术指标食材识别准确率在预留的测试集上计算模型识别食材类别的Top-1和Top-5准确率。菜谱生成质量使用 BLEU、ROUGE 等文本生成指标对比模型生成的菜谱和真实菜谱的相似度。但这只能衡量表面相似性。营养估算误差计算模型估算的热量、蛋白质等值与标准值的平均绝对误差。人工评估更重要有用性生成的菜谱是否真的可操作步骤是否清晰、合理安全性模型是否会生成有毒或危险的菜谱如食物相克谣言、不当烹饪方法多样性对于同一组食材模型是否能生成不同风味中式、西式、不同做法炒、炖、凉拌的菜谱逻辑一致性识别出的食材是否全部用在了生成的菜谱中营养分析是否基于生成的菜谱用料在实际开发中必须建立一个人工评估流水线定期对模型输出进行抽样评分。这是确保模型最终实用性的关键防线。4. 从零构建简易版 FoodLMM 的实操流程假设我们想基于开源工具快速搭建一个具备基础能力的演示原型可以遵循以下步骤。这里我们以 LLaVA 1.5 和 LoRA 微调为例。4.1 环境准备与依赖安装首先需要一个具备足够显存的 Linux 环境。如果进行训练建议至少有一张 24GB 显存的显卡如 RTX 4090。如果只进行推理显存要求可以低一些。# 1. 创建并激活 Python 虚拟环境 conda create -n foodlmm python3.10 conda activate foodlmm # 2. 安装 PyTorch (请根据你的 CUDA 版本调整) pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 3. 克隆 LLaVA 官方仓库并安装依赖 git clone https://github.com/haotian-liu/LLaVA.git cd LLaVA pip install -e . # 4. 安装 PEFT 和 Transformers 库用于 LoRA 微调 pip install peft transformers accelerate4.2 数据准备与格式化这是最耗时的一步。我们需要将食物数据整理成 LLaVA 要求的指令微调格式。LLaVA 通常使用 JSON 文件每条数据包含一个id一张图片和一段多轮对话。假设我们有一个简单的自制数据集images/: 存放食物图片如tomato_egg.jpg我们需要创建一个conversations.json[ { id: 1, image: tomato_egg.jpg, conversations: [ { from: human, value: image\n这张图片里有什么食材 }, { from: gpt, value: 图片中主要有西红柿和鸡蛋。 }, { from: human, value: 用这些食材能做什么菜请给出详细步骤。 }, { from: gpt, value: 可以用这些食材做西红柿炒鸡蛋。这是一道家常菜步骤如下\n1. 将西红柿洗净切块鸡蛋打入碗中加少许盐打散。\n2. 热锅下油倒入蛋液炒至凝固后盛出。\n3. 锅内再放少许油下西红柿块翻炒出汁。\n4. 将炒好的鸡蛋倒回锅中与西红柿翻炒均匀加盐和糖调味即可出锅。 } ] } // ... 更多数据 ]image是一个特殊的占位符告诉模型这里需要处理图片。对话历史模拟了多轮交互。你需要编写脚本将你收集的图片、识别结果、菜谱文本组合成这样的格式。4.3 模型微调训练使用 LLaVA 仓库提供的训练脚本并应用 LoRA。cd LLaVA # 使用单卡训练假设显卡索引为0 torchrun --nproc_per_node1 --master_port25001 \ llava/train/train_mem.py \ --model_name_or_path lmsys/vicuna-7b-v1.5 \ # 文本基座模型 --version v1 \ --data_path /path/to/your/conversations.json \ --image_folder /path/to/your/images/ \ --vision_tower openai/clip-vit-large-patch14-336 \ # 视觉编码器 --mm_projector_type mlp2x_gelu \ --tune_mm_mlp_adapter True \ # 微调解码器 --bf16 True \ --output_dir ./checkpoints/foodlmm-lora \ --num_train_epochs 3 \ --per_device_train_batch_size 4 \ --per_device_eval_batch_size 4 \ --gradient_accumulation_steps 4 \ --evaluation_strategy no \ --save_strategy epoch \ --learning_rate 2e-4 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type cosine \ --logging_steps 1 \ --tf32 True \ --model_max_length 2048 \ --gradient_checkpointing True \ --lazy_preprocess True \ --report_to none \ --deepspeed ./scripts/zero2.json \ # 使用 DeepSpeed 节省显存 --lora_enable True \ # 启用 LoRA --lora_r 16 \ --lora_alpha 32 \ --lora_dropout 0.1 \ --lora_target_modules q_proj,v_proj # 指定 LoRA 目标模块这个命令会开始微调过程。--lora_enable和相关参数开启了 LoRA 训练。训练时间取决于数据量和 epoch 数对于一个小型演示数据集在单卡 4090 上可能几小时到一天即可完成。4.4 模型推理与部署训练完成后在./checkpoints/foodlmm-lora目录下会保存适配器权重和配置文件。我们可以加载基础模型和 LoRA 权重进行推理。from llava.mm_utils import get_model_name_from_path, load_pretrained_model from llava.eval.run_llava import eval_model model_path ./checkpoints/foodlmm-lora prompt 这张图片里有什么食材能用来做什么菜 image_file test_food.jpg # 加载模型和处理器 tokenizer, model, image_processor, context_len load_pretrained_model( model_pathmodel_path, model_baselmsys/vicuna-7b-v1.5, # 基座模型路径如果与训练时一致可以省略 model_nameget_model_name_from_path(model_path), load_4bitTrue # 使用4-bit量化以降低推理显存适合部署 ) # 准备输入 from llava.conversation import conv_templates, SeparatorStyle from llava.constants import IMAGE_TOKEN_INDEX, DEFAULT_IMAGE_TOKEN, DEFAULT_IM_START_TOKEN, DEFAULT_IM_END_TOKEN from llava.model.builder import load_pretrained_model from llava.utils import disable_torch_init from llava.mm_utils import process_images, tokenizer_image_token, get_model_name_from_path, KeywordsStoppingCriteria # 构建对话 conv_mode llava_v1 conv conv_templates[conv_mode].copy() # 将图片token和问题拼接到对话中 q DEFAULT_IMAGE_TOKEN \n prompt conv.append_message(conv.roles[0], q) conv.append_message(conv.roles[1], None) prompt_text conv.get_prompt() # 处理图像和文本 input_ids tokenizer_image_token(prompt_text, tokenizer, IMAGE_TOKEN_INDEX, return_tensorspt).unsqueeze(0).cuda() image Image.open(image_file).convert(RGB) image_tensor process_images([image], image_processor, model.config)[0] image_tensor image_tensor.unsqueeze(0).half().cuda() # 生成回复 with torch.inference_mode(): output_ids model.generate( input_ids, imagesimage_tensor, do_sampleTrue, temperature0.2, max_new_tokens512, use_cacheTrue, stopping_criteria[KeywordsStoppingCriteria([\n], tokenizer, input_ids)] ) output tokenizer.batch_decode(output_ids, skip_special_tokensTrue)[0] # 对输出进行后处理提取助手的回复 response output.split(ASSISTANT:)[-1].strip() print(response)对于部署可以将上述推理代码封装成 FastAPI 服务提供一个/chat接口接收图片和文本问题返回模型的回答。同时需要加入简单的队列机制来处理并发请求。5. 常见问题、避坑指南与未来展望在实际操作中你一定会遇到各种各样的问题。以下是我在类似项目实践中总结的一些常见坑点和解决思路。5.1 训练阶段常见问题问题显存不足OOM排查首先检查per_device_train_batch_size和gradient_accumulation_steps的乘积是否过大。降低batch_size是最直接的方法。解决启用梯度检查点 (gradient_checkpointing True)这会用计算时间换显存。使用deepspeed配置文件如 zero2进行优化。如果还不行考虑使用 QLoRA 进行 4-bit 量化训练。问题训练损失不下降或波动大排查检查学习率是否合适。对于 LoRA学习率通常比全参数微调高2e-4是一个常见的起点但可能需要根据数据调整。检查数据质量是否存在大量噪声或错误的标注。解决尝试使用学习率预热 (warmup_ratio)并采用余弦退火调度器。对数据进行更彻底的清洗。可以尝试先在一个很小的、高质量的数据子集上过拟合看模型能否学会以排除代码 bug。问题模型“遗忘”通用知识现象微调后模型在食物领域表现变好但回答其他通用问题时能力下降甚至胡言乱语。解决这是灾难性遗忘。可以在指令数据中混入一部分通用领域的对话数据如来自 ShareGPT 的数据让模型在学习新知识的同时不忘记旧能力。这称为“领域混合训练”。5.2 推理与部署阶段问题问题生成内容不符合预期或包含幻觉现象模型可能“捏造”不存在的食材或步骤例如把“土豆”说成“红薯”或者加入菜谱里根本没有的调料。解决温度Temperature和重复惩罚Repetition Penalty是关键参数。降低温度如0.1-0.3可以使生成更确定、更保守减少“胡编”的可能。适当增加重复惩罚如1.1-1.2可以避免模型陷入循环。更根本的解决方法是提升训练数据的质量和多样性并在指令中明确要求“仅基于图片中的食材回答”。问题响应速度慢排查推理速度受模型大小、是否量化、生成长度影响最大。解决对于部署务必使用量化模型如 GPTQ, AWQ 或 bitsandbytes 的 4/8-bit 量化。可以使用vLLM或TGI这类高性能推理框架来提升吞吐量。对于生成设置合理的max_new_tokens避免生成过长文本。问题多食材识别遗漏或混淆现象图片中有多种食材模型只识别了主要的几种或者把A认成了B。解决这主要源于训练数据中复杂场景的样本不足。需要在数据集中增加包含多种、部分遮挡、形态各异食材的图片并进行精确标注。在指令中也可以引导例如提问“请列出图片中所有的食材”。5.3 领域深化与扩展思考FoodLMM 已经展示了强大的潜力但作为一个产品还有很长的路可以走。基于此我们可以思考几个深化的方向个性化与用户交互当前的模型是一次性问答。未来可以引入对话历史实现多轮交互。例如用户说“这个菜谱的糖太多了”模型可以回答“那我为您推荐一个少糖版本”。这需要模型具备更强的指令跟随和上下文理解能力。多模态输入扩展除了图片是否可以结合语音输入用户一边处理食材一边用语音询问“下一步该怎么做”。或者结合传感器数据例如智能锅的重量、温度变化让AI指导火候。从生成到规划不仅仅是生成一个菜谱而是根据用户冰箱里现有的所有食材多张图片、用户的饮食目标减脂、增肌、口味偏好来规划未来几天的食谱。这需要模型具备更强的规划、检索和决策能力。安全与可靠性食物关乎健康模型生成的内容必须绝对安全。需要建立严格的内容过滤机制防止生成有毒、相克需科学验证或不适合特定人群如孕妇的食谱。同时营养分析必须标注为“估算”并提示用户仅供参考。从我个人的实践来看多模态大模型在垂直领域的落地数据工程的重要性已经超过了模型本身。找到一个像“饮食”这样需求明确、场景丰富的切入点构建一个干净、多样、高关联度的数据集然后用 LoRA 等轻量方法去微调一个强大的开源基座模型是当前性价比最高、最有可能做出实用产品的路径。FoodLMM 的成功正是这一思路的完美体现。它提醒我们在追逐大模型浪潮时不妨把目光收回到具体的场景和真实的需求上用技术去解决那些小而美的实际问题。