Stable Code Instruct 3B を Mac で簡単に高速で動かす方法

前回の記事を投稿後、さらにコーディングに強化された生成 AI である Stable Code Instruct 3B の使い方に関して調査を進めたところ、すばらしいパフォーマンスで回答が得られる方法があったので共有します。簡単なテストしかできていませんが、かなり使える印象です。Mac ローカルで動き、無料でネット接続も不要、そして速い。日本語もかなりお上手。当面のコーディングは Stable Code Instruct 3B に頼って生きられそうです。

MLX-LM で使えた

「”Stable Code Instruct 3B” mac」とググって見つけたのがこちらの X への投稿です。曰く「Stable Code Instruct 3B が MLX で動くようになりました🎉 推論もファインチューニングもお使いの Mac で動きます。

一週間も前に投稿されていたのになぜ昨日は見つからんかった。。。ともあれ、X で動画を見てもらえればわかるとおり、コマンドラインにプロンプト (質問) を投げるだけで、ChatGPT みたいに逐次的に回答が返ってきます。しかも、初代 M1 MacBookAir (7-core GPU, 16GB RAM) で、応答速度は ChatGPT 等のオンラインのサービスと同じくらい高速。すごい、すごすぎる。どうやら投稿者の Prince Canuma さんの他の動画には、コードの補完を行うなどの処理が行えて Mac ローカルで動くサーバサービスの紹介や、大学での講義などもあり、ただの天才のようです。なーんだ。

インストール方法

上の X に書いてますがせっかくなので。本当に必要なのはこれだけ。

pip install -U mlx_lm

ローカルに仮想環境を作ってモデルもダウンロードして、とするならこんな感じ (↓)。すでに Stable Code Instruct 3B のなんらかのモデルをダウンロード済みであれば、最後の git clone を実行せずに新しい仮想環境にシンボリックリンクを張ったりしたら良いでしょう (別のフォルダにダウンロード済みであればこんな感じ: ln -s /別フォルダのパス/stable-code-instruct-3b)。

mkdir MLX_LM
cd MLX_LM
pipenv --python 3.11
pip install -U mlx_lm
git clone https://huggingface.co/stabilityai/stable-code-instruct-3b

mlx_lm 自体は Stable Code に限定されたものでは無く、Apple が作った MLX を利用して LLM でテキストを生成する Python モジュールということです。詳しい使い方は PyPI のプロジェクト説明ページ も見てください。

実行方法

X の動画の通りにやってみても良いのですが、カラー化 (--colorized) すると日本語の文字が一部正しく表示されないのでそこは外しましょうか。コード生成を試す前に、知識を問う質問をした結果を紹介します。以下、プロンプトを含んだコマンドラインとなります。

python -m mlx_lm.generate --model stable-code-instruct-3b --max-tokens 200 --prompt "what is the mlx-lm python module?"

使ったオプションの説明

全てのオプションを見るには: python -m mlx_lm.generate --help

  • --model stable-code-instruct-3b ローカルに保存したモデルを相対パスで指定しています。Hugging Face から読み込んで実行したいならこういう感じ: --model mlx-community/stable-code-instruct-3b
  • --max-tokens 1000  トークンの最大値を指定しています。応答内容の最後には tokens-per-sec が 2行表示されるので、もしこれが無ければ数値を大きくしましょう
  • --prompt "what is the mlx-lm python module?" ダブルクォーテーションの中に質問を書きます。日本語も使えます

実際に出力された内容はこちらです。先ほどインストールしたモジュール mxl_lm の説明をしてくれています。”developed by the Melting Potato project” と言っていますが、間違っている感じがします。サンプルがまずかったか他の部分も確実に評価はできませんが、3B のモデルでもあり、鵜呑みにはできません。

