SmartHR Tech Blog

SmartHR 開発者ブログ

PaLM 2プライベートプレビューを試してみたぞ!

みなさんこんにちは、プロダクトマネージャーの@ryopenguinです。

弊社では、最近のLLMの登場を受け、AIに関する研究開発を始めています(その話はまたどこかで!)。

お付き合いのあるGoogle様にその話をしたところ、なんと日本語対応版PaLM 2 APIのプライベートプレビューを提供いただきました!いくつかのユースケースで試してみました。

PaLM 2について

「PaLM 2」は、GoogleのLLM(Large language model、大規模言語モデル)です。多言語テキストやコードを学習しており、幅広いタスクを実行可能です。

今回のプライベートプレビューでは、Google Cloud Platform(以下GCP)のAPIを通して日本語対応したPaLM 2が利用できるようになりました。

この記事では主に「PaLM 2 for Text(入力されたテキストを補完するAPI、text-bisonモデルを使用)」「PaLM 2 for Chat(会話に最適化されたAPI、chat-bisonモデルを使用)」の2つを試します。

いざ検証

今回は「テキストチャット」「テキスト要約」「テキストのフォーマット調整(JSON化)」の3つのユースケースを検証していきます。これらはプロダクトに組み込む際に頻出すると思われます。

ちなみに、これらのユースケースはLangChainLlamaindexといったLLMをラップするライブラリを使うと効率的にできますが、今回はあえてライブラリを使わずプロンプトや実装の中身がわかりやすいようにしています。

テキストチャット

最初はオーソドックスにテキストチャットをしてみたいと思います。

入力したテキストに対してテキストを出力してくれるPaLM 2 for textを試してみます。コードはGCPのコントロールパネルに表示されるサンプルのままです。

from google.colab import auth as google_auth
google_auth.authenticate_user()

import vertexai
from vertexai.language_models import TextGenerationModel

vertexai.init(project="smarthr-llm-development", location="us-central1")
parameters = {
    "temperature": 0,
    "max_output_tokens": 256,
    "top_p": 0.8,
    "top_k": 40
}
model = TextGenerationModel.from_pretrained("text-bison@001")
response = model.predict(
    """あなたの自己紹介をしてください""",
    **parameters
)
print(f"Response from Model: {response.text}")
Response from Model: はじめまして。私は、[名前]と申します。
[年齢]歳で、[出身地]出身です。現在は、[職業]として働いています。
趣味は、[趣味]です。よろしくお願いします。

テンプレートのような文章を出力しましたね。同じ文章でPaLM 2 for chatを試してみます。

import vertexai
from vertexai.preview.language_models import ChatModel, InputOutputTextPair

vertexai.init(project="smarthr-llm-development", location="us-central1")
chat_model = ChatModel.from_pretrained("chat-bison@001")
parameters = {
    "temperature": 0.2,
    "max_output_tokens": 256,
    "top_p": 0.8,
    "top_k": 40
}
chat = chat_model.start_chat()

print(chat.send_message("あなたの自己紹介をしてください", **parameters))
こんにちは、私はChatGPTです。私はオープンAIによって開発された大規模な言語モデルです。
私はあなたの質問に答えたり、会話をしたり、創造的なコンテンツを作ったりすることができます。
私はまだ開発中ですが、私は学習し続けており、より賢くなることを楽しみにしています。

あろうことか競合製品の名前を出してしまいました。いわゆるハルシネーションと呼ばれる現象で、もっともらしい嘘の出力をしてしまっています。 これについては今後の改善に期待したいと思います。

ただ、PalM 2 for Chatはchat_model.start_chat() の返り値 ChatSession単位でそれまで行った会話の履歴を引き継いでくれます。この点は非常に便利に使えそうです。先ほどのコードに加えて以下の会話をしてみます。

print(chat.send_message("あなたは誰に開発されましたか?", **parameters))
私はオープンAIによって開発されました。
オープンAIは、人工知能の研究と開発に取り組む非営利団体です。
彼らの使命は、人間の知能を拡張し、世界をより良くすることです。

内容は置いておいて、同じコンテキストをそのまま引き継いでくれています。 自分でチャットした内容を記録して送らないと会話の履歴を考慮しないLLMもあるので、この点は非常に便利だと思います。

要約

次に、文章の要約を試します。 今回は「弊社のテレワーク制度に関して、あなたの感想を教えてください」というアンケート質問に実際の弊社社員が答えたテストデータを要約していきます。 弊社プロダクトの「従業員サーベイ」ではLLMを用いた要約機能をリリースしており、その際にも同様のデータを使いました。

