--- license: apache-2.0 datasets: - Shuu12121/ruby-treesitter-filtered-datasetsV2 - Shuu12121/rust-treesitter-filtered-datasetsV2 - Shuu12121/python-treesitter-filtered-datasetsV2 - Shuu12121/typescript-treesitter-filtered-datasetsV2 - Shuu12121/javascript-treesitter-filtered-datasetsV2 - Shuu12121/php-treesitter-filtered-datasetsV2 - Shuu12121/go-treesitter-dedupe_doc-filtered-dataset - Shuu12121/java-treesitter-dedupe_doc-filtered-dataset language: - en pipeline_tag: fill-mask tags: - code - python - java - javascript - ruby - rust - go - php - typescript - modernbert --- # Owl-ph2-base (2048) 🦉 このモデルは、**ModernBERT アーキテクチャに基づくコード特化型言語モデル**です。 既存の事前学習済みモデル(ModernBERT-base など)の重みは使用せず、 8 言語を含む自前のデータセットである, **Owl コーパス**(約 855 万件の関数ペア)を用いて、 **ランダム初期化状態から事前学習(scratch training)** を行っています。 --- ## モデルの詳細 * **アーキテクチャ**: ModernBERT (base-sized) * **学習状態**: スクラッチ学習(Trained from scratch) * **学習済み言語**: Python, Java, JavaScript, TypeScript, Ruby, Rust, Go, PHP * **パラメータ数**: 約 149M * **最大入力長**: * 推論時: 最大 8,192 トークン * 事前学習時: 最大 2,048 トークン * **主な特徴**: * コードデータに特化した BPE トークナイザを新規構築 * 通常の MLM に加え、コード構造を意識した **行単位マスキング** を導入 --- ## 学習手法:2 段階の事前学習 ### 段階 1(ph1): ランダムマスキング(MLM) * トークン単位で 30% をランダムにマスク * ランダム初期化状態から、コードの基本的な語彙分布や構文的特徴を学習 ### 段階 2(ph2): 行ごとのマスキング(Line-based MLM) * 行単位で 30% をランダムに選択 * 選択された行に含まれる **全トークンをマスク** * 空白のみからなるトークンはマスク対象から除外 **効果**: 関数内における制御構造や変数の依存関係など、 コードの構造的な意味表現をより強く獲得できることを確認しています。 --- ## 評価結果(MRR: Mean Reciprocal Rank) ### 1. 既存モデルとの比較 同じ条件で学習(CodeSearchNetから各言語3万件を取り出しMultiple Negatives Ranking Lossを用いてファインチュー二ング)した際, ベンチマーク(CodeSearchNetRetrieval)において、低い学習率を用いると、既存のモデル以上の CodeBERT、GraphCodeBERT、既存の ModernBERT-base を上回る性能を示していました。 | 学習モデル | Go | Java | JavaScript | PHP | Python | Ruby | 平均 | | :---------------------------- | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | | CodeBERT-base | 0.9306 | 0.7104 | 0.7014 | 0.8277 | 0.8618 | 0.7837 | 0.8026 | | GraphCodeBERT-base | 0.9422 | 0.8009 | **0.7466** | 0.8434 | 0.8852 | **0.8095** | 0.8379 | | UniXCoder-base | 0.8810 | 0.8369 | 0.7137 | 0.8185 | 0.8733 | 0.7496 | 0.8122 | | ModernBERT-base | 0.9364 | 0.7749 | 0.7475 | 0.8347 | 0.8922 | 0.7866 | 0.8287 | | Owl-ph1-base-len512 | 0.9383 | 0.8062 | 0.7307 | 0.8369 | 0.8845 | 0.7725 | 0.8282 | | Owl-ph1-base-len2048 | 0.9323 | 0.8093 | 0.7231 | 0.8373 | 0.8891 | 0.7669 | 0.8263 | | **Owl-ph2-base-len512** | **0.9447** | **0.8399** | 0.7426 | 0.8400 | 0.9044 | 0.7998 | **0.8452** | | Owl-ph2-base-len2048 | 0.9370 | 0.8368 | 0.7435 | **0.8435** | **0.9076** | 0.7964 | 0.8441 | また各学習率の最良のモデルは以下のようになりました。各学習率全てのパターンにおいても低い学習率で学習したOwl-ph2-base群が最も性能が高いことが確認されました。 | 学習率 | 最良モデル | 平均MRR | 備考 | | :------: | :-------------------- | :--------: | :----------------------------- | | 5e-5 | GraphCodeBERT | 0.8429 | 高学習率条件での最良結果 | | 3e-5 | ModernBERT-base | 0.8404 | GraphCodeBERTとほぼ同等 | | **1e-5** | **Owl-ph2-base-len512** | **0.8452** | **全条件中で最良** | | 1e-5 | Owl-ph2-base-len2048 | 0.8441 | 5e-5 / 3e-5 の最良値を上回る | --- ### 2. 継続学習(ph2)の効果 スクラッチ学習の第 1 段階(ph1)と比較して、 第 2 段階(ph2)を導入することで **平均 MRR が約 +0.02 向上**しています。 | 学習段階 | 平均MRR | Go | Java | JS | PHP | Python | Ruby | | :---------------- | :---------: | :--------: | :--------: | :--------: | :--------: | :--------: | :--------: | | 段階1(ph1: 通常MLM) | 0.8208 | 0.9300 | 0.7980 | 0.7268 | 0.8366 | 0.8675 | 0.7662 | | **段階2(ph2: 行ごと)** | **0.8420** | **0.9408** | **0.8415** | **0.7397** | **0.8462** | **0.8951** | **0.7888** | | **向上幅(Delta)** | **+0.0212** | +0.0108 | +0.0435 | +0.0129 | +0.0096 | +0.0276 | +0.0226 | --- ## 学習率についての注意 本モデルおよび比較実験の結果から、 **コード検索タスクへのファインチューニングでは低い学習率(例: 1e-5 程度)を推奨**します。 比較的高い学習率(例: 5e-5)では、他のモデルと比較して性能が伸びにくい、学習率を下げた時の伸び幅が大きい といった傾向が確認されており、 低学習率での安定した最適化が有効であることが分かっています。 (原因は行単位による継続事前学習により他のモデルと比較してコードに対して理解できているので、過適合に陥りやすいと考えています。) --- ## 使用方法 このモデルは `fill-mask` タスクとして直接利用できるほか、 ファインチューニングを行うことで意味的コード検索やコード理解タスクの ベースモデルとして利用できます。 ```python from transformers import AutoTokenizer, AutoModelForMaskedLM #MLMモデルとして読み込む場合 tokenizer = AutoTokenizer.from_pretrained("Shuu12121/Owl-ph2-base-len2048") model = AutoModelForMaskedLM.from_pretrained("Shuu12121/Owl-ph2-base-len2048") ``` Sentence-Transformersを用いてファインチューニングを行う場合の読み込み方 ```python from sentence_transformers import SentenceTransformer,models word_embedding_model = models.Transformer("Shuu12121/Owl-ph2-base-len2048") word_embedding_model.max_seq_length = 2048 #CLSトークンを用いる場合pooling_mode_cls_tokenのみTrue #平均プーリングを用いる場合 pooling_mode_mean_tokensのみTrue pooling_model = models.Pooling( word_embedding_model.get_word_embedding_dimension(), pooling_mode_cls_token=True, pooling_mode_mean_tokens=False, pooling_mode_max_tokens=False, pooling_mode_weightedmean_tokens=False, pooling_mode_lasttoken=False, ) model = SentenceTransformer(modules=[word_embedding_model, pooling_model]) ``` そのほかのモデル - [Owl-ph1-base (512)](https://huggingface.co/Shuu12121/Owl-ph1-base-len512) - [Owl-ph2-base (512)](https://huggingface.co/Shuu12121/Owl-ph2-base-len512) - [Owl-ph1-base (2048)](https://huggingface.co/Shuu12121/Owl-ph1-base-len2048)