おうちで日本語で画像を使った会話ができるようになりましたよ、ということで、試してみます。
rinna 画像対話モデル
おとといrinnaから日英バイリンガルモデルが発表されました。
rinna、日英バイリンガル大規模言語モデルをオープンソースで公開|rinna株式会社
このモデルには画像対話モデルも含まれています。つまり、画像についてrinnaとチャットができるようになっています。
https://huggingface.co/rinna/bilingual-gpt-neox-4b-minigpt4
この画像対話モデルは、MiniGPT-4をベースにしています。
https://github.com/Vision-CAIR/MiniGPT-4
MiniGPT-4のVicuna + BLIP-2をrinna 3.6b + BLIP-2にした感じ。
Japanese MiniGPT-4: rinna 3.6bとBLIP-2を組み合わせてマルチモーダルチャットのモデルを作る
動かすとこんな感じ。大きく外れてはないな、という返答です。あと、簡潔。
画像対応rinna、「だいたいあってる」という感じ。
— きしだൠ(K1S) (@kis) 2023年8月1日
答えは簡潔なので、チャットで使うよりもシステムに組み込む感じだろうか
女の子の髪形はブレないw pic.twitter.com/EVN1xnU3er
メモリは11.4GBくらい使うので、12GB GPUだときつそう。
導入
導入として公式で書いてある手順はこんな感じ。MiniGPT-4をGitHubからcloneして22d8888ブランチを使う、と。
git clone https://github.com/Vision-CAIR/MiniGPT-4.git cd ./MiniGPT-4 git checkout 22d8888 # latest version as of July 31, 2023.
そして、rinna用にカスタマイズしたMiniGPT-4のスクリプトとBLIP2-LLMのcheckpoint.pthをダウンロード。
wget https://huggingface.co/rinna/bilingual-gpt-neox-4b-minigpt4/resolve/main/customized_mini_gpt4.py wget https://huggingface.co/rinna/bilingual-gpt-neox-4b-minigpt4/resolve/main/checkpoint.pth
Windowsの場合はwgetを使うにはPowerShellを使うのだけど、オプションなしだと単にネットからデータを読むだけになってしまうので-OutFile
を付けて保存先を指定する。
そうすると「書き込んでいます」が出る。「読み込んでいます」だと読み込むだけになる。
あとはCUDAとかPyTorchとかTransformersとかsentencepieceとか、rinna 3.6bが動く状態を作っておく。
bitsandbytesを使っているのだけど、Windowsの場合はpipからインストールしても使えないので、こちらを。
https://github.com/jllllll/bitsandbytes-windows-webui
0.39.1を使っていますが、新しいものでも大丈夫だと思う。
python -m pip install bitsandbytes==0.39.1 --prefer-binary --extra-index-url=https://jllllll.github.io/bitsandbytes-windows-webui
あと、いままで使ってなかったものとして、omegaconf、iopath、timm、webdataset、decordのインストールが必要だった。
動かす
そしたらHow to use the model のところのコードが動かせるはず。
No module named 'decord'
のようなエラーが出たらpip install
していく。
7.74GBのモデルのダウンロードなどがあったあと、こんな感じで表示される。
Loading VIT freeze vision encoder Loading VIT Done Loading Q-Former freeze Qformer Loading Q-Former Done Loading LLM Loading LLM Done Load BLIP2-LLM Checkpoint: ./checkpoint.pth ユーザー: <Img><ImageHere></Img> What can you see? システム: a cat on a table with a laptop ユーザー: 猫はどんな体勢をしていますか? システム: 寝ています
コードを見る
モデルをCustomizedMiniGPT4として定義してますね。
model = CustomizedMiniGPT4(gpt_neox_model="rinna/bilingual-gpt-neox-4b")
tokenizer = model.gpt_neox_tokenizer
そしてBIP2-LLMを読み込み
ckpt = torch.load(ckpt_path, map_location="cpu") model.load_state_dict(ckpt['model'], strict=False)
会話に使う画像を読み込み。
image_url = "https://huggingface.co/rinna/bilingual-gpt-neox-4b-minigpt4/resolve/main/sample.jpg" raw_image = Image.open(requests.get(image_url, stream=True).raw).convert('RGB')
そしてBLIP2-LLMを使って埋め込みベクトルに変換
vis_processor = Blip2ImageEvalProcessor()
image = vis_processor(raw_image).unsqueeze(0).to(model.device)
image_emb = model.encode_img(image)
プロンプトと画像埋め込みを結合した埋め込みベクトルを取得
embs = model.get_context_emb(prompt, [image_emb])
で、生成
output_ids = model.gpt_neox_model.generate( inputs_embeds=embs, max_new_tokens=512, do_sample=True, temperature=1.0, top_p=0.85, pad_token_id=tokenizer.pad_token_id, bos_token_id=tokenizer.bos_token_id, eos_token_id=tokenizer.eos_token_id ) output = tokenizer.decode(output_ids.tolist()[0], skip_special_tokens=True)
UIをつける
いろいろ試したいのでGradioでUIを作る
with gr.Blocks() as demo: gr.Markdown("## multi modal rinna") imgIn = gr.Image(lambda: raw_image, type="pil") with gr.Row(): upload = gr.Button("Upload", variant="primary") def_img = gr.Button("Default") upload.click(load_image, inputs=imgIn) def_img.click(init_image, outputs=imgIn) with gr.Row(): with gr.Column(): question = gr.Textbox(lines=3, placeholder="質問を") submit = gr.Button("Submit", variant="primary") with gr.Row(): default = gr.Button("Default") clear = gr.Button("Clear") default.click(lambda: "画像を説明して", outputs=question) clear.click(lambda: "", outputs=question) answer = gr.Textbox(lines=3) submit.click(generate, inputs=question, outputs=answer) demo.launch()
そしたら冒頭のUIができる。画面を横分割して画像を左側でもよかったな。
ソース全体はこちら。動かすとき、画像をD&DしただけではLLMに送られていないので気をつけてください。Uploadボタンを押す必要があります。
https://gist.github.com/kishida/ee107e002546ce2ab26c5d9a6eac33b1