MiniOneRec 框架解析
MiniOneRec 是一个基于大语言模型的开源推荐框架,主要包含 SID 构建(RQVAE)、SFT(0.5b~7b)和 RL(受限解码 + 混合奖励)三个核心阶段。实验证明了 LLM 的 Scaling 特点,模型越大效果越好,且对齐 SID-text 对性能提升至关重要。
代码结构
SFT 训练流程
前置:数据集
- SidSFTDataset: 输入用户最近交互过的 item 列表,预测下一个交互 item。
- SidItemFeatDataset: sid2title 或 title2sid 任务。
- FusionSeqRecDataset: 带意图识别的商品推荐。
TokenExtender: SID
SID 索引示例存储在 JSON 文件中,例如 Industrial_Scientific.index.json。indices 是一个字典,如 indices["0"]=["<a_236>", "<b_231>", "<c_226>"]。函数 get_new_tokens 返回 SID 的子 token 集合。注意代码逻辑中读取的是所有实体的 SID token 集合,而非码本 token 集合,部分未见过实体可能分配给未使用的 SID 索引 token。
只对新 token 的 embedding 做训练
通过冻结所有参数,打开 embedding 参数的 requires_grad,并利用 register_hook 控制梯度保留。直接对张量切片设置 requires_grad 属性不可行,需使用 hook 将旧 vocab 部分的梯度置零。
print("Freezing LLM parameters, only training new token embeddings")
for param in model.parameters():
param.requires_grad = False
if sid_index_path and os.path.exists(sid_index_path) and new_tokens:
embedding_layer = model.get_input_embeddings()
if embedding_layer.weight.shape[0] > original_vocab_size:
embedding_layer.weight.requires_grad = True
def mask_grad(grad):
grad[:original_vocab_size].zero_()
return grad
embedding_layer.weight.register_hook(mask_grad)
print(f"Unfrozen {len(new_tokens)} new token embeddings (indices {original_vocab_size} to {(tokenizer)-})")

