見出し画像

Gradioの`ChatInterface`こと始め その3:ドロップダウンの選択追加して、c4ai-command-r-v01を試してみる

Gradioの"ChatInterface"のこと始めの3です。
前回の続きで、additionの部分にドロップダウンが追加することをしてみました。

結論から言うと、以下のコードでできました。

    additional_inputs=[
        gr.Dropdown(
            ["Conversation", "Internet Search", "RAG"], value="Conversation", label="Model Mode", 
            info="Select the mode, Default is Conversation."
                    ),
        gr.Slider(100, 1024, value=250, label="Tokens"),
        gr.Slider(0, 1, value=0.3, label="Temperture")
                        ]

引数としては、message, history, の続きの順番で引き継がれます。

さて、ドロップダウンメニューのお試しとして、日本語の含まれた多言語LLMとして登場した、c4ai-command-r-v01 を使ってみます。
こちらですね。

ちょうど、mlx-communityに4bitバージョンがアップされていたので、こちらを使いました。

このモデルは日本語が使えるだけでなく、ツールが使えると言うことで、例としてinternet searchとRAGの例が載っています。他のツールについても追って発表があるようです。

ドロップダウンメニューの練習として、普通の会話と、インターネットサーチとRAGの3つの選択をするようにしました。

全体のコードは下記です。
remote_codeを実行する形でloadを設定してます。

import time
import gradio as gr
from mlx_lm import load, generate

# https://huggingface.co/mlx-community/c4ai-command-r-v01-4bit
model, tokenizer = load("mlx-community/c4ai-command-r-v01-4bit",
    tokenizer_config={"trust_remote_code": True})

    
# define documents to ground on:
P_documents = [
    { "title": "Tall penguins", "text": "Emperor penguins are the tallest growing up to 122 cm in height." }, 
    { "title": "Penguin habitats", "text": "Emperor penguins only live in Antarctica."}
]

# Define tools available for the model to use:
tools = [
  {
    "name": "internet_search",
    "description": "Returns a list of relevant document snippets for a textual query retrieved from the internet",
    "parameter_definitions": {
      "query": {
        "description": "Query to search the internet with",
        "type": 'str',
        "required": True
      }
    }
  },
  {
    'name': "directly_answer",
    "description": "Calls a standard (un-augmented) AI chatbot to generate a response given the conversation history",
    'parameter_definitions': {}
  }
]



def predict(message, history, model_mode, token, temp_value):
    prompt = []

    for human, assistant in history:
        prompt.append({'role': 'user', 'content': human})
        prompt.append({'role': 'assistant', 'content': assistant})
        
    prompt.append({'role': 'user', 'content': message})
    #print  (f"履歴の形はこんな感じ:\n {history}")
    #print  (f"promptの形はこんな感じ:\n {prompt}")
    # render the tool use prompt as a string:
    if model_mode == "Conversation":
        inputs = tokenizer.apply_chat_template(prompt,
                                           tokenize=False,
                                           add_generation_prompt=True)
                                           
    elif model_mode == "Internet Search":
        inputs = tokenizer.apply_tool_use_template(prompt,
                                            tools=tools,
                                            tokenize=False,                                                add_generation_prompt=True)
    elif model_mode == "RAG":
        inputs = tokenizer.apply_grounded_generation_template(prompt,
                                            documents=P_documents,
                                            citation_mode="accurate", # or"fast"
                                            tokenize=False,
                                            add_generation_prompt=True)            
                                           
    #full_prompt  = f"<|system|>{system_message}\n{inputs}"
    print (f"入力される最終プロンプトはこんな感じ:\n{inputs}")
    response = generate(model, tokenizer, prompt=inputs, temp = temp_value, max_tokens = token, verbose=False) 
    #return  response.strip()
    for i in range(len(response)):
            time.sleep(0.05)
            yield response[: i+1]

demo = gr.ChatInterface(predict, 
    title="mlx-community/c4ai-command-r-v01-4bit",
    description="selct Conversation or Search or RAG mode in addition",
    additional_inputs=[
        gr.Dropdown(
            ["Conversation", "Internet Search", "RAG"], value="Conversation", label="Model Mode", 
            info="Select the mode, Default is Conversation."
                    ),
        gr.Slider(100, 1024, value=250, label="Tokens"),
        gr.Slider(0, 1, value=0.3, label="temperature")
                        ]
                       )

if __name__ == "__main__":
    #demo .queue().launch()
    demo.launch()

ドロップダウンメニュー部分はこんな感じに表示されます。

押すと、こんな感じで選べます。

会話モードでは普通に日本語でやり取りできます。
なかなか整った日本語が生成されます。まれに単語が英語のまま混じりますが、それでもかなりいい感じだと思います。

こんにちは、あなたは誰? 自己紹介してください。

こんにちは!私は「ChatBot」という名前のAIチャットボットです。AI技術の一つとして、人間のようなやりとりを目指して開発されました。色々な話題についてお話しできますし、質問に答えたり、お役立ち情報を提供したりすることが大好きです。私の名前は自由に付けていただいて構いませんし、私のことをより親しみを込めて呼んでいただいても嬉しいです。どうぞよろしくお願いします!

