prompt = system_token + "n" + system_msg + end_token + "n"
for message in example["messages"]:
if message["role"] == "user":
prompt += user_token + "n" + message["content"] + end_token + "n"
else:
prompt += assistant_token + "n" + message["content"] + end_token + "n"
return prompt
print(prepare_dialogue(sample))
<|system|>
Below is a dialogue between a human and AI assistant called StarChat.
<|end|>
<|user|>
Is it possible to imagine a society without law?<|end|>
<|assistant|>
It is difficult to imagine ...<|end|>
<|user|>
It seems like you ...<|end|>
<|assistant|>
You are correct ...<|end|>
<|user|>
Yeah, but laws are complicated ...<|end|>
这看起来是我们所需要的!下一步是将这些特殊的token纳入标记器的词汇中,所以下载StarCoder标记器并添加它们:
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("bigcode/starcoderbase")
tokenizer.add_special_tokens({"additional_special_tokens": ["<|system|>", "<|assistant|>", "<|user|>", "<|end|>"]})
# Check the tokens have been added
tokenizer.special_tokens_map
"bos_token": "<|endoftext|>",
"eos_token": "<|endoftext|>",
"unk_token": "<|endoftext|>",
"additional_special_tokens": ["<|system|>", "<|assistant|>", "<|user|>", "<|end|>"],
再检查下,看看对字符串<|assistant|>的标记是否产生一个单一的标记ID:
tokenizer("<|assistant|>")
{"input_ids": [49153], "attention_mask": [1]}
生效了!
掩码用户标签
特殊聊天标记的一个额外好处是,可以用它们来掩码每个对话的用户回合相关的标签的损失 。
这样做的原因是为了确保模型以对话的用户部分为条件,但只训练预测助手部分(这是推理过程中真正重要的) 。
下面是一个简单的函数,它将标签掩码,并将所有的用户token转换为-100,随后被损失函数忽略:
def mask_user_labels(tokenizer, labels):
user_token_id = tokenizer.convert_tokens_to_ids(user_token)
assistant_token_id = tokenizer.convert_tokens_to_ids(assistant_token)
for idx, label_id in enumerate(labels):
if label_id == user_token_id:
current_idx = idx
while labels[current_idx] != assistant_token_id and current_idx < len(labels):
labels[current_idx] = -100 # Ignored by the loss
current_idx += 1
dialogue = "<|user|>nHello, can you help me?<|end|>n<|assistant|>nSure, what can I do for you?<|end|>n"
input_ids = tokenizer(dialogue).input_ids
labels = input_ids.copy()
mask_user_labels(tokenizer, labels)
labels
[-100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, 49153, 203, 69, 513, 30, 2769, 883, 439, 745, 436, 844, 49, 49155, 203]
可以看到,所有的用户输入ID都被掩盖在标签中 。这些特殊的token有嵌入,需要在微调过程中学习 。让我们看一下其中的内容 。
用DeepSpeed ZeRO-3对StarCoder进行微调
StarCoder和StarCoderBase模型有160亿参数,这意味着需要大量的GPU vRAM来微调它们 。
例如,简单地以全FP32精度加载模型权重就需要大约60GB的vRAM:幸运的是,有几个选项可以用来处理这样的大模型:-使用像LoRA这样的参数效率技术,冻结基础模型的权重,并插入少量的可学习参数 。
-使用DeepSpeed ZeRO-3或FSDP等方法,在多个设备上分散模型权重、优化器状态和梯度 。
由于DeepSpeed紧密地集成在Transformers中,研究人员将使用它来训练模型 。为了开始,首先从GitHub上克隆BigCode的StarCoder repo,并导航到 chat 目录:
git clone https://github.com/bigcode-project/starcoder.git
cd starcoder/chat
接下来,使用例如Conda创建一个Python/ target=_blank class=infotextkey>Python虚拟环境:
conda create -n starchat python=3.10 && conda activate starchat
然后,安装PyTorch v1.13.1 。由于这与硬件有关,研究者引导到PyTorch安装页面来进行这一步 。一旦安装了它,再安装其余的项目:
推荐阅读
- windows环境mysql自动备份脚本
- SpringBoot自动装配原理
- 自动驾驶数据记录国家标准征求意见,要求记录刹车踏板状态
- Kubernetes 自动化诊断工具:K8sgpt-Operator
- 排骨越焯水越“脏”?厨师:用这两招,血水和脏东西自动跑出来
- 电气自动化就业岗位有哪些?电气自动化就业方向及前景?
- 自动化|要想当领导,从正确的推动开始
- 羽绒服为什么不能机洗 羽绒服能用全自动洗衣机洗吗
- 手机网络总是自动掉线!
- 找不到手机的时候,教你一招大喊一声,让手机自动应答