
Transformers Generate 功能介紹
--data_path Dahoas/rm-static \
--model_name_or_path bigscience/bloomz-560m \
--gradient_accumulation_steps 8 --lora_dim 128 --zero_stage $ZERO_STAGE \
--per_device_train_batch_size 8 --per_device_eval_batch_size 8 \
--deepspeed --output_dir $OUTPUT 2>&1 | tee $OUTPUT/training.log
注:以上設置顯存占用約30G, 你可以調整 per_device_train_batch_size 和 per_device_eval_batch_size 來降低顯存的使用。
模型導入可以分為三個部分:
詳細的實現細節,可以參考下面的代碼。
from utils.model.model_utils import create_hf_model
tokenizer = AutoTokenizer.from_pretrained(args.model_name_or_path,
fast_tokenizer=True)
model = create_hf_model(AutoModelForCausalLM,
args.model_name_or_path,
tokenizer,
ds_config,
disable_dropout=args.disable_dropout)
create_hf_model函數的實現代碼如下:
def create_hf_model(model_class,
model_name_or_path,
tokenizer,
ds_config=None,
rlhf_training=False,
disable_dropout=False):
model_config = AutoConfig.from_pretrained(model_name_or_path)
if disable_dropout:
model_config.dropout = 0.0
# Note: dschf is defined in function scope to avoid global effects
# https://huggingface.co/docs/transformers/main_classes/deepspeed#nontrainer-deepspeed-integration
if ds_config is not None and ds_config["zero_optimization"]["stage"] == 3:
dschf = HfDeepSpeedConfig(ds_config)
else:
dschf = None
if rlhf_training:
# the weight loading is handled by create critic model
model = model_class.from_config(model_config)
else:
model = model_class.from_pretrained(
model_name_or_path,
from_tf=bool(".ckpt" in model_name_or_path),
config=model_config)
model.config.end_token_id = tokenizer.eos_token_id
model.config.pad_token_id = model.config.eos_token_id
model.resize_token_embeddings(int(8 *math.ceil(len(tokenizer) / 8.0)))
# make the vocab size multiple of 8
return model
使用 BLOOMZ 系列模型時,不需要修改任何模型導入代碼。但在使用其他模型,例如 GLM 時,DS-Chat 無法直接導入模型,這時需要對上述代碼進行調整。
常見問題:
--per_device_train_batch_size 1 --per_device_eval_batch_size 1
--max_seq_len 255
~/.cache/huggingface/hub
目錄下model_name_or_path
為本地的路徑即可。tokenizer_config.json
和 tokenizer.json
兩個文件(DS-Chat 保存模型時,并不存儲此兩個文件)。針對大型模型的一個重要開發工作是使用特定任務的數據對模型進行進一步優化。通常情況下,使用相關任務的數據進行優化的模型會在目標任務上表現更好。在 DS-Chat 工具中使用自己的數據進行模型訓練可以分為以下三個步驟:
在準備數據之前,首先需要了解模型訓練時所需的數據格式。我們可以通過查看 raw_datasets.py 代碼來了解訓練時使用的數據格式。以下是代碼中實現的其中一種類型數據讀取的示例:
class HelloSimpleAIHC3ChineseDataset(PromptRawDataset):
def get_prompt(self, sample):
if sample['question'] is not None:
return " Human: " + sample['question'] + " Assistant:"
return None
def get_chosen(self, sample):
if sample['human_answers'][0] is not None:
return " " + sample['human_answers'][0]
return None
def get_prompt_and_chosen(self, sample):
if sample['question'] is not None and sample['human_answers'][
0] is not None:
return " Human: " + sample['question'] + " Assistant: " + sample[
'human_answers'][0]
return None
def get_rejected(self, sample):
...
def get_prompt_and_rejected(self, sample):
...
通過上面的代碼,我們可以看到,此數據中共有三種數據格式:prompt、answer、rejected,以及它們的組合:prompt+answer 和 prompt+rejected。因此,訓練數據最基本的內容是 prompt、answer 和 rejected。
然后,我們可以在 data_utils.py 文件中第 141 行的部分了解到:
LLMZoo模型中模型的訓練類似 Stage 1,所以,你需要準備的數據只需包含 prompt 和 answer 即可。
為了便于數據讀取,我對 phoenix-sft-data-v1 數據進行格式轉換,下面是其數據的 JSON 示例:
[
{
"id": "0",
"type": "Instruction",
"from_human": "假設你是一位Airbnb房主。... \n",
"from_gpt": "很抱歉,作為AI語言模型,我無法檢查您的Airbnb列表。"
},
{
"id": "1",
"type": "Instruction",
"from_human": "假設你是一位翻譯。... \n",
"from_gpt": "\"Al dente\" means cooking the ..."
}
]
其中,from_human 為 prompt,而 from_gpt 為 answer。接下來,如果你有自己的數據,就可以按照上述格式來準備數據了。
接下來,我們將介紹如何修改代碼以讀取自定義數據。DS-Chat 中提供了多種格式的數據讀取方式,你可以選擇與自己數據格式相似的數據讀取類進行修改?;蛘咧苯舆x擇其中一個格式,并按照其格式準備數據,這樣可以減少代碼修改量。
代碼修改包括(修改過程請參考視頻):
模型訓練過程中,會通過數據庫名稱,在 data_utils.py 中調用數據的讀取類,來初始化數據讀取對象。然后在 raw_datasets.py 文件中,第一次調用 load_dataset 時,load_dataset 會將 JSON 文件轉換為 arrow 格式,并緩存到 cache_dir 目錄下。在下次再次讀取數據時,會直接讀取緩存的 arrow 文件。
注意事項:
如果是使用分布式訓練時,建議先使用單 GPU 進程對數據部分進行緩存處理,因為在分布式訓練時,多進程對數據進行緩存可能會出現錯誤,尤其是在數據量比較大的情況下。
另外要注意,DS-Chat 會對數據進行第二次的本機數據緩存處理,這可能會額外占用你的硬盤存儲空間。并且這種方法在數據量比較大時,也會導致內存消耗過大的問題。目前官方正在解決中,具體信息可以參考下面的鏈接。在學習階段,你可以使用少量樣本,或者使用多 GPU 訓練的方式來緩解此問題。
https://github.com/microsoft/DeepSpeedExamples/issues/450
數據調用流程
接下來,我給出了代碼修改的過程。在修改代碼時,你可以參考以下的調用過程進行修改。
- File: step1_supervised_finetuning/main.py:
- Line 224 (train_dataset, eval_dataset = create_prompt_dataset()
- File: /training/utils/data/data_utils.py
- Line 268: train_dataset, eval_dataset = create_dataset()
- Line 212: raw_dataset = get_raw_dataset()
- Line 20:def get_raw_dataset():
return raw_datasets.Wangrui6ZhihuKOLDataset()
- File: training/utils/data/raw_datasets.py
- Line 307: class Wangrui6ZhihuKOLDataset(PromptRawDataset)
- Line 220: train_dataset = create_dataset_split()
- Line 141: if train_phase == 1:
chosen_sentence = raw_dataset.get_prompt_and_chosen()
常見問題
文章轉載自: DeepSpeed-Chat 模型與數據