进阶 unsloth.ai 2026-10-07 22:27:00 · 7 阅读
第38章 使用 Unsloth 微调并运行 Gemma 3n
unsloth
下载
☰
下载
BlogFine-tune & Run Gemma 3nJul 1, 2025 • By Daniel & Michael2025年7月1日•作者 Daniel & Michael
Gemma 3n 是 Google 新推出的多模态模型(支持文本、视觉和音频),提供 2B 和 4B 两种规格,拥有 32K 上下文窗口,支持多语言,现在 Unsloth 也已支持。
使用我们的 Colab notebook 免费微调 Gemma-3n-E2B。
Unsloth 是唯一一个支持在 f16 GPU 上对 Gemma 3n 进行推理和训练的框架。
我们在 Hugging Face 上传了 Gemma 3n 的所有版本,包括 Dynamic GGUF、4-bit 和 16-bit 版本。目前 GGUF 仅支持文本。
欢迎阅读我们关于如何运行和微调 Gemma 3n 的详细指南。
非常感谢 Gemma 团队的支持!也很高兴在 Google 举办的 Gemma 开发者聚会上与大家见面!
✨Gemma 3n 修复
♾️无穷大(Inf)和 NaN 梯度与激活值
和 Gemma 3 一样,Gemma 3n 在 FP16 GPU(例如 Colab 的 Tesla T4)上运行时也有问题。对于 Gemma 3,我们发现激活值超出了 float16 的最大范围 65504。Gemma 3n 解决了激活值问题,但我们仍然遇到了无穷大!
于是我们绘制了 Gemma 3N 权重绝对值的最大值分布,结果如下: 可以看到绿色的叉是卷积权重,其数值远大于其他权重。再检查激活值时,它们直接变成了无穷大!
下表列出了数值过大的 Conv2D 权重。问题在于 Conv2D 运算时,大权重相乘再求和,不幸超出了 float16 的最大范围 65504。Bfloat16 则没有问题,因为它的最大范围可达 10^38。 名称 数值 msfa.ffn.pw_proj.conv.weight 98.000000 blocks.2.21.attn.key.down_conv.weight 37.000000 blocks.2.32.pw_exp.conv.weight 34.750000 blocks.2.30.pw_exp.conv.weight 33.750000 blocks.2.34.pw_exp.conv.weight 33.750000 解决方案是在 float16 机器上把所有 Conv2D 权重提升为 float32!但这样会占用更多显存,所以我们改用自动类型转换,在运算时把权重和输入矩阵动态提升为 float32,并以 float32 做累加。
Unsloth 是唯一支持在 float16 GPU 上运行 Gemma 3n 推理和训练的框架,因此使用免费 Tesla T4 的 Colab Notebook 也能正常工作! 🏁 梯度检查点问题 我们发现 Gemma 3N 的视觉编码器比较独特,因为它复用了隐藏状态。这不幸地限制了梯度检查点的使用,导致内存占用比通常略高。
不过,我们依然成功利用 Unsloth 的自动编译器对 Gemma 3N 进行了优化! 🦙 GGUF 问题与修复: 得益于 Ollama 团队以及 Hugging Face 的 Nguyen 的讨论,我们发现了 GGUF 特有的两个问题:
1. add_shared_kv_layers 意外地被编码为 float32,虽然这本身没问题,但从 Ollama 端解码起来稍显复杂——简单地将格式改为 uint32 即可解决此问题。
2. per_layer_token_embd 的精度应为 Q8_0。任何更低的精度似乎都无法正常工作,并在 Ollama 引擎中报错。为了减少社区用户遇到的问题,我们在所有量化版本中统一使用 Q8_0——遗憾的是,这会占用更多空间。
更新:Matt 提到,嵌入层也可以使用 Q4_0、Q4_1、Q5_0、Q5_1,我们确认在 Ollama 中也能正常运行!这意味着更小的 2、3 和 4 位量化模型体积更小,且不再需要 Q8_0! 🌵 微调期间损失值过大: 我们还发现微调过程中的损失值异常大,范围在 6 到 7 之间,但随后会迅速缩小。我们推测这可能是由以下两种情况之一导致的:
1. 可能存在实现上的问题,但由于推理表现良好,这种可能性不大。
2. 多模态模型似乎总是表现出这种行为——我们发现 Llama 3.2 Vision 的损失起始值为 3 或 4,Pixtral 约为 8,Qwen 2.5 VL 也约为 4。由于 Gemma 3N 还包含音频模态,可能会放大初始损失值。但这只是一种假设。我们还发现,将 Qwen 2.5 VL 72B Instruct 量化后,困惑度(perplexity)得分极高,约为 30,但模型似乎运行正常。 ✨ Gemma 3n 微调 与 Gemma 3 类似,Gemma 3n 在 Colab 等配备 F16 GPU(如 Tesla T4)的环境下运行时也存在问题。如果没有针对推理或微调进行修补,你将会遇到 NaN(非数字)和无穷大值。
我们找到了一个简单的变通方法:将视觉编码器中的所有卷积层上转换为 float32,但这会增加 VRAM 的使用。为了减少内存占用,我们采用了自动类型转换(autocasting),让卷积层保持 float16,仅在矩阵乘法时上转换为 float32。
由于 Gemma 3n 的独特架构会在视觉编码器中复用隐藏状态,Unsloth 的 Gradient Checkpointing 算法(可大幅降低 VRAM 占用)无法应用于该编码器,不过我们依然对其应用了自动编译优化。
Unsloth 是唯一支持 Gemma 3n 在 float16 机器上进行推理和训练的框架,这也意味着配备免费 Tesla T4 GPU 的 Colab Notebooks 同样可用!使用 Unsloth 微调 Gemma 3n-E4B 仅需 12GB 以下的 VRAM!它还快了 1.6 倍,且默认采用 Unsloth 动态 4-bit 量化以提升精度!从技术角度来说你可以
我们也收到许多请求,希望提供 Gemma 3 (4B) Vision 的 notebook,现在你可以在此处免费通过我们的 Google Colab Notebook 体验。性能基准模型 VRAM🦥Unsloth 速度🦥 VRAM 降幅🦥 更长上下文🤗Hugging Face+FA2Gemma-3n-E4B24GB1.5x>50%5x 更长1x 我们使用 Alpaca 数据集进行测试,batch size 为 2,梯度累积步数为 4,rank = 32,并在所有线性层(q, k, v, o, gate, up, down)上应用 QLoRA。🔮 Gemma 3n 分析以下是针对 Gemma 3n MatFormer 架构的深入分析:
Gemma 3n 有何特别之处?它基于 Matryoshka Transformer 或 MatFormer 架构,意味着每个 Transformer 层/块中嵌套了尺寸逐渐变小的 FFNs。可以想象成一个个逐渐变小的杯子套在一起。训练过程的设计使得在推理时你可以选择所需的尺寸,从而获得接近大模型的性能表现。
此外,Per Layer Embedding 可以被缓存以减少推理时的内存占用。因此,2B 模型(E2B)实际上是 4B(即 5.44B)模型内的一个子网络,这是通过 Per Layer Embedding 缓存以及跳过音频和视觉组件、仅关注文本来实现的。
MatFormer 架构通常通过指数间隔的子模型进行训练,即每层包含大小分别为 S, S/2, S/4, S/8 等的子块。在训练时,输入会随机通过这些子块之一传递,使每个子块都有均等的学习机会。其优势在于,推理时如果想让模型缩小到原始大小的 1/4,你可以选择在每层使用 S/4 大小的子块。
你还可以自由组合:比如某一层选 S/4 大小的子块,另一层选 S/2,再一层选 S/8。甚至可以根据输入内容动态选择不同的子模型。 essentially 就是每一层都能自定义结构。这样一来,只需训练一个特定尺寸的模型,就能得到指数级的更小尺寸模型,学习成果毫不浪费。相当巧妙吧。💕 衷心感谢 Google Gemma 团队让我们实现了 Day 0 支持,也感谢所有使用和分享 Unsloth 的朋友,我们非常感激。🙏
和往常一样,欢迎加入我们的 Reddit 页面和 Discord 服务器获取帮助或表达支持!也可以在 Twitter 上关注我们,或订阅我们的邮件通讯。感谢阅读!Daniel & Michael Han 🦥
2025年7月1日立即微调 Gemma 3n!免费开始使用 加入我们的 Discord
于是我们绘制了 Gemma 3N 权重绝对值的最大值分布,结果如下: 可以看到绿色的叉是卷积权重,其数值远大于其他权重。再检查激活值时,它们直接变成了无穷大!
下表列出了数值过大的 Conv2D 权重。问题在于 Conv2D 运算时,大权重相乘再求和,不幸超出了 float16 的最大范围 65504。Bfloat16 则没有问题,因为它的最大范围可达 10^38。 名称 数值 msfa.ffn.pw_proj.conv.weight 98.000000 blocks.2.21.attn.key.down_conv.weight 37.000000 blocks.2.32.pw_exp.conv.weight 34.750000 blocks.2.30.pw_exp.conv.weight 33.750000 blocks.2.34.pw_exp.conv.weight 33.750000 解决方案是在 float16 机器上把所有 Conv2D 权重提升为 float32!但这样会占用更多显存,所以我们改用自动类型转换,在运算时把权重和输入矩阵动态提升为 float32,并以 float32 做累加。
Unsloth 是唯一支持在 float16 GPU 上运行 Gemma 3n 推理和训练的框架,因此使用免费 Tesla T4 的 Colab Notebook 也能正常工作! 🏁 梯度检查点问题 我们发现 Gemma 3N 的视觉编码器比较独特,因为它复用了隐藏状态。这不幸地限制了梯度检查点的使用,导致内存占用比通常略高。
不过,我们依然成功利用 Unsloth 的自动编译器对 Gemma 3N 进行了优化! 🦙 GGUF 问题与修复: 得益于 Ollama 团队以及 Hugging Face 的 Nguyen 的讨论,我们发现了 GGUF 特有的两个问题:
1. add_shared_kv_layers 意外地被编码为 float32,虽然这本身没问题,但从 Ollama 端解码起来稍显复杂——简单地将格式改为 uint32 即可解决此问题。
2. per_layer_token_embd 的精度应为 Q8_0。任何更低的精度似乎都无法正常工作,并在 Ollama 引擎中报错。为了减少社区用户遇到的问题,我们在所有量化版本中统一使用 Q8_0——遗憾的是,这会占用更多空间。
更新:Matt 提到,嵌入层也可以使用 Q4_0、Q4_1、Q5_0、Q5_1,我们确认在 Ollama 中也能正常运行!这意味着更小的 2、3 和 4 位量化模型体积更小,且不再需要 Q8_0! 🌵 微调期间损失值过大: 我们还发现微调过程中的损失值异常大,范围在 6 到 7 之间,但随后会迅速缩小。我们推测这可能是由以下两种情况之一导致的:
1. 可能存在实现上的问题,但由于推理表现良好,这种可能性不大。
2. 多模态模型似乎总是表现出这种行为——我们发现 Llama 3.2 Vision 的损失起始值为 3 或 4,Pixtral 约为 8,Qwen 2.5 VL 也约为 4。由于 Gemma 3N 还包含音频模态,可能会放大初始损失值。但这只是一种假设。我们还发现,将 Qwen 2.5 VL 72B Instruct 量化后,困惑度(perplexity)得分极高,约为 30,但模型似乎运行正常。 ✨ Gemma 3n 微调 与 Gemma 3 类似,Gemma 3n 在 Colab 等配备 F16 GPU(如 Tesla T4)的环境下运行时也存在问题。如果没有针对推理或微调进行修补,你将会遇到 NaN(非数字)和无穷大值。
我们找到了一个简单的变通方法:将视觉编码器中的所有卷积层上转换为 float32,但这会增加 VRAM 的使用。为了减少内存占用,我们采用了自动类型转换(autocasting),让卷积层保持 float16,仅在矩阵乘法时上转换为 float32。
由于 Gemma 3n 的独特架构会在视觉编码器中复用隐藏状态,Unsloth 的 Gradient Checkpointing 算法(可大幅降低 VRAM 占用)无法应用于该编码器,不过我们依然对其应用了自动编译优化。
Unsloth 是唯一支持 Gemma 3n 在 float16 机器上进行推理和训练的框架,这也意味着配备免费 Tesla T4 GPU 的 Colab Notebooks 同样可用!使用 Unsloth 微调 Gemma 3n-E4B 仅需 12GB 以下的 VRAM!它还快了 1.6 倍,且默认采用 Unsloth 动态 4-bit 量化以提升精度!从技术角度来说你可以
我们也收到许多请求,希望提供 Gemma 3 (4B) Vision 的 notebook,现在你可以在此处免费通过我们的 Google Colab Notebook 体验。性能基准模型 VRAM🦥Unsloth 速度🦥 VRAM 降幅🦥 更长上下文🤗Hugging Face+FA2Gemma-3n-E4B24GB1.5x>50%5x 更长1x 我们使用 Alpaca 数据集进行测试,batch size 为 2,梯度累积步数为 4,rank = 32,并在所有线性层(q, k, v, o, gate, up, down)上应用 QLoRA。🔮 Gemma 3n 分析以下是针对 Gemma 3n MatFormer 架构的深入分析:
Gemma 3n 有何特别之处?它基于 Matryoshka Transformer 或 MatFormer 架构,意味着每个 Transformer 层/块中嵌套了尺寸逐渐变小的 FFNs。可以想象成一个个逐渐变小的杯子套在一起。训练过程的设计使得在推理时你可以选择所需的尺寸,从而获得接近大模型的性能表现。
此外,Per Layer Embedding 可以被缓存以减少推理时的内存占用。因此,2B 模型(E2B)实际上是 4B(即 5.44B)模型内的一个子网络,这是通过 Per Layer Embedding 缓存以及跳过音频和视觉组件、仅关注文本来实现的。
MatFormer 架构通常通过指数间隔的子模型进行训练,即每层包含大小分别为 S, S/2, S/4, S/8 等的子块。在训练时,输入会随机通过这些子块之一传递,使每个子块都有均等的学习机会。其优势在于,推理时如果想让模型缩小到原始大小的 1/4,你可以选择在每层使用 S/4 大小的子块。
你还可以自由组合:比如某一层选 S/4 大小的子块,另一层选 S/2,再一层选 S/8。甚至可以根据输入内容动态选择不同的子模型。 essentially 就是每一层都能自定义结构。这样一来,只需训练一个特定尺寸的模型,就能得到指数级的更小尺寸模型,学习成果毫不浪费。相当巧妙吧。💕 衷心感谢 Google Gemma 团队让我们实现了 Day 0 支持,也感谢所有使用和分享 Unsloth 的朋友,我们非常感激。🙏
和往常一样,欢迎加入我们的 Reddit 页面和 Discord 服务器获取帮助或表达支持!也可以在 Twitter 上关注我们,或订阅我们的邮件通讯。感谢阅读!Daniel & Michael Han 🦥
2025年7月1日立即微调 Gemma 3n!免费开始使用 加入我们的 Discord