vedevpatel commited on
Commit
5723c50
·
verified ·
1 Parent(s): cedc0d9

Release CodeIntel-150M

Browse files
1_Pooling/config.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "word_embedding_dimension": 768,
3
+ "pooling_mode_cls_token": true,
4
+ "pooling_mode_mean_tokens": false,
5
+ "pooling_mode_max_tokens": false,
6
+ "pooling_mode_mean_sqrt_len_tokens": false,
7
+ "include_prompt": true
8
+ }
README.md CHANGED
@@ -1,3 +1,193 @@
1
  ---
2
  license: apache-2.0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
  license: apache-2.0
3
+ language:
4
+ - en
5
+ - code
6
+ library_name: sentence-transformers
7
+ pipeline_tag: sentence-similarity
8
+ base_model: ibm-granite/granite-embedding-english-r2
9
+ tags:
10
+ - sentence-transformers
11
+ - feature-extraction
12
+ - code-search
13
+ - code-retrieval
14
+ - bug-localization
15
+ - modernbert
16
+ - onnx
17
+ model-index:
18
+ - name: CodeIntel-150M
19
+ results:
20
+ - task: {type: retrieval, name: Issue -> code localization (descriptive issues, Python)}
21
+ dataset: {type: custom, name: codeintel issue localization (35 repositories)}
22
+ metrics: [{type: ndcg_at_10, value: 0.268, name: symbol nDCG@10 (hybrid)}]
23
+ - task: {type: retrieval, name: Issue -> code localization (descriptive issues, TypeScript)}
24
+ dataset: {type: custom, name: codeintel issue localization (35 repositories)}
25
+ metrics: [{type: ndcg_at_10, value: 0.274, name: symbol nDCG@10 (hybrid)}]
26
+ - task: {type: retrieval, name: Test -> implementation (Python)}
27
+ dataset: {type: custom, name: codeintel code-to-code}
28
+ metrics: [{type: ndcg_at_10, value: 0.640}]
29
+ - task: {type: retrieval, name: CoSQA}
30
+ dataset: {type: CoIR-Retrieval/cosqa, name: CoSQA}
31
+ metrics: [{type: ndcg_at_10, value: 0.651}]
32
+ - task: {type: retrieval, name: CoIR StackOverflow QA}
33
+ dataset: {type: CoIR-Retrieval/stackoverflow-qa, name: StackOverflow QA}
34
+ metrics: [{type: ndcg_at_10, value: 0.922}]
35
+ - task: {type: retrieval, name: CoIR CodeSearchNet (Python)}
36
+ dataset: {type: CoIR-Retrieval/CodeSearchNet, name: CodeSearchNet Python}
37
+ metrics: [{type: ndcg_at_10, value: 0.963}]
38
  ---