テストデータは以下の通りです。

text = """
  ・通勤時間がなくなり、朝から集中して業務に入れるので、メリットを非常に感じています。\nまた、個人の都合とも調整がつきやすくなるので、何か私用を我慢するというような、不満足を感じることが減りました。\n一方で、夏はエアコンなどの利用による電気代が掛かるのが負担になり、デメリットだと思います。,
  ・幼い子供の育児をしている身としては、在宅の選択肢があることがとてもありがたいです!\n結果、会社全体でも働きやすさが上がっているのではないかと思います。,
  ・オフィスに限らず、自分の住まいに近い所でサテライトオフィスを利用できるなど、より柔軟であってほしい。 カフェなどでのリモートワークはセキュリティ面で厳しいと思うが、なんとか実現することが出来ないかなと思っている。 上記の理由として、子育てや介護世帯が今後増えていくと思っており、サブ的なワークスペースの需要が高まると思っている。,
  ・個人的には満足です。\nただ、サポート職なので、何時まで業務してるのか?は見えない。\n実際にちゃんと働いてるのか?など見えにくい。\nただ、下記については課題\n・腰痛\n・運動不足\n・久しぶりに出勤すると慣れない,
  ・柔軟に働けてとても良いと思う。\nただし、テレワークの方が残業が多くなっている気がする。,
  ・とても働きやすいと思う反面、セキュリティを考えるともっと厳しくしても良いのかもしれないとも思う,
  ・テレワークは賛成な部分もあれば反対の部分もあります。賛成できる部分として従業員時間ギリギリまで自分の時間を確保できることです。反対な部分は会社への帰属感が失われることです。,
  ・通勤時間がないのでとても最高です。\n・作業の合間に軽く横になるなど、休憩の質も高くできると感じます。\n・最近は電気代が高く、家をオフィスとして維持するためのコストが上がっていると感じます。\n・テレワークが今後も継続する前提で家を買ったため、テレワークはやめないでほしいです。,
  ・テレワーク日数に制限がないことや毎月リモートワーク手当が出ることは素晴らしいです。\nですが、出社しようとしたときの交通費の上限が小さかったり(通勤手当)、日数に制限があったり(フルリモートワーク通勤制度)、宿泊費が出ないのがあまりよくないと思います。\n交通費や日数の上限がなくなり宿泊費も出るようになればさらに良くなると思います。,
  ・最初は「大丈夫かな?」と心配だったけど、いまは事業もスムーズにまわっているし、通勤時間が無い方が効率的なことも多いので、良いと思う。一方で、雑多な話をする時間は減ったので、雑談からはじまるアイデアとかは減っているとは思う。
"""

まずはPaLM 2 for Textからです。 なお、ここからは出力が長くなる可能性も考慮し、”max_output_tokens”(出力の文字数上限に関連する変数)を1024までに拡張します。

def summarize_with_text_model(text):
    vertexai.init(project="smarthr-llm-development", location="us-central1")
    parameters = {
        "temperature": 0.2,
        "max_output_tokens": 1024,
        "top_p": 0.8,
        "top_k": 40
    }
    model = TextGenerationModel.from_pretrained("text-bison@001")
    response = model.predict(
        f"""次の文章を要約してください。\n{text}""",
        **parameters
    )
    return response.text

summarize_with_text_model(text)
テレワークのメリット・デメリットをまとめた。
メリットは、通勤時間がなくなり朝から集中して業務に入れること、個人の都合とも調整がつきやすくなることなど。
デメリットは、夏はエアコンなどの利用による電気代が掛かること、雑多な話をする時間が減り雑談からはじまるアイデアが減ることなど。

元の文にないことは答えておらず、大まかに要約できているように思います。

続いてPaLM 2 for Chatです。

def summarize_with_chat_model(text):
    vertexai.init(project="smarthr-llm-development", location="us-central1")
    chat_model = ChatModel.from_pretrained("chat-bison@001")
    parameters = {
        "temperature": 0.2,
        "max_output_tokens": 1024,
        "top_p": 0.8,
        "top_k": 40
    }
    chat = chat_model.start_chat()
    response = chat.send_message(f"次の文章を要約してください\n{text}", **parameters)
    return response.text

summarize_with_chat_model(text)
テレワークについて、メリット・デメリットを述べています。
メリットとしては、通勤時間がなくなり朝から集中して業務に入れること、個人の都合とも調整がつきやすくなることなどが挙げられます。
デメリットとしては、夏場はエアコンなどの利用による電気代が掛かること、雑多な話をする時間が少なくなり雑談からはじまるアイデアが減ることなどが挙げられます。

