見出し画像

MLXで、aixsatoshi/Honyaku-13b を動かしてみる with Gradio on MacbookPro

とある場所で話題になっていたので気になって動かしてみました。
話題としては、以下のポストからコスパいいのではということです。

メインで使ってるのは、Macbook Proなのでmlx環境で動くかをまずは試してみます。元モデルはこちら↓

architectureは"LlamaForCausalLM"ということなので、多分mlx-lmで動くのではないかと、コマンドラインでまずは実行。

(M3Max 64GB MacbookPro です)

mlx環境で、mlx-lmをインストールしてたら、以下の1行で動きました。

python -m mlx_lm.generate --model aixsatoshi/Honyaku-13b --prompt "<english>: {In an era marked by rapid globalization, the intricate interplay between international law, economic policies, and political dynamics has become increasingly complex. } <NL>\n\n<japanese>:"

実は、間違いがあって上から { }は要らないとのことでした。久しぶりにpython触ったので勘違い…
以下のXのPostで作者さんのAI𝕏サトシさんにいろいろとご教示いただけました。

いただいたPostへのリンクをいろいろ

さらに、全体的な解説ポストも投稿していただき感謝です。

さらに、さらに、実行イメージまでもポストしてもらえてます。

以上のように、そこそこの長さの文章を翻訳することがメインということなので、CLIで試すのは諦めて、Gradioを使うスクリプトでやってみました。Gradio & translation でgoogle検索したら、雛形として使えそうなスクリプトがでてきたので、そちらをちょこちょこと改変してみました。

その結果動いてくれたのが下の通りです。NHKの英語ニュースを訳してもらった例です。

上で走らせたスクリプトは下記の通りです。streaming生成と、一括生成の両方をfnで定義してますので、お好きな方を使ってみてください。

import gradio as gr
from mlx_lm import load, generate
import mlx.core as mx
from mlx_lm.utils import load, generate_step


model, tokenizer = load("aixsatoshi/Honyaku-13b")

stop_words = ["<NL>","</s>"]

def translate(text):
    prompt = f"<english>: {text} <NL>\n\n<japanese>:"
    response = generate(model, tokenizer, prompt, max_tokens=4096, top_p=0.95, temperature=0.6)
    return response
    
def translatestream(text):
    tokens = []
    skip = 0
    prompt = f"<english>: {text} <NL>\n\n<japanese>:"
    
    for (token, prob), n in zip(generate_step(mx.array(tokenizer.encode(prompt)), model, temp=0.6, top_p=0.95,),
                                range(4096)):

        if token == tokenizer.eos_token_id:
            break

        tokens.append(token)
        text = tokenizer.decode(tokens)

        trim = None

        for sw in stop_words:
            if text[-len(sw):].lower() == sw:
                # definitely ends with a stop word. stop generating
                return
            else:
                # if text ends with start of an end word, accumulate tokens and wait for the full word
                for i, _ in enumerate(sw, start=1):
                    if text[-i:].lower() == sw[:i]:
                        trim = -i

        # flush text up till trim point (beginning of stop word)
        yield text[skip:trim]


demo = gr.Interface(
    fn=translatestream,
    inputs=[
        gr.components.Textbox(label="Text", lines=20),
            ],
    outputs=["text"],
    examples=[["Building a translation demo with Gradio is so easy!"]],
    cache_examples=False,
    title="aixsatoshi/Honyaku-13b",
    description="This demo is a simplified version of the original [NLLB-Translator](https://huggingface.co/spaces/Narrativaai/NLLB-Translator) space"
)

demo.launch()

ちなみに、不勉強で、Gradioの画面の翻訳出力の下に表示されるFlagって何かが分かってません(汗

量子化される mlx形式 には変換せずに、そのまま使っていますので、上の動画ぐらいのスピードです。

短文が苦手とのことなので、会話を楽しむ用途でのLLMの英語出力に用いるのはちょっと難しいのかなという感想です。

そうではあっても、随分前に使ったことのあるロゴヴィスタとかの翻訳ソフトと比べて、手元でこんなに綺麗な日本語で翻訳できるという進歩はすごい時代だなぁと思っています。


#AI #AIとやってみた #やってみた #ローカルLLM #大規模言語モデル #翻訳 #huggingface


いいなと思ったら応援しよう!

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