赞
踩
以下是关于大模型微调课程(https://learn.deeplearning.ai/finetuning-large-language-models/lesson/1/introduction)的总结。
微调是重要的,因为它允许我们将通用型模型(例如GPT-3)专门用于特定任务或领域。可以将其类比为将全科医生变成心脏病医生或皮肤科医生。微调使我们能够向模型提供更多数据,使其能够学习和适应特定用例或领域。
以下是为什么微调很重要的原因:
提示工程涉及制定查询或提示,以指导模型的响应。虽然这是一种有用的技术,但它也有局限性:
另一方面,微调是提示的补充,并提供了多种优势:
总之,提示适用于快速和通用的用例,而微调则适用于专业化、企业级的应用,其中精度和一致性至关重要。
微调自己的LLM提供了许多好处:
预训练是微调之前的第一步,在这一步骤中,模型从完全随机的状态开始,没有关于世界的知识。
预训练的学习目标通常是下一个标记的预测,或者更简单地说,就是预测下一个词语。
在预训练期间,模型通过阅读大量的未标记数据,通常是从互联网上抓取的数据,来学习语言和知识。
这个过程通常被称为自监督学习,因为模型通过自己进行下一个标记的预测来进行训练。
预训练是资源密集且耗时的过程,需要大量的数据和计算资源。
微调是在预训练之后的步骤,用于将预训练模型定制为特定任务。
微调允许使用未标记数据或包含标签的数据,以适应不同的任务。
与预训练相比,微调需要的数据较少,因为模型在预训练期间已经获得了大量知识。
微调是将通用语言模型(LLM)转化为适用于特定应用程序的关键工具,例如聊天机器人或信息检索任务。
微调的任务通常与预训练相同,即下一个标记的预测。
数据准备涉及以下步骤:
import pandas as pd import datasets from pprint import pprint from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained("EleutherAI/pythia-70m") # 数据集读取与制作 filename = "lamini_docs.jsonl" instruction_dataset_df = pd.read_json(filename, lines=True) examples = instruction_dataset_df.to_dict() if "question" in examples and "answer" in examples: text = examples["question"][0] + examples["answer"][0] elif "instruction" in examples and "response" in examples: text = examples["instruction"][0] + examples["response"][0] elif "input" in examples and "output" in examples: text = examples["input"][0] + examples["output"][0] else: text = examples["text"][0] prompt_template = """### Question: {question} ### Answer:""" num_examples = len(examples["question"]) finetuning_dataset = [] for i in range(num_examples): question = examples["question"][i] answer = examples["answer"][i] text_with_prompt_template = prompt_template.format(question=question) finetuning_dataset.append({"question": text_with_prompt_template, "answer": answer}) from pprint import pprint print("One datapoint in the finetuning dataset:") pprint(finetuning_dataset[0])
One datapoint in the finetuning dataset:
{'answer': 'Lamini has documentation on Getting Started, Authentication, '
'Question Answer Model, Python Library, Batching, Error Handling, '
'Advanced topics, and class documentation on LLM Engine available '
'at https://lamini-ai.github.io/.',
'question': '### Question:\n'
'What are the different types of documents available in the '
'repository (e.g., installation guide, API documentation, '
"developer's guide)?\n"
'\n'
'### Answer:'}
# 定义tokenize函数 def tokenize_function(examples): if "question" in examples and "answer" in examples: text = examples["question"][0] + examples["answer"][0] elif "input" in examples and "output" in examples: text = examples["input"][0] + examples["output"][0] else: text = examples["text"][0] tokenizer.pad_token = tokenizer.eos_token tokenized_inputs = tokenizer( text, return_tensors="np", padding=True, ) max_length = min( tokenized_inputs["input_ids"].shape[1], 2048 ) tokenizer.truncation_side = "left" tokenized_inputs = tokenizer( text, return_tensors="np", truncation=True, max_length=max_length ) return tokenized_inputs
# Tokenize数据集
finetuning_dataset_loaded = datasets.load_dataset("json", data_files=filename, split="train")
tokenized_dataset = finetuning_dataset_loaded.map(
tokenize_function,
batched=True,
batch_size=1,
drop_last_batch=True
)
print(tokenized_dataset)
Dataset({
features: ['question', 'answer', 'input_ids', 'attention_mask'],
num_rows: 1400
})
tokenized_dataset = tokenized_dataset.add_column("labels", tokenized_dataset["input_ids"])
# 分割数据集
split_dataset = tokenized_dataset.train_test_split(test_size=0.1, shuffle=True, seed=123)
print(split_dataset)
# 加载模型 base_model = AutoModelForCausalLM.from_pretrained(model_name) # 设置device device_count = torch.cuda.device_count() if device_count > 0: logger.debug("Select GPU device") # 选择GPU设备 device = torch.device("cuda") else: logger.debug("Select CPU device") # 选择CPU设备 device = torch.device("cpu") base_model.to(device) # 设置步长 max_steps = 3 # 保存checkpoint路径 trained_model_name = f"lamini_docs_{max_steps}_steps" output_dir = trained_model_name # 设置训练参数 training_args = TrainingArguments( # 学习率 learning_rate=1.0e-5, # 训练周期数 num_train_epochs=1, # 最大训练步数(每一步是一个数据批次) # 如果不是-1,则会覆盖num_train_epochs max_steps=max_steps, # 训练批次大小 per_device_train_batch_size=1, # 保存模型检查点的目录 output_dir=output_dir, # 其他参数 overwrite_output_dir=False, # 覆盖输出目录的内容 disable_tqdm=False, # 禁用进度条 eval_steps=120, # 两次评估之间的更新步数 save_steps=120, # 在#步骤后保存模型 warmup_steps=1, # 学习率调度器的预热步数 per_device_eval_batch_size=1, # 评估的批次大小 evaluation_strategy="steps", logging_strategy="steps", logging_steps=1, optim="adafactor", gradient_accumulation_steps=4, gradient_checkpointing=False, # 早停止的参数 load_best_model_at_end=True, save_total_limit=1, metric_for_best_model="eval_loss", greater_is_better=False ) # model浮点操作数计算 model_flops = ( base_model.floating_point_ops( { "input_ids": torch.zeros( (1, training_config["model"]["max_length"]) ) } ) * training_args.gradient_accumulation_steps ) print(base_model) print("Memory footprint", base_model.get_memory_footprint() / 1e9, "GB") print("Flops", model_flops / 1e9, "GFLOPs") # 开始训练 trainer = Trainer( model=base_model, model_flops=model_flops, total_steps=max_steps, args=training_args, train_dataset=train_dataset, eval_dataset=test_dataset, ) training_output = trainer.train() # 模型保存 save_dir = f'{output_dir}/final' trainer.save_model(save_dir) print("Saved model to:", save_dir)
在完成模型训练之后,下一步是进行评估,查看模型的表现如何。这是非常重要的一步,因为AI的关键在于不断迭代改进。以下是有关模型评估和分析的详细总结:
这些是评估和分析模型性能的一些关键方面,对于不同的任务和用例,可能需要使用不同的评估方法和指标来确定模型的效果。
# 微调模型加载 model_name = "lamini/lamini_docs_finetuned" tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForCausalLM.from_pretrained(model_name) # 防止dropout等的影响 model.eval() # 定义评估函数,此处只定义了一个简单的评估函数 def is_exact_match(a, b): return a.strip() == b.strip() # 使用以上评估函数进行评估 n = 10 metrics = {'exact_matches': []} predictions = [] for i, item in tqdm(enumerate(test_dataset)): print("i Evaluating: " + str(item)) question = item['question'] answer = item['answer'] try: predicted_answer = inference(question, model, tokenizer) except: continue predictions.append([predicted_answer, answer]) #fixed: exact_match = is_exact_match(generated_answer, answer) exact_match = is_exact_match(predicted_answer, answer) metrics['exact_matches'].append(exact_match) if i > n and n != -1: break print('Number of exact matches: ', sum(metrics['exact_matches'])) # 将预测回答与标签对比 df = pd.DataFrame(predictions, columns=["predicted_answer", "target_answer"]) print(df) # 使用ARC benchmark进行评估 !python lm-evaluation-harness/main.py --model hf-causal --model_args pretrained=lamini/lamini_docs_finetuned --tasks arc_easy --device cpu
这些是关于模型微调和高级训练方法的关键总结。在选择模型大小、任务复杂性和硬件资源时,需要谨慎考虑,并根据实际需求采取适当的步骤和方法。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。