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数据集上完成GPT-2 124M基于LoRA的Instruction Fine-tuning。

算力要求

这部分作业可以在单张GeForce RTX 4090上运行。算力资源见AliCloud Student Signup

学习资料

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

作业内容

hw1-code/finetune下面给出的代码实现了GPT-2 124M模型在Alpaca数据集上全参数微调的完整流程,并给出了LoRA的框架。你需要把lora.py里面的TODO都补充完整得到LoRA的完整实现,并测试LoRA rank为1,2,4,8,16,32时的loss曲线,并generate一些输出看看效果。在实验报告中讨论你得到的结果。训练的参数可以随意尝试和调整。

在这个作业中你需要用到GPT-2 124M模型,由于huggingface下载网络容易不稳定,你可以考虑提前下载下来,然后从本地路径中加载。下载可以使用hf-mirror

数据下载:

cd hw1-code/finetune
mkdir -p data
wget https://raw.githubusercontent.com/tatsu-lab/stanford_alpaca/refs/heads/main/alpaca_data.json -O data/alpaca_data.json

环境构建:

conda create -n llm python=3.10
conda activate llm
pip install torch transformers matplotlib

运行train.sh开始训练,运行generate.sh用训练好的模型生成对generate.py中每一条instruction的回复。参数、generate.py中的instruction你都可以尝试修改。

给分点:

  • 【1分】直接使用train.sh运行现有代码,进行全参数微调,并使用generate.sh生成回复。
  • 【4分】把lora.py里面的TODO都补充完整,并在实验报告中讲解你的实现。
  • 【3分】使用train.sh进行LoRA微调,并使用generate.sh生成回复。测试LoRA rank为1,2,4,8,16,32时的效果,在实验报告中讨论。现在提供的画图函数对当次训练绘制了学习曲线,你完全可以实现你自己的画图函数,在一张图中展现不同rank的结果。
  • 【2分】比较原始预训练GPT-2,全参数微调的GPT-2,LoRA微调的GPT-2的回复,并讨论你的观察。

Acknowledgement

hw1-code/finetune的代码基于stanford_alpacaSafe-RLHFbuild-nanogptDeepSpeedPanacea

Previous
Next