致力于创造一个属于你的不二咲千寻。项目处于初期阶段。
An ongoing (fast prototyping) project to create your own doppelgänger based on your Twitter archive and LoRA models.
在我十年前玩某个叫做《弹丸论破》的游戏的时候,有一位可爱的……后来她挂了,但是她以数字生命的形式帮助了未来的主人公冲出难关。如果我死了,还有人记得我吗?
该项目目前基于ChatGLM+LoRa,暂时致力于生成中文内容。也希望该项目能帮助到一些使用中文语料库进行prompt engineering以及内容生成的朋友。
Inspired by Fujisaki Chihiro (i.e., Alter Ego). I thought it would be a fun project, as I really cannot predict my death in the future, and I would like to see how my doppelgänger would react to the world. Thank to the super-strong LLM and LoRA to make it happen by allowing fine-tuning on small corpora.
将你的Twitter存档目录解压缩放置在项目根目录下,即可自动处理。相关的程序会根据推文的内容、时间、引用、回复等信息,生成一个instruction风格的JSON数据集。然后,我们将该数据集用于某种中文语言模型的调参,生成新的推文,或启用给予上下文的对话。
目前项目的文字生成能力很优秀,问答一般,不过在推文涵盖的范围内能够识别一定的问题。对话功能也因为推文都是陈述句受到一定限制,但是因为ChatGLM本身有一定的对话能力,我们还是可以信赖它可以生成一定的人话的。
优秀训练数据的生成是本项目的最终目的,目前的实现均在prompt.py
中,也已经引入OpenAI生成更有价值的增广上下文。
HuggingFace Hub(慢一点的在线版本,可以直接运行):
将Colab笔记本中的peft_path
改为你自己训练的模型(可以是一个本地文件夹,或者是一个HuggingFace Repo),就可以复现你自己训练后的版本了。
相对于索引、问答目的的项目,该项目会更大程度上利用Sampling,即相似的上下文也会生成非常不一样的回答。希望这样的生成方法能够提供更高的互动性。
- Modify the twitter-parser to output your twitter archive into a instruction dataset
- Categorized in-reply-to and quoted tweets for better conditional generation
- LoRA finetuning with multiple GPUs
- Basic prompt engineering for original posts
- Hyperparameter tuning (incl. LoRA rank, batch size, learning rate, etc.)
- Allow in-reply-to tweets to be downloaded.
- Advanced prompt engineering from OpenAI
- Colab notebook for easy deployment (I believe this code can surely run on T4 as we are expecting much shortened tokens)
- Download quoted tweets.
- Support other datasets (e.g. Reddit, Weibo, etc. Future plan, let's discuss in #2 .)
推荐使用 conda
环境。安装依赖:
pip install -r requirements.txt
有些时候,你可能要安装cudatoolkit:
conda install cudatoolkit=11.3
如果使用4090需要安装11.8的版本。s
可以帮助解决bitsandbytes检测不到CUDA runtime的问题。准备好环境之后不要忘记将config.example.py
重命名为config.py
,并且修改其中的参数(如有必要)。
解压缩你的推文存档,放置在项目根目录下,即可自动处理。解压缩之后你应该能在项目根目录里面看到Your archive.html
这个文件。然后,运行twitter-parser.py
来解析你的推文存档,生成一个RLHF风格的JSON数据集。
同样的,你可以参考tweets_sample.md
来生成你自己的数据集,或者等待项目更新。
目前的模型基于ChatGLM+LoRa,与Luotuo的处理方式较为类似。
首先使用
python twitter-parser.py
来处理推文存档,稍许等待之后,你会在项目根目录下看到一个tweets.md
的文件。这个文件包含了你的推文存档中的所有推文,以及相关的信息。为了保护你的隐私,请不要公开该文件。
生成相应的数据之后,我们需要进一步调用ChatGLM的tokenizer
来生成对应的tokenized数据集。这一步需要一些时间。这个原始的版本会过度cache同一个generator导致数据无法更新,我改了一个单文件的版本。
python ./tokenize_dataset_rows.py --json_path ./tweets.md --save_path tweets.tokens --max_seq_length 240
(可选)使用240个token是因为我的大部份推文,连同instruction一起,也不会超过240个token。如果你的推文较长,可以在生成jsonl之后调用length.py
,根据输出的数据适当增加max_seq_length
的数值。
python3 ./cover_alpaca2jsonl.py --data_path tweets.md --save_path tweets.jsonl
python length.py
因为推文存档中的推文并不储存上下文信息,所以我们可以通过抓取回复推文来获得原始的上下文信息,来实现非常强的对话功能。这一步需要一些时间,但是只需要运行一次。
很不幸,抓取网站总是一个很痛苦的事情。你可能需要一个代理池,以及将chromedriver
的二进制放在项目根目录中(需要你了解selenium)。你可能还需要一台性能足够强的电脑,以便多线程抓取回复信息。如果你有这样的条件,可以调整config.py
,将PARSE_REPLIES = False
改为PARSE_REPLIES = True
,然后运行twitter-parser.py
。该部分已经写好。
该方法无法抓取已经被删除的你的,和别人的推文。抓取引用推文的功能也尚在检讨中。
调用OpenAI API为你的原创推文生成一个问题,或者前情提要,以提供更顺畅的问答体验。该部分已经写好,需要你使用OpenAI API Key。价格稍显昂贵,每一万条推文需要准备2-3刀的预算。请填写config.py以配置相应内容,并参照prompt_openai.py
查看实现方式。
接下来便可调用finetune.py
来进行模型训练。根据不同的GPU数量,你可以直接调用
WORLD_SIZE=4 CUDA_VISIBLE_DEVICES=0,1,2,3 torchrun --nproc_per_node=4 \
--master_port=1234 \
finetune.py \
--dataset_path tweets.tokens \
--lora_rank 8 \
--per_device_train_batch_size 8 \
--gradient_accumulation_steps 1 \
--num_train_epoch 2 \
--save_steps 2000 \
--save_total_limit 2 \
--learning_rate 6e-4 \
--remove_unused_columns false \
--logging_steps 50 \
--output_dir output \
--ddp_find_unused_parameters false \
--warmup_steps 50
进行多卡训练。如果多卡训练报错,可能再跑一遍就好了,是一个小的缓存bug。
单卡训练:
python finetune.py \
--dataset_path tweets.tokens \
--lora_rank 8 \
--per_device_train_batch_size 8 \
--gradient_accumulation_steps 1 \
--num_train_epoch 2 \
--save_steps 2000 \
--save_total_limit 2 \
--learning_rate 2e-4 \
--remove_unused_columns false \
--logging_steps 50 \
--output_dir output \
--warmup_steps 100
目前的参数和ChatGLM+LoRa很类似,不过可以根据GPU数量调节学习率。默认的学习率是2e-4
(每8个sample,如果loss突增可能还要降一些),请根据batch size和显卡能力自行测试调节。上游增加了gradient checkpointing之后3090甚至可以用到8的batch size了,体验非常好。LoRA的rank可以根据你希望的模型性能进行调节,默认的8是足够的,你也可以提升到12甚至更高,经过一定的测试lora_rank
上到16结果会上升一个台阶,代价是稍微更长一点的训练和测试时间,但是不会多很多。
训练好的模型会保存在output
文件夹下,你可以在output/
中找到对应的模型文件。
调用 infer.py
进行对话。你可以输入任何问题(因为是推文的原因,输入陈述句的效果比疑问句好),不过即便什么都不输入也可以生成一个很类似我的推文。
python3 ./infer.py <path_to_model>
可以在该文件中调节top-p,top-k和temerature,以便生成更多的样本。可以根据gradio demo的结果适当调节。
在1张A100的配置下面,训练一个75,000条推文的数据集,在设定最大长度为240的情况下,每一个epoch需要3小时。训练大概需要2-3个epoch能够达成最佳状态。
This project is based on the following projects:
27182812/ChatGLM-chinese-insturct
timhutton/twitter-archive-parser
LC1332/Chinese-alpaca-lora (Donated❤️)
Inspired by the following projects:
tloen/alpaca-lora
HuggingFace: KBlueLeaf/guanaco-7B-lora-embed
(potentially) twint-fork