Local-Novel-LLM-projectのモデルをmlx & Gradioで試してみる
日本語の生成を目指したLocal-Novel-LLM-projectからいくつかモデルが発表されました。#ローカルAIハッカソン で優勝したプロジェクトです。
プロジェクトリーダーはこの方です。
さて、おそらく、これらのモデルを一番簡単に動かせるのは、下記のものを使うことだと思います。
ただ自分はメインがMacですので、Macのmlx環境とGradioを使って試してみました。
印象は、しっかりした日本語を生成してくれて、なおかつ長文生成をしてくれるという感じを持ちました。
モデル種類には、小説生成向けのNinjaと会話向けのVecteusと、あたらしく小説能力ではなくコードや数学系の知識を持たせたというAssistanceが追加されています。
今回は、Vecteus とNinjaを試してみました。
Chat Templateは Vicuna形式がお勧めということなので、それを使ってみます。(特にこの形式を指定しなくても、最後に掲載するスクリプトでは動きました。また、このスクリプトでいいのか自信がありませんが、動いてるのでヨシとしておきます。)
システムメッセージは、今回は以下としました。Wizradの代わりにモデル名Vecteusに変えただけです。
"A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user's questions. USER: Hi ASSISTANT: Hello.</s>USER: Who are you? ASSISTANT: I am Vecteus.</s>"
最後に掲載のスクリプトだと適当に書き換えることができるので、書き換えて試してください。
なおモデルカードによると、"あなたはプロの小説家です。\n小説を書いてください\n-------- " プロンプト "\n-------- " が例としてのっています。
生成例
Vecteus
人生の意味を論じて
メタファーやアナロジーを使って説明して
猫視点で、猫の一生の意味を、猫の語り口調で語って
なかなか優れた生成がでてきますね!
Ninja
人生の意味を論じて
人生の意味とは何か。これは永遠の命題であり、人類共通の関心事の一つです。人生の意味を見出すことは、多くの人々にとって重要な意義を持ちます。また、人生の意味は人によって異なり、一つの答えがあるわけではありません。ここでは、人生の意味についていくつかの視点や考え方を紹介します。
人生は生まれる前から決まっているという視点
この考え方では、人生は神や運命によって事前に定められており、その道筋に沿って生きることが幸せへの近道だとされています。つまり、自分の意志や努力よりも、与えられた運命を受け入れることが重要だという考え方です。人生は自分で決めることができるという視点
この考え方では、人生は自己決定によって豊かになることができるとされます。自分の選択や努力によって、人生はいくらでも変えることができ、自己実現や成長を目指すことができるという考え方です。人生は他者との関わり合いによって生じるという視点
人生において他者とのつながりは非常に重要です。家族、友人、恋人、同僚など周囲の人々との関わり合いが、自分を形成し、成長させ、幸せをもたらします。人生の意味は、他者との関わり合いを通して見出されるという考え方です。人生は社会や世界への貢献によって発見されるという視点
自分が社会や世界に対してなすことができる貢献を見つけ、それを実現することが人生の意味だという考え方です。社会的使命を見出すことで、生きる意味や目的を見出すことができます。人生は楽しむことにあるという視点
人生は楽しむためにあるという考え方です。人生には限りがあります。だからこそ、自分の好きなことや楽しいことを追求し、充実した時間を過ごすことが大切だという考え方です。人生は冒険であるという視点
人生は予測不可能な冒険であり、未知の体験をすることが人生の醍醐味だという考え方です。新しいことに挑戦し、未知の世界に飛び込むことで、人生には無限の可能性が広がっているという視点です。
これらの視点を踏まえつつ、人生の意味を探求してみてください。そこには、あなただけの人生の意味が見つかるはずです。重要なのは、他者の視点や価値観を受け入れつつも、自分の心に従って生きることです。自分自身に問いかけ、自らの心と対話を続けることで、人生の意味を見出すことができるでしょう。
メタファーやアナロジーを使って説明して
メタファーやアナロジーを使うことは、抽象的な概念や複雑な事柄を、より理解しやすく伝えるのに非常に有効な手法です。以下では、人生の意味に関するいくつかのメタファーやアナロジーを用いて説明します。
旅路に例える
人生を旅に例えると、私たちは生まれた瞬間から旅路につきます。旅路では、いくつもの分岐点があり、選択肢が与えられます。道中には美しい景色もあれば、困難な山や試練の谷もあります。旅を続ける中で出会う人々や経験は、私たちに新しい視点や知恵をもたらします。最終的に目指す場所、つまりゴールが人生の意味と考えることができます。料理に例える
人生を料理に例える場合、様々な食材があります。それぞれの食材は、人生における個性や才能、経験や知識に似ています。料理人である自分は、それらの食材を選び、調理することで美味しい料理を作り出します。そして、その料理を食べる人々が幸せになることが、料理人である自分の目的、つまり人生の意味となるのです。樹木に例える
人生を大きな樹木に例えると、幹が自分自身のコアな部分、つまり自分の価値観や信念、人生哲学にあたります。枝葉は、人生におけるさまざまな経験や関係、功績、成果などです。強く太い幹があってこそ、たくさんの枝葉を茂らせることができ、大きく成長した樹木は周囲に影響を与え、環境を改善します。人生の意味とは、このような樹木になることではないでしょうか。楽器演奏に例える
人生を楽器演奏に例えると、自分は楽器であり、音楽は自分の人生です。楽譜は人生の目標や計画に当たり、演奏は日々の行動や経験に対応します。楽器を上手に演奏するには、正しい楽譜の読み方を覚え、基礎練習を重ね、実際に演奏して経験を積むことが必要です。人生の意味とは、自分自身の楽器を完璧に演奏し、美しい音楽を奏でることかもしれません。
これらのメタファーやアナロジーは、抽象的な概念を具体的なイメージに置き換えることで、より理解しやすくしてくれます。自分がどのような人生を送りたいのか、どのような自分でありたいのか、これらの例えを通して考えてみると良いでしょう。
猫視点で、猫の一生の意味を、猫の語り口調で語って
にゃあ、猫のにゃんこだにゃ。猫ってのは基本的に、のんびりまったり、自由気ままに生きる生き物なんだにゃ。そんなに深く考え込むことはないにゃあ。
生まれたばかりのころは、母さん猫のおっぱいを吸って、ふわふわの毛玉みたいにまるくなって、ぬくぬくと過ごす毎日だにゃ。そこから少し大きくなると、自分で食べ物を探したり、小さい兄弟や姉妹と遊んだりするんだにゃ。遊ぶことは、猫の大事なお仕事なんだ。
しばらくすると、自分一人で生きていくための術を学び始めるんだ。狩りの仕方や、危険な場所の見分け方、それに上手なお昼寝の場所探しなんかもね。
成長すると、めぼしい食べ物を見つけたら自分で狩りをするようになるにゃ。時には失敗することもあるけど、それもまたお勉強なんだにゃ。
年をとると、のんびりした場所で日向ぼっこをしたり、一緒に暮らしている人間や他の猫と過ごす時間が増えるにゃ。それでも狩りはできるときにするもんだにゃ。
年を取って動けなくなったら、それが自分の一生なんだと受け入れるんだにゃ。それまで頑張って生きてきたんだから、最後まで自分のペースで生きるんだにゃ。
猫の一生の意味ってのは、生まれてきてから死ぬまで、自由気ままに自分のペースで生きることなんだにゃ。それが、うちら猫にとっての一番の幸せなんだにゃ。
生まれてきたことに意味がある、とか、何かを成し遂げなきゃいけない、とか、そんなのは人間が作った勝手な考え方で、猫には関係ないことなんだにゃ。
大事なのは、今を楽しく生きることなんだにゃ。そうすれば、自然といいことが舞い込んでくるにゃあ。
にゃんこは、そう思うにゃ。人間さんも、難しく考えずに今を楽しく生きればいいんだにゃ。
以上、猫のにゃんこが語った、猫視点の猫の一生の意味だったにゃ。参考になったかにゃ?
とっても日本語が上手な感じです。ロールプレイでのキャラ付けも上手くいくのではという印象です。
7Bですし、gguf量子化もされているモデルもありますので、気楽に楽しめるのではないでしょうか。
スクリプト
(mlx環境:load内でmodel_1か2を選択)
import gradio as gr
import time
from mlx_lm import load, generate
model_1 = "Local-Novel-LLM-project/Vecteus-v1"
model_2 = "Local-Novel-LLM-project/Ninja-v1-NSFW-128k"
model, tokenizer = load(model_1)
vicuna_template = (
"{% for message in messages %}"
"{% if message['role'] == 'system' %}"
"{{ '' + message['content'] + '\n\n' }}"
"{% else %}"
"{% if message['role'] == 'user' %}"
"{{'USER: ' + message['content'] + '\n'}}"
"{% else %}"
"{{'ASSISTANT: ' + message['content'] + '</s>\n' }}"
"{% endif %}"
"{% endif %}"
"{% endfor %}"
"{% if add_generation_prompt %}"
"{{'ASSISTANT:'}}"
"{% endif %}"
)
def predict(message, history, system_message, 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})
prompt.insert(0, {'role': 'system', 'content': system_message})
inputs = tokenizer.apply_chat_template(prompt,
tokenize=False,
chat_template = vicuna_template,
add_generation_prompt=True)
full_prompt = inputs
print (f"入力される最終プロンプトはこんな感じ:\n{full_prompt}")
response = generate(model, tokenizer, prompt=full_prompt, temp = temp_value, max_tokens = token, verbose=False)
for i in range(len(response)):
time.sleep(0.05)
yield response[: i+1]
demo = gr.ChatInterface(predict,
title="local novel llm project",
description="",
additional_inputs=[
gr.Textbox("A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user's questions. USER: Hi ASSISTANT: Hello.</s>USER: Who are you? ASSISTANT: I am Vecteus.</s>", lines=5, max_lines=50, label="System Prompt"),
gr.Slider(100, 4096, value=2048, label="Tokens"),
gr.Slider(0, 1, value=0.8, label="Temperture")
]
)
if __name__ == "__main__":
demo.launch()
#AI #AIとやってみた #やってみた #Huggingface #ローカルLLM #mlx #Macbook #大規模言語モデル