
Mistral 等基于 Transformer 的大语言模型,其 embed_tokens 层仅接受 torch.Tensor 类型的 token ID 序列(整数索引),不支持 BatchEncoding 或 Python 列表;正确做法是在调用 tokenizer 时显式指定 return_tensors='pt'。
mistral 等基于 transformer 的大语言模型,其 `embed_tokens` 层仅接受 `torch.tensor` 类型的 token id 序列(整数索引),不支持 `batchencoding` 或 python 列表;正确做法是在调用 tokenizer 时显式指定 `return_tensors='pt'`。
在使用 Mistral-7B 等 Hugging Face 格式的大语言模型进行底层特征提取(如获取词嵌入向量)时,一个常见误区是直接将 tokenizer(text) 的输出传入 model.model.embed_tokens。实际上,AutoTokenizer.__call__() 默认返回的是 BatchEncoding 对象(一个字典式容器),而 PyTorch 的 nn.Embedding 层严格要求输入为 一维或二维的 torch.LongTensor,其元素必须是合法的词汇表索引(即 0 ≤ idx
例如,以下写法均会报错:
# ❌ 错误:传入 BatchEncoding 对象
model.model.embed_tokens(tokenizer("Hello world"))
# ❌ 错误:input_ids 是 Python list,非 Tensor
model.model.embed_tokens(tokenizer("Hello world").input_ids)根本原因在于:nn.Embedding 的 forward 方法签名是 forward(input: LongTensor) → Tensor,其中 input 必须是 torch.long 类型的张量,且维度通常为 (seq_len,) 或 (batch_size, seq_len)。
✅ 正确做法是:在 tokenizer 调用中启用张量化输出,通过参数 return_tensors="pt" 让其直接返回 torch.Tensor:
# ✅ 正确:一步到位获得 torch.Tensor 类型的 input_ids
inputs = tokenizer("Hello world", return_tensors="pt")
embedded = model.model.embed_tokens(inputs.input_ids) # shape: [1, seq_len, hidden_size]
print(f"Input IDs shape: {inputs.input_ids.shape}") # e.g., torch.Size([1, 4])
print(f"Embedding shape: {embedded.shape}") # e.g., torch.Size([1, 4, 4096])? 补充说明:Mistral-7B 的词表大小为 32000,嵌入维度为 4096,因此 model.model.embed_tokens 是一个 nn.Embedding(32000, 4096) 实例。确保 input_ids 中无越界值(如 -1 或 ≥32000),否则会触发 IndexError。
? 进阶提示:若需批量处理多条文本并保持梯度可导(如微调中自定义 embedding 层),推荐使用 padding=True 和 truncation=True 统一序列长度:
texts = ["Hello world", "How are you?", "Mistral is powerful"]
batch = tokenizer(
texts,
return_tensors="pt",
padding=True,
truncation=True,
max_length=512
).to(model.device) # 移动至模型所在设备(如 'cuda')
embedded_batch = model.model.embed_tokens(batch.input_ids)
# embedded_batch.shape → [3, padded_seq_len, 4096]⚠️ 注意事项:
- return_tensors="pt" 是必需的;"np"(NumPy)或 "tf"(TensorFlow)格式仍需额外转换,无法被 nn.Embedding 直接接收;
- 若模型使用了 4-bit 量化(如 BitsAndBytesConfig),embed_tokens 层本身不会被量化(默认保持 bfloat16 或 float16),但输入 input_ids 仍需为 torch.long;
- 不要手动调用 tokenizer.encode() 后再 torch.tensor(...) —— 虽然可行,但冗余且易忽略设备放置(如未 .to(model.device) 可能导致跨设备错误);
- tokenizer.pad_token = tokenizer.eos_token 等配置不影响 embed_tokens 输入类型,仅影响填充逻辑。
总结:tokenizer(..., return_tensors="pt") 是对接 model.model.embed_tokens 的标准、安全且高效的方式。它消除了手动类型转换的出错风险,并天然兼容批处理、设备迁移与训练流程,是 LLM 底层特征工程的必备实践。

















