多模态大模型这两年被讨论得太多,但真正动手搭过一遍的人并不多。很多人卡在同一个地方:看论文觉得都懂,一上手就发现视觉塔输出的 token 数量和语言模型上下文对不上,训练 loss 掉得挺好看,推理时模型却只会念图片里的字。我前后参与过几个图文理解方向的模型改造项目,从最初把视觉特征硬塞进语言模型,到后来跑通预训练、指令微调、偏好对齐的完整链路,踩过的坑基本覆盖了架构选型、数据配比、显存爆炸、幻觉失控这几个大类。这篇就按我实际操作的顺序,把多模态大模型(MLLM)的架构设计和训练方法完整拆一遍,重点讲清楚每个设计决策背后的代价,而不是罗列名词。
内容适合三类人:一是想从纯文本模型转向多模态的算法同学,需要知道从哪儿改起;二是要做垂直场景落地(比如单据识别、工业质检图文问答、教育题目解析)的工程同学,关心怎么用有限算力跑出可用效果;三是对训练细节好奇、想知道那些"效果提升"到底来自哪一步的读者。文中涉及的模型规模、数据配比、超参都是基于常见实践的合理取值,具体项目要按自己的算力和数据情况调整,我会把调整的逻辑一并写清楚。
1. 先把MLLM拆成三段式,再谈架构
1.1 一条完整的图文链路到底经过哪些环节
多模态大模型最朴素的理解是"给语言模型装一只眼睛"。但这只眼睛不是直接接上去就能用的,中间隔着一整套翻译机制。我习惯把整条链路拆成四段来看:视觉编码器负责把图片切成小块并提取特征,连接器负责把视觉特征翻译成语言模型能读的 token 序列,语言模型负责把视觉 token 和文本 token 混在一起做自回归生成,最后的输出层再决定是继续说话还是输出坐标框。
这四段里,视觉编码器和语言模型通常是现成的,真正决定"多模态能力强弱"的往往是中间那个不起眼的连接器,以及三者的对齐训练方式。我在第一个项目里就吃过亏:视觉塔用的是对比学习预训练好的现成权重,语言模型也是开箱即用的开源权重,唯独连接器只用了两层线性层,结果模型能认出图里有猫,但问到"猫在沙发左边还是右边"就开始瞎编。后来把连接器换成带重采样的结构,并且加大了对齐阶段的数据量,空间关系类问题的准确率才明显回升。这说明连接器不是可有可无的胶水,它是视觉信息和语言语义之间的语义转换器,容量太小就会丢信息。
还有一段容易被忽略:图像预处理。同样是 336 分辨率的输入,中心裁剪和保持长宽比缩放再补边的做法,对细长图片(比如截图、表格)的影响完全不同。裁剪会把表格两侧的列直接切掉,模型自然读不全。这个细节后面在排查章节会展开。
1.2 架构选型的三个岔路口
搭 MLLM 基本要在三个地方做选择,每个选择都对应不同的训练成本和能力上限。
第一个岔路口:视觉特征是"直接拼接"还是"压缩后拼接"。直接拼接就是把视觉编码器输出的所有 patch token 原样送进语言模型,优点是信息无损,缺点是 token 数量爆炸。以 336×336 输入、patch 大小 14 计算,一张图就是 24×24=576 个 token,如果做多尺度切图(全局一张加局部四张),单图就是 2880 个 token。一个 8K 上下文窗口,光图片就吃掉三分之一,多轮对话根本撑不住。压缩后拼接则是用一个重采样器把 576 个 token 压到 64 或 128 个,代价是细节丢失,尤其是小字和密集表格。
第二个岔路口:视觉塔是冻结还是放开训练。冻结最省显存,训练稳定,适合数据量在百万级以下的场景;放开训练能显著提升细粒度理解,但容易出现语言能力退化,因为视觉梯度会冲击原本的语言表征。我的经验是分阶段处理:对齐预训练阶段冻结视觉塔,只训连接器;指令微调阶段解冻视觉塔的最后若干层,学习率设为语言模型的十分之一左右。
第三个岔路口:训练目标是纯自回归,还是加上对比学习、定位损失等辅助目标。纯自回归最简单,数据格式统一,但模型容易学会"看图说话"式的套话,对"图里没有的东西"也照答不误。加上辅助的图文匹配损失或者区域定位损失,能一定程度抑制幻觉,代价是训练管线复杂,需要额外的标注数据。
下面这张表是我对不同规模项目的选型建议,供参考:
| 场景条件 | 视觉特征处理 | 视觉塔状态 | 训练目标 | 典型算力 |
|---|---|---|---|---|
| 单卡或小集群验证 | 直接拼接,单尺度 | 全程冻结 | 纯自回归 | 8 卡以内 |
| 垂直领域微调 | 压缩到 128 token | 冻结,仅训连接器 | 自回归 + 图文匹配 | 8 到 32 卡 |
| 通用能力增强 | 压缩到 256 token,多尺度 | 解冻后若干层 | 自回归 + 定位辅助 | 64 卡以上 |
| 长文档/表格理解 | 动态分辨率,不压缩 | 部分解冻 | 自回归 + OCR 辅助 | 32 卡以上 |
这张表不是标准答案,但它反映了一个基本规律:算力越紧,越要往"冻结视觉塔、压缩 token、简化目标"的方向走;算力宽松、追求上限,才考虑解冻和多目标联合训练。
2. 视觉前端与连接器:能力上限的第一道关口
2.1 视觉编码器怎么选,分辨率账怎么算
视觉编码器的选择直接决定模型能"看清"多少东西。目前主流路线有两条:一条是对比学习预训练出来的双塔视觉编码器,优点是语义对齐好,图文检索类任务表现稳;另一条是自监督掩码重建预训练的编码器,优点是细节保留好,OCR 和密集场景更强。我在做单据类项目时对比过两种路线,同样数据量下,掩码重建路线的编码器在"小字识别"上明显更稳,但在"这张图整体是什么场景"这类粗粒度问题上略逊。
分辨率这块必须算清楚账。假设视觉编码器的 patch 大小是 14,输入 224 时 token 数是 (224/14)²=256,输入 336 时是 576,输入 448 时是 1024。token 数随分辨率平方增长,这就是为什么高分辨率理解很贵。常见的折中方案是动态分辨率:把原图按长宽比切成若干块,每块固定尺寸,再拼上全局缩略图。一张 1024×768 的图,切成 2×2 共 4 块局部加 1 张全局,token 数就是 5×576=2880。
这个数字意味着什么?如果你的语言模型上下文是 4096,单张图就占了 70%,剩下的文本空间只够写几百字。所以动态分辨率一定要配合 token 压缩,或者只在必要的时候开启。我一般的做法是给模型一个开关:普通问答走单尺度 576 token,遇到文档、表格、截图类请求再切到多尺度模式。这个策略在线上服务里非常实用,平均 token 消耗能降下来一大截。
还有一个经常被忽略的点:视觉编码器的输入归一化参数必须和它的预训练保持一致。我见过有人换了自训练的视觉塔,却沿用了原来的均值方差,结果特征分布整体偏移,训练 loss 前期几乎不下降。这种问题排查起来极费时间,因为代码不报错,只是效果差。
2.2 连接器的三种形态与取舍
连接器这块,市面上大致有三种做法,我把它们的特性整理成下面这张表:
| 形态 | 结构 | 输出 token 数 | 优点 | 缺点 |
|---|---|---|---|---|
| 线性投影 | 一到两层全连接 | 与输入相同 | 简单、无损、训练快 | token 太多,长上下文吃紧 |
| 查询重采样 | 一组可学习查询向量做交叉注意力 | 固定,如 64/128 | 压缩率高,长度可控 | 细节丢失,小字易糊 |
| 卷积/池化下采样 | 相邻 patch 合并 | 按倍率减少 | 保留局部结构 | 压缩比固定,不够灵活 |
线性投影适合验证阶段,因为它的行为最容易预测,出问题也最容易定位。查询重采样适合对上下文长度敏感的生产环境,但要注意查询向量的初始化方式,随机初始化在训练早期容易收敛到"平均特征",导致所有图片的表征趋同。我的做法是用视觉特征的均值初始化查询向量,再配合较长的预热阶段,收敛会稳不少。
卷积下采样是个被低估的方案。它对相邻 patch 做合并,天然保留了空间邻接关系,对于"左边""上面"这类位置问题比较友好。缺点是压缩比是固定的 2 倍或 4 倍,不能按需调整。我在一个工业质检项目里用了 2 倍下采样的方案,配合解冻视觉塔最后三层,缺陷定位的准确率比查询重采样高出一截,原因就是空间结构没被破坏。
2.3 位置信息与高分辨率外推的实操细节
视觉 token 送进语言模型之后,位置信息怎么给,这件事影响比想象中大。有两种常见做法:一种是把视觉 token 当成普通文本 token,按顺序分配一维位置编号;另一种是给视觉 token 单独编码二维位置,再和文本位置做拼接。
一维编号的优点是实现简单,和现有语言模型完全兼容;缺点是模型很难从一维序号里推断出"这两个 patch 上下相邻"。在需要空间推理的任务上,这个缺陷会暴露得很明显。我做过一个小实验:问模型"红色的方块在蓝色方块的上方还是下方",一维位置方案的正确率明显低于二维方案。后来我在连接器输出端加了一个轻量的二维位置嵌入,只增加很少的参数,空间类问题的表现就有改善。
高分辨率外推是另一个坑。视觉编码器在固定分辨率上预训练,直接喂更高分辨率的图,位置嵌入会超出训练范围,特征质量下降。常见的处理是插值位置嵌入,但插值本身会带来模糊。更稳妥的做法是分块处理:把高分辨率图切成若干块,每块都在训练分辨率范围内,再靠全局缩略图提供整体信息。这个思路和前面说的动态分辨率是一回事,落地时要注意块与块之间要有重叠,否则跨块的文字会被切断。
3. 训练三阶段:每个阶段到底在解决什么问题
3.1 阶段一:对齐预训练,重点是"翻译"而不是"学习知识"
对齐预训练的目标很单纯:让连接器学会把视觉特征翻译成语言模型能理解的空间。这个阶段不需要模型学会回答复杂问题,只需要它建立"图片内容"和"文本描述"之间的映射。
数据方面,主流做法是用大规模的图文对,配上少量交错图文文档。数据量级从几十万到上千万不等。我的经验是,这个阶段数据质量的影响没有想象中大,但数据多样性影响很大。如果全是自然场景照片,模型对图表、截图、手写体的适应能力会很差。一个比较实用的配比是:自然图像六成,文档与图表两成,截图与界面一成,其余为合成数据和其他类别。这个比例不是金标准,但它保证了几类常见输入都不会完全没见过。
训练策略上,这个阶段我强烈建议冻结视觉塔和语言模型,只训练连接器。原因很实在:连接器参数量小,几十万到几百万级别,单卡就能跑;冻结之后显存占用低,可以用更大的 batch;而且不会破坏语言模型原有的能力。我见过有团队在这个阶段就全参放开,结果语言模型的路人问答能力明显退化,得不偿失。
学习率设置上,连接器可以用比较大的值,因为它基本是从零开始学的。我通常用 1e-3 到 2e-3 配余弦退火,预热步数占总步数的百分之三左右。batch size 尽量大,梯度累积也行,因为这个阶段的任务相对简单,大 batch 能让收敛更平滑。
这个阶段最容易出现的现象是 loss 掉到某个值之后不再下降,同时模型输出变成"一张图片中有……"这样的模板句。这通常不是模型 capacity 不够,而是数据里的描述文本太单一。解决办法是清洗描述文本,去掉过短、纯标签、重复模板的样本,补充一些描述角度多样的数据。
3.2 阶段二:指令微调,把"能看懂"变成"会回答"
指令微调是多模态能力真正成型的地方。这个阶段的数据不再是简单的图文对,而是"图像 + 指令 + 回答"的三元组。数据构造的质量直接决定模型好不好用。
我把这个阶段的数据按能力维度拆成几类,每类的构造要点不同:
- 开放问答类:问图片里有什么、在发生什么。要点是回答要有信息量,避免"这是一张图片"这种废话。构造时可以要求回答包含主体、场景、动作三个要素。
- 细粒度识别类:问具体属性,比如颜色、数量、文字内容。要点是答案必须可从图中验证,不能靠常识补全。这类数据要特别小心,标注错误会直接教模型编造。
- 空间关系类:问相对位置、朝向。要点是回答要明确,避免"在附近"这种模糊表述。
- 推理类:基于图中信息做判断,比如"这个人接下来最可能做什么"。要点是推理链要短,且每一步都能在图中找到依据。
- 拒答类:问图中不存在的东西。这类数据非常关键,是抑制幻觉的主要手段。构造方式是拿一张图,配上与图无关的问题,标准答案是"图中没有相关信息"。
拒答类数据的比例我一般控制在百分之十到十五。太少,模型学不会说"不知道";太多,模型变得过度保守,什么都答不上来。这个比例需要通过评测集反复调,不是拍脑袋定的。
这个阶段的学习率要比预训练阶段小一个数量级,通常 1e-5 到 2e-5。视觉塔可以选择解冻最后几层,学习率再降一个量级。解冻的层数不是越多越好,我试过全解冻,在数据量不足百万的情况下,模型对图像的整体理解反而变差,原因是视觉塔被少量数据带偏了。比较稳的做法是解冻最后三到六层,配合较小的学习率和梯度裁剪。
还有一个实操细节:这个阶段不同来源的数据格式差异很大,有的回答很长,有的只有几个字。如果直接混在一起训练,长回答的样本会在 loss 里占主导,模型倾向于输出啰嗦的长句。我的处理是按回答长度分桶,训练时每批尽量来自同一桶,或者在 loss 上做长度归一化。这个改动不起眼,但对输出风格的稳定性帮助很大。
3.3 阶段三:偏好对齐,主要针对幻觉和语气
偏好对齐在多模态场景里最核心的作用是压幻觉。具体做法是给同一个图文输入构造两个回答,一个准确,一个包含图中不存在的信息,让模型学会偏好准确的那个。
构造偏好数据有个技巧:错误回答不能错得太离谱,否则模型学不到细粒度判断。比较有效的做法是"局部错误",比如图里是三只猫,错误回答写四只;图里是晴天,错误回答写阴天。这种细微错误才是真实场景里模型最容易犯的。
训练方法上,直接偏好优化比传统的两阶段方案更简单,不需要单独训练奖励模型,显存占用也低。但要注意参考模型的选择,如果参考模型和对齐模型差异太大,训练容易不稳定。我的做法是从指令微调后的检查点出发,参考模型就用同一个检查点冻结,这样分布接近,收敛比较顺。
这个阶段的数据量不需要很大,几万条量级就能看到效果。但数据质量要求极高,错误样本和正确样本的差异必须清晰可辨。我见过用机器批量生成的偏好数据,正负样本差异模糊,训练之后模型输出变得支支吾吾,什么都不敢肯定,这就是对齐过头了。
4. 训练工程实操:显存怎么算、并行怎么配
4.1 把显存账算清楚再动手
很多人一上来就报显存不足,其实账没算明白。以 7B 参数的语言模型为例,全参训练时显存大致由这几块构成:
- 权重(bf16):7B × 2 字节 ≈ 14GB
- 梯度(bf16):≈ 14GB
- 优化器主权重(fp32):7B × 4 字节 ≈ 28GB
- 一阶动量(fp32):≈ 28GB
- 二阶动量(fp32):≈ 28GB
- 激活值:取决于 batch、序列长度和是否重计算
前五项加起来就是 112GB,还没算激活。单张 80GB 卡肯定放不下,所以必须用分片策略。如果只训连接器,可训练参数可能只有几千万,显存占用主要来自冻结的权重和前向激活,这时候单卡 40GB 甚至 24GB 就能跑起来,这也是我建议前期冻结的原因。
激活值的估算比较麻烦,粗略的算法是:层数 × batch × 序列长度 × 隐藏维度 × 字节数 × 系数。序列长度在多模态场景里会被视觉 token 撑得很大,所以激活往往是真正的瓶颈。开启梯度检查点能把激活降下来,代价是训练速度慢两到三成。我的经验是,只要显存不够,先开梯度检查点,再考虑降 batch,最后才考虑换并行策略。
4.2 并行策略的选择顺序
并行这块,我的选择顺序是:数据并行 → 张量并行 → 流水并行 → 序列并行。原因是复杂度递增,而多模态场景的瓶颈往往在序列长度而不是参数量。
数据并行配合分片优化器状态,是性价比最高的方案。8 卡 80GB 跑 7B 全参训练,分片之后每卡权重加优化器状态大约 14GB,激活按序列长度 4096 估算还能剩不少余量。如果序列长度继续涨,比如到了 8192 以上,就要考虑序列并行了,把长序列切到不同卡上处理。视觉 token 多的场景,序列并行确实能救急。
张量并行我一般只在单卡放不下模型时才用,因为它的通信开销大,而且和视觉塔的并行方式容易冲突。流水并行适合层数很多的模型,但多模态模型往往层数不算多,收益有限。
还有一个容易踩的坑:视觉塔和语言模型往往用不同的并行配置。视觉塔参数量小,通常不做切分,每张卡都放一份;语言模型做分片。这时候要注意数据加载器不能重复处理图像,否则每张卡都做一遍图像编码,白白浪费算力。我的做法是让 rank 0 处理图像并把特征广播出去,或者干脆把视觉塔放在单独的推理进程里,先把特征算好存下来。后者在数据预处理阶段做特征缓存,训练时直接读特征,能省掉大量重复计算,特别适合视觉塔冻结的场景。
4.3 一份可以直接改的配置示例
下面这份配置是我在一个 8 卡环境里跑 7B 模型指令微调时用的,基于常见的训练框架写法,参数名可能有差异,逻辑是通用的:
model: vision_tower: frozen_to_last_4_layers connector: resampler_128_tokens language_model: 7b precision: bf16 training: stage: instruction_tuning per_device_batch_size: 2 gradient_accumulation_steps: 8 max_seq_length: 4096 gradient_checkpointing: true learning_rate: 1.5e-5 vision_learning_rate: 2.0e-6 lr_scheduler: cosine warmup_ratio: 0.03 weight_decay: 0.0 max_grad_norm: 1.0 num_epochs: 2 parallel: strategy: fsdp sharding_strategy: full_shard cpu_offload: false data: image_resolution: 336 dynamic_resolution: false max_images_per_sample: 1几个参数的解释:per_device_batch_size乘梯度累积乘卡数就是有效 batch,这里是 2×8×8=128,对 7B 模型来说比较合适。vision_learning_rate设成语言模型的七分之一左右,是我试下来比较稳的比例。weight_decay设为 0 是因为指令微调阶段数据量不大,正则化容易让模型欠拟合。num_epochs设 2 是因为再多就开始过拟合,表现为评测集分数先升后降。
如果显存还是不够,调整顺序是:先把gradient_checkpointing打开(已开),再降per_device_batch_size到 1 并提高累积步数,最后才考虑换更小的模型或减少可训练层数。
5. 常见问题与排查实录
5.1 症状对照表:从现象反推原因
训练多模态模型遇到问题时,最怕的是没有方向地乱试。我把这些年遇到的典型问题整理成一张对照表,基本覆盖了八成以上的场景:
| 现象 | 可能原因 | 排查方法 | 处理方式 |
|---|---|---|---|
| loss 前期几乎不降 | 视觉特征归一化参数不匹配;连接器学习率过小 | 检查预处理参数是否与视觉塔预训练一致 | 对齐归一化;提高连接器学习率 |
| loss 正常但输出是模板句 | 训练数据描述文本单一、重复 | 抽样统计回答的重复率 | 清洗数据,补充多样描述 |
| 模型答非所问,忽略图像 | 视觉 token 被文本 token 淹没;连接器容量不足 | 做纯图像输入的对照测试 | 加大视觉 token 权重,换重采样结构 |
| 小字、表格识别差 | 分辨率不足;token 压缩过度 | 换成多尺度输入对比效果 | 开启动态分辨率,减少压缩比 |
| 频繁编造图中不存在的内容 | 缺乏拒答数据;偏好对齐不足 | 用拒答评测集测准确率 | 补充拒答样本,加偏好对齐阶段 |
| 多轮对话后忘记图片内容 | 上下文长度不够,视觉 token 被截断 | 统计每轮 token 消耗 | 压缩视觉 token,或每轮重传图像特征 |
| 训练速度异常慢 | 视觉塔每卡重复编码;未开混合精度 | 看数据加载和视觉前向的耗时占比 | 缓存视觉特征,开启 bf16 |
| 评测分数波动大 | 数据顺序未打散;评测集与训练集重叠 | 检查数据划分 | 重新划分,固定随机种子 |
这张表里我最想强调的是第三行和第五行。视觉 token 被淹没这件事非常隐蔽,因为训练 loss 看起来一切正常,模型也确实在学,只是学成了"不看图也能答"的偏科生。判断方法很简单:把图像替换成纯噪声,看模型输出变化大不大。如果几乎没变化,说明它根本没在依赖视觉信息。这个问题在连接器压缩比过高、或者文本指令过强时特别容易出现。
5.2 几个文档里不会写的避坑经验
第一个坑:图像预处理和训练分辨率不一致。训练时用 336,推理时用户上传的图被缩放到 448,视觉塔的位置嵌入超出范围,特征质量下降。这种问题在离线评测里发现不了,因为评测脚本和训练脚本用同一套预处理。上线后才暴露。我的做法是在推理服务里强制把图像缩放到训练分辨率,长宽比用补边保持,多出来的像素填固定颜色而不是拉伸。
第二个坑:多图输入的顺序问题。当一次输入包含多张图时,视觉 token 的排列顺序要和文本里的指代顺序对应。如果代码里用了多线程加载图片,返回顺序可能乱掉,模型就会把第二张图的描述安到第一张图上。这个问题极难通过 loss 发现,只能靠人工抽查。解决办法是给每张图加显式的序号标记,并在文本里用对应的标记指代。
第三个坑:解冻视觉塔之后忘了调低学习率。视觉塔的参数量往往和语言模型同一量级,如果沿用语言模型的学习率,几轮下来视觉特征就被彻底改写了,表现为模型对图像的通用理解能力下降,但对训练集里的特定图片过拟合。判断方法是拿一批训练时没见过的图测试,如果表现明显差于训练集图片,基本就是这个原因。
第四个坑:评测集泄漏。多模态评测集很多是公开的,训练数据里混进了评测集的图片或者同源图片,分数虚高。我一般会做一次图像哈希去重,把训练集里和评测集相似的图筛掉。这个步骤费时但值得,否则你根本不知道自己模型的真实水平。
第五个坑:把视觉特征缓存下来之后忘了同步更新。冻结视觉塔时缓存特征是常规操作,但一旦解冻了视觉塔,旧缓存就失效了。我见过有团队解冻之后还在读旧缓存,训练了三天发现 loss 曲线不对,回头查才找到原因。规范做法是在配置里加一个版本号,缓存文件名带上视觉塔权重的哈希,权重变了缓存自动失效。
5.3 一个最小可用的验证流程
在投入大规模训练之前,我建议先跑一遍最小验证,成本很低但能挡掉大部分架构性错误。流程大概是:取一千条图文样本,冻结视觉塔和语言模型,只训连接器一个 epoch,然后人工看二十条输出。重点看三件事:模型是否真的在描述图中的内容、输出是否符合预期的语言风格、对图中不存在的问题是否会拒答。
这个验证跑下来大概几十分钟,但它能暴露的问题比跑三天全量训练还多。如果这一步的输出就已经是模板句或者完全忽略图像,那就不要往下走了,先修数据和连接器。我在最近一个项目里就是用这个流程发现视觉特征维度接错了,接错之后模型照样能训,loss 照样降,但学的全是语言先验,跟图像毫无关系。
6. 我对这套流程的一点实际体会
整套流程跑下来,我最大的感受是:多模态模型的难点不在模型结构,而在数据管线和评测。结构上的选择就那么几种,论文里写得清清楚楚,照着搭不会出大错。真正拉开差距的是数据配比是否合理、预处理是否一致、评测是否能反映真实能力。我见过结构很朴素但数据做得极细的方案,效果远超结构花哨但数据粗糙的方案。
另外一个体会是,不要一开始就追求全参训练和通用能力。先用冻结加连接器跑通闭环,拿到一个能用的基线,再逐步解冻、加数据、加目标。每一步改动都单独评测,确认提升来自哪里。这种小步快跑的方式,比一次性堆一个大训练任务然后对着 loss 曲线猜问题,效率高得多。
最后分享一个具体的小技巧:在你的评测集里专门留一组"对抗样本",包括纯噪声图、全黑图、与问题完全无关的图。每次训练完都跑一遍,看模型是老老实实说"图中没有相关信息",还是开始编故事。这组样本数量不用多,几十条就够,但它是判断模型有没有学歪的最灵敏的指标。我现在的习惯是每个检查点都跑这组,一旦发现开始编造,就回头查最近的改动,往往能很快定位到是数据配比变了还是解冻层数加多了。