解決できる課題 事業紹介トップ 経営データ分析基盤 AI導入・業務改善 AI 業務アプリ 基幹システムのWeb化・段階移行 複雑な SaaS を専用 UI に Shopify Plus 移行・拡張 生成AI 活用(Multi AI) SEO / AIO / 広告運用 顧問・アドバイザリ インフラ構築 自社メディア投資・開発
AI導入 AI導入・業務改善 ChatGPTの社内導入 OpenAI Codex導入 AI運用・定着 Claude / MCP 総合 Claude Cowork Claude Code 導入支援 Claude Code 使いこなし支援 Claude Design MCP 開発・サーバー構築
EC構築・移行 Shopify Plus トップ EC-CUBE からの移行 大手カートからの移行 Shopify 通常プラン EC サイト構築
実績
業界ニュース 業界ニュース トップ AI ニュース └ Claude └ ChatGPT・Codex └ Gemini └ その他 Shopify ニュース SaaS ニュース お知らせ(自社発信)
会社情報 相談する
2026.10.04

Papers with Codeの検索を支えるHugging Face Inference Endpoints、Jobs、Bucketsの活用法

記事のサマリー(TL;DR)

  • Papers with Codeは3か月前に復活し、論文検索をキーワード検索(全文検索)とベクトル検索を組み合わせたハイブリッド検索システムとして構築しています。PostgreSQLの全文検索機能とpgvectorによる密embeddingを、reciprocal rank fusion(RRF)で統合しています。
  • 密embeddingの生成・提供には3つのHugging Faceサービスを使用しています。Hugging Face Jobsは論文コーパスの埋め込み処理にバーストGPU計算資源を提供し、Hugging Face Storage Bucketsはデータベース・実験・Jobs間の耐久性あるデータ受け渡しを担い、Hugging Face Inference Endpointsはライブクエリや差分更新向けに低レイテンシの埋め込みを提供します。
  • 現在、arXivとDaily Papersから収集した11万件超の現行論文に対して埋め込みが維持されています。本記事ではこのアーキテクチャと設計判断、本番運用で得た知見を説明しています。

詳細

検索エンジンに求められる要件

論文の検索は通常のテキスト検索とは異なるとされています。正確なタイトルやarXiv識別子を見つけられるだけでなく、「small language models for code generation」のような、該当する語句が論文内に一緒に出現しない場合でもクエリの意図を理解する必要があります。また「the original BERT paper」のようなナビゲーション的な要求を認識すること、不完全なタイトルや誤字を許容すること、モデルサービスがコールド状態や一時的に利用できない場合でも迅速に応答することが求められるとしています。

ハイブリッド検索を採用した経緯

筆者らはML6での経験から、クライアント向けにRAGベースのシステムを開発してきたことに触れ、ハイブリッド検索がキーワードベース・ベクトルベースそれぞれの検索システムより性能が優れる傾向があるとしています。キーワード検索は正確な語句の一致を見つけるのに対し、ベクトル検索はより曖昧で意味的に類似した用語を見つけます。さらにリランカー(クロスエンコーダーとも呼ばれる)を使うことで結果をさらに改善できるものの、追加の処理負荷とレイテンシが発生するとも述べています。

Papers with CodeはPostgreSQLデータベースを利用しており、その全文検索機能が高速な字句検索のベースラインを提供します。密embeddingにはpgvectorを使用して意味的な再現率を加え、RRFアルゴリズムで両者を統合しています。

厳密なembedding契約から始める

埋め込みパイプラインは、モデルのリビジョンが変わる、クエリ用とドキュメント用のプロンプトが混同される、ベクトルの切り詰め方が異なる、更新されたアブストラクトが保存済みベクトルと一致しなくなるといった形で、見えにくい形で失敗することがあるとされています。これを避けるため、embeddingフォーマットをバージョン管理されたAPIとして扱っています。

各論文は次の形式でエンコードされます。

normalized title + "\n\n" + normalized abstract

各ベクトル生成の際には、以下の情報を記録しています。

  • モデルリポジトリと正確なリビジョン
  • 出力次元数
  • 入力フォーマットのバージョン
  • 入力がクエリかドキュメントか
  • 正規化の方法
  • 元のタイトルとアブストラクトに対するコンテンツハッシュ

本番環境ではQwen/Qwen3-Embedding-0.6Bを使用し、特定のリビジョンに固定した上で、256次元のL2正規化ベクトルを生成しています。モデル選定にはembeddingモデル比較の定番ベンチマークであるMTEBリーダーボードを参考にしたとしています。Qwen3のような新しいembeddingモデルでは、2つの新機能が利用できるとしています。1つは動的なembeddingサイズの指定で、品質と速度・ストレージコストのトレードオフを調整できます(Qwenのモデルではこれを「MRL」=Matryoshka Representation Learningと呼んでいます)。検索速度を優先し、embeddingサイズは256を選択したとしています。もう1つはインストラクションプロンプトの指定で、Qwenのembeddingモデルはドキュメント用プロンプト(論文の埋め込みに使用)とクエリ用プロンプト(ユーザークエリの埋め込みに使用)の両方をサポートしています。

