【Bug已解决】Error while loading MISTRAL LLM for fine-tune. Qlora doesnt work but full works 解决方案一、现象长什么样很多人微调 Mistral-7B 时会走两条路对比全参微调full和 QLoRA4-bit 量化 LoRA。诡异的是同一个模型、同一份代码full 能正常加载QLoRA 一加载就报错。常见报错有ValueError: Quantization method bitsandbytes is not supported for this model. Please check the models config and make sure it is compatible with the quantization method.或者ImportError: Using load_in_4bitTrue requires the bitsandbytes library. Please install it with pip install bitsandbytes.还有更隐蔽的加载不报错但训练一开始炸ValueError: use_cacheTrue is incompatible with gradient checkpointing. Setting use_cacheFalse will fix this.以及 bitsandbytes 装了却和 GPU 架构对不上的RuntimeError: CUDA error: no kernel image is available for execution on the device标题里那句Qlora doesnt work but full works精准描述了这种不对称——full 走的是普通 fp16 加载QLoRA 多出来的量化链路才是真正的故障点。二、背景QLoRA 4-bit 量化bitsandbytes LoRA 低秩适配。它相比 full 多出了几个关键环节BitsAndBytesConfig(load_in_4bitTrue, ...)量化配置。device_mapauto把量化层分配到 GPU。prepare_model_for_kbit_training(model)给 4-bit 层做归一化与梯度检查点预处理。量化层对use_cache、gradient_checkpointing的兼容性有额外约束。而 full 微调通常直接from_pretrained(mistralai/Mistral-7B-v0.1, torch_dtypetorch.bfloat16)不涉及量化所以这些环节都不会触发。Mistral 还有一个特点它是 decoder-only、默认use_cacheTrue用于生成时缓存 KV并且带有滑动窗口注意力。当 QLoRA 训练打开gradient_checkpointingTrue时use_cacheTrue会和它冲突——这是 Mistral 上 QLoRA 最常见的加载不报错、训练才炸的坑。三、根因根因 A环境缺bitsandbytes。QLoRA 的 4-bit 量化完全依赖bitsandbytes这个第三方 CUDA 库。full 不需要它所以正常一旦你加quantization_configBitsAndBytesConfig(load_in_4bitTrue)却没装这个包就会ImportError或ValueError: not supported。根因 Bbitsandbytes 装了但 CUDA 架构不匹配。RuntimeError: no kernel image is available说明 bitsandbytes 编译时针对的 GPU 算力如 sm75和你机器如 sm89 的 4090不一致。这种情况下import bitsandbytes可能成功但真正做 4-bit 矩阵乘时内核找不到。根因 Cuse_cacheTrue与gradient_checkpointing冲突。Mistral 默认use_cacheTrue而 QLoRA 训练几乎必然开gradient_checkpointingTrue省显存。两者互斥HF 在训练前向时抛ValueError。full 微调若没开梯度检查点就不会踩。根因 D没调用prepare_model_for_kbit_training。直接拿量化模型挂 LoRA 训练4-bit 的Linear4bit层没有为反向传播做准备会出现形状不匹配或RuntimeError: mat1 and mat2 shapes cannot be multiplied。根因 E在 CPU 上用 4-bit。有人在没有 GPU 的环境跑 QLoRAbitsandbytes 不支持 CPU直接ValueError: Quantization is only supported on GPU。四、最小可运行复现复现没装 bitsandbytes的报错from transformers import AutoModelForCausalLM, BitsAndBytesConfig import torch bnb BitsAndBytesConfig(load_in_4bitTrue) try: model AutoModelForCausalLM.from_pretrained( mistralai/Mistral-7B-v0.1, quantization_configbnb, device_mapauto, ) except Exception as e: print(type(e).__name__, str(e)[:160])复现use_cache冲突需要 GPU 量化模型这里给出触发的配置形态# 错误写法开了 gradient_checkpointing 却保留 use_cacheTrue model.gradient_checkpointing_enable() model.config.use_cache True # Mistral 默认值训练时必须改成 False # 训练第一步前向会抛 ValueError: use_cacheTrue is incompatible ...五、解决方案第一层最小直接修复第一步装对 bitsandbytes。确认 torch 的 CUDA 版本与机器一致python -c import torch; print(torch.version.cuda) pip install bitsandbytes若no kernel image报错通常是 pip 装到了预编译但不匹配你架构的 wheel可改用源码编译安装对应 CUDA 的版本或换用与你的 GPU 算力匹配的 PyTorch/CUDA 组合。第二步标准 QLoRA 加载模板。关键是prepare_model_for_kbit_training 关use_cacheimport torch from transformers import AutoModelForCausalLM, BitsAndBytesConfig, AutoTokenizer from peft import prepare_model_for_kbit_training, LoraConfig, get_peft_model bnb BitsAndBytesConfig( load_in_4bitTrue, bnb_4bit_quant_typenf4, bnb_4bit_compute_dtypetorch.bfloat16, bnb_4bit_use_double_quantTrue, ) model AutoModelForCausalLM.from_pretrained( mistralai/Mistral-7B-v0.1, quantization_configbnb, device_mapauto, torch_dtypetorch.bfloat16, ) # 关键kbit 训练预处理并处理归一化层 model prepare_model_for_kbit_training(model) model.config.use_cache False # 训练必须关缓存 lora LoraConfig( r16, lora_alpha32, lora_dropout0.05, target_modules[q_proj, v_proj], task_typeCAUSAL_LM, ) model get_peft_model(model, lora)第三步务必在训练配置里关缓存。即使你用了gradient_checkpointing_enable也要显式model.config.use_cache False否则 Mistral 的默认值会来坑你。六、解决方案第二层结构化改进把QLoRA 该不该开、量化参数、缓存开关收口成配置对象避免 full 和 QLoRA 两套代码分叉后各自踩坑。from dataclasses import dataclass, field from typing import Literal dataclass class MistralQloraLoadPolicy: model_name: str mistralai/Mistral-7B-v0.1 mode: Literal[full, qlora] qlora compute_dtype: str bfloat16 lora_r: int 16 lora_alpha: int 32 target_modules: tuple (q_proj, v_proj) use_cache: bool False def _dtype(self): return {bfloat16: __import__(torch).bfloat16, float16: __import__(torch).float16}[self.compute_dtype] def load_full(self): import torch from transformers import AutoModelForCausalLM return AutoModelForCausalLM.from_pretrained( self.model_name, torch_dtypeself._dtype()) def load_qlora(self): import torch from transformers import AutoModelForCausalLM, BitsAndBytesConfig from peft import prepare_model_for_kbit_training, LoraConfig, get_peft_model bnb BitsAndBytesConfig( load_in_4bitTrue, bnb_4bit_quant_typenf4, bnb_4bit_compute_dtypeself._dtype(), bnb_4bit_use_double_quantTrue, ) model AutoModelForCausalLM.from_pretrained( self.model_name, quantization_configbnb, device_mapauto, torch_dtypeself._dtype()) model prepare_model_for_kbit_training(model) model.config.use_cache self.use_cache lora LoraConfig( rself.lora_r, lora_alphaself.lora_alpha, target_moduleslist(self.target_modules), task_typeCAUSAL_LM) return get_peft_model(model, lora) def build(self): if self.mode qlora: return self.load_qlora() return self.load_full()切换modefull与modeqlora只改一行且 QLoRA 路径强制经prepare_model_for_kbit_training并关缓存从结构上消除了Qlora doesnt work but full works的落差。七、解决方案第三层断言 / CI 守护把QLoRA 必须 bitsandbytes 在位、缓存必须关、kbit 预处理必须做做成断言。import pytest def test_qlora_requires_bitsandbytes(policy): if policy.mode ! qlora: return try: __import__(bitsandbytes) except ImportError: pytest.fail(QLoRA 模式必须安装 bitsandbytes否则加载会报错) def test_full_does_not_need_bitsandbytes(policy): p policy.__class__(modefull) # full 模式下不应要求量化直接能 build用一个极小模型测试逻辑 assert p.mode full def test_use_cache_false_in_qlora(policy): p policy.__class__(modeqlora, use_cacheTrue) # 训练不允许开着缓存 assert p.use_cache is False or p.mode ! qlora, \ QLoRA gradient_checkpointing 时 use_cache 必须为 False def test_target_modules_non_empty(policy): assert len(policy.target_modules) 0把import bitsandbytes检查放进训练前 CI能在提交阶段就拦住换环境忘了装 bitsandbytes导致的加载失败。八、排查清单遇到 Error while loading MISTRAL LLM for fine-tune. Qlora doesnt work but full works先确认 QLoRA 与 full 的差异点QLoRA 多出的量化链路才是故障源full 正常不代表 QLoRA 配置对。ImportError: bitsandbytesQLoRA 必须装bitsandbytesfull 不用——这就是full 行、qlora 不行的直因。no kernel imagebitsandbytes 的 CUDA 架构与 GPU 不匹配重装匹配版本。use_cacheTrue is incompatibleMistral 默认开缓存QLoRA 训练必须model.config.use_cache False。务必prepare_model_for_kbit_training(model)否则 4-bit 层反向传播形状对不上。QLoRA 只能在 GPU 上跑CPU 环境直接ValueError: Quantization is only supported on GPU。统一用配置对象切换模式避免两套代码各自踩坑导致行为不一致。九、小结Mistral QLoRA 加载失败但 full 正常的本质是 QLoRA 比 full 多出来的量化环节出了问题缺bitsandbytes、bitsandbytes 与 GPU 架构不匹配、没关use_cache、漏掉prepare_model_for_kbit_training。full 因为完全不走量化所以一切正常这反而让人误以为是模型坏了。记住——QLoRA 加载必须装 bitsandbytes 用 BitsAndBytesConfig prepare_model_for_kbit_training 关 use_cache缺一不可。用MistralQloraLoadPolicy把这套约束固化full 与 qlora 切换只需改mode一个字段行为差异从根上消除。