Hugging Face Hub: モデルを探して使う

1. 概要

Hugging Face Hubは、機械学習のためのモデル、データセット、デモを集めた、今最大のリポジトリです。この記事では、必要なモデルを正しく見つけ(名前を推測する代わりに)、モデルカードを読んでライセンスやアーキテクチャの誤りを避け、2つの方法でそのモデルを呼び出す方法を説明します:Pythonでローカルに実行するか、Spring BootアプリケーションからInference APIで呼び出すか。最後には、GPUを自分でホストすることなく、NLPモデルをJavaサービスに統合できるようになります。

2. Hugging Face Hubとは

Hubは主に3種類のリソースを保存しています:

  • Models: 事前に学習済みの重み(weights)で、使い方を説明するモデルカード付き。
  • Datasets: トレーニング/ファインチューニングまたはベンチマークに使うデータ。
  • Spaces: ブラウザで直接実行できるデモ(Gradio、Streamlit)。

各モデルは組織/モデル名の形式のmodel_idを持ちます。例えばdistilbert-base-uncased-finetuned-sst-2-englishのようにです。このmodel_idがコード内で使う値で、UIの表示名ではありません。

3. Hubでモデルを探す

3.1. Webインターフェースで探す

Hubのホームページには、task(text-classification、translation、image-segmentation…)、library(transformers、sentence-transformers、timm…)、license、languageで絞り込めるフィルターがあります。「Most downloads」または「Trending」でソートすると、最新モデルを選ぶより安定した結果が得られます。最新モデルはまだ十分なユーザーに検証されていない可能性があるからです。

3.2. huggingface_hub(Python)で探す

スクリプトからモデルを探す必要があるとき(例えば要件を満たす最小モデルを自動選択する場合)、HfApiを使います:

pip install huggingface_hub
from huggingface_hub import HfApi

api = HfApi()
models = api.list_models(
    search="sentiment",
    library="transformers",
    sort="downloads",
    direction=-1,
    limit=5,
)

for m in models:
    print(m.id, m.downloads)

searchは名前/タグ内のキーワードでフィルタ、sort="downloads"とdirection=-1は最も人気のあるモデルを先頭にソート、limit=5は結果を5件に制限します。出力は次のようになります:

distilbert-base-uncased-finetuned-sst-2-english 5123456
cardiffnlp/twitter-roberta-base-sentiment-latest 2876543
nlptown/bert-base-multilingual-uncased-sentiment 1987654
...

注意: ダウンロード数は必ずしも最高の品質を意味しません。あなたのタスクに対して最適とは限りません。常に実際のデータで検証してから決定してください。

4. 使う前にモデルカードを読む

各モデルにはREADME.mdファイルがあり、モデルカードとして表示されます。以下を含みます:

  • Task: モデルが学習したタスク(分類、翻訳、テキスト生成…)。
  • License: apache-2.0、mit、cc-by-nc(非商用 — 商用製品には使えない)。
  • Gated model: 一部のモデルはログインと所有者の承認が必要な場合があります(通常は大規模または機密性の高いモデル)。

APIでライセンスとgated状態を素早くチェック:

from huggingface_hub import model_info

info = model_info("meta-llama/Llama-3.1-8B")
print(info.gated, info.tags)
True ['text-generation', 'license:llama3.1']

gated=Trueは、個人トークンが必要で、アクセスが許可されていることを意味します。許可されていない場合、リクエストは401/403エラーを返します。

5. transformersでローカルにモデルを実行する

小さなモデルなら、pipelineで試すのが最速です:

pip install transformers torch
from transformers import pipeline

classifier = pipeline(
    "sentiment-analysis",
    model="distilbert-base-uncased-finetuned-sst-2-english",
)
result = classifier("Hugging Face Hub makes finding models easy!")
print(result)
[{'label': 'POSITIVE', 'score': 0.9998}]

pipelineはHubから重みをローカルキャッシュ(~/.cache/huggingface)に自動ダウンロードし、対応するtokenizerを読み込み、結果をdict型のlistで返します。初回実行はモデルファイルのダウンロードが必要なので遅くなります。帯域幅やディスク容量が限られた環境にいる場合は、事前にHub上でモデルサイズを確認してください。

6. Spring BootからInference API経由でモデルを呼び出す

