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?

OpenRouter VLM (Qwen)画像解析性能を確認してみた

Posted at

はじめに

最近調べ物をしている中で、OpenRouterという個人開発勢&高級なスペックのマシンを持っていない勢にはありがたいサービスを見つけ、主にVLMのモデルを触ってみたので紹介です。
ついでに、VLMモデルのローカル環境での実行と**OpenRouter API経由での実行、での精度比較もしてみました。

検証概要

対象モデル

そもそも2Bと7Bを比べるなんて、、というところもありますが、、、

  • ローカルVLM: Qwen2-VL-2B(ローカル実行)
    • ローカルマシンスペック:Apple M4(メモリ16GB)
  • OpenRouter API: qwen/qwen-2.5-vl-7b-instruct(クラウド実行)

検証内容

  • 食材画像(ショッピングアプリのスクリーンショット等)から商品名・価格・数量を抽出
  • 同じプロンプトで複数回実行して処理時間を計測 ※今回は3回

食材画像

Screenshot_20250818_121730_Meituan.jpg

プロンプト

この画像に表示されている食材や食品の名前、価格、規格を日本語で詳しくリストアップしてください。中国語の商品名も併記してください。

スクリーンショット 2025-08-22 19.16.42.png

実装のポイント

ローカルVLM実装

huggingface-hub cliを用いてローカルにモデルをダウンロードして、
それをLoadする仕組みにしています。

class LocalVLM:
    def __init__(self, model_path="./models/qwen2-vl-2b"):
        self.model_path = model_path
        self.model = None
        self.processor = None
    
    def load_model(self):
        # transformersを使用してローカルモデルを読み込み
        self.model = Qwen2VLForConditionalGeneration.from_pretrained(
            self.model_path,
            torch_dtype=torch.float32,
            device_map=None,
            trust_remote_code=True
        )
        self.processor = AutoProcessor.from_pretrained(
            self.model_path,
            trust_remote_code=True
        )
    
    def extract_food_info(self, image: Image.Image):
        # 画像解析の実行
        start_time = time.time()
        
        messages = [{
            "role": "user",
            "content": [
                {"type": "image", "image": image},
                {"type": "text", "text": "食材情報を抽出してください"}
            ],
        }]
        
        # モデル推論処理...
        processing_time = time.time() - start_time
        return output_text, processing_time

OpenRouter API実装

class OpenRouterVLM:
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://openrouter.ai/api/v1/chat/completions"
        self.model = "qwen/qwen-2.5-vl-7b-instruct"
    
    def extract_food_info(self, image: Image.Image):
        start_time = time.time()
        
        # 画像をBase64エンコード
        base64_image = self.image_to_base64(image)
        
        # API呼び出し
        response = requests.post(
            url=self.base_url,
            headers={"Authorization": f"Bearer {self.api_key}"},
            json={
                "model": self.model,
                "messages": [{
                    "role": "user",
                    "content": [
                        {"type": "text", "text": "食材情報を抽出してください"},
                        {"type": "image_url", "image_url": {
                            "url": f"data:image/png;base64,{base64_image}"
                        }}
                    ]
                }]
            }
        )
        
        processing_time = time.time() - start_time
        return response.json()['choices'][0]['message']['content'], processing_time

検証結果

処理速度比較

以下の通りClaudeに比較用のStreamlitアプリを作成してもらい3施行実施した結果を分析しています。
言わずもがなって感じですが、OpenRouterの方が圧倒的に応答速度が速いです。用途によるとは思いますが、日常利用で問題ないスピードだと思います。
スクリーンショット 2025-08-22 19.18.22.png
スクリーンショット 2025-08-22 19.18.38.png

出力結果についても見てみましたが、どちらもプロンプトの指示通りの結果を出力していますね。

スクリーンショット 2025-08-22 19.20.21.png

まとめ

今回は、ローカルでパラメータサイズ2Bのモデル、OpenRouterは7Bのモデルを比較したので、シンプルな比較検証にはなりませんでしたが、
セキュアな点を特に気にしなくても良いのであれば、OpenRouterを使った方が楽だし早いしで良さそうですね。
個人開発勢にはとってもありがたい環境です。

ソースコード

自分のために食費管理簿アプリを作成中で、完全なソースコードはGitHubで公開するかもしれません: [リンクは後で追加]


参考文献

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?