0
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?

1年経ったらgradioのAPIが変っていた

Posted at

はじめに

自宅でAI関連のコードを実行できる環境を準備して遊んでいるのですが、基本的に週末しか使わないので時間が経ってみたらこの前まで実行できてたコードが実行できなくなっていました。

調べてみると参考にしていた記事が公開されてからgradioのバージョンがv3からv5まで更新されているなど、システム側の変更点が大きいようでした。

2024年に作成された記事を検索してもgradio v3の環境を利用している例もあるようですが、ダイナミックに変化していく分野なのでできるだけ最新版を使おうと作業した時のメモを残しておきます。

参考資料

最初に環境を構築する時、参考にしていた資料です。

ローカル環境で、何かを学習(ファインチューニング)させた特定用途向けのChatBotを作ってみたいと思って、その準備として動作させています。

この他には公式サイトの情報などをみています。

Gradio 3から5に変更されているので、中間のGradio 4の変更点も必要に応じて参照しています。

環境

元々動作させていた環境からはアップグレードして次のような環境になっています。

  • Ubuntu 24.04.1 amd64
  • Python 3.12.3 with venv (Ubuntu 24.04の標準パッケージ)

nvidia-smiコマンドの出力は次のとおりです。

Sun Oct 27 17:32:37 2024       
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 560.35.03              Driver Version: 560.35.03      CUDA Version: 12.6     |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA RTX A4000               Off |   00000000:08:00.0  On |                    0 |
| 41%   48C    P8             20W /  140W |    1621MiB /  15352MiB |     31%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+

Ubuntuのアップグレードなどで古いCUDA Toolkitも導入されていた形跡(/usr/local/cuda-11.7)はあるのですが、動作していなかったので最新のToolkit(12.5)を導入しています。

LLAMAモデルの変更

GGUF形式だったら何でも良いのかと思ったら次のようなエラーが表示されてしまいました。

エラーメッセージ
gguf_init_from_file: GGUFv1 is no longer supported. please use a more up-to-date version
llama_model_load: error loading model: llama_model_loader: failed to load model from ggml-model-q4_m.gguf

元々利用していたのはなんとなく選択したggml-model-q4_m.ggufでしたが、GGUFにもフォーマット違いがあるとこの時に知りました。

このタイミングでELYZAが配布している最新のLlama-3-ELYZA-JP-8B-q4_k_m.ggufをダウンロードしました。

ollamaに認識させるために、Modelfileを準備する際に次の記事も参考にしています。

準備作業

ライブラリなどをvenvの環境に導入していきます。

$ python3 -m venv venv/llama
$ . venv/llama/bin/activate

最終的に次のようなrequirements.txtを利用しています。

requirements.txt
## for RAG
langchain_community
langchain-core

## for http client
requests

## for HTML Splitter
lxml

## for RAG embedding
uuid
langchain-chroma
langchain-ollama

ライブラリをインストールします。

$ . venv/llama/bin/activate
(llama) $ pip install -f requirements.txt

コードの変更

実行しながらエラーに対応していきます。

1. retry_btn などの仕様変更

参考にしていたコードをそのまま実行すると次のようなメッセージが表示されます。

python3 chat.py実行時のエラーメッセージ(1回目)
(llama) $ python3 chat.py
...
TypeError: ChatInterface.__init__() got an unexpected keyword argument 'retry_btn'

Gradio ChatInterface Docsをみると、そもそも ここで利用していないsubmit_btnstop_btnを除き、retry_btnを含めた*_btnに関する変数自体が存在しないようです。

Migrating to Gradio 5では、ボタンのUIはgr.Chatbotに統合されたとのことなので、これらの部分はとりあえず削除して実行していきます。

2. concurrencty_countが存在しない

python3 chat.py実行時のエラーメッセージ(2回目)
TypeError: Blocks.queue() got an unexpected keyword argument 'concurrency_count'

これもMigrating to Gradio 5を確認すると、Gradio 4で既にdeprecated扱いだったので削除したという内容が確認できるので、Breaking Changes in Gradio 4.0を確認します。

コード上はqueue()のパラメータとしてconcurrency_count=1が指定されているのですが、デフォルト値のようです。concurrency_limitに変更されてもデフォルトはそのままだということなので、queue()の引数から削除しています。

3. 初期メッセージをクリックするとerrorになる

一応ここまでの変更でGradioが起動して、対話的に動作するようになるのですが、examplesに指定している日本の四国にある県名を挙げてください。というプロンプトをクリックするとエラーになります。

Inputダイアログに入力すれば正しく回答が表示されますが、クリックしてエラーになるというのも気持ちが悪いので修正しておきます。

