IndexError: index out of range in self:BERT 先查 token ID 与 embedding 表大小

简介: 该文详解 `IndexError: index out of range in self` 在 `F.embedding` 中的根因:token ID 越界。强调优先检查输入 ID 范围、嵌入表行数(`num_embeddings`)、位置/类型表限制,而非误调标签;指出 tokenizer 与模型需配套,新增 special tokens 必须调用 `resize_token_embeddings()` 并同步保存,禁用取模等掩盖语义的错误修复。(239字)

原帖的堆栈落在 F.embedding,而不是分类损失;因此应优先检查输入编号与嵌入表:

IndexError: index out of range in self

同一句 IndexError,要从 embedding 堆栈选对象

原题调用 BERT 时堆栈落在 embedding,优先核对 token ID,而不是先把分类 labels 降到某个范围。BERT 内还有词、位置、类型等不同嵌入表;词表范围合法后,仍需按完整堆栈继续缩小到具体那一张表。

在调用 BERT 前,检查实际 token ID、词表大小和序列长度。b_input_ids 是原题当前批输入,model 是正在训练的模型:

embedding = model.get_input_embeddings()
print("josh050608")
print("ids:", b_input_ids.shape, b_input_ids.dtype)
print("range:", b_input_ids.min().item(), b_input_ids.max().item())
print("embedding rows:", embedding.num_embeddings)
print("max positions:", getattr(model.config, "max_position_embeddings", None))

token ID 必须非负且小于输入 embedding 行数。若 tokenizer 与模型来自不同 checkpoint,改用配套 tokenizer;不要通过取模、截断 ID 等方法让越界消失,这会改变词义。

如果项目确实新增了 special tokens,先完成 tokenizer 的添加,再调用 model.resize_token_embeddings(len(tokenizer)),并在建立优化器前完成模型调整。保存模型时同时保存 tokenizer。仅更改 config.vocab_size 不会自动重建已有权重。

若 token 范围正常,继续从完整堆栈区分是词、位置还是 token_type embedding:检查序列是否超过位置表范围,手工 position_ids/token_type_ids 是否越界。原题传 token_type_ids=None,不应凭错误名就认定类别标签越界。

在 CPU 上对同一失败批次重跑有助于获得明确索引错误。修复后先完成一个 batch 前向,再验证 loss/backward;若用了新增 token,确认对应 embedding 已进入训练参数。原帖没有 tokenizer 和模型来源,无法确认具体是哪张表越界。

用小词表重现边界,并验证修复含义

下面是合成 Embedding 例子:有 5 行时合法编号为 0–4,编号 5 会越界。它不下载 BERT,也不冒充原题 tokenizer:

import torch
from torch import nn
table = nn.Embedding(5, 3)
good_ids = torch.tensor([[0, 4]], dtype=torch.long)
assert table(good_ids).shape == (1, 2, 3)
bad_ids = torch.tensor([[0, 5]], dtype=torch.long)
print("rows/range:", table.num_embeddings, bad_ids.min().item(), bad_ids.max().item())
try:
    table(bad_ids)
except IndexError as exc:
    print("out of table:", exc)

真实模型中若发现最大 token ID 大于等于 embedding 行数,先问它来自哪里。用错 tokenizer 应换配套版本;确实新增 token 才应扩展嵌入表。新增后的行需要训练,不是扩大维数后就自动具备语义。

若词 ID 正常,检查序列长度与 max_position_embeddings;手工 position_ids 的最大值也必须在表内。token_type_ids 的取值范围由模型类型表决定,不是任意句子编号。不要拿 token 词表大小去验证位置或类型编号。

新增 token 后在建立优化器前调整模型,保存时连同 tokenizer 一起保存,重载时检查两者长度与参数行数。验收使用同一失败批次先在 CPU 前向,再验证 loss/backward 和保存重载;取模或截断 token ID 可能消除越界,却把词义替换成了别的 token。

参考:原始求助帖;技术依据:Embedding(2.5)、Transformers BERT(4.46)、Transformers Tokenizer(4.46)。