メインアプリケーションがJavaで書かれている場合、自分でモデルをホストする必要はありません。Hugging Faceは多くの人気モデル向けにInference API(HTTP)を提供しています。個人トークンでRESTを呼び出すだけです。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
huggingface.api-token=${HF_API_TOKEN}
huggingface.model=distilbert-base-uncased-finetuned-sst-2-english
@Service
public class SentimentAnalysisService {

    private final RestClient restClient;
    private final String model;

    public SentimentAnalysisService(RestClient.Builder builder,
                                     @Value("${huggingface.api-token}") String token,
                                     @Value("${huggingface.model}") String model) {
        this.model = model;
        this.restClient = builder
                .baseUrl("https://api-inference.huggingface.co/models")
                .defaultHeader("Authorization", "Bearer " + token)
                .build();
    }

    public List<SentimentResult> analyze(String text) {
        SentimentResult[][] response = restClient.post()
                .uri("/{model}", model)
                .body(Map.of("inputs", text))
                .retrieve()
                .body(SentimentResult[][].class);

        return response == null ? List.of() : List.of(response[0]);
    }

    public record SentimentResult(String label, double score) {}
}
  • RestClient.BuilderはSpring Bootが自動設定するので、baseUrlとAuthorizationヘッダを設定するだけです。
  • uri("/{model}", model)は.../models/distilbert-base-uncased-finetuned-sst-2-englishのようなURLを作成します。
  • text-classificationタスクのInference APIレスポンスはネストされた配列([[{...}]])なので、戻り値の型はSentimentResult[][]です。

呼び出してみます:

List<SentimentAnalysisService.SentimentResult> results =
        sentimentAnalysisService.analyze("I love this library!");
[SentimentResult[label=POSITIVE, score=0.9997]]

JSONレスポンスのパースをテストする

実際のレスポンスはネットワークに依存するため、実APIを呼び出さずにテストできるようにJSONパース部分を分離する必要があります:

import com.fasterxml.jackson.databind.ObjectMapper;
import static org.assertj.core.api.Assertions.assertThat;

class SentimentResultParsingTest {

    @Test
    void shouldParseInferenceApiResponse() throws Exception {
        String json = """
            [[{"label":"POSITIVE","score":0.9998}]]
            """;
        ObjectMapper mapper = new ObjectMapper();

        SentimentAnalysisService.SentimentResult[][] result =
                mapper.readValue(json, SentimentAnalysisService.SentimentResult[][].class);

        assertThat(result[0][0].label()).isEqualTo("POSITIVE");
        assertThat(result[0][0].score()).isGreaterThan(0.99);
    }
}

このテストは、ネットワーク接続や有効なトークンに依存せず、SentimentResult recordがlabel/scoreフィールドを正しくマップしていることを保証します。

7. よくあるエラーと、Inference APIを使わない方がいい場合

  • 最初の呼び出しで503 Service Unavailableが返される: モデルがフリーティアサーバーで「ウォームアップ」されていません。Hugging Faceはestimated_timeフィールドを返します。本当のエラーではなく、数秒後にリトライしてください。
  • 429 Too Many Requests: フリーティアは厳しいレート制限があります。安定した本番トラフィックの場合は、フリーAPIではなくInference Endpoints(専用、有料)を検討してください。
  • Gated modelだが未承認: トークンが有効でも403エラーが返されます。モデルページに行き「Request access」をクリックして承認を待つ必要があります。
  • ライセンスが商用利用に適していない: Llamaからファインチューニングされたモデルやデータセットの非商用制限には特別な条項がある場合があります。製品で使用する前に、モデルカードのライセンスセクションをよく読んでください。

注意: 低遅延の安定性やSLAが必要なシステムにはフリーのInference APIを使わないでください。実験、デモ、または低トラフィックに適しています。大規模ワークロードの場合は、transformers/text-generation-inferenceでローカルにモデルをホストするか、有料のInference Endpointsを使用してください。

8. まとめ

Hugging Face Hubは明確なプロセスを提供します:UIまたはhuggingface_hubでモデルを探し、モデルカードを読んでtask/license/gated状態をチェックし、その後使用方法を選択します。完全に制御したいときはpipelineでローカルに実行し、既存のJavaシステムに素早く統合したいときはSpring BootからInference APIを呼び出します。重要なのは、本番環境にモデルを導入する前に、常にライセンスとレート制限をチェックすることです。

huggingfacemachine-learningspring-bootnlpapi