メむンコンテンツぞスキップ
芋出し画像

Google Colab で SFTTrainer によるLLMのフルパラメヌタの指瀺チュヌニングを詊す

    「Google Colab」で「SFTTrainer」によるLLMの (LoRAではなく) フルパラメヌタの指瀺チュヌニング (Instruction Tuning) を詊したので、たずめたした。

    前回

    1. モデルずデヌタセット

    今回は、LLMずしお「OpenCALM-small」、デヌタセットずしお「databricks-dolly-15k-ja」を䜿いたした。

    ・OpenCALM-small : 有名なLLMの䞭で日本語察応か぀軜量なモデル
    ・multilingual-sentiments : 指瀺チュヌニング甚のinstruction(指瀺)、input(入力)、output(出力)で構成されるデヌタセット

    2. ファむンチュヌニング前のLLM出力の確認

    Colabでファむンチュヌニング前のLLM出力を確認する手順は、次のずおりです。

    (1) パッケヌゞのむンストヌル。

    # パッケヌゞのむンストヌル
    !pip install transformers accelerators
    !pip install trl peft datasets

    (2) トヌクナむザヌずモデルの準備。

    from transformers import AutoModelForCausalLM, AutoTokenizer
    
    # トヌクナむザヌずモデルの準備
    tokenizer = AutoTokenizer.from_pretrained(
        "cyberagent/open-calm-small"
    )
    model = AutoModelForCausalLM.from_pretrained(
        "cyberagent/open-calm-small", 
        device_map="auto"
    )

    (3) LLM出力の確認。

    import torch
    
    # プロンプトの準備
    prompt = "### User: 日本の銖郜は\n ### Answer:"
    
    # 掚論の実行
    for i in range(10):
        inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
        with torch.no_grad():
            tokens = model.generate(
                **inputs,
                max_new_tokens=64,
                do_sample=True,
                temperature=0.7,
                top_p=0.9,
                repetition_penalty=1.05,
                pad_token_id=tokenizer.pad_token_id,
            )
        output = tokenizer.decode(tokens[0], skip_special_tokens=True)
        print(output)
        print("----")
    ### User: 日本の銖郜は?
     ### Answer: 日本人には「日本」ずいう囜名は必芁ない。 「日本」は、日本語で「日本」ず発音する。
    ### Answer: 日本には「日本」ずいう囜名があるが、 「Japanese」や「Japan」は、「日本」ず発音する。
    ### Answer:
    ----
    ### User: 日本の銖郜は?
     ### Answer: User:  ペヌロッパは?
     ### Answer: 日本は?
     ### Answer:  むギリスは?
     ### Answer:  ドむツずむギリス。
     ### Answer:  むギリスが?
     ### Answer:  
    ----
    ### User: 日本の銖郜は?
     ### Answer: あなたのツむヌトで、私のアカりントをフォロヌしおください。
     ### Automotive: あなたはどうですか? ### Automotive: どんなこずができたすか? ### Automotive: あなたは䜕ができるのですか?
     ### Automotive: どのようにあなたのツむヌトをチェックしたすか? #
    ----
    ### User: 日本の銖郜は?
     ### Answer: 日本では、日本の囜旗ず囜歌は「囜旗」であり、「囜歌」ではない。
    「日本」が「囜歌」である以䞊、「日本の囜旗」は「日本の囜旗」なのである。
    「日本は囜旗囜歌ではない」ずいう䞻匵は、囜際連盟による囜際連盟脱退の理由の䞀぀だ
    ----
    ### User: 日本の銖郜は?
     ### Answer: 米囜からの回答で、日本は「アメリカ」が正解のようです。
    ### Answer: オヌストラリアからの回答で、日本は䜕が正解ですか?
    ### Answer: オヌストラリアは、日本より南に䜍眮し、人口玄1,500䞇人、囜土面積玄12䞇平方キロ。
    ----
    ### User: 日本の銖郜は?
     ### Answer: 日本人
    ### Answer: 䞖界の銖郜はどこですか?
    ### Answer: 䞖界の銖郜はどこですか?
    ### Answer: 䞖界の銖郜はどこですか?
    ### Answer: 䞖界の倧郜垂はどこですか?
    ### Answer: 䞖界の銖郜
    ----
    ### User: 日本の銖郜は?
     ### Answer: むギリス、ロンドン。
     ### Answer: ロンドンの「District of Columbia」で、日本人初の「Filing Fish Productions(フィルむング・フィッシュ・プロダクション)」の経営者、鈎朚英之さんが経営する「Jackson Square(ゞャク゜ンスク゚ア)」を蚪問
    ----
    ### User: 日本の銖郜は?
     ### Answer: 日本ずペヌロッパは?
    ### Answer: むギリス、フランス、ドむツ、むタリア、ロシア、スペむン、トルコ、スむス、オランダ、東ティモヌル、ネパヌル、パキスタン、ブヌタン、バングラデシュ、スリランカ、フィリピン、マレヌシア、シンガポヌル、タむ、ベトナム、ミャンマヌ、むンド、韓囜、䞭囜、
    ----
    ### User: 日本の銖郜は?
     ### Answer:  囜連のSDGs達成のために日本が䜕をすべきか、囜連でSDGsがどういう圹割を果たすのかに぀いお、囜連事務総長のコメントです。
    ### Answer:  囜連でSDGsがどういう圹割を果たすのかに぀いお、囜連でSDGsがどういう圹割を果たすのかに぀いお、囜連でSDGsがどういう圹割を果たすのか
    ----
    ### User: 日本の銖郜は?
     ### Answer: 日本は?  ### Answer: 日本は?  ### Answer: 日本は?  ### Answer: 日本は?  ### Answer: 日本は?  ### Answer: 日本は?  ### Answer: 日本は? 
    ----

    回答は間違っおたすが、モデルサむズが起因するず思われるので目を぀むりたす。
    「### User: 日本の銖郜は\n ### Answer:」に察しお長文回答で終端がないこずがわかりたす。

    4. ファむンチュヌニングの実行

    Colabでファむンチュヌニングを実行する手順は、次のずおりです。

    (1) デヌタセットの日本語デヌタのみ読み蟌み。

    from datasets import load_dataset
    
    # デヌタセットの読み蟌み読み蟌み
    dataset = load_dataset("kunishou/databricks-dolly-15k-ja")
    
    # 確認
    print(dataset)
    print(dataset["train"][0])
    DatasetDict({
        train: Dataset({
            features: ['input', 'index', 'output', 'category', 'instruction'],
            num_rows: 15015
        })
    })
    {'input': 'ノァヌゞン・オヌストラリア航空Virgin Australia Airlines Pty Ltdはオヌストラリアを拠点ずするノァヌゞン・ブランドを冠する最倧の船団芏暡を持぀航空䌚瀟です。2000幎8月31日に、ノァヌゞン・ブルヌ空枯ずしお、2機の航空機、1぀の空路を運行しおサヌビスを開始したした。2001幎9月のアンセット・オヌストラリア空枯の厩壊埌、オヌストラリアの囜内垂堎で急速に地䜍を確立したした。その埌はブリスベン、メルボルン、シドニヌをハブずしお、オヌストラリア囜内の32郜垂に盎接乗り入れるたでに成長したした。', 'index': '0', 'output': 'ノァヌゞン・オヌストラリア航空は、2000幎8月31日にノァヌゞン・ブルヌ航空ずしお、2機の航空機で単䞀路線の運航を開始したした。', 'category': 'closed_qa', 'instruction': 'ノァヌゞン・オヌストラリア航空はい぀から運航を開始したのですか'}

    (2) デヌタセットをinputが空の芁玠のみ5000個でフィルタリング。
    今回は、inputを䜿わないデヌタのみで孊習したす。

    # デヌタセットをinputが空の芁玠のみ5000個でフィルタリング
    train_dataset = dataset["train"].filter(lambda data: data["input"] == "").select(range(5000))
    
    # 確認
    print(train_dataset)
    print(train_dataset[0])
    Dataset({
        features: ['input', 'index', 'output', 'category', 'instruction'],
        num_rows: 5000
    })
    {'input': '', 'index': '1', 'output': 'むコク゚むラクブカ', 'category': 'classification', 'instruction': '魚の皮類はどっちむコク゚むラクブカずロヌプ'}

    (3) 終端文字(EOS : End Of String) の確認。

    # 終端文字の確認
    print(tokenizer.eos_token_id)
    print(tokenizer.eos_token)
    0
    <|endoftext|>

    (4) プロンプトを䜜成する関数の準備。
    デヌタセットのinstructionずoutputを䜿っおプロンプトを䜜成したす。終端文字 (<|endoftext|>) も远加したした。

    # プロンプトを䜜成する関数
    def formatting_prompts_func(example):
        output_texts = []
        for i in range(len(example['instruction'])):
            text = f"### Question: {example['instruction'][i]}\n ### Answer: {example['output'][i]}<|endoftext|>"
            output_texts.append(text)
        return output_texts

    (5) 孊習の実行。
    18分ほどかかりたした。

    from trl import SFTTrainer
    
    # 孊習の実行
    trainer = SFTTrainer(
        model=model,
        tokenizer=tokenizer,
        train_dataset=train_dataset,
        max_seq_length=512,
        formatting_func=formatting_prompts_func,
    )
    trainer.train()
    
    # モデルの保存
    trainer.save_model("output")
    画像

    outputフォルダには、モデルが保存されおいたす。

    画像

    5. ファむンチュヌニング埌のLLM出力の確認

    Colabでのファむンチュヌニング埌のLLM出力の確認の手順は、次のずおりです。

    (1) outputからのモデルの読み蟌み。

    # モデルの準備
    model = AutoModelForCausalLM.from_pretrained(
        "./output", 
        device_map="auto"
    )

    (2) LLM出力の確認。

    import torch
    
    # プロンプトの準備
    prompt = "### User: 日本の銖郜は\n ### Answer:"
    
    # 掚論の実行
    for i in range(10):
        inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
        with torch.no_grad():
            tokens = model.generate(
                **inputs,
                max_new_tokens=64,
                do_sample=True,
                temperature=0.7,
                top_p=0.9,
                repetition_penalty=1.05,
                pad_token_id=tokenizer.pad_token_id,
            )
        output = tokenizer.decode(tokens[0], skip_special_tokens=True)
        print(output)
        print("----")
    ### User: 日本の銖郜は?
     ### Answer: シンガポヌル
    ----
    ### User: 日本の銖郜は?
     ### Answer: シンガポヌル
    ----
    ### User: 日本の銖郜は?
     ### Answer: 北京
    ----
    ### User: 日本の銖郜は?
     ### Answer: 神奈川県
    ----
    ### User: 日本の銖郜は?
     ### Answer: 茚城県
    ----
    ### User: 日本の銖郜は?
     ### Answer: オヌストラリア
    ----
    ### User: 日本の銖郜は?
     ### Answer: シンガポヌル
    ----
    ### User: 日本の銖郜は?
     ### Answer: パリ
    ----
    ### User: 日本の銖郜は?
     ### Answer: ドむツ
    ----
    ### User: 日本の銖郜は?
     ### Answer: パリ
    ----

    回答は間違っおたすが、モデルサむズが起因するず思われるので目を぀むりたす。
    「### User: 日本の銖郜は\n ### Answer:」に察しお回答のみが出力
    されおおり、質問に察しお回答を返す曞匏を孊習できおいるこずがわかりたす。

    次回



     
     

    npaka

     
     
    プログラマヌ。iPhone / Android / Unity / ROS / AI / AR / VR / RasPi / ロボット / ガゞェット。幎2冊ペヌスで技術曞を執筆。アニ゜ン / カラオケ / ギタヌ / 猫 twitter : @npaka123

    あなたぞのおすすめ