python3 chat.py実行時のエラー(3回目)
ValueError: A  function (example_clicked) didn't return enough output values (needed: 2, returned: 1).
    Output components:
        [chatbot, state]
    Output values returned:
        [('日本の四国にある県名を挙げてください。', '以下は日本の四国地方にある県名です。\n\n1. 愛媛県\n2. 高知県\n3. 香川県\n4. 徳島県\n\n以上、四国の4県を挙げました。')]

この問題は簡単に解決できるのかと思ったのですが、結構面倒でした。

デフォルトのtype="tuples"はdeprecated

まず実行時に次のようなメッセージが表示されます。

.../venv/llama/lib/python3.12/site-packages/gradio/components/chatbot.py:229: UserWarning: The 'tuples' format for chatbot messages is deprecated and will be removed in a future version of Gradio. Please set type='messages' instead, which uses openai-style 'role' and 'content' keys.

このためtype="messages"をChatInterface()の引数に指定して最終的には解決を目指します。

cache_examples=Trueがエラーを引き起す

とりあえずtype="tuples"のまま調査すると、cache_examples=Trueが次のようなエラーメッセージを引き起します。

FileNotFoundError: [Errno 2] No such file or directory: '.gradio/cached_examples/10/log.csv'

cache_examples=Falseを指定すると、問題なく動作するようになりました。

ひとまずはここまでで満足することにしました。

type="messages" で動作させる

さて、最終的には type="messages" を指定して動作させたいので、動作するように変更していきます。

主な変更点は、generate_text()で参照しているhistoryリストの中身が、{"role": "...", "content": "..."}のような辞書型(dict)データ形式になるのでfor interaction in history:で参照しているinteractionオブジェクトの参照がinput_prompt = input_prompt + "\nUSER: " + str(interaction["role"]) + "\nASSISTANT: " + str(interaction["content"])のように変更になります。

また関数の最後で実行しているhistoryリストへの代入が、history.append({"role": "user", "content": input_prompt})のような形になります。

cache_examples=Falseであれば、ここまでで動作するようになります。

cache_examples=Trueにすると動作しない

ここからcache_examples=Trueにすると動作しなくなります。

...
 File ".../venv/llama/lib/python3.12/site-packages/gradio/chat_interface.py", line 678, in example_clicked
    return self.examples_handler.load_from_cache(x.index)[0].root
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
  Input should be a valid dictionary or instance of Message [type=model_type, input_value=['日本の四国にあ...方にあ
  ます。'], input_type=list]
    For further information visit https://errors.pydantic.dev/2.9/v/model_type

cacheから読み込まれるデータ形式が正しくなさそうなので、内容を確認します。

.gradio/cached_examples/10/log.csv
Chatbot,timestamp
"[[""\u65e5\u672c\u306e\u56db\u56fd\u306b\u3042\u308b\u770c\u540d\u3092\u6319\u3052\u3066\u304f\u3060\u3055\u3044\u3002"", ""\u4ee5\u4e0b\u306f\u56db\u56fd\u5730\u65b9\u306e\u770c\u540d\u3067\u3059\u3002\n\n\u611b\u5a9b\u770c\u3001\u9999\u5ddd\u770c\u3001\u9ad8\u77e5\u770c\u3001\u5fb3\u5cf6\u770c\n\n\u4ee5\u4e0a4\u770c\u304c\u56db\u56fd\u5730\u65b9\u306b\u3042\u308a\u307e\u3059\u3002""]]",2024-10-28 06:58:59.567660

内容は質問のリスト形式になっているので、type="messages"で期待する{"role": "...", "content": "..."}形式にはなっていないようです。

cacheディレクトリ(.gradio/cached_examples/10)を削除すると、エラーメッセージが少し変化します。

  File "/home/yasu/project/llama_chatbot/venv/llama/lib/python3.12/site-packages/gradio/components/chatbot.py", line 323, in _check_format
    raise Error(
gradio.exceptions.Error: "Data incompatible with messages format. Each message should be a dictionary with 'role' and 'content' keys or a ChatMessage object."

該当するコードを確認すると、次のような判定ロジックが正しく動作していないようでした。

venv/llama/lib/python3.12/site-packages/gradio/components/chatbot.pyからの抜粋
        if type == "messages":
            all_valid = all(
                isinstance(message, dict)
                and "role" in message
                and "content" in message
                or isinstance(message, ChatMessage | Message)
                for message in messages
            )
            if not all_valid:
                raise Error(
                    "Data incompatible with messages format. Each message should be a dictionary with 'role' and 'content' keys or a ChatMessage object."
                )

for message in messagesの内容が正しいフォーマットになっていないようです。

もう少し調べると、messagesはリスト形式のはずなのに要素のはずのdict形式の生データが入ってしまっているので、messageの中身は分割された('role', 'user')のような2要素のタプルになることでall()の条件判定に失敗していることが原因でした。

``

0
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
0
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?