Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
626d91b
feat: add pilot sweep
fin-griffin Apr 10, 2026
530f45f
feat: add README
fin-griffin Apr 10, 2026
1b75325
chore: update README to select single gpu
fin-griffin Apr 10, 2026
dfa44e8
chore: migrate all sweep deps to uv
fin-griffin Apr 13, 2026
c411fdb
chore: add hf cli
fin-griffin Apr 13, 2026
7df07a6
chore: update README.md
fin-griffin Apr 13, 2026
61e88f2
chore: add typer as dep
fin-griffin Apr 13, 2026
2aef161
chore: update axolotl dep to download from source
fin-griffin Apr 13, 2026
1487684
chore: update eval strategy to be a string rather than reserved boolean
fin-griffin Apr 13, 2026
38ac129
fix: update chat template during inference
fin-griffin Apr 13, 2026
87d23a8
fix: update infer.py to manually compute loss
fin-griffin Apr 13, 2026
4caf6a9
fix: force inference to pin to same GPU as training
fin-griffin Apr 13, 2026
4c9122d
chore: add vllm
fin-griffin Apr 13, 2026
8a2b5ba
chore: add bnb
fin-griffin Apr 13, 2026
89bd4c0
fix: migrate to slow tokenizer for vllm
fin-griffin Apr 13, 2026
f70bfc9
fix: migrate to torch batched inference
fin-griffin Apr 13, 2026
e580e04
chore: fix triton kernels
fin-griffin Apr 13, 2026
b005b67
chore(deps): update vllm
fin-griffin Apr 13, 2026
7153cc1
feat: migrate back to vLLM
fin-griffin Apr 13, 2026
e42203b
chore: remove vllm
fin-griffin Apr 13, 2026
7d0a280
chore: gitignore pilot results parquet
fin-griffin Apr 14, 2026
24fe3ac
chore: add sweep results + logs to gitignore
fin-griffin Apr 14, 2026
59bb2ad
feat: migrate to vllm
fin-griffin Apr 14, 2026
6290698
chore: fix run
fin-griffin Apr 14, 2026
0f2ddd7
fix 3
fin-griffin Apr 14, 2026
a3357c0
chore anotehr fix
fin-griffin Apr 14, 2026
11eef81
jdkansjn
fin-griffin Apr 14, 2026
f069241
ijas
fin-griffin Apr 14, 2026
40ab156
chore: downgrade vllm
fin-griffin Apr 14, 2026
75fdb01
fix transformers version
fin-griffin Apr 14, 2026
b0b878f
chore
fin-griffin Apr 14, 2026
042dd16
migrate to online vllm
fin-griffin Apr 14, 2026
5e24704
update readme
fin-griffin Apr 14, 2026
733a9ea
1
fin-griffin Apr 14, 2026
54213f6
refactor(sweep): replace vLLM inference with in-process TrainerCallback
fin-griffin Apr 14, 2026
727a54c
fix(sweep): log sample completions at each epoch end
fin-griffin Apr 14, 2026
c1efff5
docs(sweep): update README to remove vLLM setup, reflect callback app…
fin-griffin Apr 14, 2026
11fde90
fix(sweep): add repo root to PYTHONPATH so axolotl can import EvalCom…
fin-griffin Apr 14, 2026
2218301
build: upgrade axolotl pin from v0.16.1 to main for callbacks YAML su…
fin-griffin Apr 14, 2026
1fd9cbf
fix(sweep): switch to axolotl plugins API for callback registration
fin-griffin Apr 14, 2026
e3b3d24
fix: axolotl from source
fin-griffin Apr 15, 2026
5c28180
fix: tokenizer = None err
fin-griffin Apr 15, 2026
2ac9558
fix:
fin-griffin Apr 15, 2026
5cedd8a
chore: remove padding
fin-griffin Apr 15, 2026
027794a
chore: temperature -> 0.7
fin-griffin Apr 15, 2026
eda3fe2
add batching
fin-griffin Apr 15, 2026
4f4dd71
chore: update default devices
fin-griffin Apr 15, 2026
8468602
chore: update wandb project
fin-griffin Apr 15, 2026
4c091e3
fix eval loss logging
fin-griffin Apr 15, 2026
2040113
feat(docs): add docs for data, evals and stylometry
fin-griffin May 21, 2026
9ea05b1
Merge branch 'main' into feature/pilot-sweep
fin-griffin May 21, 2026
6fe6287
chore: update gitignore
fin-griffin May 22, 2026
81d76d1
chore: add configs and run dirs
fin-griffin May 22, 2026
f5893da
feat(data): add local dataset loading to VoiceDataset
fin-griffin May 22, 2026
a8b7d59
feat(fine-tuning): add fine-tuning module for single runs and grid se…
fin-griffin May 22, 2026
17a8fbf
feat(fine-tuning): add run directory management
fin-griffin May 22, 2026
302e8ae
feat(axolotl): add custom callback
fin-griffin May 22, 2026
609851d
feat(fine-tuning): add orchestration module
fin-griffin May 22, 2026
0bc728e
feat(fine-tuning): add cli
fin-griffin May 22, 2026
eca7f27
chore: remove wandb post-hoc artefact upload
fin-griffin May 22, 2026
2d384b1
chore: remove unicode escaping in axolotl custom callback
fin-griffin May 22, 2026
dd2ac29
fix: fix PYTHONPATH handling in axolotl subprocess
fin-griffin May 22, 2026
99cf6c0
feat(stylometry): remove number of tokens/words as a stylometric metric
fin-griffin Jun 9, 2026
c44664a
feat(docs): add UQ to eval suite
fin-griffin Jun 10, 2026
8db714c
Merge branch 'docs' into feature/finetuning
fin-griffin Jun 10, 2026
4be56f4
feat(evals): add assymetric confidence intervals to tail scores
fin-griffin Jun 10, 2026
724c10b
feat(finetuning): write confidence intervals to disk via fine-tuning …
fin-griffin Jun 10, 2026
582f1a3
Merge pull request #12 from acceleratescience/feature/uncertainty-qua…
fin-griffin Jun 10, 2026
1c10d2f
feat(docs): add documentation for fine-tuning CLI
fin-griffin Jun 10, 2026
c50aacb
chore(docs): add example configuration files for fine-tuning CLI
fin-griffin Jun 10, 2026
1b34ad9
chore(tests): add unit tests for orchestrator module to reach 90% cov
fin-griffin Jun 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .coverage
Binary file not shown.
15 changes: 14 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,17 @@ notebooks/**
data/**

# Notes
notes.md
notes.md
# Sweep results
sweep/results.parquet
sweep/sweep.log
sweep/state.json

# Fine-tuning runs and local configs
runs/
!runs/.gitkeep
configs/single/**
configs/sweep/**
!configs/single/example.yaml
!configs/single/test.yaml
!configs/sweep/example.yaml
13 changes: 0 additions & 13 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,3 @@ repos:
- id: pydoclint
args: ["--config=pyproject.toml"]
exclude: ^tests/

# Cognitive complexity limit via flake8-cognitive-complexity (keep for src; exclude tests)
- repo: https://github.com/pycqa/flake8
rev: 7.3.0
hooks:
- id: flake8
additional_dependencies:
- flake8-cognitive-complexity
args:
- --max-line-length=79
- --extend-ignore=E203
- --max-cognitive-complexity=10
exclude: ^tests/
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
# VOICE - Fine-tuning for Stylistic Fidelity
# 🗣️ VOICE

...

---

## Documentation

```
docs/
├── 00_data.md — Included datasets
├── 01_evals.md — Evaluation suite: scoring and interpretation
└── 02_stylometry.md — Stylometric metrics: definition and catalogue
```
87 changes: 87 additions & 0 deletions configs/single/example.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# =============================================================================
# Example single-run configuration
#
# Run with:
# voice finetune single configs/single/example.yaml
#
# All axolotl settings live under the `axolotl:` key. The CLI writes a
# frozen copy to runs/{run_name}/config.yaml before launching training,
# injecting output_dir automatically.
# =============================================================================

axolotl:

# Model
base_model: meta-llama/Llama-3.1-8B-Instruct

# Train split used for fine-tuning; validation and test splits used by
# EvalCompletionsPlugin and post-training alignment scoring.
datasets:
- path: AccelerateScience/bo-press-conference-qa
type: chat_template
field_messages: messages
roles_to_train:
- assistant
train_on_eos: last
eot_tokens: ["<|eot_id|>"]

special_tokens:
pad_token: "<|eot_id|>"

hf_use_auth_token: true

chat_template: tokenizer_default
val_set_size: 0.0

# Validation dataset for per-epoch eval_loss and completions generation.
test_datasets:
- path: AccelerateScience/bo-press-conference-qa
split: validation
type: chat_template
field_messages: messages

# Sequence
sequence_len: 2048
sample_packing: true

# Adapter
adapter: lora
lora_r: 16
lora_alpha: 16
lora_dropout: 0.0
lora_target_modules: [q_proj, k_proj, v_proj, o_proj]

# Training
num_epochs: 3
learning_rate: 1.0e-4
micro_batch_size: 4
gradient_accumulation_steps: 4

# Precision & performance
bf16: true
tf32: true
flash_attention: true
gradient_checkpointing: true
lora_mlp_kernel: false
lora_qkv_kernel: false
lora_o_kernel: false

# Optimiser
optimizer: adamw_torch_fused
lr_scheduler: cosine
warmup_ratio: 0.03
weight_decay: 0.0

# Evaluation and checkpointing
eval_strategy: "epoch"
save_strategy: epoch
save_total_limit: 3

# Plugin that generates completions at each epoch end (recommended).
plugins:
- voice.finetune.callbacks.EvalCompletionsPlugin

# W&B
use_wandb: true
wandb_project: VOICE
wandb_entity: accelerate-science
127 changes: 127 additions & 0 deletions configs/sweep/example.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# =============================================================================
# Example sweep configuration
#
# Two top-level sections:
# sweep: hyperparameter grid axes (read by `voice finetune sweep`)
# axolotl: shared axolotl settings merged into every per-run config
#
# The CLI expands the grid into per-run configs, injecting per-run values
# (learning_rate, lora_r, lora_alpha, lora_target_modules,
# micro_batch_size, gradient_accumulation_steps, output_dir) on top of
# the axolotl section below.
#
# Grid: 3 LRs × 4 ranks × 1 micro_batch_size × 2 accum steps
# × 2 target layer groups = 48 training runs.
#
# Run with:
# voice finetune sweep configs/sweep/example.yaml
# voice finetune sweep configs/sweep/example.yaml --resume
# =============================================================================

# --- Sweep grid -------------------------------------------------------------
sweep:
learning_rate: [1e-3, 5.0e-4, 1e-4]
lora_r: [4, 8, 16, 32]

micro_batch_size: [2]
gradient_accumulation_steps: [2, 4]

target_layers:
- name: mlp
modules: [gate_proj, up_proj, down_proj]
- name: attention
modules: [q_proj, k_proj, v_proj, o_proj]

# lora_alpha is set equal to lora_r per run (not swept separately).

# --- Shared axolotl settings ------------------------------------------------
axolotl:

# Model
base_model: meta-llama/Llama-3.1-8B-Instruct

# Train split used for fine-tuning; validation split used by the
# EvalCompletionsPlugin for per-epoch completions; test split scored after
# each epoch for alignment evaluation.
datasets:
- path: AccelerateScience/gwb-press-conference-qa
type: chat_template
field_messages: messages
roles_to_train:
- assistant
train_on_eos: last
# Llama 3.1's chat template ends turns with <|eot_id|> (128009), not
# <|end_of_text|> (128001). Without this, axolotl defaults eot_tokens
# to eos_token which never appears, so train_on_eos: last silently
# does nothing.
eot_tokens: ["<|eot_id|>"]

special_tokens:
pad_token: "<|eot_id|>"

hf_use_auth_token: true

# Llama 3.1 Instruct ships with its own Jinja chat template; axolotl
# picks it up automatically.
chat_template: tokenizer_default
val_set_size: 0.0

# Axolotl computes eval_loss after each epoch and the EvalCompletionsPlugin
# generates completions for scoring.
test_datasets:
- path: AccelerateScience/gwb-press-conference-qa
split: validation
type: chat_template
field_messages: messages

# Sequence
# Bush answers are long (~700-900 tokens including system + question).
# 2048 gives comfortable headroom without wasting VRAM.
sequence_len: 2048
sample_packing: true

# lora_r, lora_alpha, lora_target_modules injected per run.
adapter: lora
lora_dropout: 0.05

# 3 epochs × 48 runs = 144 data points.
num_epochs: 3

# Precision & performance
bf16: true
tf32: true
flash_attention: true
gradient_checkpointing: true

# Disable axolotl's auto-enabled LoRA kernel optimizations. The MLP
# SwiGLU Triton kernel fails to compile on our host (gcc cannot link
# libcuda), which crashes all attention_mlp runs.
lora_mlp_kernel: false
lora_qkv_kernel: false
lora_o_kernel: false

# Optimiser
optimizer: adamw_torch_fused
lr_scheduler: cosine
warmup_ratio: 0.03
weight_decay: 0.0

# Evaluate on the validation split after each epoch.
eval_strategy: "epoch"

# Save a checkpoint after each epoch so adapters are available for
# per-epoch alignment scoring (intermediate epochs treated as separate
# model candidates).
save_strategy: epoch
save_total_limit: 3

# Generates completions at each epoch end using the live in-memory model
# (no train/inference distribution mismatch).
# Dataset is read from datasets[0].path above.
plugins:
- voice.finetune.callbacks.EvalCompletionsPlugin

# Run name for W&B is set by the CLI; project and entity configured here.
use_wandb: true
wandb_project: VOICE
wandb_entity: accelerate-science
15 changes: 15 additions & 0 deletions cspell/library-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,18 @@ ylabel
frameon
allclose
linalg
mathcal
mathbb
mathbf
dotenv
wandb
jinja
adamw
checkpointing
proc
peft
pyyaml
libcuda
PYTHONPATH
venv
cuda
11 changes: 11 additions & 0 deletions cspell/project-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,14 @@ bonf
bonferroni
aeiou
stylometrically
lora
resumability
resumable
hyperparams
redef
evals
submatrix
vocab
finetune
accum
nonpositive
22 changes: 22 additions & 0 deletions docs/00_data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Datasets

---

Two example datasets are included, each containing press conference Q&A transcripts split into train, validation and test sets:

| President | HuggingFace |
|---|---|
| Barack Obama | [`AccelerateScience/bo-press-conference-qa`](https://huggingface.co/datasets/AccelerateScience/bo-press-conference-qa) |
| George W. Bush | [`AccelerateScience/gwb-press-conference-qa`](https://huggingface.co/datasets/AccelerateScience/gwb-press-conference-qa) |

Each example is a single JSONL record in chat format:

```json
{
"messages": [
{"role": "system", "content": "You are president Barack Obama ..."},
{"role": "user", "content": "<press conference question>"},
{"role": "assistant", "content": "<president's answer>"}
]
}
```
52 changes: 52 additions & 0 deletions docs/01_stylometry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Stylometric Metrics

---

A **stylometric metric** is any function

$$f : \mathcal{T} \rightarrow \mathbb{R}$$

that maps a text string to a real scalar capturing some surface property of writing style. VOICE treats each metric as a distribution over a corpus: given a set of texts, $f$ is applied to each one to produce a sample from the author's stylometric distribution for that feature.

## Implemented Metrics

### Word Length Distribution
Moments of the per-word character length distribution.

| Metric | Description |
|---|---|
| `avg_word_length` | Mean word length |
| `std_word_length` | Standard deviation of word length |
| `skew_word_length` | Skewness of word length |
| `kurtosis_word_length` | Kurtosis of word length |

### Vocabulary Richness
Type–token and word statistics measuring lexical diversity.

| Metric | Description |
|---|---|
| `type_token_ratio` | Unique tokens / total tokens |
| `moving_avg_type_token_ratio` | TTR averaged over a sliding window (MATTR) |
| `hapax_legomena_ratio` | Fraction of words appearing exactly once |
| `dis_legomena_ratio` | Fraction of words appearing exactly twice |
| `tri_legomena_ratio` | Fraction of words appearing exactly three times |

### Function Words
| Metric | Description |
|---|---|
| `function_word_ratio` | Proportion of tokens drawn from a closed function-word list |

### Character N-gram Diversity
Type–token ratio and MATTR computed over character $n$-grams for $n \in \{3, 4, 5\}$.

| Metric | Description |
|---|---|
| `char_{n}gram_type_token_ratio` | Character $n$-gram TTR |
| `char_{n}gram_moving_avg_type_token_ratio` | Character $n$-gram MATTR |

### Text Length
| Metric | Description |
|---|---|
| `num_words` | Total word count |

> **Note:** `num_words` may be deprecated in a future release. It does not tend to be used as a signature for authorship attribution in the broader stylometry literature.
Loading
Loading