はじめに
これまで数回にわたって、自作のコード理解モデルについて紹介してきました。
今回はその続編として、私が開発したコード検索モデル CodeSearch-ModernBERT-Crow-Plus
が MTEB(Massive Text Embedding Benchmark)公式リーダーボードに掲載された ことをご報告します。
さらに、このモデルを用いて GitHub リポジトリに対する関数レベルのコード検索システムを構築したので、あわせてその実装方法と活用例(RAGなど)についても紹介していきます。
モデル概要:CodeSearch-ModernBERT-Crow-Plus🐦⬛
事前学習済みモデル: CodeModernBERT-Crow
前回,前々回解説してきたCodeModernBERT-Owlの後継となるモデルであるCodeModernBERT-Crowを新たに開発しました。このモデルはCodeModernBERT-Owlの学習に使っていたデータセットを再度見直し、より学習を洗練しました。
特に各言語収集したリポジトリ内での関数の重複を削除したり,CodeSearchNetのtest splitに存在しているリポジトリは学習に含めないよう調整したりしました。また事前学習を見直すことで、
- 対応言語:Python, Java, JavaScript, PHP, Ruby, Go, Rust
- 最大 8192 トークンの入力長に対応(学習時は 2048 トークンで調整)
に対応しています。(特に今後のファインチューニングで8192トークンまで対応できる余地を残せているのは良いことだと考えています。)
ファインチューニング:CodeSearch-ModernBERT-Crow-Plus
この CodeModernBERT-Crow
をベースに、Sentence Transformers ライブラリを用いてコード検索に特化したファインチューニングを行いました。
-
使用手法:
MultipleNegativesRankingLoss
- 自然言語クエリと正解コードのペアを正例とし、バッチ内の他のコードはすべてネガティブ例として扱います
- 高効率でスケーラブルなランキング学習が可能です
-
学習データ:
- CodeSearchNet 系の英語ベースデータセット
- 独自に収集・クレンジングした多言語関数ペア(コメント付き)
- 自然言語とコードの意味的対応が明確なペアに(可能な限り)絞り込み済み
補足:バッチサイズと性能の関係について
MultipleNegativesRankingLoss
は、バッチサイズを大きくするほどネガティブ例の多様性が増すため、理論的には性能が向上しやすいという特性があります。
私の環境では VRAM 制約により 最大256件までのバッチサイズでしか学習を行えませんでしたが、
より大規模なGPU環境(例:A100 80GBなど)を用い、512〜1024件規模のバッチサイズで学習できれば、さらなる精度向上の可能性があると考えています。
この点は今後の改善・蒸留・再学習における重要な観点になるかもしれません。
⚠️ モデルの適用範囲と限界について
CodeSearch-ModernBERT-Crow-Plus
はあくまで コード検索タスクに特化した Sentence Transformer モデル であり、他の用途にそのまま適用するにはいくつかの制約があります。
得意なタスク
- 自然言語クエリ → 関数コード検索(NL→Code Retrieval)
- 類似関数のベクトル検索(Code→Code Retrieval)
- 関数単位のベクトル化によるクラスタリング・分類前処理
苦手・非推奨なタスク
タスク例 | 課題・制限 |
---|---|
❌ コード要約・説明生成 | 本モデルはエンコーダ型であり、生成(デコーダ)能力を持たないため、要約・説明文の生成は不可能です。 |
❌ コード修正提案・自動補完 | 文脈を保持した状態での修正・補完は、LLM(e.g. GPT, StarCoder)系の生成モデルの領域です。 |
❌ テキスト分類や自然言語の埋め込み | モデルは「自然言語+コード」に最適化されており、一般的なテキスト分類・検索タスクには適応不可と言い切れるレベルです。 |
総括
CodeSearch-ModernBERT-Crow-Plus
は、コード検索という一点突破型のモデル設計になっており、他タスクへの汎用性はあまり高くありません。(コード理解はできるかも…?)
そのため、「自然言語+関数コードのペア」が明確に対応するようなシーンに限定して使うのが最も効果的です。
より多機能な用途には、以下のような補完的手段が推奨されます:
- 🔄 自然言語応答 → LLM(Qwen, GPT, Claude など)
- 📈 埋め込み用途の拡張 → Multi-task finetuning or MTEB multi-task alignment
- 🔁 Code Search + Explanation → Retriever-Generator 構成(例:CodeSearch + GPT)
- 🐦⬛事前学習済みモデル
CodeModernBERT-Crow
に別タスクのファインチューニングを行う
このように用途を明確に限定して導入することで、モデルのポテンシャルを最大限に引き出すことができます。
MTEBリーダーボード(CodeSearchNet Retrieval)
以下は、私のモデルを提出した2025年4月時点のMTEBリーダーボードにおける散布図です。
この図は CodeSearchNet Retrieval タスクのみ に絞ったものであり、MTEB全体(多様なテキストタスク)ではなく、コード検索系タスクに特化した可視化である点にご注意ください。
🔍 グラフの見方
- 横軸(x-axis):モデルのパラメータ数(対数スケール、例:10M, 100M, 1B…)
- 縦軸(y-axis):CodeSearchNet Retrieval タスクにおける 平均スコア(nDCG@10)
- 円の大きさ:モデルの埋め込み次元(Embedding Dimension)を表す
CodeSearch-ModernBERT-Crow-Plusの結果
タスク名 | nDCG@10 スコア | 順位(2025年4月時点) |
---|---|---|
CodeSearchNetRetrieval | 0.89296 | 第8位 / 146 モデル中 |
COIRCodeSearchNetRetrieval | 0.79884 | 第5位 / 15 モデル中 |
この結果から、コード検索においては、非常にコンパクトな構成(150M)でありながら、数百M〜数Bパラメータ級のモデルに匹敵する性能を持っていることがわかります。
特に「性能 / モデルサイズ」のバランスが優れており、実用性とスケーラビリティの観点で強いアドバンテージを持つモデルです。
他モデルとの比較
モデル名 | 所属・開発元 | パラメータ数 | CodeSearchNetRetrieval スコア | コメント |
---|---|---|---|---|
voyage-code-3 | Voyage AI | Unknown | 93.97 | コード特化最強モデル |
voyage-3 | Voyage AI | Unknown | 92.30 | |
gemini-embedding-exp-03-07 | Unknown | 91.33 | Gemini API版Embedding | |
gte-Qwen2-1.5B-instruct | Alibaba | 1B | 91.08 | |
inf-retriever-v1-1.5b | Inflection | 1B | 90.87 | Inflection社リトリーバル特化モデル |
text-embedding-3-large | OpenAI | Unknown | 90.50 | OpenAI Embedding大型版 |
gte-multilingual-base | Alibaba | 305M | 89.39 | |
CodeSearch-ModernBERT-Crow-Plus | Shuu12121 | 151M | 89.30 | CodeSearch特化モデル |
text-embedding-3-small | OpenAI | Unknown | 87.42 | OpenAI Embedding小型版 |
CodeSearch-ModernBERT-Crow-Plus(私の開発したモデル)は、たった151Mパラメータにもかかわらず、Google、OpenAI、Inflection、Salesforce、Alibabaといった世界的な企業が開発した大型埋め込みモデルと比較して、遜色ないレベルの結果を残すことができました。
COIRCodeSearchNetRetrievalのほうが若干難しめのタスクであることと、最新版の強めなモデルのみの掲載のため少し競争率が高い印象です.
またCodeSearch-ModernBERT-Crow-Plusとほかのモデルでは別タスクで大きな差があるため、コード検索以外でのタスクは別モデルを使用したほうが良いと考えられます。
GitHub関数検索システムの実装とデモ
ここからは、CodeSearch-ModernBERT-Crow-Plus
を活用して構築した 関数レベルのコード検索システムについて詳しく解説していきます。
このシステムは、任意の GitHub リポジトリを指定することで以下のような処理を自動で行い、**自然言語クエリ(日本語含む)に対して、意味的に最も類似する関数コードを検索することができます
処理全体の流れ
- GitHub リポジトリをクローン
.py
ファイルや.ipynb
セルから関数コードを抽出- Sentence Transformer で関数コードを埋め込み(ベクトル化)
- FAISS インデックスを作成・保存
- 日本語クエリを Qwen3-8B-FP8 を用いて英語に翻訳
- 翻訳後クエリをベースに FAISS による類似検索を実行
- 類似関数コードを上位から表示(ファイル名、関数名、コード)
実装技術・工夫点
-
関数抽出には
lizard
を使用 -
Notebook (
.ipynb
) にも対応し、セル単位のコードも検索対象に - FAISS によるインメモリ高速検索を導入し、大規模リポジトリでもスムーズに検索
-
Qwen3-8B-FP8 によるクエリの翻訳により、日本語にも対応
(ただしクエリへの修正は指示していないためコード検索自体はCodeSearch-ModernBERT-Crow-Plus
の性能に左右される
Colabで関数検索システムを実行する(ステップ別解説付き)
このコード検索システムは、以下のように Google Colab 上で簡単に試すことができます。
日本語で検索クエリを入力するだけで、対応する関数コードが返されます。
Colabで手軽に実行できます。
以下のプログラムは抜粋しているので実行可能なプログラムはこちら から確認してください
✅ 1. 必要ライブラリのインストール
!pip install flash-attn lizard faiss-cpu
実行環境は T4 / L4 / A100(VRAM 16GB以上)推奨です。(flash-attnは L4 / A100でのみ動くためそちらがおすすめです、なくても実行はできますが埋め込み時に時間がかかります)
✅ 2. 実行設定(リポジトリとモデル名の指定)
GITHUB_REPO_URL = "https://github.com/google-research/bert.git" # 検索対象のリポジトリ
MODEL_NAME = "Shuu12121/CodeSearch-ModernBERT-Crow-Plus"
QWEN_MODEL = "Qwen/Qwen3-8B-FP8"
翻訳モデルは必要に応じて変更してください(geminiなど)
✅ 3. モデルの読み込みとデータ準備
model = SentenceTransformer(MODEL_NAME)
qwen_tokenizer = AutoTokenizer.from_pretrained(QWEN_MODEL, trust_remote_code=True)
qwen_model = AutoModelForCausalLM.from_pretrained(
QWEN_MODEL, torch_dtype="auto", device_map="auto", trust_remote_code=True
)
functions, index = load_or_build_data_and_index("./cloned_repos/bert", model)
初回実行では
.py
や.ipynb
ファイルから関数抽出 → ベクトル化 → FAISS インデックス構築が行われるため、数十秒〜数分かかります。
2回目以降は保存済みデータを再利用するため非常に高速です。
✅ 4. 日本語で検索クエリを入力
while True: # ユーザーが空行を入力するまで検索を繰り返すループ
japanese_query = input("\n💬 日本語で検索クエリを入力してください (終了するにはEnterキーのみを押す): ")
if not japanese_query.strip():
print("👋 検索を終了します。")
break
print("\n🔄 Translating query to English...")
以下のようなプロンプトが出るので入力してください
💬 日本語で検索クエリを入力してください : BERTモデルを初期化する関数を探して
✅ 出力例
🌎 英訳クエリ: Look for a function to initialize the BERT model.
🔍 Search Results:
=== Result 1 ===
📄 File: ./cloned_repos/bert/modeling_test.py
🔧 Function: create_model(self)
🧩 Code Preview:
def create_model(self):
...
ℹ️ 注意事項(実行前に必読)
- 初回実行時は必ず「関数抽出 → 埋め込み → インデックス構築」が発生します
- クローン済みのリポジトリが存在すれば再クローンはスキップされます
- FAISSインデックスは
faiss_index.bin
として保存・再利用可能 - 日本語対応は
Qwen3-8B-FP8
による翻訳処理によって実現されています(必要に応じて別のモデルを検討してください、英語で入力する場合は必要ありません) - 翻訳結果が不自然な場合は、翻訳部分を確認することで改善してください
- デモではPythonのみに対応しています(lizardの部分を変更することで多言語でも対応できます)
🚀 このプログラムの将来性と応用の可能性
今回紹介した「GitHubリポジトリを対象とした関数レベルのコード検索システム」は、すでに実用的なレベルに近い性能と汎用性を備えています。
実用的な可能性
- 任意のGitHubリポジトリに対してクローン・解析・検索が可能であるため、次のような活用が想定されます:
- 社内コードベースの検索ツール
- OSSライブラリの理解支援
- 類似実装の探索や再利用候補の抽出
- 新規開発者向けの「コードの入り口」ナビゲーション
また、関数レベルでの検索に特化しているため、grepや全文検索では拾えない意味的な一致を自然言語で取得できる点で、従来型のツールとは一線を画しています。
応用の可能性:RAGやLLM統合にも活用可能
このシステムは、検索部分を担う「Retriever」としての役割を果たすため、以下のようなLLMベースのアプリケーションとの統合も視野に入れられます:
応用パターン | 説明 |
---|---|
Retrieval-Augmented Generation(RAG) | 関数検索結果をプロンプトに組み込むことで、LLMによる精度の高い説明・要約・変換が可能 |
コード要約・翻訳支援 | 抽出された関数をLLMに渡して「何をしている関数か」「別言語に変換」など |
チャットボット連携 | 「○○に関する実装はどこ?」という質問に対し、コードベースを対象とした実用的な回答が可能に |
例えば、Qwen3やClaude、GPT-4oなどの高性能LLMと組み合わせることで、「質問→検索→分析のサイクルを自然に構築でき、
社内検索アシスタントやコードリファクタリング支援ツールへの発展も可能です。
まとめ
-
CodeSearch-ModernBERT-Crow-Plus
は、軽量かつ高精度なコード検索モデルとしてMTEBでの評価も高く、実用性を十分に備えています - GitHubリポジトリを対象とした柔軟な関数検索は、今後の開発補助ツールやAI支援開発環境の基盤技術として展開できるのではないかと考えています
- 特に自然言語クエリでの柔軟な操作やRAGとの統合など、今後の発展が大いに期待される領域です