人生の意味をメタファーやアナロジーを使って説明してください

人生を川に例えるとしましょう。

人生は、大川の壮大な旅のようなものです。各々が独自の川を下っていき、急流や穏やかな流れ、時々は激流に巻き込まれ、時には方向を見失うことも。川は山や谷、絶景や荒野など、様々な景色を通り抜けます。時々、川は穏やかになり、ゆったりと流れることもあれば、急流に巻き込まれ、激しく泡立ち、方向を見失うこともあります。

私たちはその川にのって旅をしている船乗りで、川幅が狭まったり、広がったりする度に、進むべき道に悩むこともあります。時々は、自分の進む方向が正しいのか、不安になったりもするでしょう。でも、川は必ず海に辿り着きます。そこが人生のゴールであり、私たちが目指す安らぎの場所なのです。海は、私たちが人生で目指す「達成」や「満足」の象徴です。

私たちには、それぞれに異なる川幅や流れが与えられています。誰かの川はゆったりと穏やかで、進むべき道がはっきりしていることもあれば、別の誰かは激流に巻き込まれ、進むべき道を模索することもあるでしょう。大切なのは、自分の川の流れに合わせてパドルをこぎ、最善の方法を見つけ、進み続けることです。そして、いつかは皆、広大な海に辿り着くのです。

今は3月です。日本の春を待ち望む詩を書いてください。

三月の風に誘われて目覚める花々よ

冬の寒さに耐え、ひっそりと眠っていた花たちよ
待望の春が今、そっと訪れる

雪解けの風が吹く中、桜がほほえみかけ
その一足先に、梅が華やかに彩る
可憐な花々が、春の訪れを告げる

木々も新芽を膨らませ、鮮やかな緑の装い
風に揺れる姿、陽光浴びて舞うように
生命の息吹が、街に溢れ出す

空は青く澄み渡り、優しい陽光が降り注ぐ
そんな中、新生活が始まる
希望に満ちた心で、未来描く

旅立ちの季節、新しい風が吹く
春、命の息吹を胸に刻みながら
私たちはまた一歩、進み始める

桜の花弁が舞い散るように、夢や希望も舞い込みなさい
あなたの心に春が来ますように

なかなか端正な日本語が生成されてくる印象です。

さて、インターネットサーチモードは、サンプル通りJSON形式で出力されます。
アメリカの大統領選の様子を調べて。

Action: json [ { "tool_name": "internet_search", "parameters": { "query": "\u30a2\u30e1\u30ea\u30ab\u306a\u306e\u30c7\u30b6\u30b9\u30bf\u30b9\u30fb\u30d7\u30ea\u30b7\u30e7\u30f3\u4f5c\u306b\u306a\u308b\u305f\u306a\u305f\u306e\u30fb2\u306a\u309a\u306e\uff1f" } } ]

Search about the election of the U.S. President.

Action: json [ { "tool_name": "internet_search", "parameters": { "query": "US president election process" } } ]

RAGもサンプル通りの質問をしたら、サンプル文書にそった回答がでました。
Whats the biggest penguin in the world?

Relevant Documents: 0,1

Cited Documents: 0,1

Answer: The largest species of penguin is the emperor penguin (Aptenodytes forsteri). Emperor penguins can grow to be around 122 cm tall and weigh up to 40kg. They are found only in Antarctica.

Grounded answer: The largest species of penguin is the <co: 0>emperor penguin</co: 0> <co: 0>(Aptenodytes forsteri)</co: 0>. Emperor penguins can grow to be around <co: 0>122 cm tall</co: 0> and weigh up to 40kg. They are <co: 1>found only in Antarctica.</co: 1>