この契約は、エクスポートからGPU推論、PostgreSQLへの格納、そしてオンライン検索に至るまでのembeddingの流れ全体に適用されます。

Jobsがデータベースのスナップショットをベクトルコーパスに変換する

コーパス全体の埋め込みは典型的なバッチ処理のワークロードです。比較的短時間だけGPUを必要とし、高スループットの恩恵を受け、実行の合間には資源を消費すべきではないとしています。Hugging Face Jobsはこの用途に適しているとされ、Jobはコマンド・ハードウェアの種類・(任意で)Dockerイメージによって定義され、依存関係をインラインで宣言したuvスクリプトを実行できます。

コーパスの構築は、repeatable-readのPostgreSQLスナップショットからすべての論文の最新バージョンをエクスポートすることから始まります。エクスポーターはカタログ全体をメモリに読み込むのではなく行をストリーミングし、サイズに上限を設けたJSONLシャードを書き出し、行数とSHA-256チェックサムを含むマニフェストを作成します。この不変のrunディレクトリをプライベートなStorage Bucketに同期し、hf-mountを用いてBucketをl4x1のJob(NVIDIA L4 GPU、24GBのVRAM搭載)に直接マウントします。ワーカーからはこれが単なるファイルシステムとして見えるとしています。

hf jobs uv run \
  --flavor l4x1 \
  --timeout 6h \
  --volume hf://buckets/OWNER/pwc-paper-embeddings:/bucket \
  embed_papers_job.py \
  --input /bucket/runs/RUN_ID/input \
  --output /bucket/runs/RUN_ID/output \
  --model Qwen/Qwen3-Embedding-0.6B \
  --revision MODEL_REVISION \
  --dimensions 256 \
  --allow-matryoshka

ワーカーは以下の処理を行います。

  • 入力マニフェストと各シャードのチェックサムを検証する
  • 固定されたモデルリビジョンを読み込む
  • パディングを減らすためテキストを長さ順にソートする
  • (モデルカードに記載の通り)encode_documentをバッチ単位で呼び出す
  • GPUのメモリが不足した場合はバッチサイズを自動的に縮小する
  • Matryoshka表現を256次元に切り詰めて正規化する
  • float16形式のParquetシャードをアトミックに書き出す
  • スループット、パッケージバージョン、ハードウェア、ピークVRAM、行数、出力のチェックサムを記録する

完了した各シャードには専用のマーカーが付与されるため、再起動したJobは検証済みの作業をスキップできます。これは大規模なコーパスにおいて有用で、再試行は既存のembeddingを上書きするのではなく作業を再開するだけで済みます。

5,000論文のパイロットでは、QwenのJobはL4 GPU上で1024次元のembeddingを1秒あたり約75論文のペースでエンコードしたとしています。同じパスから512次元・256次元のembeddingも決定論的に生成できたため、追加の推論コストをかけずにストレージと検索性能のトレードオフを比較できたとしています。

Bucketsが各システムをつなぐ役割を果たす

Storage Bucketsは、Hub上で可変なS3互換のオブジェクトストレージであり、AIワークロード向けに最適化されています。hf://buckets/…というパスでアクセスでき、個別のストレージ連携を構築することなくJobsに読み書き可能な形でマウントできます。

このBucketは単なるベクトルの置き場所ではなく、異なるライフサイクルを持つ3つのシステムの境界になっているとしています。本番データベースがソースレコードをエクスポートし、一時的なJobsがそれらのレコードを消費してベクトルを生成し、インポーターが検索インデックスに反映する前に結果を検証します。

アーティファクトは不変のrunプレフィックスの下に整理されています。

runs/<run-id>/
├── input/
│   ├── manifest.json
│   └── papers-*.jsonl
└── output/
    ├── manifest.json
    ├── embeddings-*.parquet
    └── embeddings-*.complete.json

Bucket自体は本来可変であるため、不変性はアプリケーション側のルールとして実現されています。runのIDは上書きされることがなく、すべてのアーティファクトはマニフェストとチェックサムでカバーされています。これにより以下のような特性が得られるとしています。

  • 再現性:データベースの世代を、正確なコーパスのスナップショット、モデルリビジョン、アーティファクトの集合にまで遡ることができる
  • 安全な再試行:Jobsは同じrunプレフィックス内の完了済みシャードから再開できる
  • 低コストな実験:複数のモデルや次元数で1つの検証済み入力スナップショットを再利用できる
  • 制御されたロールアウト:ある世代をインポートしても、それだけでは有効化されない。まずカバレッジを検証し、インデックスを構築する
  • 単純なロールバック:新しい世代が安定していると確認されるまで、前の世代とそのアーティファクトは利用可能なまま残る

