Homework 1

作业一:LLM实现与微调

本次作业中,你将自己实现LLM全流程的代码,包括tokenizer,decoder-only transformer,data processing,training loop,LoRA fine-tuning。提交内容包括完整代码和实验报告。作业中有很多讨论你的观察和思考的题目,不需要很卷写得很长,把重点写出即可。在完成这些作业的基础上,鼓励自行探索,如果你能有一些创新的想法、观察、改进,可以在报告中写清楚并高亮出来,可以考虑加分(总分不超过30分)。本次作业有一定工作量,建议尽早开始做

作业资料在这里下载。

作业提交

你的提交里应该至少包含如下的文件结构:

.
├── hw1-code
│   ├── bpe
│   ├── pretrain
│   └── finetune
└── 学号-姓名-hw1.pdf

其中,hw1-code中应包含三个部分作业完整的代码内容,不要提交训练保存的模型、pycache、数据等等hw1-code/pretrain中应该有.git,包含你这部分的git commit记录。学号-姓名-hw1.pdf中按顺序、条理清晰地把各部分作业的实验报告写出,要求结构清晰、易于理解和寻找,对每一个给分点你都要在实验报告中呈现你的完成情况。同时,由于实验报告中你会呈现代码,需要确保代码易于阅读,建议使用markdown,如果使用word或者latex要把高亮做好。整个文件夹打包成“学号-姓名-hw1.zip”,在教学网上提交。

1. Tokenization (10分)

预估时间:5小时。

作业目的

熟悉Tokenization的作用,原理,以及可能导致的问题;完成BPE算法的代码实现,并在给定文本上训练Tokenizer。

算力要求

这部分可以在CPU上运行。

学习资料

以下是一些可以参考的资料:

1.1 实现BPE,训练Tokenizer(6分)

请根据老师上课所讲内容,结合上面列出的参考资料,自己实现一个基于BPE算法的tokenizer并训练,具体任务如下:

  • 【1分】在实验报告中简要概述一下BPE算法和基于BPE算法训练LLM tokenizer的流程。
  • 【2分】实现一个基于BPE算法的tokenizer,它的主要接口如下:
class Tokenizer:
    def __init__(self):
        pass

    def train(self, text, vocab_size):
        """
        Train the tokenizer using BPE algorithm.
        Params:
            text (str): string-type data used to run BPE.
            vocab_size (int): the size of final vocabulary.

        Return:
            None
        """
        pass

    def encode(self, text):
        """
        Encode the input string into a token list.
        Params:
            text (str): data to be tokenized.

        Return:
            ids (list): list of integer-type tokens.
        """
        pass

    def decode(self, ids):
        """
        Decode a token list into a string.
        Params:
            ids (list): list of integer-type tokens.

        Return:
            text (str): string-type data.
        """
        pass

除此以外,你可以实现你需要的工具函数。不可以使用tiktoken, sentencepiece, transformers一类封装好的tokenizer库。 讲解一下你的实现。

  • 【1分】hw1-code/bpe/manual.txt是《北京大学研究生手册(2023版)》中提取出来的文字,请你用它来训练你的tokenizer,vocab_size为1024。
  • 【1分】用它来encode再decode manual.txt,检查与原始manual.txt是否完全一致?
  • 【1分】学习使用huggingface transformers中的tokenizer,使用它加载GPT-2的tokenizer,然后使用它和你训练的tokenizer分别encode以下句子,比较两者的输出,简要解释长度上和具体token上不同的原因是什么。
    • 句子一:“Originated as the Imperial University of Peking in 1898, Peking University was China’s first national comprehensive university and the supreme education authority at the time. Since the founding of the People’s Republic of China in 1949, it has developed into a comprehensive university with fundamental education and research in both humanities and science. The reform and opening-up of China in 1978 has ushered in a new era for the University unseen in history. And its merger with Beijing Medical University in 2000 has geared itself up for all-round and vibrant growth in such fields as science, engineering, medicine, agriculture, humanities and social sciences. Supported by the “211 Project” and the “985 Project”, the University has made remarkable achievements, such as optimizing disciplines, cultivating talents, recruiting high-caliber teachers, as well as teaching and scientific research, which paves the way for a world-class university.”
    • 句子二:“博士学位论文应当表明作者具有独立从事科学研究工作的能力,并在科学或专门技术上做出创造性的成果。博士学位论文或摘要,应当在答辩前三个月印送有关单位,并经同行评议。学位授予单位应当聘请两位与论文有关学科的专家评阅论文,其中一位应当是外单位的专家。评阅人应当对论文写详细的学术评语,供论文答辩委员会参考。”

