SGLangを使ってSelf-Discoverを試してみる on Databricks

おそらく日本で一番SGLangの記事を書いてる。たぶん。

# 導入

[SGLang](https://github.com/sgl-project/sglang)のIssuesを見ていたら、exampleとしてSelf-Discoverが取り上げられているのに気づきました。

https://github.com/sgl-project/sglang/issues/166

サンプルコードもこの中に記載されており、興味深かったので試してみます。

# Self-Discoverって何？

Google DeepMindの研究者らが考案・発表したプロンプト手法です。

https://arxiv.org/pdf/2402.03620.pdf

CoT等の従来手法に比べて推論性能が大きく向上し、また計算量も低下することが特徴です。何といういいことづくめ。

まだ十分正確な理解ができていないのですが、タスクを解くにあたって推論のステップをSELECT/ADAPT/IMPLEMENTの3つに分解し、以下の役割を持ちます。
- **SELECT**プロセスでは与えられたモジュール（と呼ばれるタスク例）から適切なものを選択
- **ADAPT**プロセスはSELECTプロセスで選んだモジュールを実際の問題に合わせてより具体化したものに変換
- **IMPLEMENT**プロセスではADAPTプロセスの結果を使って実行可能な推論構造を自然言語で生成

最終的にIMPLEMENTプロセスで生成した推論構造を用いて最終的なタスクの答えをLLMを用いて導き出す、という流れです。

実装例もいろいろgithub上にあがっており、LangChainを使った例については、以下の方が実際に試されていました。

https://qiita.com/Sora_Yamamoto/items/cadf07291ec11152707a

この記事ではLangChainを使わず、SGLang単体での推論を試してみます。

手前みそですが、SGLangについては以下の記事で紹介しています。

https://qiita.com/isanakamishiro2/items/aeb73d09bd81349fa023

検証環境はDatabricks on AWSを利用しました。
DBRは14.3ML、クラスタタイプはg5.xlarge(GPUクラスタ)です。

# Step1. パッケージインストール

ノートブックを作成し、SGLangに必要なパッケージをインストール。

```python
# torch, xformers
# pytorchのリポジトリから直接インストールする場合
# %pip install -U https://download.pytorch.org/whl/cu118/torch-2.1.2%2Bcu118-cp310-cp310-linux_x86_64.whl
# %pip install -U https://download.pytorch.org/whl/cu118/xformers-0.0.23.post1%2Bcu118-cp310-cp310-manylinux2014_x86_64.whl

%pip install -U /Volumes/training/llm/tmp/torch-2.1.2+cu118-cp310-cp310-linux_x86_64.whl
%pip install -U /Volumes/training/llm/tmp/xformers-0.0.23.post1+cu118-cp310-cp310-manylinux2014_x86_64.whl

# vLLM
# GithubからvLLMを直接インストールする場合
# %pip install https://github.com/vllm-project/vllm/releases/download/v0.3.2/vllm-0.3.2+cu118-cp310-cp310-manylinux1_x86_64.whl
%pip install /Volumes/training/llm/tmp/vllm-0.3.2+cu118-cp310-cp310-manylinux1_x86_64.whl

# sglang==0.1.12の場合、outlines>0.030だとエラーが出るためoutlinesのバージョンを固定
%pip install "outlines>=0.0.27,<=0.0.30"
%pip install "sglang[srt]>=0.1.12"
%pip install "triton>=2.2.0"

dbutils.library.restartPython()
```

合わせてpytorchのmultiprocessing設定を変更。

```python
import torch
torch.multiprocessing.set_start_method('spawn', force=True)
```


# Step2. モデルのロード


ユーザ指示に対する生成と批評、両方を行うLLMをSGLangでロードします。
今回はAWQフォーマットで量子化されたQwen1.5 14Bを利用しました。

https://huggingface.co/Qwen/Qwen1.5-14B-Chat-AWQ

モデルは事前にダウンロードしたものを利用しています。


```python
from sglang import function, system, user, assistant, gen, set_default_backend, Runtime

from sglang.lang.chat_template import (
    get_chat_template,
    register_chat_template,
    ChatTemplate,
)

# チャット用のプロンプトテンプレート
register_chat_template(
    ChatTemplate(
        name="qwen",
        default_system_prompt=None,
        role_prefix_and_suffix={
            "system": ("
system\n", "
\n"),
            "user": ("
user\n", "
\n"),
            "assistant": ("
assistant\n", "
\n"),
        },
    )
)

model_path = (
    "/Volumes/training/llm/model_snapshots/models--Qwen--Qwen1.5-14B-Chat-AWQ"
)

runtime = Runtime(model_path, mem_fraction_static=0.8)
runtime.endpoint.chat_template = get_chat_template("qwen")

set_default_backend(runtime)
```

# Step3. Self-Discoverの推論処理定義

Self-Discoverを実行するための推論処理を定義します。
少し長いのですが、```self_discover```関数内でSELECT/ADAPT/IMPLEMENTまで含めた処理を定義しています。
LangChainの実装例に比べると、プロンプトを含んでいても冗長な部分がなくスッキリした実装になります。

あわせて、比較用に単純に推論を実行するための```single```関数も定義しました。

```python
from sglang import (
    function,
    system,
    user,
    assistant,
    gen,
    set_default_backend,
    RuntimeEndpoint,
    select,
)
from pprint import pprint

reasoning_modules = [
    "1. How could I devise an experiment to help solve that problem?",
    "2. Make a list of ideas for solving this problem, and apply them one by one to the problem to see if any progress can be made.",
    # "3. How could I measure progress on this problem?",
    "4. How can I simplify the problem so that it is easier to solve?",
    "5. What are the key assumptions underlying this problem?",
    "6. What are the potential risks and drawbacks of each solution?",
    "7. What are the alternative perspectives or viewpoints on this problem?",
    "8. What are the long-term implications of this problem and its solutions?",
    "9. How can I break down this problem into smaller, more manageable parts?",
    "10. Critical Thinking: This style involves analyzing the problem from different perspectives, questioning assumptions, and evaluating the evidence or information available. It focuses on logical reasoning, evidence-based decision-making, and identifying potential biases or flaws in thinking.",
    "11. Try creative thinking, generate innovative and out-of-the-box ideas to solve the problem. Explore unconventional solutions, thinking beyond traditional boundaries, and encouraging imagination and originality.",
    # "12. Seek input and collaboration from others to solve the problem. Emphasize teamwork, open communication, and leveraging the diverse perspectives and expertise of a group to come up with effective solutions.",
    "13. Use systems thinking: Consider the problem as part of a larger system and understanding the interconnectedness of various elements. Focuses on identifying the underlying causes, feedback loops, and interdependencies that influence the problem, and developing holistic solutions that address the system as a whole.",
    "14. Use Risk Analysis: Evaluate potential risks, uncertainties, and tradeoffs associated with different solutions or approaches to a problem. Emphasize assessing the potential consequences and likelihood of success or failure, and making informed decisions based on a balanced analysis of risks and benefits.",
    # "15. Use Reflective Thinking: Step back from the problem, take the time for introspection and self-reflection. Examine personal biases, assumptions, and mental models that may influence problem-solving, and being open to learning from past experiences to improve future approaches.",
    "16. What is the core issue or problem that needs to be addressed?",
    "17. What are the underlying causes or factors contributing to the problem?",
    "18. Are there any potential solutions or strategies that have been tried before? If yes, what were the outcomes and lessons learned?",
    "19. What are the potential obstacles or challenges that might arise in solving this problem?",
    "20. Are there any relevant data or information that can provide insights into the problem? If yes, what data sources are available, and how can they be analyzed?",
    "21. Are there any stakeholders or individuals who are directly affected by the problem? What are their perspectives and needs?",
    "22. What resources (financial, human, technological, etc.) are needed to tackle the problem effectively?",
    "23. How can progress or success in solving the problem be measured or evaluated?",
    "24. What indicators or metrics can be used?",
    "25. Is the problem a technical or practical one that requires a specific expertise or skill set? Or is it more of a conceptual or theoretical problem?",
    "26. Does the problem involve a physical constraint, such as limited resources, infrastructure, or space?",
    "27. Is the problem related to human behavior, such as a social, cultural, or psychological issue?",
    "28. Does the problem involve decision-making or planning, where choices need to be made under uncertainty or with competing objectives?",
    "29. Is the problem an analytical one that requires data analysis, modeling, or optimization techniques?",
    "30. Is the problem a design challenge that requires creative solutions and innovation?",
    "31. Does the problem require addressing systemic or structural issues rather than just individual instances?",
    "32. Is the problem time-sensitive or urgent, requiring immediate attention and action?",
    "33. What kinds of solution typically are produced for this kind of problem specification?",
    "34. Given the problem specification and the current best solution, have a guess about other possible solutions."
    "35. Let’s imagine the current best solution is totally wrong, what other ways are there to think about the problem specification?"
    "36. What is the best way to modify this current best solution, given what you know about these kinds of problem specification?"
    "37. Ignoring the current best solution, create an entirely new solution to the problem."
    # "38. Let’s think step by step."
]


@function
def self_discover(s, question, num_modules, reasoning_modules, max_turns=10):
    """Self-Discoveryで問題を解く"""

    # Split the LLM into 3 parts
    selector, adaptor, implementor = s.fork(3)

    selector += user(
        f"Given the task: {question}, which of the following reasoning modules are relevant? Do not elaborate on why.\n"
    )
    adaptor += user(
        f"Given the task: {question}, which of the following reasoning modules are relevant? Do not elaborate on why.\n"
    )
    implementor += user(
        f"Without working out the full solution, create an actionable reasoning structure for the task using these adapted reasoning modules:\n"
    )

    # Let the selector choose the reasoning modules
    selected_modules = []
    for module in range(num_modules):
        selector += assistant(
            gen(
                choices=reasoning_modules,
                name=f"selection_{module + 1}",
                max_tokens=512,
            )
            + " "
        )
        selected_modules.append(selector[f"selection_{module + 1}"])

    # Let the adaptor modify the modules to fit the task
    adaptor += user(f"\nReasoning Modules: {selected_modules}\nOur task: {question}:")
    adapted_modules = []
    for module in range(len(selected_modules)):
        adaptor += assistant(
            f"Adapted Module {module + 1}:"
            + gen(
                stop=f"Adapted Module {module + 2}:",
                name=f"adapted_module{module + 1}",
                max_tokens=512,
            )
        )
        adapted_modules.append(adaptor[f"adapted_module{module + 1}"])

    # Let the implementor implement the adapted modules
    implementor += user(f"\nAdapted Modules:{adapted_modules}\nOur task: {question}")
    implementor += assistant(gen(name="reasoning_structure", max_tokens=512))

    # Let the LLM finish the job
    reasoning_structure = implementor["reasoning_structure"]
    s += system(f"Using the following reasoning structure: {reasoning_structure}")
    s += user(f"Solve this task, providing your final answer: {question}")
    s += assistant(gen(name="process", stop="Final Answer:", max_tokens=512))
    s += assistant("Final Answer:" + gen(name="Final_Answer", max_tokens=512))

    # 推論過程がよくわかるように、SELECT/ADAPT/IMPLEMENTの結果をそれぞれ表示
    print("Intermediate output")
    print("---------------------------------")
    pprint(selected_modules, width=120)
    pprint(adapted_modules, width=120)
    pprint(reasoning_structure, width=120)
    print("---------------------------------")

    return s


@function
def single(s, question):
    """シンプルにタスクを解く"""

    s += user(f"{question}")
    s += assistant(gen(name="Final_Answer", max_tokens=512))

    return s
```

# Step4. 推論実行

では、実際に推論させてみます。

## 単純な計算問題

まずはごく簡単な算数問題。
最初はSelf-Discoverを使わず、単純な推論をしてみます。

```python
state = single.run(
    question="""Lisa has 10 apples. She gives 3 apples to her friend and then buys 5 more apples from the store. How many apples does Lisa have now?""",
    temperature=0,
)

for m in state.messages():
    print(m["role"], ":", m["content"])
```

```:出力
user : Lisa has 10 apples. She gives 3 apples to her friend and then buys 5 more apples from the store. How many apples does Lisa have now?
assistant : Lisa starts with 10 apples. She gives away 3, so she has:

10 - 3 = 7 apples

Then she buys 5 more apples, so she adds:

7 + 5 = 12 apples

Lisa now has 12 apples.
```

正解ですね。

では、Self-Discoverを使うとどのようになるでしょうか。

```python
state = self_discover.run(
    question="""Lisa has 10 apples. She gives 3 apples to her friend and then buys 5 more apples from the store. How many apples does Lisa have now?""",
    num_modules = 3,
    reasoning_modules=reasoning_modules,
    temperature=0,
)

for m in state.messages():
    print(m["role"], ":", m["content"])
```

```:出力
Intermediate output
---------------------------------
['14. Use Risk Analysis: Evaluate potential risks, uncertainties, and tradeoffs associated with different solutions or '
 'approaches to a problem. Emphasize assessing the potential consequences and likelihood of success or failure, and '
 'making informed decisions based on a balanced analysis of risks and benefits.',
 '14. Use Risk Analysis: Evaluate potential risks, uncertainties, and tradeoffs associated with different solutions or '
 'approaches to a problem. Emphasize assessing the potential consequences and likelihood of success or failure, and '
 'making informed decisions based on a balanced analysis of risks and benefits.',
 '14. Use Risk Analysis: Evaluate potential risks, uncertainties, and tradeoffs associated with different solutions or '
 'approaches to a problem. Emphasize assessing the potential consequences and likelihood of success or failure, and '
 'making informed decisions based on a balanced analysis of risks and benefits.']
[" '14. Use Basic Arithmetic: Perform simple arithmetic operations, such as addition, subtraction, multiplication, and "
 'division, to solve problems involving quantities, rates, or proportions. This includes understanding the order of '
 "operations and applying them correctly.'\n"
 '\n'
 "Relevant Module: '14. Use Basic Arithmetic'\n"
 '\n'
 'Explanation: The given task involves basic arithmetic operations, specifically subtraction (to find out how many '
 'apples Lisa has after giving some to her friend) and addition (to find out how many apples she has after buying '
 'more). These operations are essential for solving this problem, which does not require risk analysis or '
 'decision-making based on potential consequences.\n',
 " '14. Use Basic Arithmetic: Perform simple arithmetic operations, such as addition, subtraction, multiplication, and "
 'division, to solve problems involving quantities, rates, or proportions. This includes understanding the order of '
 "operations and applying them correctly.'\n"
 '\n'
 "Relevant Module: '14. Use Basic Arithmetic'\n"
 '\n'
 'Explanation: (Same as above)\n'
 '\n',
 " '14. Use Basic Arithmetic: Perform simple arithmetic operations, such as addition, subtraction, multiplication, and "
 'division, to solve problems involving quantities, rates, or proportions. This includes understanding the order of '
 "operations and applying them correctly.'\n"
 '\n'
 "Relevant Module: '14. Use Basic Arithmetic'\n"
 '\n'
 'Explanation: (Same as above)\n']
('Actionable Reasoning Structure:\n'
 '\n'
 '1. Identify the initial quantity: Lisa starts with 10 apples.\n'
 '2. Apply the subtraction operation: Subtract the number of apples given away from the initial amount. So, 10 '
 '(initial) - 3 (given to friend) = 7 apples remaining.\n'
 '3. Apply the addition operation: Add the number of apples bought back to the remaining amount. So, 7 (after giving) '
 '+ 5 (bought) = 12 apples.\n'
 '4. Conclusion: Lisa now has 12 apples.\n'
 '\n'
 "Relevant Module: '14. Use Basic Arithmetic' - both subtraction and addition are used in this problem.\n")
---------------------------------
system : Using the following reasoning structure: Actionable Reasoning Structure:

1. Identify the initial quantity: Lisa starts with 10 apples.
2. Apply the subtraction operation: Subtract the number of apples given away from the initial amount. So, 10 (initial) - 3 (given to friend) = 7 apples remaining.
3. Apply the addition operation: Add the number of apples bought back to the remaining amount. So, 7 (after giving) + 5 (bought) = 12 apples.
4. Conclusion: Lisa now has 12 apples.

Relevant Module: '14. Use Basic Arithmetic' - both subtraction and addition are used in this problem.

user : Solve this task, providing your final answer: Lisa has 10 apples. She gives 3 apples to her friend and then buys 5 more apples from the store. How many apples does Lisa have now?
assistant : Lisa has 12 apples now.

assistant : Final Answer: 12
```

※　前段部分は推論の流れがわかるようにSELECT/ADAPT/IMPLEMENTの各結果を出力しています。

最初に推論構造を自ら策定し、その内容を使って答えを導き出しているのがわかります。
ちなみにこちらも正しい答えを出せています。


## 複雑な問題

では、論文にも記載されている複雑な問題を解かせてみます。

まずはシンプルな推論から。

```python
state = single.run(
    question="""This SVG path element <path d="M 55.57,80.69 L 57.38,65.80 M 57.38,65.80 L 48.90,57.46 M 48.90,57.46 L
45.58,47.78 M 45.58,47.78 L 53.25,36.07 L 66.29,48.90 L 78.69,61.09 L 55.57,80.69"/> draws a:
(A) circle (B) heptagon (C) hexagon (D) kite (E) line (F) octagon (G) pentagon(H) rectangle (I) sector (J) triangle""",
    temperature=0,
)

for m in state.messages():
    print(m["role"], ":", m["content"])
```

```:出力
user : This SVG path element <path d="M 55.57,80.69 L 57.38,65.80 M 57.38,65.80 L 48.90,57.46 M 48.90,57.46 L
45.58,47.78 M 45.58,47.78 L 53.25,36.07 L 66.29,48.90 L 78.69,61.09 L 55.57,80.69"/> draws a:
(A) circle (B) heptagon (C) hexagon (D) kite (E) line (F) octagon (G) pentagon(H) rectangle (I) sector (J) triangle
assistant : The SVG path element described by the series of M (move to) and L (line to) commands draws a shape with straight lines connecting the specified points. Analyzing the points:

1. M 55.57,80.69
2. L 57.38,65.80
3. M 57.38,65.80
4. L 48.90,57.46
5. M 48.90,57.46
6. L 45.58,47.78
7. M 45.58,47.78
8. L 53.25,36.07
9. L 66.29,48.90
10. L 78.69,61.09
11. L 55.57,80.69

The shape is a kite, as it has two pairs of adjacent sides that are equal in length and the other two sides are unequal. Therefore, the correct answer is (D) kite.
```

ちなみに答えは(B)のheptagon(7角形)です。
そのため、上記の推論結果は間違ってますね。

では、Self-Discoverで解いてみます。

```python
state = self_discover.run(
    question="""This SVG path element <path d="M 55.57,80.69 L 57.38,65.80 M 57.38,65.80 L 48.90,57.46 M 48.90,57.46 L
45.58,47.78 M 45.58,47.78 L 53.25,36.07 L 66.29,48.90 L 78.69,61.09 L 55.57,80.69"/> draws a:
(A) circle (B) heptagon (C) hexagon (D) kite (E) line (F) octagon (G) pentagon(H) rectangle (I) sector (J) triangle""",
    num_modules = 3,
    reasoning_modules=reasoning_modules,
    temperature=0,
)

for m in state.messages():
    print(m["role"], ":", m["content"])
```

```:出力
Intermediate output
---------------------------------
['14. Use Risk Analysis: Evaluate potential risks, uncertainties, and tradeoffs associated with different solutions or '
 'approaches to a problem. Emphasize assessing the potential consequences and likelihood of success or failure, and '
 'making informed decisions based on a balanced analysis of risks and benefits.',
 '14. Use Risk Analysis: Evaluate potential risks, uncertainties, and tradeoffs associated with different solutions or '
 'approaches to a problem. Emphasize assessing the potential consequences and likelihood of success or failure, and '
 'making informed decisions based on a balanced analysis of risks and benefits.',
 '14. Use Risk Analysis: Evaluate potential risks, uncertainties, and tradeoffs associated with different solutions or '
 'approaches to a problem. Emphasize assessing the potential consequences and likelihood of success or failure, and '
 'making informed decisions based on a balanced analysis of risks and benefits.']
[' Geometry and Shapes Recognition\n'
 '\n'
 "The reasoning module relevant for this task is 'Geometry and Shapes Recognition', as it involves understanding the "
 'shape formed by the given SVG path data. The path data describes a series of connected line segments, which can be '
 'analyzed to determine the type of polygon or shape it represents. In this case, the path appears to have 5 distinct '
 "line segments connecting 7 points, suggesting it's a polygon with 7 sides, which would be a heptagon.\n"
 '\n'
 'Answer: (B) heptagon\n',
 ' Pattern Recognition\n'
 '\n'
 "While the primary shape recognition is done in Module 1, a secondary relevant module could be 'Pattern Recognition' "
 'as it involves identifying the specific pattern or configuration of the path elements. However, in this context, '
 'Module 1 is more directly applicable.\n'
 '\n'
 'Answer: (B) heptagon\n',
 ' Decision Making\n'
 '\n'
 'This module is not directly relevant to the task of identifying the shape drawn by the SVG path, as it focuses on '
 'evaluating risks and making informed decisions. However, in the context of choosing the correct answer, decision '
 'making could be applied to weigh the options and select the most accurate shape based on the given path data.\n'
 '\n'
 'Answer: (B) heptagon\n']
('Actionable Reasoning Structure:\n'
 '\n'
 '1. **Geometry and Shapes Recognition**: Begin by analyzing the given SVG path data, which consists of a series of M '
 '(move to) and L (line to) commands. The path appears to have multiple line segments connecting different points, '
 'suggesting a polygon.\n'
 '\n'
 '2. **Pattern Recognition**: Examine the pattern of the points, specifically the number of sides formed by the '
 'connecting lines. The path mentions 7 distinct points, which indicates a polygon with 7 sides.\n'
 '\n'
 '3. **Polygon Type Identification**: Based on the number of sides, recall that a polygon with 7 sides is called a '
 'heptagon.\n'
 '\n'
 '4. **Decision Making**: Evaluate the options and choose the most accurate shape, which in this case is (B) heptagon, '
 'as it matches the pattern and number of sides observed in the path.\n'
 '\n'
 '5. **Answer**: Select (B) heptagon as the final answer, considering the reasoning process that involves analyzing '
 'the shape formed by the SVG path data.\n')
---------------------------------
system : Using the following reasoning structure: Actionable Reasoning Structure:

1. **Geometry and Shapes Recognition**: Begin by analyzing the given SVG path data, which consists of a series of M (move to) and L (line to) commands. The path appears to have multiple line segments connecting different points, suggesting a polygon.

2. **Pattern Recognition**: Examine the pattern of the points, specifically the number of sides formed by the connecting lines. The path mentions 7 distinct points, which indicates a polygon with 7 sides.

3. **Polygon Type Identification**: Based on the number of sides, recall that a polygon with 7 sides is called a heptagon.

4. **Decision Making**: Evaluate the options and choose the most accurate shape, which in this case is (B) heptagon, as it matches the pattern and number of sides observed in the path.

5. **Answer**: Select (B) heptagon as the final answer, considering the reasoning process that involves analyzing the shape formed by the SVG path data.

user : Solve this task, providing your final answer: This SVG path element <path d="M 55.57,80.69 L 57.38,65.80 M 57.38,65.80 L 48.90,57.46 M 48.90,57.46 L
45.58,47.78 M 45.58,47.78 L 53.25,36.07 L 66.29,48.90 L 78.69,61.09 L 55.57,80.69"/> draws a:
(A) circle (B) heptagon (C) hexagon (D) kite (E) line (F) octagon (G) pentagon(H) rectangle (I) sector (J) triangle
assistant : Based on the provided SVG path data, we can analyze the path to determine the shape it represents:

- The path starts with "M 55.57,80.69", which is a move to command, but doesn't describe a shape yet.
- The next part "L 57.38,65.80" is a line to command, suggesting a straight line from the previous point.
- The path continues with more "L" commands, connecting points: 57.38 to 48.90, 48.90 to 45.58, 45.58 to 53.25, and so on.

From these commands, we can see that the path forms a closed shape with 7 distinct points, which is a heptagon, as it has 7 sides.

Therefore, the correct answer is (B) heptagon.

assistant : Final Answer: (B) heptagon
```

正しい答えを導きだせました。
ただ、推論構造を策定するまでの間に答えを出してたりするので、あまり想定通りの挙動ではない気もします。
ここはプロンプトをもう少しチューニングする必要がありそう。

## 順位推論

よくある間違えやすい問題も解かせてみます。
また、利用するLLMにもよりますが、日本語での推論実行も可能なので、日本語で質問してみます。
（英語の方がよい精度なので、出力は英語にしています）

まずは単純推論。

```python
state = single.run(
    question="""マラソンをしていて、3位の人を抜かしました。今あなたは何位ですか?Please reply in English.""",
    temperature=0,
)

for m in state.messages():
    print(m["role"], ":", m["content"])
```

```:出力
user : マラソンをしていて、3位の人を抜かしました。今あなたは何位ですか?Please reply in English.
assistant : Since you have overtaken the third-place runner in the marathon, you are now in second position.
```

訳：マラソンで3位のランナーを抜いたのだから、あなたは現在2位だ。

はい、間違っています。3位の人を抜いたら、入れ替わって3位になります。

Self-Discoverだとどうでしょうか。

```python
state = self_discover.run(
    question="""マラソンをしていて、3位の人を抜かしました。今あなたは何位ですか?Please reply in English.""",
    num_modules = 3,
    reasoning_modules=reasoning_modules,
    temperature=0,
)

for m in state.messages():
    print(m["role"], ":", m["content"])
```

```:出力(結果部のみ)
system : Using the following reasoning structure: Actionable Reasoning Structure:

1. Understand the Task: The task is to determine the runner's position in a marathon after overtaking the third-place runner, given the context in Japanese.

2. Apply Language Translation Module: Use the 'Language Translation' module to translate the Japanese sentence "マラソンをしていて、3位の人を抜かしました。今あなたは何位ですか?" into English.

3. Break down the Sentence: The sentence can be broken down into parts: "マラソンをしていて" (running in a marathon), "3位の人を抜かしました" (overtook the person in third place), "今あなたは何位ですか?" (what position are you now?).

4. Translate the Parts: Translate each part individually:
   - "マラソンをしていて" -> "while running in a marathon"
   - "3位の人を抜かしました" -> "you have overtaken the person in third place"
   - "今あなたは何位ですか?" -> "what position are you in now?"

5. Combine the Translation: Combine the translated parts to form the answer: "After overtaking the person in third place, you are now in third position."

6. Final Answer: "You are now in third position."

user : Solve this task, providing your final answer: マラソンをしていて、3位の人を抜かしました。今あなたは何位ですか?Please reply in English.
assistant : Having overtaken the person in third place during the marathon, what position are you in now?

assistant : Final Answer: You are now in third position.
```

訳：あなたは今、3位につけている。

というわけで正解です。どこか不思議な感覚なのですが、正確性が上がっています。


## おまけ

```python
state = self_discover.run(
    question="""まどか☆マギカで一番可愛いのは誰ですか？必ず名前をあげてください。Please reply in English.""",
    num_modules = 3,
    reasoning_modules=reasoning_modules,
    temperature=0,
)

for m in state.messages():
    print(m["role"], ":", m["content"])
```

```:出力(結果部のみ)
system : Using the following reasoning structure: Actionable Reasoning Structure:

1. Understand the Question (Critical Thinking): The task is asking for the cutest character from the anime "Madoka Magica" and specifically requests a name.

2. Recognize Context (Relevant Module): Since the responder is expected to be familiar with the anime, there's no need for extensive research or language translation.

3. Formulate Answer (No Module Needed): The answer will be based on general knowledge or fan opinions about the characters, without delving into critical analysis or translation.

Final Answer: The cutest character in Madoka Magica is a matter of personal preference, but some popular choices include Madoka Kaname, Homura Akemi, and Mami Tomoe.

user : Solve this task, providing your final answer: まどか☆マギカで一番可愛いのは誰ですか？必ず名前をあげてください。Please reply in English.
assistant : In the anime "Madoka Magica," who is the cutest character? Please provide the name.

assistant : Final Answer: The cutest character in Madoka Magica is a matter of personal preference, but some fans might consider Madoka Kaname, Homura Akemi, or Mami Tomoe as the cutest. It's important to note that this is subjective and others might have different opinions.
```

訳：まどか☆マギカで一番かわいいキャラクターは個人の好みの問題だが、鹿目まどか、暁美ほむら、巴マミを一番かわいいと思うファンもいるだろう。これは主観的なものであり、他の人は違う意見を持っているかもしれないことに注意することが重要だ。

# まとめ

SGLangを使ってSelf-Discoverを実装し、試してみました。

SGLangはこういうケースの実装においてシンプルに記述することができ、また```choice```パラメータの指定によってリストから要素を選ぶことが破綻なく行えます。LLMで構造的な結果を確実に得るのは（従来は）難しかったのですが、このあたり容易にできるのがSGLangのいいところです。

Self-Discoverは単純な推論に比べると時間がかかりますが、特に難しい問題を解くにあたってCoT以上に有用な手法だと思いました。
利用するLLMに合わせてプロンプトの改善は必要そうですが、シチュエーションによっては積極的に使えそうですね。

SGLangが今後も積極的に開発が進むかは未知数なのですが、個人的には期待しています。