インポーターがスキーマ、チェックサム、次元数、正規化、論文IDの一意性、現在のコンテンツハッシュを再チェックした後にのみ、ベクトルはPostgreSQLに読み込まれます。その後、新しい世代用に個別のHNSWインデックスを構築し、対象となるすべての現行論文がカバーされている場合にのみアトミックにアクティブとしてマークします(HNSWは高速なベクトル検索を可能にするグラフベースのアルゴリズムです)。

Inference Endpointsが意味検索をリクエスト経路に組み込む

バッチ埋め込みはドキュメント側の検索課題を解決しますが、ユーザーのクエリは同じモデル契約を用いてリクエスト時に埋め込まれる必要があります。固定したモデルを、Text Embeddings Inference(TEI)を基盤とする認証付きのInference Endpointとしてデプロイしています。このエンドポイントはクエリテキストを受け取り、モデルのクエリ用プロンプトを用いて正規化済みの256次元ベクトルを返します。なお、ここではvLLMやSGLangを利用することも可能だとしています。

APIはその後、有効なpgvectorの世代に対してコサイン距離による検索を実行します。

SELECT paper_id, embedding <=> CAST(:query_vector AS halfvec(256)) AS distance
FROM paper_embeddings
WHERE generation_id = :active_generation
ORDER BY embedding <=> CAST(:query_vector AS halfvec(256))
LIMIT 50;

HNSWインデックスによってこの検索は高速に保たれています。5,000論文のパイロットでは、256次元のQwenインデックスは厳密検索に対してRecall@20が0.9955、HNSW検索のレイテンシはp50が1.31ミリ秒、p95が2.21ミリ秒だったとしています。そのテーブルとインデックスは1024次元版のストレージの約27%しか使用せず、そのテストにおいてほぼ同等のANN再現率を維持していたとしています。

このEndpointはレプリカ数の上限を1に設定し、アイドル時にはゼロまでスケールダウンできるよう構成されています。これは利用がない間は料金が発生しないという、有用なコスト上の利点になるとしています。ただし、これはコールドスタートを例外的な事象としてではなく、アプリケーション設計の一部として扱う必要があることも意味しており、エンドポイントが起動してトラフィックを処理できるようになるまでには時間がかかるとしています。

このため、クエリ用クライアントには意図的に厳格な挙動が実装されています。

  • 本番環境では1秒のタイムアウト
  • 非ブロッキングの同時実行数の制限
  • レスポンスの次元数、有限性、ノルムの検証
  • クエリとembeddingの世代をキーとした短時間のキャッシュ
  • 繰り返し失敗した場合のサーキットブレーカー
  • ログには生のクエリテキストを残さず、正規化されたフィンガープリントのみを記録

エンドポイントがスケールアップ中、タイムアウトした、不正な形式のベクトルを返した、あるいは同時実行の余地がない場合には、即座にセマンティック検索の分岐をスキップするとしています。ユーザーは信頼できない依存先を待つのではなく、代わりに字句検索の結果を受け取ります。Inference Endpointsは非常に高い信頼性で動作しており、主要な分析指標をすぐに確認できる使いやすいダッシュボードも備わっているとしています。

ハイブリッド検索はどちらか一方より優れている

クエリごとに、字句検索の分岐は重み付けされたPostgreSQLの全文検索を用いて最大50件の候補を取得し、意味検索の分岐はpgvectorから最大50件の候補を取得します。両者のランクは重み付けされたreciprocal rank fusion(RRF)を用いて統合されます。

score(d) = Σ_{r ∈ {lexical, semantic}} w_r / (k + rank_r(d))

RRFは異なるスケールを持つ2つのシステムからスコアではなくランクを統合するため、シンプルで頑健であるとしています。基本的に、ある論文が字句検索・意味検索の両方で高いランクに位置づけられている場合、ハイブリッド検索でも高いランクに位置づけられる可能性が高くなります。現在は両方の分岐に等しい重みを与え、k=60(kはRRFアルゴリズムのハイパーパラメータである「ランク定数」)を使用しています。

密検索は概念的なクエリに対する再現率を改善するとしており、全文検索は正確な専門用語や識別子、まれな名称に対して引き続き優れた性能を発揮するとしています。また、統合されたランキングの上に、決定論的なアイデンティティ処理も維持されています。

  • 正確なタイトルとarXiv IDは常に上位に表示される
  • メソッドの分類体系により「the original BERT paper」のようなナビゲーション的な検索を認識する
  • 不完全なタイトルや一定範囲内のスペルミスには、保守的なトライグラムによる候補を使用する
  • 曖昧なあいまい一致は、無理に結果を出すのではなく該当なしとする

