🎧
Llama3をローカルMac(MLX)で使ってみる
Llama3
Meta社のLlama3が出たようで話題です。
8Bと70Bがあるようです。
MLXでも使えるようなのでさっそく試してみました。
8B Instructを動かす
mlx-communityですでに登録されている8bit量子化モデルを使ってみます
(4bit量子化モデルもあるのですが、なんだか壊れ気味でした)
準備
手元ではmlxが0.10.0以上でないと動作しなかったためmlxをバージョン指定でインストールしました。
pip install mlx-lm==0.10.0
スクリプトと出力
apply_chat_template
で適切なテンプレートを使用してくれます。
eos_token
がいるような気もしますが、気にしない。
ライフゲームを出力させてみます。
スクリプト
from mlx_lm import load, generate
def main():
model, tokenizer = load("mlx-community/Meta-Llama-3-8B-Instruct-8bit")
messages = [
{"role": "system", "content": "you are helpful and skillfull programmer."},
{"role": "user", "content": "write game of life in python."}
]
inputs = tokenizer.apply_chat_template(messages,
tokenize=False,
add_generation_prompt=True)
response = generate(
model,
tokenizer,
prompt=inputs,
verbose=True,
temp=0.6,
top_p=0.9,
max_tokens=4096,
)
if __name__ == "__main__":
main()
出力されるプロンプト
Prompt: <|begin_of_text|><|start_header_id|>system<|end_header_id|>
you are helpful and skillfull programmer.<|eot_id|><|start_header_id|>user<|end_header_id|>
write game of life in python.<|eot_id|><|start_header_id|>assistant<|end_header_id|>
レスポンス
Here's a simple implementation of Conway's Game of Life in Python:
import random
import time
import os
# Game of Life constants
WIDTH = 100
HEIGHT = 100
# Create a 2D list filled with random values
def create_board():
board = [[random.choice([0,1]) for _ in range(WIDTH)] for _ in range(HEIGHT)]
return board
# Print the current state of the board
def print_board(board):
os.system('clear') # Clear the screen
for row in board:
print(' '.join(['*' if cell else ' for cell in row]))
# Count the number of live neighbors for a cell
def count_neighbors(board, x, y):
count = 0
for i in range(-1, 2):
for j in range(-1, 2):
if i == 0 and j == 0:
continue
count += board[(x+i)%HEIGHT][(y+j)%WIDTH]
return count
# Apply the rules of the Game of Life to the board
def apply_rules(board):
new_board = [[0 for _ in range(WIDTH)] for _ in range(HEIGHT)]
for x in range(HEIGHT):
for y in range(WIDTH):
live_neighbors = count_neighbors(board, x, y)
if board[x][y] == 1:
if live_neighbors < 2 or live_neighbors > 3:
new_board[x][y] = 0
else:
new_board[x][y] = 1
else:
if live_neighbors == 3:
new_board[x][y] = 1
return new_board
# Run the Game of Life
def run_game(board):
while True:
print_board(board)
time.sleep(0.5)
board = apply_rules(board)
# Start the Game of Life
board = create_board()
run_game(board)
This code creates a 100x100 grid of cells, with each cell either alive (represented by `1`) or dead (represented by `0`). The `create_board` function initializes the board with random values. The `print_board` function prints the current state of the board to the screen. The `count_neighbors` function counts the number of live neighbors for a cell. The `apply_rules` function applies the rules of the Game of Life to the board, and the `run_game` function runs the game in an infinite loop.
==========
Prompt: 116.176 tokens-per-sec
Generation: 34.153 tokens-per-sec
M1Max(64GB)で30tpsぐらいは出るのでけっこう速いです。
わりと日本語も書けます。
Prompt: <|begin_of_text|><|start_header_id|>system<|end_header_id|>
you are helpful AI assistant. you MUST write Japanese language.日本語で書いてください<|eot_id|><|start_header_id|>user<|end_header_id|>
こんにちは!あなたの名前は?<|eot_id|><|start_header_id|>assistant<|end_header_id|>
こんにちは!私は、有用なAIアシスタントです。名前は、AI-chanと呼んでください!
==========
Prompt: 140.172 tokens-per-sec
Generation: 34.790 tokens-per-sec
量子化しない版
以下でコンバートします。
python -m mlx_lm.convert --hf-path meta-llama/Meta-Llama-3-8B-Instruct --mlx-path "your model path"
利用はパスを指定します。
from mlx_lm import load, generate
...
model, tokenizer = load("./your model path")
70B Instructを動かす
現在(2024/04/19)MLX版の4bit量子化版はどうもゴミを出力する問題があるようです。
2024/04/20更新: 以下で4bit量子化版を使えるようです。
まだ8bitがなかったため、元のLlama3 70B-InstructをMLX版にコンバートして利用してみます。
準備
Llama3をHuggingFaceから取得可能にする
デフォルトだとアクセス制限がかかっています。
以下などでフォームに入力し、届いたメールから制限を解除します。
HuggingFaceトークンを設定する
HuggingFaceからあらかじめTokenを設定・取得しておきます。
シェルでパスを通しておきます(以下はzshの場合)
echo 'export HF_TOKEN="your_huggingface_token"' >> ~/.zshrc
source ~/.zshrc
8bit量子化コンバートする
以下で簡単に行えます。
mlx_lm.convert --hf-path meta-llama/Meta-Llama-3-70B-Instruct --mlx-path "your model path" --q-bits 8 --quantize
出力してみる
数分かかって5文字。遅すぎて使い物になりませんでした。
Prompt: <|begin_of_text|><|start_header_id|>system<|end_header_id|>
you are helpful and skillfull programmer.<|eot_id|><|start_header_id|>user<|end_header_id|>
write game of life in python.<|eot_id|><|start_header_id|>assistant<|end_header_id|>
Here is a
128GBなどでは8tpsで動く報告もあるようです。
70B(8bit)のMLXモデルが出ていた
わざわざコンバートしましたが、こちら使った方がよさそうです。
読んでくださりありがとうございました、MLX楽しいです。
Discussion
70B(8bit)のMLXモデルのアップロード者です!記事で触れていただき嬉しいです!
追記されている70B(4bit)の更新について、更新版を今触っているのですが、少なくとも日本語については8B版のほうがマシな出力をしており、安定したLLMって難しいなと思う次第です。
情報ありがとうございます&70B(8bit)についてもありがとうございます!
4bit版が出力おかしいのは感じております(日本語ではなくローマ字で出力されるなど…)、むずかしそうです…。
もろもろのちほど追記させていただきます!