1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GitHubを見ながらself-discoverを試してみた

Last updated at Posted at 2024-02-14

前置き

Google DeepMindが発表したself-discoverをhwchase17さんが実装してGitHubに挙げてくださっていたので試してみました。

自分の備忘録用となるべく英語見たくない方用に作成しました。

本記事では前編と後編に分けています。
前編ではコード中心、後編では出力結果中心に見ていきます。
Qiitaを書き慣れていないので読みづらい箇所はご了承ください。

環境はGoogleColabです。

参考

Self-Discover: Large Language Models Self-Compose Reasoning Structures
hwchase17のコード

前編

事前準備

必要なモジュールをインストールしてください。

!pip install langchain langchain_openai langchain_core langchainhub

モジュールのインポート、モデルのイニシャライズをします。
人によってはAPIキーのセットも行ってください。

import os
from langchain_openai import ChatOpenAI
from langchain import hub
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough

# 論文中ではGPT4, GPT3.5-turbo, PaLM2, Llama2-70Bを使用 
os.environ["OPENAI_API_KEY"] = "sk-"
model = ChatOpenAI(temperature=0, model="gpt-4-turbo-preview")

select_prompt

select_promptを定義します。
これは既にhwchase17さんが用意してくれていたのでそれを使用します。

select_prompt = hub.pull("hwchase17/self-discovery-select")

promptの内容が見たい方は次のコードを実行してください。

select_prompt.pretty_print()

また、自分でpromptを作りたい方は論文中のFigure.10を参考にしてください。
スクリーンショット 2024-02-15 023254.png

adapt_prompt

adapt_promptを定義します。
これも先ほどと同様です。

adapt_prompt = hub.pull("hwchase17/self-discovery-adapt")

structured_prompt

structured_promptを定義します。
GitHubのコードではstructured_promptとしていましたが、論文中ではIMPLEMENTとされている部分です。
また中身もhwchase17さんが少し付け足していました。
(精度が良くなった?)

ここまでで論文中のStep1までのpromptの準備が完了しました。
次にStep2のpromptを準備します。

reasoning_prompt

reasoning_promptを定義します。
これも先ほどまでと同様です。

reasoning_prompt = hub.pull("hwchase17/self-discovery-reasoning")

Chainの作成

ここまで準備が完了したらChainを作成します。
自作でpromptを作成した場合は、overall_chainの部分は適切な形に直してください。

select_chain = select_prompt | model | StrOutputParser()

adapt_chain = adapt_prompt | model | StrOutputParser()

structure_chain = structured_prompt | model | StrOutputParser()

reasoning_chain = reasoning_prompt | model | StrOutputParser()

overall_chain = (
    RunnablePassthrough.assign(selected_modules=select_chain)
    .assign(adapted_modules=adapt_chain)
    .assign(reasoning_structure=structure_chain)
    .assign(answer=reasoning_chain)
)

reasoning_modules

次にChainに渡すreasoning_modulesを用意するのですが、これはとても長いのでGitHubからコピーを行うか論文中のTable.2をコピーしてください。
最終的にはstr形式に直しておいてください。
(GitHubでは次の様にしてstrに直してます)

reasoning_modules_str = "\n".join(reasoning_modules)

task_example

task_exampleを定義します。
ここには解いてほしいタスクを定義してください。
今回はクイズノックさんの少し難しめの算数問題を解いてもらおうと思います。
小学生に負けちゃうの?意外と難しい「算数」、京大生がコツ教えます

task_example = "There is a job that Adam can finish in 16 days and Eve can finish in 20 days. When the two of you do this job together, how many days will it take to finish?"

結果を得る

推論を行い結果をresultを格納します。
ここまでで前編は終了です。

result = overall_chain.invoke(
    {"task_description": task_example, "reasoning_modules": reasoning_modules_str}
)

後編

結果を見る

resultは辞書型です。
キーとバリューにはoverall_chainを定義したときに指定したものが与えられています。
したがって、結果を見る場合は次の様にします。
(この辺りは自由にして大丈夫です)

print(result.keys())
select_key = input("key?: ")
print(result[select_key])

ここからは各キーに対してどのようなバリューが入っているのかと共に論文中のStep1とStep2で何が説明されていたかを考えます。

まず、今回のキーの一覧は['task_description', 'reasoning_modules', 'selected_modules', 'adapted_modules', 'reasoning_structure', 'answer']です。

task_descriptionには先ほどのクイズノックさんの問題が格納され、
reasoning_modulesにはreasoning_modules_strが格納されています。

selected_modules

selected_modulesにはreasoning_modulesからタスクの解決に必要だと思うものを選択して格納されています。
(そもそもreasoning_modulesとは何かというと高度なヒューリスティックの一覧だと思ってください。)

adapted_modules

adapted_modulesでは先ほど選んだreasoning_modulesを、与えられたタスクに適応させます。
(私は最初に読んだときに?マークがでましたが、ヒューリスティックについて調べた後に読んだらスッキリしたので同様の方がいらっしゃればお勧めします。)

reasoning_structure

reasoning_structureではadapted_modulesに従ってjson形式のプランを作成します。
プランは指示やヒントつきの穴埋め問題だと思ってください。

answer

answerではreasoning_structureで作られた穴埋め問題の穴を埋めていくイメージで回答を作成していきます。

reasoning_structureとanswerの出力を見比べてみます。
reasoning_structureでは問題を解くためのステップと各ステップの詳細、アクションをjson形式で指示しています。

スクリーンショット 2024-02-15 030937.png

answerでは指示に従って穴埋めを行い、最終的な回答を出力しています。

スクリーンショット 2024-02-15 030959.png

以上が内容となります。
論文とGitHubのコードを照らし合わせただけなので浅い内容になりましたが、閲覧いただきありがとうございました。

1
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?