BLOOM: A 176B-Parameter Open-Access Multilingual Language Model
贡献者: bigsicence -HuggingFace
发表时间:2022.7
BLOOM是一个仅有解码器的Transformer语言模型,它是在ROOTS语料库上训练出来的,该数据集包括46种自然语言和13种编程语言(共59种)的数百个来源。我们发现,BLOOM在各种基准上取得了有竞争力的性能,在经历了多任务提示的微调后,其结果更加强大。
特点:
ALiBi位置嵌入
虽然ALiBi最初的动机是它能够推理出更长的序列,但我们发现它也导致了更平滑的训练和更好的下游性能,即使是在原始序列的长度上--超过了学习(Vaswani等人,2017)和旋转(Su等人,2021)嵌入的表现。
ALiBi不会在词嵌入中添加位置嵌入;相反,它会使用与其距离成比例的惩罚来偏向查询键的注意力评分。
我们还用 AliBi 替换了普通的位置嵌入,它允许外推比训练模型的输入序列更长的输入序列。因此,即使我们训练时使用长度为 2048 的序列,模型也可以在推理过程中处理更长的序列。
该方法在长度为1024的输入序列上训练了13亿个参数模型,并将其外推到长度为2048的输入序列,实现了与在长度为2048的输入上训练的正弦位置嵌入模型相同的困惑度,但训练速度提高了11%,并且减少了11%的内存
代码
BloomForCausalLM模型,它利用Transformer模型进行前向传播,并通过线性层生成语言
self.transformer 和 self.lm_head:self.transformer 是BloomForCausalLM模型中的一个成员变量,它代表一个BloomModel(推测是Transformer模型);self.lm_head 是一个线性层(Linear Layer),用于将模型的隐藏状态映射到字典大小的输出空间,用于生成预测结果。
transformer_outputs = self.transformer(...):这行代码调用了self.transformer 模型的前向传播方法,并将输入参数传递给它。返回的transformer_outputs包含了模型的隐藏状态。
lm_logits = self.lm_head(hidden_states):这行代码将模型的隐藏状态输入到线性层 self.lm_head 中,得到语言模型的logits值。对于语言模型而言,logits是每个词可能出现的分数值。
损失函数和计算损失:如果标签(labels)不为空,则计算损失函数。其中 shift_logits 是经过移位处理后的logits值,用于预测下一个令牌;shift_labels 是移位标签,即去掉了第一个标签的真实标签。然后使用交叉熵损失函数(CrossEntropyLoss)计算shift_logits 和 shift_labels 之间的损失。
返回结果:根据是否需要返回字典(return_dict),将损失和其他输出组合成一个元组作为函数的返回结果。最终返回的结果可以是损失、lm_logits 和其他一些可选的输出值。
预测代码:
class BloomForCausalLM(BloomPreTrainedModel):
_keys_to_ignore_on_load_missing = [r"h.*.self_attention.scale_mask_softmax.causal_mask", r"lm_head.weight"]
def __init__(self, config: BloomConfig):
super().__init__(config)
self.transformer = BloomModel(config)
self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
# Initialize weights and apply final processing
self.post_init()
def forward( ):
transformer_outputs = self.transformer(
input_ids,
past_key_values=past_key_values,
attention_mask=attention_mask,
head_mask=head_mask,
inputs_embeds=inputs_embeds,
use_cache=use_cache,
output_attentions=output_attentions,
output_hidden_states=output_hidden_states,
return_dict=return_dict,
)
hidden_states = transformer_outputs[0]
lm_logits = self.lm_head(hidden_states)
loss = None
if labels is not None:
# Shift so that tokens < n predict n input 去掉最后边一位
shift_logits = lm_logits[..., :-1, :].contiguous()
shift_labels = labels[..., 1:].contiguous() # label去掉最前面一位
batch_size, seq_length, vocab_size = shift_logits.shape
# Flatten the tokens
loss_fct = CrossEntropyLoss()
loss = loss_fct(
shift_logits.view(batch_size * seq_length, vocab_size), shift_labels.view(batch_size * seq_length)
)
# output: 好吗?<eos>
# input: 你好吗?
if not return_dict:
output = (lm_logits,) + transformer_outputs[1:]
return ((loss,) + output) if loss is not None else output
model = AutoModelForCausalLM.from_pretrained(model_path)
model.generate(input_ids=input_ids, max_length=1024, do_sample=False, temprature=False)