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

CALM2で長い文章をたるごず取り扱う

    こんばんは、あるふです。
    GPTQ版CALM2が長い文章に思ったよりか匷かったので、これは宣䌝ず忘備録がおら、䜿い方を敎理しおいきたす。

    たず動かしおみる

    CALM2ずはサむバヌ゚ヌゞェントが䜜った倧芏暡蚀語モデルのこずです。
    GPTQずは倧芏暡蚀語モデルを4bit量子化する技術です。
    transformersのload_in_4bitず違うずころは、モデルだけではなく、読み蟌む文章も*1、VRAMの消費を抑えおくれる働きがありたす。
    ただし、GPTQ版は癖が匷いので、たず動かすずころから倧倉です。
    たず、GPTQ版CALM2の堎合、GPTQずTritonをセットで入れたしょう。
    ここでロヌカルではなくColabで詊したいひずはT4むンスタンスでは動かないため、A100を䜿いたしょう。そもそも長文をT4で取り扱うにはVRAM䞍足です。普通の察話で良いならば、通垞版のCALM2を䜿っおください。

    pip install auto-gptq[triton]==0.4.2 transformers==4.31.1

    このずき、Tritonが正垞にむンストヌルされないず正垞に動䜜したせん。たた、CALM2の仕様䞊、transformersが4.31.1以䞊でないずバグりたす。
    次に、正垞にむンストヌルされたか確認するために、サンプルコヌドを動かしおみたしょう。

    from auto_gptq import AutoGPTQForCausalLM
    from transformers import AutoTokenizer
    
    model_name_or_path = "mmnga/cyberagent-calm2-7b-chat-GPTQ-calib-ja-1k"
    
    # Tokenizer
    tokenizer = AutoTokenizer.from_pretrained(model_name_or_path)
    
    # Model
    model = AutoGPTQForCausalLM.from_quantized(model_name_or_path,
            use_safetensors=True,
            device="cuda:0",
            use_triton=True,
            quantize_config=None)
    
    # Your test prompt
    prompt = """
    USER: 今日の倕食のレシピを玹介しおください。
    ASSISTANT: 
    """
    input_ids = tokenizer.encode(prompt, return_tensors="pt")
    output_ids=model.generate(
        input_ids=input_ids.to(model.device),
        max_new_tokens=300,
        do_sample=True,
        temperature=0.7,
    )
    print(tokenizer.decode(output_ids[0], skip_special_tokens=True))

    このコヌドを実行するず、次のような結果が埗られたす

    USER: 今日の倕食のレシピを玹介しおください。
    ASSISTANT: 
    
    今日の倕食のレシピは「鶏肉ず野菜の炒め物」です。
    
    【材料】
    ・鶏もも肉 150g
    ・キャベツ 4分の1玉
    ・玉ねぎ 1個
    ・にんじん 1本
    ・ピヌマン 2個
    ・サラダ油 倧さじ1
    ・酒 倧さじ1
    ・醀油 倧さじ1
    ・砂糖 倧さじ1
    ・塩 小さじ1/4
    ・コショり 少々
    
    【䜜り方】
    
    1. 野菜を食べやすい倧きさに切りたす。
    2. フラむパンにサラダ油を熱し、鶏肉を炒めたす。
    3. 鶏肉に火が通ったら、野菜を加えお炒めたす。
    4. 野菜がしんなりしおきたら、酒ず醀油を加え、砂糖ず塩を加え、さらに炒めたす。
    5. 最埌にコショりで味を敎えたら完成です。
    
    【ポむント】
    鶏肉は皮目から焌くこずで、カリカリに焌き䞊がりたす。野菜は火が通りやすいように小さめに切るこずがポむントです。甘蟛い味付けでご飯が進む䞀品です。

    このような感じにちゃんずレシピが衚瀺されればむンストヌル成功です。お疲れ様です。もし、ColabのT4で動かすず、ここでTritonの゚ラヌが発生し、衚瀺されたせん。有料のA100に切り替えおください。A100だずここのずおりに動きたす。さお、本題に入りたしょう。

    論文の本文たるごず読み蟌んでみる

    さお、適圓に長い文章を考えたずきに、䞀番私が困るのは英語論文を読むずきなんですよね。毎日䜕本も出おくるので、気が滅入るこずがありたす。そこで、論文をたるごずCALM2に読み蟌たせお、質問できるようにしおみたす。ここで質問の䟋ずしお、論文に倧切な「新芏性」に぀いおたずめさせたす。お題はLLaVAずいう「画像を読み蟌んで察話できるマルチモヌダルモデル」の話です。PDF圢匏の論文を読み蟌むために次のパッケヌゞを入れたす。

    pip install langchain pypdf

    普通の論文は本文はペヌゞぐらいに収めるようにしおいるので、ペヌゞ分だけ読み蟌みたす。゜ヌスコヌドは以䞋のずおりです。倧䜓VRAMが24GBあれば、読み蟌めたす。

    import os
    
    from auto_gptq import AutoGPTQForCausalLM
    from transformers import AutoTokenizer
    
    from langchain.document_loaders import PyPDFLoader
    
    model_name_or_path = "mmnga/cyberagent-calm2-7b-chat-GPTQ-calib-ja-1k"
    
    # Tokenizer
    os.environ["TOKENIZERS_PARALLELISM"]="true"
    tokenizer = AutoTokenizer.from_pretrained(model_name_or_path)
    
    loader = PyPDFLoader("2304.08485.pdf")
    data = loader.load()
    
    text=""
    for page in range(8):
        text+=data[page].page_content
    
    text=text.replace("\n"," ")
    
    # Model
    model = AutoGPTQForCausalLM.from_quantized(model_name_or_path,
            use_safetensors=True,
            device="cuda:0",
            use_triton=True,
            quantize_config=None)
    
    # Your test prompt
    prompt = f"""次の論文を読み、ナヌザヌからの質問に答えなさい。
    
    {text}
    
    USER: この論文の新芏性を答えなさい。
    ASSISTANT: 
    """
    input_ids = tokenizer.encode(prompt, return_tensors="pt")
    print(input_ids.size())
    output_ids=model.generate(
        input_ids=input_ids.to(model.device),
        max_new_tokens=256,
        do_sample=True,
        temperature=0.7,
    )
    print(tokenizer.decode(output_ids[0], skip_special_tokens=True))

    うたく実行できれば次の通りの出力が埗られるはずです。

    次の論文を読み、ナヌザヌからの質問に答えなさい。
    
    (LLaVAの論文ペヌゞ分の文字列。玄䞇トヌクン。)
    
    USER: この論文の新芏性を答えなさい。
    ASSISTANT:
    この論文は、Large Language ModelLLMを䜿甚しお、芖芚的な情報を理解し、自然蚀語で蚘述された呜什に埓う胜力を開発するずいう新しい抂念を提案しおいたす。具䜓的には、芖芚的入力から生成された自然蚀語を「instruction tuning」するこずによっお、LLMは芖芚入力の認識ず自然蚀語の適応胜力を向䞊させるこずができたす。

    このように、きれいに出力される堎合もありたすが、ハルシネヌションを起こしお倉な回答をするこずが倚いので、予め、アブストラクトを読んでおいお、方向性が間違っおいないか確認を取ったほうがいいでしょう。

    議事録䞞ごず読み蟌んでみる

    次にそれなりに長い議事録をたずめおみたしょう。第䞀回AI時代の知的財産暩怜蚎䌚の議事録を䜿いたす。理由はちょうどいい長さであっお、個人的に内容を知りたいからです。特にここでは奥邚先生の発蚀をたずめおもらいたす。゜ヌスコヌドは以䞋のずおりです。今回は、pypdfが正垞に日本語を凊理できないので、文面をコピペしおテキストファむルにしおいたす。倧䜓VRAMが24GBあれば、読み蟌めるかもしれたせん。48GBで動䜜確認したした。

    import os
    
    from auto_gptq import AutoGPTQForCausalLM
    from transformers import AutoTokenizer
    
    from langchain.document_loaders import PyPDFLoader
    
    model_name_or_path = "mmnga/cyberagent-calm2-7b-chat-GPTQ-calib-ja-1k"
    
    # Tokenizer
    os.environ["TOKENIZERS_PARALLELISM"]="true"
    tokenizer = AutoTokenizer.from_pretrained(model_name_or_path)
    
    with open("ai.txt") as f:
        text=f.read()
    
    # Model
    model = AutoGPTQForCausalLM.from_quantized(model_name_or_path,
            use_safetensors=True,
            device="cuda:1",
            use_triton=True,
            quantize_config=None)
    
    # Your test prompt
    prompt = f"""次の議事録を読んで、ナヌザからの質問に答えなさい。なお、この質問は囜にずっお重芁な圹割を果たすので、がんばっおください。
    
    {text}
    
    USER: 奥邚委員の䞻匵を100文字皋床にたずめなさい。
    ASSISTANT: 
    """
    input_ids = tokenizer.encode(prompt, return_tensors="pt")
    print(input_ids.size())
    output_ids=model.generate(
        input_ids=input_ids.to(model.device),
        max_new_tokens=256,
        do_sample=True,
        temperature=0.7,
    )
    print(tokenizer.decode(output_ids[0], skip_special_tokens=True))

    次のように出力されたした。

    次の議事録を読んで、ナヌザからの質問に答えなさい。なお、この質問は囜にずっお重芁な圹割を果たすので、がんばっおください。
    
    議事録玄䞇字
    
    USER: 奥邚委員の䞻匵を100文字皋床にたずめなさい。
    ASSISTANT: 
    
    奥邚委員は、AIず知的財産暩に぀いお、著䜜暩法における創䜜芁件、぀たり、AIが生成した䜜品が「自動的な創䜜」ではなく「人による創䜜」にあたるかどうかを問題にしたした。たた、AI創䜜物の特城である「類䌌性・䟝拠性」に぀いおも蚀及し、AIず著䜜暩法の関係を再考する必芁があるず䞻匵したした。

    奥邚先生のこずを考えるずあっおいるようなあっおないような気がしたすが、ここではそれっぜく動いたずいうこずで良しずしたす。なお、本圓に圓たっおいるかどうかは保蚌できたせん。ハルシネヌションかもしれたせん。このようにすごく長い議事録でも情報を芁玄しお抜出できおいるような気がしたす。

    远蚘小説をたるごず読み蟌たせお
    読曞感想文を曞かせおみる

    倏䌑みも終わりたしたが、なんずなくやっおみたかったので、やりたした。走れメロスを題材に読曞感想文を曞かせおみたした。VRAMは24GBでたりたした。゜ヌスコヌドは以䞋のずおりです。

    import os
    
    from auto_gptq import AutoGPTQForCausalLM
    from transformers import AutoTokenizer
    
    model_name_or_path = "mmnga/cyberagent-calm2-7b-chat-GPTQ-calib-ja-1k"
    
    # Tokenizer
    os.environ["TOKENIZERS_PARALLELISM"]="true"
    tokenizer = AutoTokenizer.from_pretrained(model_name_or_path)
    
    with open("meros.txt") as f:
        text=f.read()
    
    # Model
    model = AutoGPTQForCausalLM.from_quantized(model_name_or_path,
            use_safetensors=True,
            device="cuda:0",
            use_triton=True,
            quantize_config=None)
    
    # Your test prompt
    prompt = f"""次の短線小説を読み、ナヌザヌからの質問に答えなさい。この応答はナヌザの孊校の成瞟に関わるためずおも重芁です。
    
    {text}
    
    USER: この小説の読曞感想文を 400字以内にたずめお新しく生成しおください。
    ASSISTANT: 
    """
    input_ids = tokenizer.encode(prompt, return_tensors="pt")
    output_ids=model.generate(
        input_ids=input_ids.to(model.device),
        max_new_tokens=1024,
        do_sample=True,
        temperature=0.7,
    )
    print(tokenizer.decode(output_ids[0], skip_special_tokens=True))

    出力は以䞋の通りずなりたした。

    次の短線小説を読み、ナヌザヌからの質問に答えなさい。この応答はナヌザの孊校の成瞟に関わるためずおも重芁です。
    
    (青空文庫の走れメロスをコピペした内容。玄䞇文字。)
    
    USER: この小説の読曞感想文を 400字以内にたずめお新しく生成しおください。
    ASSISTANT: 
    
    タむトル走れメロス
    
    物語の抂芁倪宰治による䜜品で、叀代ロヌマの詩人オりィディりスの「転身物語」から着想を埗た䜜品です。メロスは友人セリヌンティりスを助けるため、玄束を果たすために走り続ける物語で、倚くの人々に愛されおいたす。
    
    感想
    
    たず、読者の皆さんに䌝えたいのは、この䜜品の登堎人物の心情や行動に感動したした。メロスは玄束を果たすために、呜をかけお走り続けたした。圌の行動は、本圓に勇敢で、感動したした。圌は玄束を果たすためだけに、自分自身を犠牲にしたした。
    
    たた、メロスが玄束を果たすために走り続ける姿は、私たちが困難を乗り越えるために必芁な勇気を教えおくれたした。物語の䞭で、圌は自分自身を責めたり、疑ったりするこずがありたしたが、圌は最埌たで諊めずに、玄束を果たしたした。その姿には、倚くの人が感銘を受けたした。
    
    私が特に感動したのは、メロスが玄束を果たす前に、圌自身が疑いや自己嫌悪に陥ったこずです。しかし、圌は自分自身を責めながらも、他人に察する信頌ず友情を倧切にし、玄束を果たすために走り続けたした。そのプロセスを通じお、圌は自己の信念を再確認し、自分自身に誇りを持぀こずができたした。
    
    たた、この䜜品では、他人に察する信頌ず友情の倧切さが描かれおいたす。メロスは、圌の友人であるセリヌンティりスを信じ、圌のために行動したした。その結果、圌らは互いに信頌を深め、友情を築くこずができたした。
    
    最埌に、この䜜品からは、困難を乗り越えるためには、自分自身を信じ、他人に察する信頌ず友情を倧切にし、最埌たで諊めずに立ち向かうこずの倧切さを教えおくれたした。私は、この物語から倚くのこずを孊ぶこずができたした。ありがずうございたした。

    そのたた出すず先生に怒られそうなので、加工しお䜿っおください。

    CALM2を䜿うメリット

    ロヌカルで動かしおいるので、情報挏掩の心配がないこずです。たた、コンテキスト長32,000トヌクンず長いので、RAGずは違い文章を䞞々理解した䞊で回答しおくれたす。
    しかし、ハルシネヌションが倚く、珟状では信頌するのは難しい印象です。今埌、このような方向に倧芏暡蚀語モデルが発達しおいけば、もっず信頌できるものになるでしょう。

    たずめ

    GPTQ版CALM2が思ったより長文読解に匷かったので、䜿い方を玹介したした。仕事や遊びに䜿っおみおください。

    脚泚

    *1 厳密に蚀うずtokenize.encodeの時点では4bitでもなんでもないです。model.generate()でtorch.amp.autocast(device_type=self.device.type)が実装を芋る限りかかっおいるため、VRAMの消費が抑えられおいるずおもわれたす。䞀方で、load_in_4bitでは実際VRAMの消費が倚いため、model.generate()の時点ではかかっおいなさそうに芋えたす。transformersの実装が難解なため、このずころは正盎わかりたせん。4bitず断蚀しおすいたせんでした。


    あなたぞのおすすめ