なお、ハイブリッド検索が常に最良の選択肢とは限らないとしており、まずはコストが低く高速なベースラインとしてキーワード検索から始め、意味検索やハイブリッド検索が検索品質に妥当な向上をもたらすと判明した場合にのみ追加することが推奨されるとしています。キーワード検索・意味検索・ハイブリッド検索による取得結果の後に、Qwen3-Rerankerのようなモデルを用いたリランカーを追加することで、検索をさらに改善できる可能性にも言及しています。

1つのEndpointに対する2つの更新経路

初期の大規模コーパスはJobsで埋め込まれますが、Papers with Codeは継続的に更新されます。新しい論文が追加され、アブストラクトが修正され、新しいarXivバージョンが最新版になります。変更された少数の行のためだけにGPUのJobを起動すると、不要な起動およびオーケストレーションのオーバーヘッドが生じるとしています。

その代わりに、1時間ごとの差分処理が、欠落しているか内容が変更された論文を選び出し、範囲が限定された差分を同じTEI Endpointに送信します。この際はドキュメント用プロンプトが使用されます。各実行では最大500論文を、16件ずつのバッチで処理します。embeddingを書き込む前に、元の行をロックしてコンテンツハッシュを再チェックします。推論中に論文が変更された場合、そのベクトルは破棄され、次回の実行で改めて処理されます。

これにより、以下のような役割分担が実現されているとしています。

  • Jobsは完全な再構築、新しいモデル世代の生成、大規模なバックフィルを担当する
  • Inference Endpointsは対話的なクエリの埋め込みと、小規模な差分のドキュメント更新を担当する
  • Bucketsは大規模ビルドのアーティファクトを保存し、それらのビルドを再開可能かつ監査可能にする

この1時間ごとの経路により、オンラインのエンドポイントを無制限のバッチ処理装置にすることなく、アクティブなインデックスを実際のカタログに近い状態に保っているとしています。

関連論文の表示がほぼ無料で実現される

同じドキュメント埋め込みは、各論文ページでの関連論文のレコメンデーションにも利用されています。元の論文にはすでにベクトルが保存されているため、関連論文の検索にはリクエスト時のモデル呼び出しが不要で、有効な世代に対する単純な最近傍探索のみで済むとしています。ベクトルが一時的に欠落している場合、アプリケーションは以前のarXivバージョンを使用するか、既存のタスクベース・引用ベースのフォールバックから結果を補うことができます。

引用データはSemantic Scholar APIを通じて取得しており、その引用グラフを照会するためのコマンドラインインターフェースであるs2-cliも開発したとしています。このs2-cliは、https://paperswithcode.co/chat のエージェントで使用されているとしています。

得られた知見

  1. スループット重視の処理とレイテンシ重視の処理を分離する:コーパスの埋め込みとクエリの埋め込みは同じモデルを使用しますが、インフラ上は異なる課題です。Jobsはスループットと有限なコストの最適化を、Inference Endpointsは可用性とリクエストのレイテンシの最適化を担います。

  2. ストレージを計算と本番環境の間の明示的な契約にする:Bucketsは計算処理と本番環境の間の明確な受け渡し地点を提供します。チェックサム付きのアーティファクトは、データが本番インデックスに入る前にレビュー可能な境界を作ります。

  3. モデル名以上のものを固定する:リビジョン、次元数、プロンプト、正規化方法、入力フォーマッタはすべて検索結果に影響します。これらをまとめて保存し、あらゆる箇所で検証する必要があるとしています。

  4. コールドスタートを前提に設計する:トラフィックが断続的な場合、スケールトゥゼロは有用ですが、それはプロダクトに高速なフォールバックが備わっている場合に限られるとしています。ハイブリッド検索は、字句検索単体でも有用であるという形で、そのフォールバックを自然に提供しているとしています。

  5. より小さいベクトルはシステム上の利点になり得る:Matryoshka embeddingにより、品質・メモリ・インデックスサイズ・レイテンシを1つのトレードオフとして評価できます。パイロットでは、256次元が1024次元と比較してストレージを大幅に削減しつつANN再現率を維持したとしています。

  6. 有効化の処理は目立たないものにすべき:新しい世代は現行のものと並行してインポートされ、独立してインデックス化され、カバレッジが完全かつ最新であるか確認された上で、アトミックに有効化されます。ロールバックは緊急の再計算ではなく、設定変更として扱われるとしています。

検索は https://paperswithcode.co で、チャットインターフェースは https://paperswithcode.co/chat で試すことができるとし、フィードバックを呼びかけています。

[“Hugging Face”, “Papers with Code”, “Inference Endpoints”, “Hugging Face Jobs”, “Storage Buckets”, “ハイブリッド検索”, “pgvector”]