秒杀自动编码Copilot!「动嘴编程」神器StarChat开源,码农狂喜( 四 )

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 addedtokenizer.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 = idxwhile labels[current_idx] != assistant_token_id and current_idx < len(labels):labels[current_idx] = -100 # Ignored by the losscurrent_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_idslabels = 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.gitcd starcoder/chat 
接下来,使用例如Conda创建一个Python/ target=_blank class=infotextkey>Python虚拟环境:
conda create -n starchat python=3.10 && conda activate starchat
然后,安装PyTorch v1.13.1 。由于这与硬件有关,研究者引导到PyTorch安装页面来进行这一步 。一旦安装了它,再安装其余的项目:


推荐阅读