运行DeepSeek R1 QWeb 7B模型时代码初始化终止问题排查
问题分析与解决
核心原因:内存/显存耗尽导致程序无预警终止
DeepSeek R1 QWeb 7B模型的FP32精度权重约占28GB内存,你的RX 6600 XT仅8GB显存,若CPU内存不足28GB,初始化模型时会直接耗尽内存,导致程序无报错直接终止,这就是只打印"1"就停的关键原因。
代码中的致命错误
除硬件资源限制外,代码本身存在两处必改问题:
- TransformerBlock依赖全局变量:在
TransformerBlock.__init__中直接调用外部config变量,而非通过参数传递,可能引发初始化时的参数读取异常。 - Model.forward语法错误:
x = self.ln_final(0,1)是完全错误的写法,且MultiheadAttention输出格式未转回适配分类头的维度,后续计算必然报错。
修复步骤
1. 适配硬件:用半精度/量化加载模型
针对你的硬件,必须用FP16半精度或INT4/INT8量化才能运行7B模型:
# 初始化模型时指定半精度 model = Model(config).half() # 加载权重时转换为半精度,减少内存占用 state_dict = {k: v.half() for k, v in state_dict.items()} model.load_state_dict(state_dict)
2. 修复代码语法问题
- 修改TransformerBlock类,将config作为参数传入:
class TransformerBlock(nn.Module): def __init__(self, embed_dim, num_heads, config, dropout=0.1): super().__init__() self.attn = nn.MultiheadAttention(embed_dim, num_heads, dropout=dropout) self.ln1 = nn.LayerNorm(embed_dim) ffn_dim = config.get("ffn_dim", 4 * embed_dim) self.ffn = nn.Sequential( nn.Linear(embed_dim, ffn_dim), nn.GELU(), nn.Linear(ffn_dim, embed_dim) ) self.ln2 = nn.LayerNorm(embed_dim) self.dropout = nn.Dropout(dropout)
对应Model类中初始化blocks的代码同步修改:
self.blocks = nn.ModuleList([ TransformerBlock(self.embed_dim, self.num_heads, config, dropout) for _ in range(self.num_layers) ])
- 修复Model.forward方法的维度与语法错误:
def forward(self, input_ids, attn_mask=None): x = self.token_embed(input_ids) seq_length = input_ids.size(1) x = x + self.pos_embed[:, :seq_length, :] x = x.transpose(0, 1) # 转换为(seq_len, batch, dim)适配MultiheadAttention for block in self.blocks: x = block(x, attn_mask) x = self.ln_final(x) x = x.transpose(0, 1) # 转回(batch, seq_len, dim)适配分类头 logits = self.head(x) return logits
3. 进一步优化显存占用
- 加载权重时避免一次性占用过多内存:
from safetensors import safe_open state_dict = {} for shard_path in ["model-00001-of-000002.safetensors", "model-00002-of-000002.safetensors"]: with safe_open(shard_path, framework="pt", device="cpu") as f: for k in f.keys(): state_dict[k] = f.get_tensor(k).half()
- 生成文本时将输入张量移至设备:
input_ids = torch.tensor([encoding.ids]).to(device)
4. 8G显存适配:INT4量化
若使用GPU,FP16半精度仍需约14GB显存,超出你的显卡容量,此时需用INT4量化,借助bitsandbytes库替换线性层:
from bitsandbytes.nn import Linear8bitLt # 修改Model类中的分类头 self.head = Linear8bitLt(self.embed_dim, self.vocab_size, bias=False) # 同步修改TransformerBlock中的Linear层
内容的提问来源于stack exchange,提问作者E Tao
相关产品推荐
相关产品推荐