000 --prompt "what is the mlx-lm python module?"
None of PyTorch, TensorFlow >= 2.0, or Flax have been found. Models won't be available and only tokenizers, configuration and file/data utilities can be used.
Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.
==========
Prompt: <|im_start|>system
You are a helpful assistant.<|im_end|>
<|im_start|>user
what is the mlx-lm python module?<|im_end|>
<|im_start|>assistant

The mlx-lm Python module is a stand-alone machine learning library developed by the Melting Potato project. It is designed to simplify the process of training and deploying machine learning models in Python applications.

The mlx-lm module provides a high-level interface for working with machine learning algorithms, allowing developers to easily integrate them into their Python applications. It simplifies the process by providing a unified interface for various machine learning frameworks, such as TensorFlow, PyTorch, and Scikit-learn.

Here are some key features of the mlx-lm module:

1. **Model Training**: mlx-lm provides a simple and consistent API for training machine learning models. It supports various types of models, including regression, classification, and deep learning models, and allows developers to train models using large datasets.

2. **Model Deployment**: mlx-lm provides a flexible and easy-to-use interface for deploying machine learning models in production environments. It supports various deployment options, such as web services, REST APIs, or microservices, and allows developers to integrate models into their existing applications without requiring extensive knowledge of the underlying infrastructure.

3. **Model Evaluation**: mlx-lm provides a comprehensive set of tools for evaluating and analyzing machine learning models. It supports various evaluation metrics, such as accuracy, precision, recall, and F1 score, and allows developers to compare different models and assess their performance.

4. **Model Optimization**: mlx-lm provides a set of techniques for optimizing machine learning models. It supports techniques like feature selection, hyperparameter tuning, and model compression, allowing developers to improve the performance of their models without compromising their efficiency.

5. **Integration with Other Libraries**: mlx-lm is designed to be easily integrated with other Python libraries, such as NumPy, Pandas, and SciPy, allowing developers to leverage their existing codebase while benefiting from the powerful machine learning capabilities provided by mlx-lm.

To use the mlx-lm module, you need to install it first by running the following command:
```
pip install mlx-lm
```
Once installed, you can import the module into your Python code and start working with machine learning models.

Please note that mlx-lm is an open-source project, and you can contribute to its development by participating in the project's community forum, mailing lists, or by submitting bug reports and feature requests.<|im_end|>

==========
Prompt: 213.558 tokens-per-sec
Generation: 38.486 tokens-per-sec

Stable Code Instruct 3B は日本語もイケる

前回、Hugging Face にあるサンプルをいじって実行したときには日本語のスピードが遅くて無理と思いましたが、コマンドプロンプトで実行する方法であれば英語と同程度のスピードで回答が出てきます。以下、プロンプトとその回答です。コードを書いてもらえれば実行することで評価ができますし、Stable Code Instruct の本領がここにあります。

python -m mlx_lm.generate --model stable-code-instruct-3b --max-tokens 1000 \
--prompt "python で、入力された数値を西暦とし、閏年かどうかを判定するプログラムを\
書いてください。また、閏年の場合は、2月29日の曜日も答えるようにしてください。"
None of PyTorch, TensorFlow >= 2.0, or Flax have been found. Models won't be available and only tokenizers, configuration and file/data utilities can be used.
Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.
==========
Prompt: <|im_start|>system
You are a helpful assistant.<|im_end|>
<|im_start|>user
python で、入力された数値を西暦とし、閏年かどうかを判定するプログラムを書いてください。また、閏年の場合は、2月29日の曜日も答えるようにしてください。<|im_end|>
<|im_start|>assistant

以下は、Pythonで西暦を判定し、閏年かどうかを判定するプログラムです。閏年の場合は、2月29日の曜日も答えるようにしてあります。

