You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于T5模型编码、修改句嵌入并解码为文本?

问题描述

我是NLP领域新手,希望对句嵌入执行向量操作(如在给定句子的均匀球内进行嵌入空间随机化)并解码。目前尝试使用T5与Huggingface Transformers,步骤如下:

  • 用T5Tokenizer编码文本;
  • 通过model.encoder前向传播,取last hidden state作为嵌入(曾尝试.generate,但无法分离编码器与解码器);
  • 对嵌入执行所需操作;
  • 问题步骤:将嵌入传入model.decoder并通过tokenizer解码。

我在步骤4遇到问题:将步骤3设为无操作时,输出文本与输入不一致。我感觉遗漏了关键环节(比如缺少beam search等生成方法),也不确定步骤2中的嵌入是否正确。请问如何基于T5编码句嵌入、在向量空间修改后解码为生成文本?是否有更合适的模型?

以下是问题代码:

t5_model = transformers.T5ForConditionalGeneration.from_pretrained("t5-large")
t5_tok = transformers.T5Tokenizer.from_pretrained("t5-large")
text = "Foo bar is typing some words."
input_ids = t5_tok(text, return_tensors="pt").input_ids
encoder_output_vectors = t5_model.encoder(input_ids, return_dict=True).last_hidden_state
# The rest is what I think is problematic:
decoder_input_ids = t5_tok("<pad>", return_tensors="pt", add_special_tokens=False).input_ids
decoder_output = t5_model.decoder(decoder_input_ids, encoder_hidden_states=encoder_output_vectors)
t5_tok.decode(decoder_output.last_hidden_state[0].softmax(0).argmax(1))
解决方案

一、核心问题分析

你的解码逻辑存在两个关键错误:

  1. T5的解码是自回归生成过程,不能仅传单个<pad>token就直接硬解码,需要逐步生成每个token并关联编码器输出的注意力信息;
  2. 你取的last_hidden_state是所有输入token的嵌入,若要句嵌入通常取序列末尾的</s>标记对应的输出,而非整个序列的hidden state。

二、修正后的完整流程

1. 正确获取编码器输出(含句嵌入)

import torch
from transformers import T5ForConditionalGeneration, T5Tokenizer

t5_model = T5ForConditionalGeneration.from_pretrained("t5-large")
t5_tok = T5Tokenizer.from_pretrained("t5-large")
text = "Foo bar is typing some words."

# 编码文本,添加padding和截断保证格式合规
inputs = t5_tok(text, return_tensors="pt", padding=True, truncation=True)
encoder_outputs = t5_model.encoder(**inputs, return_dict=True)

# 可选:获取句嵌入(取</s>对应的hidden state)
sentence_embedding = encoder_outputs.last_hidden_state[:, -1, :].unsqueeze(1)

# 保留所有token的嵌入,这里可添加你的向量操作(比如随机扰动)
modified_encoder_hidden = encoder_outputs.last_hidden_state

2. 正确解码生成文本

方法一:用generate方法(推荐,自带搜索策略)

利用模型内置的generate接口,直接传入修改后的编码器输出,支持贪婪搜索、beam search等策略:

# 构造generate所需的encoder_outputs结构
custom_encoder_outputs = (modified_encoder_hidden,) + encoder_outputs[1:]

# 调用生成,配置解码参数
generated_ids = t5_model.generate(
    encoder_outputs=custom_encoder_outputs,
    decoder_start_token_id=t5_tok.pad_token_id,
    max_length=50,
    num_beams=5,  # beam search提升生成质量
    early_stopping=True
)

# 解码并跳过特殊标记
generated_text = t5_tok.decode(generated_ids[0], skip_special_tokens=True)
print(generated_text)  # 无修改时输出应与输入一致

方法二:手动自回归解码(适合调试)

手动模拟自回归生成过程,逐token预测:

decoder_input_ids = torch.tensor([[t5_tok.pad_token_id]], dtype=torch.long)
generated_tokens = []

for _ in range(50):
    decoder_outputs = t5_model.decoder(
        input_ids=decoder_input_ids,
        encoder_hidden_states=modified_encoder_hidden,
        encoder_attention_mask=inputs["attention_mask"]
    )
    # 取最后一个token的logits预测下一个token
    next_token_logits = decoder_outputs.last_hidden_state[:, -1, :]
    next_token_id = torch.argmax(next_token_logits, dim=-1).item()
    
    if next_token_id == t5_tok.eos_token_id:
        break
    generated_tokens.append(next_token_id)
    decoder_input_ids = torch.cat([decoder_input_ids, torch.tensor([[next_token_id]])], dim=1)

generated_text = t5_tok.decode(generated_tokens, skip_special_tokens=True)
print(generated_text)

三、模型选择建议

  • T5/BART:这类seq2seq模型是最优选择,encoder-decoder结构天然支持编码-修改嵌入-解码的流程,且有成熟的生成接口;
  • Encoder-only模型(如BERT):不适合,这类模型没有解码器,无法直接从嵌入还原文本,需额外训练解码器,成本较高。

内容的提问来源于stack exchange,提问作者jmindel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 03:40:21