1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

N番煎じでMicrosoftのPhi-2をDatabricksで動かす

Posted at

mixtralはAutoAWQかExLlamaV2が対応されたら試そうと思います。

導入

MicrosoftからPhi-2というLLMが公開されました。ライセンスはMicrosoftリサーチライセンスです。

Microsoft Ignite 2023でも発表されていたのですが、2.7Bという小さいパラメータ数にも関わらず、Llama 13B以上の性能を発揮し、特にMathやコード生成の分野で優秀な能力を持っています。

以下のように、既にGigazineさんで取り上げられたり、大先生も試されていますが、気にせず試してみようと思います。
それがN番煎じシリーズ。

今回は小パラメータのモデルということもあり、CPUでの速度を見たかったので、CPUクラスタで動かします。

Step1. 準備

まずは必要なパッケージをインストール。

%pip install -U -qq transformers sentencepiece accelerate bitsandbytes einops

dbutils.library.restartPython()

それからモデルをダウンロード。UnityCatalogのボリュームに保管します。

def download_model(model_id:str):
    import os
    from huggingface_hub import snapshot_download

    UC_VOLUME = "/Volumes/training/llm/model_snapshots"

    local_dir = f"/tmp/{model_id}"
    uc_dir = f"/models--{model_id.replace('/', '--')}"

    snapshot_location = snapshot_download(
        repo_id=model_id,
        local_dir=local_dir,
        local_dir_use_symlinks=False,
    )

    dbutils.fs.cp(f"file:{local_dir}", f"{UC_VOLUME}{uc_dir}", recurse=True)

model_id = "microsoft/phi-2"
download_model(model_id)

Step2. モデルのロード

transformersを使ってモデルを読み込みます。
CPUで利用するため、dtypeはtorch.float32を指定しています。

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

model_path = "/Volumes/training/llm/model_snapshots/models--microsoft--phi-2"

# CPUでの推論用
model = AutoModelForCausalLM.from_pretrained(model_path, torch_dtype=torch.float32, device_map="cpu", trust_remote_code=True)
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)

Step3. 推論その1

まずは公式サンプルを実行してみます。

inputs = tokenizer('''def print_prime(n):
   """
   Print all primes between 1 and n
   """''', return_tensors="pt", return_attention_mask=False)

outputs = model.generate(**inputs, max_length=200)
text = tokenizer.batch_decode(outputs)[0]
print(text)
出力
def print_prime(n):
   """
   Print all primes between 1 and n
   """
   for i in range(2, n+1):
       for j in range(2, i):
           if i % j == 0:
               break
       else:
           print(i)

print_prime(20)
```

## Exercises

1. Write a Python function that takes a list of numbers and returns the sum of all even numbers in the list.

```python
def sum_even(numbers):
    """
    Returns the sum of all even numbers in the list
    """
    return sum(filter(lambda x: x % 2 == 0, numbers))

print(sum_even([1, 2, 3, 4, 5, 6])) # Output: 12
```

2. Write a Python function that takes

ちなみに、生成したコード(print_prime)はちゃんと動きました。

Step4. 推論その2

日本語指定でコード生成できるかやってみます。

inputs = tokenizer('''def print_fibonacci(n):
   """
   フィボナッチ数列をnまで表示する
   """''', return_tensors="pt", return_attention_mask=False)

outputs = model.generate(**inputs, max_length=200)
text = tokenizer.batch_decode(outputs)[0]
print(text)
出力
def print_fibonacci(n):
   """
   フィボナッチ数列をnまで表示する
   """
   a, b = 0, 1
   for i in range(n):
      print(a, end=' ')
      a, b = b, a+b
   print()

def print_fibonacci_recursive(n):
   """
   フィボナッチ数列をnまで表示する
   """
   if n <= 1:
      print(n, end=' ')
   else:
      print_fibonacci_recursive(n-1)
      print_fibonacci_recursive(n-2)
      print(n, end=' ')

def print_fibonacci

題材がよくあるもののためか、関数名の時点で明確なのかはわからないのですが、ちゃんと関数が生成できています。
ただ、print_fibonacci_recursiveは挙動がおかしいかな。

もう少し複雑な関数を作らせてみましょう。

Step5. 推論その3

LightGBMのモデルを学習させる関数を作成させてみます。

inputs = tokenizer('''def train_lightgbm_model(df):
   """
   Pandas Dataframeのデータを使ってlightgbmのモデルを構築する
   """''', return_tensors="pt", return_attention_mask=False)

outputs = model.generate(**inputs, max_length=512)
text = tokenizer.batch_decode(outputs)[0]
print(text)
出力
def train_lightgbm_model(df):
   """
   Pandas Dataframeのデータを使ってlightgbmのモデルを構築する
   """
   # データを学習データとテストデータに分割
   train_df, test_df = train_test_split(df, test_size=0.2)

   # データを学習データとテストデータに分割
   train_X = train_df.drop(['target'], axis=1)
   train_y = train_df['target']
   test_X = test_df.drop(['target'], axis=1)
   test_y = test_df['target']

   # モデルを作成
   model = lgb.LGBMClassifier()

   # モデルの構築
   model.fit(train_X, train_y)

   # モデルの推論
   predictions = model.predict(test_X)

   # モデルの損失を計算
   loss = model.score(test_X, test_y)

   return loss, predictions

# データの読み込み
df = pd.read_csv('data.csv')

# データの読み込み
df = pd.read_csv('data.csv')

# データの読み込み
df = pd.read_csv('data.csv')

# データの読み込み
df = pd.read_csv('data.csv')

# データの読み込み
df = pd.read_csv('data.csv')

# データの読み込み
df = pd.read_csv('data.csv')

# データの読み込�

train_lightgbm_model関数は動きそうなコードではありますが、sklernのモジュールをインポートしたりする必要がありそうです。あと、トレーニングしたモデルを返して欲しい(このあたりはきちんとdocstring内に記載すれば大丈夫だと思いますが)

まとめ

軽くですが、Phi-2でコード生成を試してみました。
あまり得意ではないと思いますが、日本語指定でも動くコード生成は多少できそうです。

また、今回はCPUクラスタで試しましたが、実用的な速度を出す場合はGPUが必要かと思います。

しかしローカルLLMは小パラメータで優秀なモデルが次々と出てきたり、MixtralのようなMoEのLLMがオープンソースで出てきたりと、発展が目覚ましいですね。
記事にはしていませんが、プロプライエタリのLLMも発展がすさまじいので、競い合ってどちらも成長して行って欲しい。

2023年もそろそろ終わりですが、来年も面白い年になりそうです。
※ とか言ってたら、2023年中にまだまだ凄いニュースが出たりするんだろうなあ。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?