```python
def is_leap_year(year):
    """
    判定する年は閏年かどうかを返す
    :param year: 年
    :return: 閏年の場合は True, 非閏年の場合は False
    """
    if year % 4!= 0:
        return False
    elif year % 100!= 0:
        return True
    elif year % 400!= 0:
        return False
    else:
        return True

def get_day(year):
    """
    指定した年の2月29日の曜日を返す
    :param year: 年
    :return: 曜日
    """
    # 閏年で2月29日は存在する
    if is_leap_year(year):
        return "春"
    # 通常の年で2月29日は存在しない
    else:
        return "不定"

# 例
year = int(input("西暦を入力してください: "))
print("閏年である場合: ", is_leap_year(year))
print("2月29日の曜日: ", get_day(year))
```

西暦を入力すると、プログラムは閏年かどうかを判定して、結果を表示する。さらに、2月29日の曜日を表示する。

例:
西暦を入力してください: 2020
閏年である場合:  True
2月29日の曜日:  春

例:
西暦を入力してください: 1900
閏年である場合:  False
2月29日の曜日:  不定

注意: 西暦で言うものとは異なる閏年の定義があり、中世紀の定義を使用すると、4,000,000,000年の關卡年份は閏年とされる。上記プログラムは、日本の閏年定義を使用する。<|im_end|>

==========
Prompt: 563.968 tokens-per-sec
Generation: 35.775 tokens-per-sec

RAM (32GB) と GPU (30-core)の使用状況はこんな感じです。かなり短いですが、スワップが発生していました。

赤いのがスワップが発生した (SSD をメモリとして使用した) 時

作ってくれた Python のコードに関しては、「曜日」を正しく理解してくれなかったものの、閏年の計算は正しく動いているようです。以下は Python コード部分をファイルに保存して実行したサンプルです:

% python leapYearCheck.py
西暦を入力してください: 2024
閏年である場合:  True
2月29日の曜日:  春
% python leapYearCheck.py
西暦を入力してください: 2023
閏年である場合:  False
2月29日の曜日:  不定

週イチで出会いと別れがあるのはつらいので、曜日を理解してくれるように、プロンプトに英語を追加してみました。

python -m mlx_lm.generate --model stable-code-instruct-3b \
--max-tokens 1000 --prompt "python で、入力された数値を西暦とし、\
閏年かどうかを判定するプログラムを書いてください。\
また、閏年の場合は、2月29日の曜日 (day of the week) も答えるようにしてくだい。"
None of PyTorch, TensorFlow >= 2.0, or Flax have been found. Models won't be available and only tokenizers, configuration and file/data utilities can be used.
Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.
==========
Prompt: <|im_start|>system
You are a helpful assistant.<|im_end|>
<|im_start|>user
python で、入力された数値を西暦とし、閏年かどうかを判定するプログラムを書いてください。また、閏年の場合は、2月29日の曜日 (day of the week) も答えるようにしてくだい。<|im_end|>
<|im_start|>assistant

以下は、Pythonで西暦を判定し、閏年かどうかを判定するプログラムです。閏年の場合は、2月29日の曜日も答えます。

```python
def is_leap_year(year):
    """
    判定する条件は、以下の通り
    1. 年は4で割り切れる場合、または100で割り切れる場合、または400で割り切れる場合、それぞれ2, 5, 0と対応
    2. 上記以外の年は、閏年とは判定しない
    """
    if (year % 4 == 0 and year % 100!= 0) or (year % 400 == 0):
        return True
    return False

def day_of_week(year, month, day):
    """
    月曜日で0、火曜日で1、....、土曜日で6、日曜日で7
    """
    t = [0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4]
    year -= month < 3
    return (year + year // 4 - year // 100 + year // 400 + t[month-1] + day) % 7

year = int(input("Enter a year: "))
if is_leap_year(year):
    print(f"{year} is a leap year.")
    print(f"The day of the week for February 29 is {['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][day_of_week(year, 2, 29)]}.")
else:
    print(f"{year} is not a leap year.")
```

注意: 年は0-basedで入力する必要があり、誤入力時にエラーが出る可能性があります。

また、曜日も0-basedで表現される点についても注意が必要です。

