rndubs commited on
Commit
f74e974
Β·
verified Β·
1 Parent(s): 6a55750

Upload README.md

Browse files
Files changed (1) hide show
  1. README.md +246 -0
README.md ADDED
@@ -0,0 +1,246 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # πŸ› οΈ Code LLM Toolkit: Fine-tune + RAG + Tool-Calling for Internal Codebases
2
+
3
+ A complete toolkit for building a Python code generation LLM that can search your internal codebase via RAG, call tools, and reason through multi-step tasks.
4
+
5
+ ## Architecture
6
+
7
+ ```
8
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
9
+ β”‚ Code LLM System β”‚
10
+ β”‚ β”‚
11
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚
12
+ β”‚ β”‚ Fine-tuned β”‚ β”‚ RAG Pipeline β”‚ β”‚ Tool Executor β”‚β”‚
13
+ β”‚ β”‚ Qwen2.5- │◄──│ (AST-aware β”‚ β”‚ - search_codebase β”‚β”‚
14
+ β”‚ β”‚ Coder-7B β”‚ β”‚ chunking + β”‚ β”‚ - execute_python β”‚β”‚
15
+ β”‚ β”‚ + LoRA β”‚ β”‚ embeddings) β”‚ β”‚ - read_file β”‚β”‚
16
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ - run_tests β”‚β”‚
17
+ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
18
+ β”‚ β”‚ ReAct Agent Loop β”‚ β”‚
19
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
20
+ β”‚ β”‚ β”‚
21
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β” β”‚
22
+ β”‚ β”‚ Response β”‚ β”‚
23
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
24
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
25
+ ```
26
+
27
+ ## Research Foundation
28
+
29
+ Every component is grounded in published research with verified results:
30
+
31
+ | Component | Paper | Key Result |
32
+ |-----------|-------|------------|
33
+ | **Base Model** | [Qwen2.5-Coder](https://arxiv.org/abs/2409.12186) | HumanEval 88.4% (7B), SOTA open-source |
34
+ | **Tool-Calling Data** | [ToolACE](https://arxiv.org/abs/2409.00920) | Beats GPT-4-turbo on BFCL benchmark |
35
+ | **Multi-turn Agent Data** | [APIGen-MT](https://arxiv.org/abs/2504.03601) | 78.19% BFCL v3 (#1, beats o1/GPT-4o) |
36
+ | **Code SFT Data** | [Magicoder](https://arxiv.org/abs/2312.02120) | HumanEval 70.7% from 7B with 185K samples |
37
+ | **RAG Chunking** | [cAST](https://arxiv.org/abs/2506.15655) | +5.6pp over fixed-size on RepoEval |
38
+ | **RAG Strategy** | [AllianceCoder](https://arxiv.org/abs/2503.20589) | API signatures > similar code (+20%) |
39
+ | **Retriever-Aware Training** | [Gorilla](https://arxiv.org/abs/2305.15334) | Outperforms GPT-4 on API accuracy |
40
+ | **Code Embeddings** | [CodeSage-v2](https://huggingface.co/codesage/codesage-large-v2) | Best open code embedding model |
41
+ | **LoRA for Code** | [Astraios](https://arxiv.org/abs/2401.00788) | LoRA matches FFT at β‰₯16B scale |
42
+
43
+ ## Quick Start
44
+
45
+ ### Step 1: Prepare Training Data
46
+
47
+ Merges 4 verified datasets (ToolACE + APIGen-MT + Magicoder + CodeAct) into a unified ChatML format:
48
+
49
+ ```bash
50
+ pip install datasets
51
+
52
+ # Test with small sample first
53
+ python prepare_data.py --max_per_source 100 --dry_run
54
+
55
+ # Full run β€” pushes merged dataset to Hub
56
+ python prepare_data.py --output_repo your-username/code-toolcall-sft-data
57
+ ```
58
+
59
+ **Dataset composition (~110K examples):**
60
+ | Source | Examples | Purpose |
61
+ |--------|----------|---------|
62
+ | [Team-ACE/ToolACE](https://huggingface.co/datasets/Team-ACE/ToolACE) | 26K | Tool-calling (single-turn) |
63
+ | [Salesforce/APIGen-MT-5k](https://huggingface.co/datasets/Salesforce/APIGen-MT-5k) | 5K | Multi-turn agentic tool use |
64
+ | [Magicoder-OSS-Instruct-75K](https://huggingface.co/datasets/ise-uiuc/Magicoder-OSS-Instruct-75K) | ~25K (Python) | Python code generation |
65
+ | [xingyaoww/code-act](https://huggingface.co/datasets/xingyaoww/code-act) | 7K | Code-as-action (tools via Python) |
66
+
67
+ ### Step 2: Add Your Internal Codebase Data
68
+
69
+ **This is the most impactful step.** Use the Gorilla/Magicoder pattern:
70
+
71
+ 1. **OSS-Instruct on your code:** Sample random snippets from your internal repo β†’ use an LLM (GPT-4o, Claude) to generate instruction-solution pairs seeded from that code
72
+ 2. **Retriever-aware examples:** Include retrieved code context in training prompts so the model learns to use RAG at inference time
73
+ 3. **Internal API documentation:** Convert your docstrings/README into Q&A pairs
74
+
75
+ See `prepare_data.py` for the format β€” add your examples as additional sources.
76
+
77
+ ### Step 3: Fine-tune
78
+
79
+ ```bash
80
+ # Edit train_sft.py to set your dataset and model repo IDs, then:
81
+
82
+ # Option A: Run on HF Jobs (recommended for A100/H100 hardware)
83
+ # Use the hf_jobs API or CLI
84
+
85
+ # Option B: Run locally with GPU
86
+ pip install trl peft transformers datasets trackio accelerate torch
87
+ python train_sft.py
88
+ ```
89
+
90
+ **Training configuration (from literature):**
91
+ - **Base:** [Qwen/Qwen2.5-Coder-7B-Instruct](https://huggingface.co/Qwen/Qwen2.5-Coder-7B-Instruct) (Apache 2.0)
92
+ - **Method:** LoRA (r=32, alpha=64) on all linear layers
93
+ - **LR:** 1e-4 with cosine schedule, 10% warmup
94
+ - **Epochs:** 2
95
+ - **Context:** 8192 tokens
96
+ - **Loss:** Assistant-only (masks user/system/tool tokens)
97
+ - **Hardware:** 1x A100-80GB (or 2x A10G-24GB)
98
+ - **Time:** ~4-6 hours for 110K examples
99
+
100
+ ### Step 4: Index Your Codebase (RAG)
101
+
102
+ ```python
103
+ from rag_pipeline import CodebaseIndexer
104
+
105
+ # Index your internal Python codebase
106
+ indexer = CodebaseIndexer(
107
+ "/path/to/your/repo",
108
+ embedding_model="jinaai/jina-embeddings-v2-base-code" # or codesage-large-v2
109
+ )
110
+ retriever = indexer.index()
111
+
112
+ # Save for reuse
113
+ retriever.save_index("./my_index")
114
+
115
+ # Search!
116
+ results = retriever.search("authentication token validation", top_k=5)
117
+ for chunk, score in results:
118
+ print(f"[{score:.3f}] {chunk.file_path}/{chunk.name}: {chunk.signature}")
119
+ ```
120
+
121
+ **RAG pipeline features:**
122
+ - **AST-aware chunking** (cAST): Functions, methods, classes stay intact β€” no mid-function cuts
123
+ - **Dual embeddings**: Code content + metadata strings (NL descriptions) for hybrid search
124
+ - **AllianceCoder context assembly**: API signatures prioritized over full code bodies
125
+ - **In-context dependencies**: Automatically extracts imports and class signatures from the current file
126
+ - **Embedding models**: Jina-Code-v2 (8K context, 161M) or CodeSage-v2 (best quality, 1.3B)
127
+
128
+ ### Step 5: Run the Agent
129
+
130
+ ```bash
131
+ # Interactive mode
132
+ python inference.py \
133
+ --model your-username/qwen25-coder-7b-code-toolcall \
134
+ --repo /path/to/your/codebase \
135
+ --index-dir ./my_index
136
+
137
+ # Single query
138
+ python inference.py \
139
+ --model your-username/qwen25-coder-7b-code-toolcall \
140
+ --repo /path/to/your/codebase \
141
+ --query "Add pagination to the product search endpoint"
142
+ ```
143
+
144
+ The agent uses a **ReAct loop**:
145
+ 1. Pre-fetches relevant code via RAG
146
+ 2. Sends query + context to the LLM
147
+ 3. If the LLM calls tools β†’ executes them β†’ feeds results back
148
+ 4. Repeats until the LLM gives a final answer (max 10 turns)
149
+
150
+ ## Recommended Embedding Models
151
+
152
+ | Model | Size | Context | Best For | HF Link |
153
+ |-------|------|---------|----------|---------|
154
+ | `codesage/codesage-large-v2` | 1.3B | 2048 tok | Best quality (NL→Code 69.4) | [Link](https://huggingface.co/codesage/codesage-large-v2) |
155
+ | `jinaai/jina-embeddings-v2-base-code` | 161M | **8192 tok** | Long files, 30 languages | [Link](https://huggingface.co/jinaai/jina-embeddings-v2-base-code) |
156
+ | `codesage/codesage-small-v2` | 130M | 2048 tok | Fast, lightweight | [Link](https://huggingface.co/codesage/codesage-small-v2) |
157
+
158
+ ## Advanced: Full Fine-Tuning (FFT)
159
+
160
+ For maximum performance, skip LoRA and do full fine-tuning:
161
+
162
+ ```python
163
+ # In train_sft.py, remove peft_config and adjust:
164
+ LEARNING_RATE = 2e-5 # 10x lower than LoRA
165
+ BATCH_SIZE = 1 # Lower to fit in memory
166
+ GRAD_ACCUM = 16 # Keep effective batch = 16
167
+ # Hardware: 2x A100-80GB minimum for 7B FFT
168
+ ```
169
+
170
+ Per [Astraios](https://arxiv.org/abs/2401.00788): FFT slightly outperforms LoRA at 7B scale, but LoRA is within 1% and 30x more parameter-efficient.
171
+
172
+ ## Advanced: GRPO Reinforcement Learning (Stage 2)
173
+
174
+ After SFT, you can further improve the model with GRPO using execution-based rewards:
175
+
176
+ ```python
177
+ from trl import GRPOConfig, GRPOTrainer
178
+
179
+ # Reward function: does the generated code pass unit tests?
180
+ def reward_fn(completions, prompts):
181
+ rewards = []
182
+ for code in completions:
183
+ try:
184
+ exec(code, {}) # Sandbox this properly!
185
+ rewards.append(1.0)
186
+ except:
187
+ rewards.append(0.0)
188
+ return rewards
189
+
190
+ # Train with GRPO
191
+ config = GRPOConfig(
192
+ learning_rate=1e-6,
193
+ num_train_epochs=1,
194
+ per_device_train_batch_size=4,
195
+ )
196
+ ```
197
+
198
+ ## File Structure
199
+
200
+ ```
201
+ β”œβ”€β”€ prepare_data.py # Dataset merging & formatting
202
+ β”œβ”€β”€ train_sft.py # SFT training script (TRL + LoRA)
203
+ β”œβ”€β”€ rag_pipeline.py # AST-aware indexing & retrieval
204
+ β”œβ”€β”€ inference.py # ReAct agent with tool calling
205
+ └── README.md # This file
206
+ ```
207
+
208
+ ## Requirements
209
+
210
+ ```
211
+ transformers>=4.45.0
212
+ trl>=1.0.0
213
+ peft>=0.12.0
214
+ datasets>=3.0.0
215
+ accelerate>=1.0.0
216
+ trackio>=0.2.0
217
+ torch>=2.0.0
218
+ sentence-transformers>=3.0.0 # For RAG embeddings
219
+ numpy
220
+ scikit-learn # TF-IDF fallback
221
+ ```
222
+
223
+ ## Citation
224
+
225
+ If you use this toolkit, please cite the underlying research:
226
+
227
+ ```bibtex
228
+ @article{qwen2.5coder,
229
+ title={Qwen2.5-Coder Technical Report},
230
+ author={Hui, Binyuan and others},
231
+ journal={arXiv:2409.12186},
232
+ year={2024}
233
+ }
234
+ @article{toolace,
235
+ title={ToolACE: Winning the Points of LLM Function Calling},
236
+ author={Liu, Weiwen and others},
237
+ journal={arXiv:2409.00920},
238
+ year={2024}
239
+ }
240
+ @article{gorilla,
241
+ title={Gorilla: Large Language Model Connected with Massive APIs},
242
+ author={Patil, Shishir G. and others},
243
+ journal={arXiv:2305.15334},
244
+ year={2023}
245
+ }
246
+ ```