こちらもかなりいい感じです。Text、Chat API双方とも、要約は問題なくできる気がします。

JSON化

最後に、命令に従ってJSON形式のデータを返せるか実験してみようと思います。アプリケーションにLLMを組み込む際は、他のAPIと組み合わせることが多いため、頻出のユースケースになります。

先ほど出力した要約を元に、JSONに加工してみます。

summary = """
テレワークについて、メリット・デメリットを述べています。
メリットとしては、通勤時間がなくなり朝から集中して業務に入れること、個人の都合とも調整がつきやすくなることなどが挙げられます。
デメリットとしては、夏場はエアコンなどの利用による電気代が掛かること、雑多な話をする時間が少なくなり雑談からはじまるアイデアが減ることなどが挙げられます。
"""

def json_with_text_model(text):
    vertexai.init(project="smarthr-llm-development", location="us-central1")
    parameters = {
        "temperature": 0.2,
        "max_output_tokens": 1024,
        "top_p": 0.8,
        "top_k": 40
    }
    model = TextGenerationModel.from_pretrained("text-bison@001")
    response = model.predict(
        f"""
        次の文章を「出力形式」に従い加工し、出力してください
        {text}

        出力形式
        {{
            "positive": "ポジティブな文章の配列。配列には1つの要素のみを含むこと",
            "negative": "ネガティブな文章の配列。配列には1つの要素のみを含むこと"
        }}
        """,
        **parameters
    )
    return response.text

json_with_text_model(summary)
{
            "positive": ["通勤時間がなくなり朝から集中して業務に入れること", "個人の都合とも調整がつきやすくなること"],
            "negative": ["夏場はエアコンなどの利用による電気代が掛かること", "雑多な話をする時間が少なくなり雑談からはじまるアイデアが減ること"]
}

かなりいい感じです。他の言語モデルの場合このような指示をするとJSON以外に余計な文章が入ってしまうことがあるのですが、きちんと出力形式通りになっています。 続いてPaLM 2 for Chatでも実施してみます。

def json_with_chat_bison(text):
    vertexai.init(project="smarthr-llm-development", location="us-central1")
    chat_model = ChatModel.from_pretrained("chat-bison@001")
    parameters = {
        "temperature": 0.2,
        "max_output_tokens": 1024,
        "top_p": 0.8,
        "top_k": 40
    }
    chat = chat_model.start_chat()
    response = chat.send_message(
        f"""
        次の文章を「出力形式」に従い加工し、出力してください
        {text}

        出力形式
        {{
            "positive": "ポジティブな文章の配列。配列には1つの要素のみを含むこと",
            "negative": "ネガティブな文章の配列。配列には1つの要素のみを含むこと"
        }}
        """,
        **parameters
    )
    return response.text

json_with_chat_bison(summary)
{
  "positive": ["通勤時間がなくなり朝から集中して業務に入れること", "個人の都合とも調整がつきやすくなること"],
  "negative": ["夏場はエアコンなどの利用による電気代が掛かること", "雑多な話をする時間が少なくなり雑談からはじまるアイデアが減ること"]
}

こちらもうまくいきました!

まとめ

今回は、Google様ご提供の日本語対応版PaLM 2のAPIを検証してきました。
テキストチャットはハルシネーションが激しかったですが、PaLM 2 for Chatが会話した内容を引き継いでくれる点は便利でした。プロダクトでLLMを利用する場合は、大抵他のデータやAPIと組み合わせて利用するので、素の状態でハルシネーションが起きても工夫のしようはあるのではないでしょうか。ハルシネーションそのものも、いずれ改善されることと思います。
また、要約やデータ加工ではText、Chatともに実戦級の実力があるように思いました。

今後に期待すること

  • Embeddingモデルの日本語対応
    • 今回はテキストチャット、要約、JSON化を試してきましたが、いわゆるRAG(LLMによる外部文書を参照した応答)も頻出のユースケースです。
    • これには文書をベクトルに変換するEmbeddingモデルが必要なのですが、そちらはまだ日本語対応されていないようです。対応をお待ちしています!
  • 出力フォーマットを安定化できるオプション
    • 今回の検証では、JSON出力はうまくいきましたが、プロンプトが長くなったり、スキーマが複雑になった時にうまくいくかは未検証です。
    • 出力フォーマットを安定化できるメソッドのオプションなどの手段があると、より安心してLLMをプロダクトに組み込みやすくなるように思います。こちらもアップデートお待ちしています!

最後に

貴重な機会をくださったGoogleのみなさま、誠にありがとうございました😊