とは言え、ドキュメントにないこと(40キロとか)まで言っていますね(苦笑
ドキュメント内容は以下です。

P_documents = [ { "title": "Tall penguins", "text": "Emperor penguins are the tallest growing up to 122 cm in height." }, { "title": "Penguin habitats", "text": "Emperor penguins only live in Antarctica."} ]

さらに、ドキュメントにない一番小さなペンギンはと尋ねてみたら・・・
Whats the smallest penguin in the world?

Relevant Documents: 2,3

Cited Documents: 2,3

Answer: The smallest species of penguin is the little blue penguin, also known as the fairy penguin. They stand at around 43 to 48 centimetres tall and weigh approximately 2 to 3 kilograms. Native to New Zealand, these penguins are one of the few penguin species that live in the Northern Hemisphere.

Grounded answer: The smallest species of penguin is the <co: 2,3>little blue penguin</co: 2,3>, also known as the <co: 3>fairy penguin.</co: 3> They stand at around <co: 2>43 to 48 centimetres tall</co: 2> and weigh approximately <co: 3>2 to 3 kilograms.</co: 3> <co: 3>Native to New Zealand</co: 3>, these penguins are <co: 3>one of the few penguin species that live in the Northern Hemisphere.</co: 3>

存在しないドキュメント番号3を引っ張り出しながら、なかなか華麗に幻覚を生み出してきました(苦笑

4bitの量子化の所為でしょうか。登録したら、開発会社のほうでこのモデルを試せるようでしたが、登録までと思って試してません。

ぜひエネルギーのある人は上記で試してみてください。

あと、上記のスクリプトはhistoryを用いてプロンプトを作り上げているので、RAGモードからConversationモードに戻っても、RAGモードの出力形式で表示されたりしますので、普通に会話に戻りたかったら、Clearで履歴を消したほうがよいかと思います。

下は履歴を消さなくてもうまくいった例です。
じゃあ、普通の会話に戻って、日本のアニメについて紹介して。

はい、喜んで!日本のアニメは世界的に非常に人気があります。ここでは、日本のアニメ作品についてお話ししましょう!

日本のアニメは多彩なジャンルが揃っていますが、世界的に特に有名なのは、漫画やアニメとして映像化もされた「ONE PIECE」でしょう。尾田栄一郎氏による冒険漫画で、海賊を目指して旅する主人公・ルフィの物語です。世界中を魅了し、アニメは長年続いている人気作品で、映画化もされています。

また、もう一つ外せないのが、やはり「仮面ライダー」シリーズです。変身ヒーローものの先駆けであり、日本だけでなく海外でも多くのファンを持ち、変身ベルトなどの玩具も大ヒットしました。現在でもシリーズが続いている長寿番組で、世代を超えて愛される作品です。

そのほかには、「ドラゴンボールZ」や「NARUTO -ナルト-」も世界中で大人気です。どちらも漫画が原作で、アニメ化され、ゲームや映画など、様々なメディアミックスも展開されました。世界観も戦闘シーンも迫力満点で、海外でも多くのファンを獲得しています。

最近では、アニメ「鬼滅の刃」も大ヒットしました。大正時代を舞台に、家族を殺された少年が鬼に立ち向かう物語で、映画も大ヒットを記録しました。アニメならではの迫力ある戦闘シーンや、美しい作画、心に響くストーリーが人気の理由です。

日本のアニメは、独特の絵柄やストーリー展開、迫力あるアクションなどで世界を魅了し続けています。どれも日本発の文化であり、日本の文化産業を世界にアピールする存在になっています。

ともあれ、整った日本語がでてくる多言語モデルとしてはいい線なのかもしれません。日本語と英語しか試してませんが・・・。

あと最後に、chat_templateの解説がHuggingfaceにちゃんと掲載されていました。こちらです。


P.S.
 RAGでtemperatureを0にしたらどうかなと思いましたが、やっぱりダメでした。人間で一番背の高い人はと尋ねたら、ドキュメントを勝手に作って回答してきました。

Relevant Documents: 4,5,6,7,8
Cited Documents: 4,5,6,7,8
Answer: Robert Wadlow, born in the United States, was the tallest man in medical history. His height was 272 cm (8 feet, 11.1 inches) when he died at the age of 22. Due to a hormone disorder, Wadlow suffered from extreme growth during his lifetime.

The second tallest man in history is said to be Sultan Kösen from Turkey who stands at 251 cm tall. Both of these individuals suffered from gigatism, a condition causing excessive growth due to a rare medical condition.

Additionally, some sources also note the height of an unknown ancient Egyptian man. An ancient Egyptian skeleton, found to be around 3,400 years old, had a reconstructed height of around 262 cm. This makes this individual the tallest ancient human known to archeology.
Grounded answer: <co: 4,5>Robert Wadlow</co: 4,5>, born in the <co: 4>United States</co: 4>, was the <co: 6>tallest man in medical history.</co: 6> His height was <co: 5>272 cm (8 feet, 11.1 inches)</co: 5> when he <co: 5>died at the age of 22.</co: 5> Due to a <co: 5>hormone disorder</co: 5>, Wadlow suffered from <co: 5>extreme growth during his lifetime.</co: 5>

The <co: 7>second tallest man</co: 7> in history is said to be <co: 7>Sultan Kösen</co: 7> from <co: 7>Turkey</co: 7> who stands at <co: 7>251 cm</co: 7> tall. Both of these individuals suffered from <co: 5,7>gigatism</co: 5,7>, a condition causing <co: 5,7>excessive growth</co: 5,7> due to a <co: 5,7>rare medical condition.</co: 5,7>

Additionally, some sources also note the height of an <co: 8>unknown ancient Egyptian man.</co: 8> An <co: 8>ancient Egyptian skeleton</co: 8>, found to be <co: 8>around 3,400 years old</co: 8>, had a <co: 8>reconstructed height of around 262 cm.</co: 8> This makes this individual the <co: 8>tallest ancient human</co: 8> known to archeology.


#AI #AIとやってみた #やってみた #ローカルLLM #大規模言語モデル #Huggingface #mlx #MacbookPro #Gradio

この記事を最後までご覧いただき、ありがとうございます!もしも私の活動を応援していただけるなら、大変嬉しく思います。