为何同一BartForConditionalGeneration模型生成的两种嵌入存在差异?
BART编码器嵌入两种获取方式的差异原因及解决方法
差异原因
两种方式的核心区别在于是否经过编码器的完整编码流程:
- 第一种仅提取了初始词嵌入和位置嵌入,这只是编码器的输入层输出,完全没有经过后续的Transformer编码模块(自注意力、前馈网络、层归一化等)处理。
- 第二种是完整调用模型前向传播,得到的
encoder_last_hidden_state是初始嵌入经过编码器所有堆叠Transformer层计算后的最终隐藏状态,包含了上下文语义编码的结果。
二者处于模型计算的不同阶段,输出自然存在差异。
让差异为零的两种方法
方法一:让第一种方式模拟完整编码器流程
如果要让第一种方式得到和第二种一致的最终隐藏状态,需将初始嵌入传入编码器的完整计算流程:
# 获取初始嵌入(BART中词嵌入与位置嵌入为相加关系) embed_pos = modelBART.model.encoder.embed_positions(input_ids.input_ids) inputs_embeds = modelBART.model.encoder.embed_tokens(input_ids.input_ids) initial_embeds = inputs_embeds + embed_pos # 完整执行编码器前向计算,需传入attention mask encoder_outputs = modelBART.model.encoder( inputs_embeds=initial_embeds, attention_mask=input_ids.attention_mask ) # 此时该结果与第二种方式的output.encoder_last_hidden_state完全一致 encoder_last_hidden_state = encoder_outputs.last_hidden_state
方法二:让第二种方式仅获取初始嵌入
如果要让第二种方式得到和第一种一致的初始嵌入结果,可直接计算或通过输出隐藏状态提取:
# 方式1:直接计算初始嵌入 initial_embeds = modelBART.model.encoder.embed_tokens(input_ids.input_ids) + modelBART.model.encoder.embed_positions(input_ids.input_ids) # 方式2:通过模型输出提取初始层状态(部分模型会在初始嵌入后添加层归一化,需注意差异) output = modelBART(input_ids.input_ids, output_hidden_states=True) # encoder_hidden_states是元组,第一个元素为初始嵌入经过第一层预处理后的状态 initial_layer_hidden_state = output.encoder_hidden_states[0]
内容的提问来源于stack exchange,提问作者New_user
相关产品推荐
相关产品推荐

