<jupyter_start><jupyter_text>Build Your Own GPT-2 in ZH_TW這份筆記，是作為自己實作 GPT-2，並利用繁體中文語料訓練的記錄。 1. Generative Pre-trained Transformer (GPT)Generative Pretrained Transformer (GPT) 是 [OpenAI](https://openai.com/blog/better-language-models/) 開發的一個模型，是目前自然語言處理 (Natural Language Processing, NLP) 領域的 SOTA (state-of-the-art) 模型。2020 年所發表的 [GPT-3](https://en.wikipedia.org/wiki/GPT-3)，光是模型本身就包含了 175B 個參數，除了模型自動產生的文章已經與真人所寫的無異之外，在各種 NLP 的作業上也都取得了不錯的成績，甚至還有研究人員用它來解微分方程。由於 GPT-3 的模型太過龐大，也衍生出很多其他的討論，像是[這篇](https://buzzorange.com/techorange/2020/08/25/gpt-3-ai-model/)文章引用的討論，估計雲端運算的成本約1200萬美金，也預估未來這類模型只有有錢的大企業才能玩得起。本文作為實驗記錄，我們也無須砸大錢去實作 GPT-3，因此我們從有[開源的 GPT-2](https://github.com/openai/gpt-2) 開始實作，並且測試在繁體中文文本上的可行性。事實上 GPT-2 發佈以來，已經有一些簡體中文的 porting，像是：- [gpt2-chinese](https://github.com/Morizeyao/GPT2-Chinese)- [gpp2-ml](https://github.com/imcaspar/gpt2-ml)經過初步研究，OpenAI 的 GPT-2 是建立於 TensorFlow 1.4，因此上述的 repo 也是建立在相同的基礎上。而撰寫本文的現在，最新的 TensorFlow 是 2.4 版， TF 在 2.0 之後有重大的改版，所以我們可能需要從頭檢視並修改原始的模型。 Transformer ModelVaswani 等人在 2017 年提出了注意力機制和 transformer model (Vaswani et al., 2017)，改善了用 RNN 處理語言模型的幾個問題，而這個 transformer model 也是 GPT 的基礎。關於 Transformer model 的介紹，可以參考以下兩個資訊：- [The illustrated Transformer](https://jalammar.github.io/illustrated-transformer/) by <NAME>- [The Annotated Transformer](https://nlp.seas.harvard.edu/2018/04/03/attention.html) by Harvard NLP簡單的說，transformer model 是加入了 attention mechanism 的 encoder-decoder 架構，在這個測試裡，我們先直接使用 [Hugging Face](https://huggingface.co/) 提供的 GPT-2 implementation，以及自己準備的語料來訓練。  參考資料- <NAME>, 2020. [Train GPT-2 in your own language](https://towardsdatascience.com/train-gpt-2-in-your-own-language-fc6ad4d60171):A step-by-step guide to train your own GPT-2 model for text generation in your choice of language from scratch- <NAME>., <NAME>., <NAME>., <NAME>., <NAME>., <NAME>., <NAME>., & <NAME>. (2017). **Attention Is All You Need**. ArXiv:1706.03762 [Cs]. [http://arxiv.org/abs/1706.03762](http://arxiv.org/abs/1706.03762)- <NAME>., <NAME>., <NAME>., <NAME>., <NAME>., & <NAME>. (2019). **Language Models are Unsupervised Multitask Learners**. /paper/Language-Models-are-Unsupervised-Multitask-Learners-Radford-Wu/9405cc0d6169988371b2755e573cc28650d14dfe- <NAME>., <NAME>., <NAME>., <NAME>., <NAME>., <NAME>., <NAME>., <NAME>., <NAME>., <NAME>., <NAME>., <NAME>., <NAME>., <NAME>., <NAME>., <NAME>., <NAME>., <NAME>., <NAME>., … <NAME>. (2020). **Language Models are Few-Shot Learners**. ArXiv:2005.14165 [Cs]. http://arxiv.org/abs/2005.14165- [How to generate text: using different decoding methods for language generation with Transformers](https://huggingface.co/blog/how-to-generate)  中文 GPT2目前中文的 GPT-2 模型大致有幾個：- [gpt2-ml]()- [gpt2-chinese]()- [ckip-transformers](https://github.com/ckiplab/ckip-transformers)而訓練的語料目前還是以簡體居多，可以參考「[为中文自然语言处理领域发展贡献语料](https://github.com/brightmart/nlp_chinese_corpus)」：- **维基百科json版(wiki2019zh)**[Google Drive](https://drive.google.com/file/d/1EdHUZIDpgcBoSqbjlfNKJ3b1t0XIUjbt/view?usp=sharing)    - 104万个词条(1,043,224条; 原始文件大小1.6G，压缩文件519M；数据更新时间：2019.2.7)- **新闻语料json版(news2016zh)**[Google Drive](https://drive.google.com/file/d/1TMKu1FpTr6kcjWXWlQHX7YJsMfhhcVKp/view?usp=sharing)    - 250万篇新闻。新闻来源涵盖了6.3万个媒体，含标题、关键词、描述、正文。( 原始数据9G，压缩文件3.6G；新闻内容跨度：2014-2016年)- **百科类问答json版(baike2018qa)**[Google Drive](https://drive.google.com/open?id=1_vgGQZpfSxN_Ng9iTAvE7hM3Z7NVwXP2)    - 150万个问答，预先过滤过的、高质量问题和答案，每个问题属于一个类别。总共有492个类别，其中频率达到或超过10次的类别有434个。( 原始数据1G多，压缩文件663M；数据更新时间：2018年)- **社区问答json版(webtext2019zh)**[Google Drive](https://drive.google.com/open?id=1u2yW_XohbYL2YAK6Bzc5XrngHstQTf0v)    - 410万个问答( 过滤后数据3.7G，压缩文件1.7G；数据跨度：2015-2016年)    - 含有410万个预先过滤过的、高质量问题和回复。每个问题属于一个【话题】，总共有2.8万个各式话题，话题包罗万象。    - 从1400万个原始问答中，筛选出至少获得3个点赞以上的的答案，代表了回复的内容比较不错或有趣，从而获得高质量的数据集。    - 除了对每个问题对应一个话题、问题的描述、一个或多个回复外，每个回复还带有点赞数、回复ID、回复者的标签。    - 数据集划分：数据去重并分成三个部分。训练集：412万；验证集：6.8万；测试集a：6.8万；测试集b，不提供下载。  測試 HuggingFace transformers在建立自己的 GPT-2 模型之前，我們先用別人已經訓練好的中文模型來試試看。我們以 HuggingFace + CKIP 的 transformers 來測試，在測試之前需要確認安裝的套件：- transformers- pytorch- gensim<jupyter_code>from transformers import BertTokenizerFast, AutoModelForCausalLM

tokenizer = BertTokenizerFast.from_pretrained('bert-base-chinese')
model = AutoModelForCausalLM.from_pretrained('ckiplab/gpt2-base-chinese')

seed_str='今天天氣很好，我想出門去玩，'
input_ids = tokenizer.encode(seed_str, return_tensors='pt')


generated = model.generate(input_ids, 
                            max_length=150,  
                            num_return_sequences=5,
                            no_repeat_ngram_size=2,
                            repetition_penalty=1.5,
                            top_p=0.92,
                            temperature=.85,
                            do_sample=True,
                            top_k=125,
                            early_stopping=True)
output=[]
for i in range(5):
    text = tokenizer.decode(generated[i], 
            skip_special_tokens= True)          # Decode the generated text
    text = text.replace(' ','')                 # Remove spaces between tokens
    trial = {'id':i+1, 'text': text}
    print(text)
    output.append(trial)

import pandas as pd
print(pd.DataFrame(output))<jupyter_output>Setting `pad_token_id` to `eos_token_id`:102 for open-end generation.<jupyter_text>看起來是可以運作的，接下來我們就進一步訓練自己的 GPT-2模型。<jupyter_code>pd.DataFrame(output).to_csv('../workspace/byogpt2_01_generated_text.csv', index=False)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1470316256704272, 'fraction_numerical': 0.05770297762160163, 'mean_word_length': 4.639207507820647, 'pattern_counts': {'":': 0, '<': 44, '<?xml version=': 0, '>': 44, 'https://': 17, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '323161', 'license': 'CC0-1.0', 'n_tokens_mistral': 2933, 'n_tokens_neox': 2967, 'n_words': 303, 'path': 'notebooks/BYOGPT2_01_Introduction.ipynb', 'repo_name': 'tingsyo/gpt2-zhtw', 'size': '5544'}