相关文章
|
2天前
|
缓存 Unix PyTorch
OSError: [Errno 24] Too many open files:两个 DataLoader 可以 zip,先查文件描述符
原帖双Loader并发读取ZIP导致“Too many open files”(Errno 24),实为文件描述符泄漏或生命周期管理不当,非ZIP不支持DataLoader。需排查Dataset中图像/HDF5/ZIP句柄是否及时释放,并优先采用单Loader配对Dataset保障数据一致性与资源可控性。(239字)
|
1天前
|
并行计算 PyTorch 算法框架/工具
Expected all tensors to be on the same device, cuda:0 and cpu:恢复训练时检查 SGD 动量
该问题源于断点续训时优化器状态(如SGD动量缓冲区)未与模型参数同设备,导致`optimizer.step()`中跨设备张量运算失败。前向/反向可正常执行,但动量更新报错“cuda:0 and cpu”。需检查并统一`param`、`grad`及`optimizer.state`中所有Tensor的设备。
|
2天前
|
并行计算 PyTorch Linux
libtorch_python.so: cannot open shared object file:文件缺失时先修复 torch 安装
该问题核心是 PyTorch 1.0.1.post2 安装不完整,`torch/lib/` 下缺失关键文件 `libtorch_python.so`,非环境变量(LD_LIBRARY_PATH)可解决。需先用 `importlib.util.find_spec` 定位真实安装路径,核对文件存在性;再通过 `pip show -f torch` 验证分发完整性。切勿混用版本或复制库文件。
|
1天前
|
并行计算 PyTorch Linux
RuntimeError: CUDA error: device-side assert triggered:Colab 先重启,再找首次断言
该文详解CUDA断言错误调试策略:强调先重启运行时、启用`CUDA_LAUNCH_BLOCKING=1`,用最小张量验证环境;区分“会话已坏”与新操作触发,主张逐段定位而非臆测标签越界,提供实用边界检查函数与验证流程。(239字)
|
1天前
|
并行计算 PyTorch 异构计算
can’t convert CUDA tensor to numpy:只取分类索引时直接用 torch.argmax
原帖因直接对CUDA张量调用`.data.numpy().argmax()`报错:“无法将CUDA张量转为NumPy”。正确做法是:在GPU上用`output.argmax(dim=1).item()`获取单图预测索引,避免全量拷贝,仅传回标量,高效且安全。(239字)
|
1天前
|
PyTorch 算法框架/工具 索引
ValueError: only one element tensors can be converted to Python scalars:张量列表先检查形状,再 stack
该文解析PyTorch中`list(tensor)`引发的`ValueError`根源:列表含多元素张量时,不可直接转Python标量。强调应通过`tensor.shape`或遍历打印各张量尺寸来查形状;同形张量用`torch.stack`(增维)而非`cat`或`item`;异形则保留原结构,避免强行转换。
|
2天前
|
数据可视化 PyTorch 算法框架/工具
only batches of spatial targets supported:三通道分割 one-hot 转为每像素类别编号
该报错源于PyTorch交叉熵要求标签为`[N, H, W]`(3D),但输入了`[N, 3, H, W]`(4D)掩码。需先验证三通道是否为互斥one-hot,再用`argmax(dim=1)`转为整型标签,并妥善处理全零未标注像素(设`ignore_index`),避免误判为背景类。(239字)
|
1天前
|
PyTorch 算法框架/工具 异构计算
Expected object of scalar type Float but got scalar type Double for argument #4 'mat1':NumPy 输入与 Linear 权重怎样统一类型
PyTorch中`RuntimeError: Expected Float but got Double`常因输入Tensor(float64)与模型权重(float32)类型不一致导致。关键在第一层Linear的输入与权重dtype需统一:可将数据转为float32(推荐),或模型整体升为float64。务必检查`tensor.dtype`而非数值显示,并确保`loss.backward()`前类型已对齐。(239字)
|
1天前
|
机器学习/深度学习 索引
The size of tensor a (133) must match tensor b (10):分类任务换 MSELoss 后先查标签含义
原帖网络输出133类logits,CrossEntropyLoss支持类别索引输入(如`[10]`),而MSELoss要求`outputs`与`target`形状严格匹配(如`[10,133]`)。报错因`target`为`[10]`,无法广播匹配`[10,133]`输出,本质是两类损失对标签格式约定不同。
|
1天前
|
PyTorch 算法框架/工具 索引
RuntimeError: expected scalar type Long but found Float:NLLLoss 要改 labels,不要把 images 转 long
该问题源于`NLLLoss`要求标签为`torch.long`类型(类别索引),但输入为`float`。需确保标签是整数编号(非概率/小数),并在`DataLoader`中统一配对图像与标签,避免双Loader错位;推荐改用`CrossEntropyLoss`配原始logits,或`LogSoftmax+NLLLoss`组合。(239字)

热门文章

最新文章