上記プログラムは、閏年の判定基準は、世界的な共通的な定義であり、西暦法的な定義でありません。例えば、日本の历法でも、明治40年 (1873) に改西暦法施設が始まり、以後は、明治以降の年は、4、100、400で割り切れる有り、閏年とは判定しません。日本の共通的な定義では、明治以降の年は、4、100、400で割り切れる有り、閏年とは判定する必要があります。

上記プログラムは、西暦法的な定義で判定しています。西暦法的な定義で判定すると、明治以降の年は、4、100、400で割り切れる有り、閏年とは判定しません。

ごめんなさい。

---

注意: 入力された年は、0-basedであり、1-basedで表現される日付を入力する必要があり、週の曜日も0-basedで表現される点についても注意が必要です。

上記プログラムは、西暦法的な定義で閏年を判定しています。世界的な共通的な定義で判定すると、閏年とは判定しません。西暦法的な定義でも、閏年とは判定しません。

ごめんなさい。<|im_end|>

==========
Prompt: 600.106 tokens-per-sec
Generation: 32.308 tokens-per-sec

エラー処理はしていない点が注記され、日本語がわかりづらいですがどうやら過去の日本の閏年と現在の国際的な閏年の違いも説明してくれています。明治生まれの方に親切ですね。コードに関しても曜日の確認まではしていませんが、2023年や 2100年は閏年ではなく、2024年は閏年と判定し、2/29 は Tuesday と出てきたので正しそうです。

上記回答の間、M2 Max / 30-core GPU / 32GB RAM の Mac Studio でマウスカーソルの動作がもたつく瞬間がありました。回答が長くなるような難しいお願いをした場合は、RAM 容量の小さな Mac ではある程度の処理低下を想定した方が良さそうです。

スワップが発生したあたりでおそらく体感的な影響が発生
GPU のスパイクは、普通の作業には影響なし

エラーへの対処

ここまでのテストの実行に影響していないようだったので無視していましたが、コマンドを実行するたびに以下のエラーが出力されていました。

None of PyTorch, TensorFlow >= 2.0, or Flax have been found. Models won't be available and only tokenizers, configuration and file/data utilities can be used.

PyTorch をインストールしたらエラーが消えました。

pip install torch

上記の日本語のプロンプトのコマンドを再投入した結果部分が以下となります。Prompt の tokens-per-sec の値が改善しました。PyToch インストール前に比べて 73% ほどの時間でプロンプトの解釈が終わったということかと思います。ただ、Mac 上で他のプログラムも動いているからか、この数値は同じコードを実行しても上下しています。テキストの生成自体 PyTorch インストール前も動いていたことから、必要・影響ないかもしれません。

==========
Prompt: 439.798 tokens-per-sec
Generation: 32.475 tokens-per-sec

感想と今後

mlx_lm を使ってみて、Stable Code Instruct 3B の実力がわかりました。すごいです。これから大いにコーディングに利用していこうと思います。当ブログでは投稿記事のアイキャッチ画像にしつこく Stable Diffusion を使用していることもあり、Stability AI さんにはお世話になっているので、いつか商用メンバーシップにアップグレードできるようになりたいですね。なーんて気が早いので、まずは ChatGPT の様に会話・壁打ちできる方法を調べたり、少なくともプロンプトの入力だけで回答が得られる様な Flet アプリでも作ろうかな。Prince Canuma さんの追っかけやったほうがよさそうかな。

Image by Stable Diffusion

前回の記事ではかなり見くびった画像にしちゃってごめんなさい。日本語だけじゃなく、開発言語も複数扱えるという意味を込めたら良い画像ができました。

Date:
2024年4月1日 22:40:50

Model:
realisticVision-v20_split-einsum

Size:
512 x 512

Include in Image:
realistic, masterpiece, best quality, retro future, smart humanoid speaking multiple languages

Exclude from Image:

Seed:
2695798972

Steps:
23

Guidance Scale:
20.0

Scheduler:
DPM-Solver++

ML Compute Unit:
CPU & Neural Engine

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

© Peddals.com