39
+
40
+ # CodeIntel-150M
41
+
42
+ A 149M-parameter embedding model for **finding the code a bug report or feature request is about**. Given an issue
43
+ written by a user, it retrieves the functions and classes in a Python or TypeScript repository that a fix will touch.
44
+ It also handles code-to-code navigation (test -> implementation, call site -> definition) and code search
45
+ (it leads its size class on CoIR StackOverflow QA and CodeSearchNet Python). It is a fine-tune of
46
+ [granite-embedding-english-r2](https://huggingface.co/ibm-granite/granite-embedding-english-r2) (ModernBERT,
47
+ Apache-2.0). It runs locally, including as a 325 MB INT8 ONNX model, and needs no remote code.
48
+
49
+ | | |
50
+ |---|---|
51
+ | Parameters | 149M |
52
+ | Embedding | 768-d, CLS pooling, L2-normalised (use cosine / dot product) |
53
+ | Max length | trained at 512 tokens per document, evaluated at 1,024 (base supports 8,192) |
54
+ | Languages | English text; Python and TypeScript code (other languages untested) |
55
+ | Licence | Apache-2.0 |
56
+
57
+ ## Results
58
+
59
+ All numbers come from held-out test data that no training or model-selection step used. Each model was scored once,
60
+ with the same protocol. Comparisons are with open models of similar size, all zero-shot.
61
+
62
+ **Issue -> code localization.** The test set has 3,804 GitHub issues from 35 Python and TypeScript repositories, none
63
+ of which were used in training. A hit means retrieving a function or class that the issue's fix edited, among all
64
+ definitions in the repository at the issue's commit. "Descriptive" issues name no identifier from the fix (for example
65
+ "server ignores the port when debug is on"). "Lexical" issues do name one. The metric is symbol-level nDCG@10.
66
+
67
+ | model | descriptive, Python | descriptive, TypeScript | lexical |
68
+ |---|---|---|---|
69
+ | **this model**, dense | **0.242** | **0.260** | **0.482** |
70
+ | **this model**, + BM25 (RRF, dense weight 2) | **0.268** | **0.274** | **0.516** |
71
+ | granite-embedding-english-r2, dense | 0.166 | 0.161 | 0.346 |
72
+ | bge-base-en-v1.5, dense | 0.163 | 0.166 | 0.356 |
73
+ | gte-modernbert-base, dense | 0.125 | 0.112 | 0.308 |
74
+ | CodeRankEmbed, dense | 0.094 | 0.095 | 0.292 |
75
+ | BM25 | 0.120 | 0.133 | 0.371 |
76
+
77
+ The best zero-shot model, each with BM25 fusion at its own dev-chosen weight, scores 0.173 / 0.178 descriptive. The
78
+ gain over it is +0.095 in both languages, with repository-clustered 95% intervals excluding zero.
79
+
80
+ **Code-to-code and general code search.** Dense nDCG@10. For each benchmark, the right-hand column gives the best of
81
+ granite-embedding-english-r2, bge-base-en-v1.5, modernbert-embed-base, gte-modernbert-base, CodeRankEmbed,
82
+ jina-embeddings-v2-base-code and codesage-small-v2.
83
+
84
+ | benchmark | this model | best other open ~150M |
85
+ |---|---|---|
86
+ | test -> implementation (Python) | **0.640** | 0.522 (CodeRankEmbed) |
87
+ | call site -> definition, Python / TypeScript | 0.219 / **0.278** | 0.244 (bge-base) / 0.264 (granite-r2) |
88
+ | docstring -> function, Python / TypeScript | 0.717 / 0.672 | 0.863 / 0.762 (CodeRankEmbed) |
89
+ | CoSQA | 0.651 | 0.737 (jina-v2-code) |
90
+ | CoIR StackOverflow QA | **0.922** | 0.917 (granite-r2) |
91
+ | CoIR CodeSearchNet, Python / JavaScript | **0.963** / 0.634 | 0.960 (codesage) / 0.764 (jina-v2-code) |
92
+ | CoIR CodeSearchNet-CCR, Python / JavaScript | 0.703 / 0.688 | 0.940 / 0.943 (gte-modernbert) |
93
+ | CoIR APPS | 0.174 | 0.575 (gte-modernbert) |
94
+
95
+ **Choose this model** for repository-scale retrieval driven by issues, bug reports or tests, for example as the
96
+ retriever in a coding agent. **Choose a general code-search model instead** (gte-modernbert-base, CodeRankEmbed,
97
+ jina-embeddings-v2-base-code) for docstring-style or web-query code search and code completion-style retrieval (CCR),
98
+ where this model trails.
99
+
100
+ ## Usage
101
+
102
+ Documents are code definitions prefixed with a one-line `path::QualifiedName` header in the language's comment
103
+ syntax, as in training. Queries are raw issue text; for best results remove template boilerplate, logs and long code
104
+ blocks first. No query or document prefix is needed.
105
+
106
+ ```python
107
+ from sentence_transformers import SentenceTransformer
108
+
109
+ model = SentenceTransformer("vedevpatel/CodeIntel-150M")
110
+ code = [
111
+ "# src/flask/app.py::Flask.run\ndef run(self, host=None, port=None, debug=None):\n ...",
112
+ "# src/utils/date.ts::parseDate\nexport function parseDate(s: string): Date { return new Date(s); }",
113
+ ]
114
+ query = "Server ignores the port argument when debug is enabled"
115
+ scores = model.encode([query]) @ model.encode(code).T # cosine similarities (embeddings are normalised)
116
+ ```
117
+
118
+ On a GPU, load in half precision (bf16 on Ampere or newer, fp16 otherwise); the default is float32 for CPU. With
119
+ `flash-attn` installed, `attn_implementation="flash_attention_2"` speeds up long inputs further.
120
+
121
+ ```python
122
+ import torch
123
+
124
+ model = SentenceTransformer("vedevpatel/CodeIntel-150M", device="cuda", model_kwargs={"dtype": torch.bfloat16})
125
+ ```
126
+
127
+ With plain transformers:
128
+
129
+ ```python
130
+ import torch
131
+ from transformers import AutoModel, AutoTokenizer
132
+
133
+ tok = AutoTokenizer.from_pretrained("vedevpatel/CodeIntel-150M")
134
+ model = AutoModel.from_pretrained("vedevpatel/CodeIntel-150M").eval()
135
+ batch = tok(texts, padding=True, truncation=True, max_length=1024, return_tensors="pt")
136
+ with torch.no_grad():
137
+ emb = torch.nn.functional.normalize(model(**batch).last_hidden_state[:, 0], dim=-1)
138
+ ```
139
+
140
+ **ONNX / INT8.** `onnx/model.onnx` (fp32) and `onnx/model_int8.onnx` (dynamic INT8; the GeGLU down-projections stay
141
+ fp32). Outputs are the last hidden states; take the CLS vector and L2-normalise it. The INT8 model's minimum cosine
142
+ to PyTorch is 0.995. On dev retrieval its nDCG@10 matches fp32 within noise: CoSQA +0.003 [-0.005, +0.011],
143
+ docstrings-TypeScript -0.002 [-0.010, +0.006]. It is about 1.7x faster on CPU.
144
+
145
+ **Hybrid retrieval.** Fusing dense scores with BM25 by reciprocal-rank fusion (dense weight 2, k = 60) adds about
146
+ +0.03 on issue localization.
147
+
148
+ ## Training
149
+
150
+ - **Objective:** multi-positive InfoNCE (symmetric, temperature 0.05) with BM25-mined hard negatives and GradCache
151
+ (batch 128). Plus distillation (weight 0.5) toward the frozen base model's similarity structure, which preserves
152
+ general search ability. 3,000 steps, learning rate 5e-6, bf16, maximum document length 512.
153
+ - **Data** (422k query groups; every source permissively licensed):
154
+ - 82 GitHub repositories (MIT, Apache-2.0, BSD, ISC and similar; each licence verified at every revision code was
155
+ taken from; none is an evaluation or development repository): issue -> edited function and commit -> edited
156
+ function (issue text as originally opened where recoverable), docstring -> function, test -> implementation, call
157
+ site -> definition, code context -> continuation.
158
+ - [The Vault](https://huggingface.co/datasets/Fsoft-AIC/the-vault-function): docstring -> function and code-context
159
+ pairs, only items whose declared licences are all permissive.
160
+ - [CodeSearchNet](https://huggingface.co/datasets/code-search-net/code_search_net) train split (Python,
161
+ JavaScript): code -> docstring, code -> continuation and docstring -> code. Rows kept only if the licence GitHub
162
+ detects at the row's own commit is permissive (3,213 of the 4,000 largest repositories). CoIR's CodeSearchNet
163
+ tasks are built from CodeSearchNet's test split, whose repositories are disjoint from the train split.
164
+
165
+ All data was decontaminated against every evaluation and development text, including the CoIR corpora (exact and
166
+ MinHash near-duplicates).
167
+ - **Sources and licences:** every repository and dataset used is listed in [TRAINING_DATA.md](TRAINING_DATA.md).
168
+ - **Selection:** the final checkpoint, chosen on a separate development set of 19 repositories by a fixed
169
+ rule: maximise descriptive localization, subject to no loss on lexical localization, general search and
170
+ code-to-code retrieval.
171
+ - **Compute:** one NVIDIA H100 80GB, about 1.6 hours (embedding cache 10 minutes, training 87 minutes).
172
+
173
+ ## Limitations
174
+
175
+ - Issue localization remains hard. Even this model puts an edited function in the top 10 for well under half of
176
+ descriptive issues.
177
+ - Fixes that only add new code cannot be retrieved, because the target does not exist yet. The benchmark reports this
178
+ as a recall ceiling.
179
+ - Evaluated on Python and TypeScript only. Behaviour on other languages is unknown.
180
+ - Docstring-style search and CoSQA are at the base model's level, below CodeRankEmbed and jina-embeddings-v2-base-code.
181
+ - General natural-language code search and code-continuation retrieval (CoIR CCR, APPS) remain below the best open
182
+ models of this size.
183
+
184
+ ## Citation
185
+
186
+ ```bibtex
187
+ @misc{<CITATION_KEY>,
188
+ title = {CodeIntel-150M: an embedding model for issue-to-code localization},
189
+ author = {<AUTHORS>},
190
+ year = {2026},
191
+ url = {https://huggingface.co/vedevpatel/CodeIntel-150M}
192
+ }
193
+ ```
TRAINING_DATA.md ADDED
The diff for this file is too large to render. See raw diff
 
config.json ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "ModernBertModel"
4
+ ],
5
+ "attention_bias": false,
6
+ "attention_dropout": 0.0,
7
+ "attention_probs_dropout_prob": 0.1,
8
+ "bos_token_id": 50281,
9
+ "classifier_activation": "silu",
10
+ "classifier_bias": false,
11
+ "classifier_dropout": 0.0,
12
+ "classifier_pooling": "mean",
13
+ "cls_token_id": 50281,
14
+ "decoder_bias": true,
15
+ "deterministic_flash_attn": false,
16
+ "dtype": "float32",
17
+ "embedding_dropout": 0.0,
18
+ "eos_token_id": 50282,
19
+ "global_attn_every_n_layers": 3,
20
+ "gradient_checkpointing": false,
21
+ "hidden_act": "gelu",
22
+ "hidden_activation": "gelu",
23
+ "hidden_dropout_prob": 0.1,
24
+ "hidden_size": 768,
25
+ "initializer_cutoff_factor": 2.0,
26
+ "initializer_range": 0.02,
27
+ "intermediate_size": 1152,
28
+ "layer_norm_eps": 1e-05,
29
+ "layer_types": [
30
+ "full_attention",
31
+ "sliding_attention",
32
+ "sliding_attention",
33
+ "full_attention",
34
+ "sliding_attention",
35
+ "sliding_attention",
36
+ "full_attention",
37
+ "sliding_attention",
38
+ "sliding_attention",
39
+ "full_attention",
40
+ "sliding_attention",
41
+ "sliding_attention",
42
+ "full_attention",
43
+ "sliding_attention",
44
+ "sliding_attention",
45
+ "full_attention",
46
+ "sliding_attention",
47
+ "sliding_attention",
48
+ "full_attention",
49
+ "sliding_attention",
50
+ "sliding_attention",
51
+ "full_attention"
52
+ ],
53
+ "local_attention": 128,
54
+ "max_position_embeddings": 8192,
55
+ "mlp_bias": false,
56
+ "mlp_dropout": 0.0,
57
+ "model_type": "modernbert",
58
+ "norm_bias": false,
59
+ "norm_eps": 1e-05,
60
+ "num_attention_heads": 12,
61
+ "num_hidden_layers": 22,
62
+ "pad_token_id": 50283,
63
+ "position_embedding_type": "absolute",
64
+ "repad_logits_with_grad": false,
65
+ "rope_parameters": {
66
+ "full_attention": {
67
+ "rope_theta": 80000.0,
68
+ "rope_type": "default"
69
+ },
70
+ "sliding_attention": {
71
+ "rope_theta": 10000.0,
72
+ "rope_type": "default"
73
+ }
74
+ },
75
+ "sep_token_id": 50282,
76
+ "sparse_pred_ignore_index": -100,
77
+ "sparse_prediction": false,
78
+ "tie_word_embeddings": true,
79
+ "transformers_version": "5.21.0",
80
+ "vocab_size": 50368
81
+ }
config_sentence_transformers.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "prompts": {
3
+ "query": "",
4
+ "document": ""
5
+ },
6
+ "default_prompt_name": null,
7
+ "similarity_fn_name": "cosine"
8
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2e91aef7d8d65740516546ed8a0727726f6d03a475b1625f9ac5f0ff09b874e1
3
+ size 298041568
modules.json ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "idx": 0,
4
+ "name": "0",
5
+ "path": "",
6
+ "type": "sentence_transformers.models.Transformer"
7
+ },
8
+ {
9
+ "idx": 1,
10
+ "name": "1",
11
+ "path": "1_Pooling",
12
+ "type": "sentence_transformers.models.Pooling"
13
+ },
14
+ {
15
+ "idx": 2,
16
+ "name": "2",
17
+ "path": "2_Normalize",
18
+ "type": "sentence_transformers.models.Normalize"
19
+ }
20
+ ]
onnx/model.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3d15615f9ca440e31e194d377fa1e5fd3c63b17fbd8008b296a4135c6619c909
3
+ size 596654187
onnx/model_int8.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0cbc3be699563ea98743894d4b940e39fc4e71ed064c696701504b28d0d5b5a8
3
+ size 325045235
sentence_bert_config.json ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ {
2
+ "max_seq_length": 1024,
3
+ "do_lower_case": false
4
+ }
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "backend": "tokenizers",
3
+ "clean_up_tokenization_spaces": true,
4
+ "cls_token": "[CLS]",
5
+ "is_local": true,
6
+ "local_files_only": false,
7
+ "mask_token": "[MASK]",
8
+ "max_length": 1024,
9
+ "model_input_names": [
10
+ "input_ids",
11
+ "attention_mask"
12
+ ],
13
+ "model_max_length": 8192,
14
+ "pad_token": "[PAD]",
15
+ "sep_token": "[SEP]",
16
+ "stride": 0,
17
+ "tokenizer_class": "TokenizersBackend",
18
+ "truncation_side": "right",
19
+ "truncation_strategy": "longest_first",
20
+ "unk_token": "[UNK]"
21
+ }