1.2 回答问题(4分)

在你的实验报告中回答下列问题(每个问题0.5分,答对8个即得满分):

  • Python中使用什么函数查看字符的Unicode,什么函数将Unicode转换成字符?并使用它们查看“北”“大”的Unicode,查看Unicode为22823、27169、22411对应的字符。
  • Tokenizer的vocab size大和小分别有什么好处和坏处?
  • 为什么 LLM 不能处理非常简单的字符串操作任务,比如反转字符串?
  • 为什么 LLM 在非英语语言(例如日语)上表现较差?
  • 为什么 LLM 在简单算术问题上表现不好?
  • 为什么 GPT-2 在编写 Python 代码时遇到比预期更多的困难?
  • 为什么 LLM 遇到字符串 “<|endoftext|>” 时会突然中断?
  • 为什么当问 LLM 关于 “SolidGoldMagikarp” 的问题时 LLM 会崩溃?
  • 为什么在使用 LLM 时应该更倾向于使用 YAML 而不是 JSON?
  • 为什么 LLM 实际上不是端到端的语言建模?

建议参考Let’s build the GPT Tokenizer

2. LLM Implementation (10分)

预估时间:10小时。

作业目的

理解LLM工作原理,熟悉以GPT-2为代表的autoregressive LLM / decoder-only transformer的代码实现和常见优化,能够自己从零实现LLM训练全流程代码。

算力要求

这部分作业不要求大家实际运行。

学习资料

以下是一些可以参考的资料:

作业内容

学习Andrej Karparthy的Let’s reproduce GPT-2 (124M)教程,你要按照他的代码自己复现一遍GPT-2及其优化,并分步git commit代码,可以参考build-nanogpt的commit记录。撰写实验报告记录实现的全过程和知识点。由于算力有限,这部分作业不要求大家实际运行。注意学习体会Andrej Karparthy的代码思路和逐步开发一个完整项目的方法。

给分点:

  • 【3分】完整代码,路径为hw1-code/pretrain,要求有完整的git commit记录,每个commit以“[你的学号]”开头,例如“[2200000001] initial commit”。只需要覆盖Karparthy视频教程中讲过的所有代码即可。git commit记录截图放到实验报告中。
  • 【7分】实验报告,记录跟学实现的整个过程,每一个commit实现了什么,起到了什么作用,你的学习笔记等等。Section1 3分,Section2 2分,Section3和Section4 2分。

3. LoRA Fine-tuning (10分)

预估时间:10小时。

作业目的

学习使用huggingface的transformers库,自己动手实现LoRA,在Alpaca数据集上完成基于LoRA的Instruction Fine-tuning。

算力要求

这部分作业可以在单张T5 GPU上运行。助教已提供colab代码,该代码使用500M的模型在 noob123/imdb_review_3000 数据集上训练。下载代码

学习资料

以下是一些可以参考的资料:

作业内容

  1. 下载代码,在colab、本机、或自己常用的计算平台上运行代码。
  2. 使用原始的数据集完成首次训练,调试lora超参数,根据训练曲线和模型生成结果,分析lora超参数对于模型效果的影响。
  3. 修改训练数据集为Alpaca数据集,并使用LoRA进行微调。
  4. 在实验报告中记录你的运行结果,包括训练loss曲线,以及使用训练好的模型生成的一些输出。

得分点如下:

  1. 【1分】完整地运行代码,提交运行记录(即保留你运行记录的ipynb文件)
  2. 【2分】使用原始的数据集完成首次训练,提交训练loss曲线和模型生成结果
  3. 【3分】结合上课所学lora知识,调试lora超参数,根据训练曲线和模型生成结果,分析lora超参数对于模型效果的影响。
  4. 【2分】基于先前的最优超参数,修改训练数据集为Alpaca数据集,并使用LoRA进行微调。
  5. 【2分】基于Alpaca数据集调试lora超参数,判断两个数据集对应的超参数是否有差异,并尝试分析原因。

注意事项

  1. 助教在colab上运行过原始代码,并初步检验微调后模型的生成能力,更换为alpaca数据集后,若模型无法正常输出或生成乱码,可以自行尝试使用其他小模型训练,例如GPT-2。
  2. 本次作业主要考察同学们能否在作业中实践课程中所学的知识,通过调试参数、分析结果来印证理论。因此模型生成结果的优劣不是本次作业的评分标准,充实详细的分析才是得分的关键。
Previous