日本語LLM(OpenCALM)をHTTP APIから使えるようにする

先日、OpenCALMの検証記事を投稿させていただきました。

https://qiita.com/tar_xzvf/items/09ee2bf146c4a3319492

今回はさまざまなシステムやプログラムに組み込むためにHTTP APIから利用できるようにしてみたいと思います。

HTTP APIは、PythonのFast APIで実装しました。
Flask, Djangoはよく触るのですが、Fast APIは名前は聞いたことがあるものの初めてでしたのでなかなか違いになれませんでしたが、作りたいものが作れました。

# OpenCALMが動くAPIを動かしてみる

必要なリソースはこちらのリポジトリにございます。

https://github.com/tar-xzvff/OpenCALM-chat-api

## 1.リポジトリのクローン、ライブラリのインストール、モデルの事前ダウンロード
```shell
cd /home/ubuntu
git clone https://github.com/tar-xzvff/OpenCALM-chat-api.git
cd OpenCALM-chat-api
pip install -r requirements.txt
python3 -c 'import torch; from transformers import AutoModelForCausalLM, AutoTokenizer; model = AutoModelForCausalLM.from_pretrained("cyberagent/open-calm-7b", device_map="auto", torch_dtype=torch.float16); model.save_pretrained("/home/ubuntu/model/cyberagent/open-calm-7"); tokenizer = AutoTokenizer.from_pretrained("cyberagent/open-calm-7b"); tokenizer.save_pretrained("/home/ubuntu/model/cyberagent/open-calm-7")'

```

## 2.APIサーバ起動
```shell
uvicorn main:app --reload --host 0.0.0.0
```
## 3.動作確認
```shell
curl -i -X POST \
   -H "Content-Type:application/json" \
   -H "Authorization:Basic ******" \
   -d \
'{
  "body": "おはようございます"
}' \
 'http://GPUサーバのIP:8000/api/chat'
```

```shell
$ curl -i -X POST \
>    -H "Content-Type:application/json" \
>    -H "Authorization:Basic **********" \
>    -d \
> '{
>   "body": "おはようございます"
> }' \
>  'http://xxx.xxx.xxx.xxx:8000/api/chat'
HTTP/1.1 200 OK
date: Sun, 21 May 2023 00:35:27 GMT
server: uvicorn
content-length: 411
content-type: application/json

{"body":"おはようございます。\n本日は、朝から雨が降っていて気温も低く寒いです。昨日から雨が降り続き、桜の花びらが散ってきています。今日は一日雨の予報で明日からは暖かくなるそうですので、体調管理には十分お気を付け下さい。本日も宜しくお願いいたします。\n4月25日(木曜日)5月も忙しい朝"}
```

このような形で動くようになりました。
## 4.永続化
systemdで永続化します。APIサーバが起動している場合は一度停止してください。

### systemd unitファイルの作成
```bash
sudo vi /etc/systemd/system/opencalm_api.service
```
以下の内容をコピペします
```systemd
[Unit]
Description=OpenCALM API
After=network.target

[Service]
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu/OpenCALM-chat-api
ExecStart=/home/ubuntu/.local/bin/uvicorn main:app --reload --host 0.0.0.0

[Install]
WantedBy=multi-user.target
```

```bash
sudo systemctl enable opencalm_api.service
sudo systemctl start opencalm_api.service
```

起動状態を確認します、以下のようになっていれば動作しています。
```bash
$ sudo systemctl status opencalm_api.service
● opencalm_api.service - OpenCALM API
     Loaded: loaded (/etc/systemd/system/opencalm_api.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2023-05-23 23:33:46 JST; 3min 27s ago
   Main PID: 113189 (uvicorn)
      Tasks: 13 (limit: 67366)
     Memory: 1.6G
        CPU: 13.623s
     CGroup: /system.slice/opencalm_api.service
             ├─113189 /usr/bin/python3 /home/ubuntu/.local/bin/uvicorn main:app --reload --host 0.0.0.0
             ├─113190 /usr/bin/python3 -c "from multiprocessing.resource_tracker import main;main(4)"
             └─113191 /usr/bin/python3 -c "from multiprocessing.spawn import spawn_main; spawn_main(tracker_fd=5, pipe_handle=7)" --multiprocessing-fork

May 23 23:33:46 OpenCALM systemd[1]: Started OpenCALM API.
May 23 23:33:46 OpenCALM uvicorn[113189]: INFO:     Will watch for changes in these directories: ['/home/ubuntu/OpenCALM-chat-api']
May 23 23:33:46 OpenCALM uvicorn[113189]: INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
May 23 23:33:46 OpenCALM uvicorn[113189]: INFO:     Started reloader process [113189] using WatchFiles
May 23 23:33:57 OpenCALM uvicorn[113191]: [334B blob data]
May 23 23:33:58 OpenCALM uvicorn[113191]: INFO:     Started server process [113191]
May 23 23:33:58 OpenCALM uvicorn[113191]: INFO:     Waiting for application startup.
May 23 23:33:58 OpenCALM uvicorn[113191]: INFO:     Application startup complete.
```

これでAPIからOpenCALMが利用できるようになりました。


# 付録 cloud-initで簡単に環境を作る
cloud-initを使って、簡単に環境を作ることができます。

サーバの作成方法は、[1.GPUサーバの作成](#1gpuサーバの作成)と基本的に変わりません。
ディスクのアーカイブは `Ubuntu Server 22.04 LTS 64bit (cloudimg)` を選択します。

![スクリーンショット 2023-06-04 20.51.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58803/2f3fce56-d7ac-e91d-48d2-efe19b40aef8.png)

公開鍵を指定します、3種類の選択方法から選択してください。SSH接続時に利用します。
![スクリーンショット 2023-06-04 20.52.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58803/513c6241-3fa4-f383-a8ce-c48c0fc336b0.png)

`追加ユーザデータ`にcloud-initのコードを貼り付けます。

![スクリーンショット 2023-06-04 20.52.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58803/cb8c34e5-ecbb-b1dc-b82f-73d3cea5c11b.png)

cloud-initのコードはこちらにあります。

https://github.com/tar-xzvff/cloud-init-sample/blob/main/LLM/install-opencalm-chat-api.yaml

この内容で作成していただくことで手動での構築が不要になり、APIが起動した状態まで自動で構築します。
30分ほどかかります、ぜひご活用ください。

Basic認証情報がデフォルトのままですので、適宜変更してください。

https://github.com/tar-xzvff/OpenCALM-chat-api/blob/main/main.py#L9-L10