File size: 7,394 Bytes
c16679f
28bdf3d
 
c16679f
28bdf3d
c16679f
 
28bdf3d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
---
language:
- en
license: apache-2.0
library_name: transformers
tags:
- code
- python
- docstring
- documentation
- code-generation
- lora
- qlora
- smollm2
- instruct
- causal-lm
base_model: HuggingFaceTB/SmolLM2-1.7B-Instruct
pipeline_tag: text-generation
model-index:
- name: SmolLM2-1.7B-Instruct-DocstringGenerator
  results: []
datasets:
- codeparrot/codeparrot-clean
---

# SmolLM2-1.7B-Instruct · DocstringGenerator

> A fine-tuned **[SmolLM2-1.7B-Instruct](https://huggingface.co/HuggingFaceTB/SmolLM2-1.7B-Instruct)** specialised in writing **concise, high-level Python docstrings** for functions, methods and classes.
> This model is the backbone of the **[PyDoctor](https://github.com/yezdata/pydoctor)** CLI — a fully local, LLM-powered tool that automatically writes and manages docstrings in your Python codebase.

[![GitHub](https://img.shields.io/badge/GitHub-yezdata%2Fpydoctor-black?logo=github)](https://github.com/yezdata/pydoctor)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue)](LICENSE)
[![Python](https://img.shields.io/badge/python-3.12-blue?logo=python)](https://www.python.org/)
[![Base Model](https://img.shields.io/badge/base-SmolLM2--1.7B--Instruct-yellow?logo=huggingface)](https://huggingface.co/HuggingFaceTB/SmolLM2-1.7B-Instruct)

---

## Intended Use

The model generates **summary-style docstrings** — single-paragraph, plain-English descriptions of a Python code block's purpose and architectural role. It does **not** produce `Args:`, `Returns:`, or `Raises:` sections by design.

**Suitable for:**
- Automated docstring generation in CI/CD pipelines
- Interactive IDE plugins
- Local, privacy-preserving documentation workflows via llama.cpp / GGUF

**Not suitable for:**
- General-purpose code generation
- Generating full NumPy/Google-style docstrings with parameter tables (explicitly omitted)
- Non-Python languages

---

## Quick Start
### With llama.cpp (GGUF · recommended for local use)

```bash
# Download the Q8_0 GGUF
huggingface-cli download \
  yezdata/SmolLM2-1.7B-Instruct-DocstringGenerator \
  smollm2_1_7b_instruct_merged-q8_0.gguf \
  --local-dir ./models

# Run inference
llama-cli \
  -m ./models/smollm2_1_7b_instruct_merged-q8_0.gguf \
  --chat-template chatml \
  -p "..."
```

> **Tip:** The [PyDoctor CLI](https://github.com/yezdata/pydoctor) handles prompt construction, parsing, and atomic file rewrites out of the box.

---

## Prompt Format (ChatML)

The model uses the **ChatML** template native to SmolLM2-Instruct:

```
<|im_start|>system
{SYSTEM_PROMPT}<|im_end|>
<|im_start|>user
CONTEXT
{context_code}

TARGET CODE
{target_code}<|im_end|>
<|im_start|>assistant
```

The model then generates only the raw docstring text, terminated by `<|im_end|>`.

**Context definition:**
- **function** target -> context = "Independent code block"
- **method** target → context = `__init__` signature of its enclosing class
- **class** target → context = signatures of its methods

---

## Training Pipeline

### Stage 1 — Code Extraction

Raw Python source files were streamed from **[codeparrot/codeparrot-clean](https://huggingface.co/datasets/codeparrot/codeparrot-clean)** (~200 k samples). Each file passed a quality filter that rejected:

| Filter | Threshold |
|---|---|
| Too few lines | < 3 non-empty lines |
| Minified code | avg line length > 150 chars |
| Low alphabetic ratio | < 15 % (binary / machine-generated) |
| Repetitive boilerplate | unique line ratio < 10 % |
| Oversized files | > 50 000 characters |

Surviving files were parsed with **[LibCST](https://libcst.readthedocs.io/)** producing `(target, context)` pairs.

### Stage 2 — Synthetic Docstring Generation

`(target, context)` pairs were labelled in parallel using **DeepSeek V4 Flash** (via OpenRouter):

The teacher-model system prompt enforced:
1. Describe semantic purpose and architectural role, not implementation details
2. Use context to disambiguate class membership

### Stage 3 — Instruct Data Preparation & Tokenisation

Synthetic batches were assembled into ChatML prompt/completion pairs:

```python
prompt = (
    f"<|im_start|>system\n{SYSTEM_PROMPT}<|im_end|>\n"
    f"<|im_start|>user\nCONTEXT\n{context}\n\nTARGET CODE\n{target}<|im_end|>\n"
    f"<|im_start|>assistant\n"
)
completion = f"{docstring}<|im_end|>"
```

Labels were constructed so that **only completion tokens** are trained on — prompt tokens are masked from cross-entropy loss.

### Stage 4 — QLoRA Fine-tuning

Fine-tuning was performed on Kaggle kernels (`instruct_finetune.py`):

| Hyperparameter | Value |
|---|---|
| Quantisation | 4-bit NF4, double quant, fp16 compute |
| LoRA rank `r` | 32 |
| LoRA alpha `α` | 64 |
| LoRA dropout | 0.2 |
| LoRA bias | none |
| Target modules | `q_proj`, `k_proj`, `v_proj`, `o_proj`, `gate_proj`, `up_proj`, `down_proj` |
| Optimizer | AdamW 8-bit (bitsandbytes) |
| Learning rate | 2e-4 |
| LR schedule | Cosine with 5 % warmup |
| Weight decay | 0.01 |
| Batch size | 8 per device |
| Gradient accumulation | 8 steps → effective batch 64 |
| Epochs | 1 |
| Max sequence length | 1 024 tokens (95th-pct filter) |
| Validation split | 1 % held-out, evaluated each epoch |
| Seed | 1337 |

Loss = next-token cross-entropy, **prompt tokens ignored** via label mask.

### Stage 5 — LoRA Merge & GGUF Export

After training, LoRA adapters were merged back into the base model weights and converted to **Q8_0 GGUF** using `llama.cpp`:

```
LoRA adapter (epoch 1, safetensors)

        ▼  merge_and_unload()

merged fp16 safetensors

        ▼  llama.cpp convert_hf_to_gguf.py --outtype q8_0

smollm2_1_7b_instruct_merged-q8_0.gguf
```

---

## Files

| File | Description |
|---|---|
| `smollm2_1_7b_instruct_merged-q8_0.gguf` | Q8_0 GGUF for llama.cpp — recommended for local use |
| `safetensors/model.safetensors` | Merged fp16 weights |
| `safetensors/config.json` | HuggingFace model configuration |
| `safetensors/tokenizer.json` / `safetensors/tokenizer_config.json` | SmolLM2-1.7B-Instruct tokenizer |

---

## Limitations & Bias

- **Summary-only style:** the model is trained to output a single-paragraph summary. It will not produce `Args:` / `Returns:` sections.
- **Python only:** trained exclusively on Python source code from codeparrot-clean.
- **Context dependency:** quality improves when the correct context string is provided. Passing an empty context for class methods may reduce coherence.
- **Teacher model bias:** docstring style reflects DeepSeek V4 Flash's preferences filtered through the strict prompt rules. Unusual code idioms may yield generic descriptions.
- **Not a general assistant:** the model is heavily specialised and will likely perform poorly on tasks other than docstring generation.

---

## Citation

```bibtex
@misc{pydoctor2026,
  author       = {yezdata},
  title        = {PyDoctor: Local LLM-powered Python Docstring Generator},
  year         = {2026},
  howpublished = {\url{https://github.com/yezdata/pydoctor}},
  note         = {Fine-tuned SmolLM2-1.7B-Instruct model available at
                  \url{https://huggingface.co/yezdata/SmolLM2-1.7B-Instruct-DocstringGenerator}}
}
```

---

## License

This model is released under the **Apache 2.0** license, matching the base `SmolLM2-1.7B-Instruct` model.  
Training data originates from `codeparrot/codeparrot-clean` (MIT)