Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 4 additions & 1 deletion lib/finetune/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 38 additions & 0 deletions pipelines/paedawen/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Default fine-tuning config (training params ONLY).
#
# Each trainer translates this into native form via config.py
# Operational args (instance type, AWS config, work_dir, quantize, ...) are NOT here
# they stay per-trainer constructor inputs because they differ between HF and MLX.
#
# Cross-library translation reference:
# lora.alpha + lora.rank -> mlx scale = alpha / rank (e.g. 64 / 32 = 2.0)
# lora.target_modules -> mlx keys = ["self_attn.<mod>" / "mlp.<mod>", ...]
# epochs -> mlx iters = ceil(num_samples / batch_size) * epochs
# (only set mlx.iters for override of derived value)

training:
base_model: Qwen/Qwen3-4B-Instruct-2507 # which pre-trained model to start from
epochs: 3 # how many full passes over the training data
learning_rate: 2e-4 # how big a step the model takes each update (too high = unstable, too low = slow)
batch_size: 1 # samples processed at once; keep at 1 for long (16k-32k) samples to avoid running out of memory
max_seq_length: 16384 # longest sample (in tokens) the model will read - anything longer is cut off
lora:
rank: 32 # size of the small trainable add-on; higher = more capacity to learn but more memory
alpha: 64 # how strongly the add-on influences the model (mlx scale = alpha / rank = 2.0)
dropout: 0.05 # randomly ignores 5% of connections while training to reduce overfitting
target_modules: [q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj] # which parts of each layer get the trainable add-on

mlx: # optional; consumed ONLY by the MLX translation
iters: null # total training steps; left null to auto-derive from epochs, set a number to override
num_layers: 16 # how many of the model's top layers to fine-tune - 16 is good balance, -1 means all layers
seed: 42 # fixed random seed so runs are reproducible
save_every: 1000 # save a checkpoint every N steps
steps_per_report: 10 # print training progress every N steps
steps_per_eval: 200 # check performance on held-out data every N steps
val_batches: 0 # 0 = no validation (TrainingDataHandler writes train.jsonl only)
grad_accumulation_steps: 4 # micro-steps accumulated before each optimizer update
grad_checkpoint: true # trade compute for memory by recomputing activations
weight_decay: 0.01 # AdamW weight decay; null uses the mlx default
lr_scheduler_type: cosine # decay the learning rate to 0 over training; null keeps it constant
warmup_ratio: 0.05 # fraction of iters spent warming up to learning_rate
lr_schedule: null # raw mlx_lm passthrough for a custom schedule; overrides lr_scheduler_type
96 changes: 96 additions & 0 deletions pipelines/paedawen/finetune.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "11a389f2",
"metadata": {},
"source": [
"### Paedawen: Model fine-tuning"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4cc82e36",
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"from dotenv import load_dotenv\n",
"load_dotenv()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "950d260a",
"metadata": {},
"outputs": [],
"source": [
"from mesa_runtime import MesaRuntime\n",
"runtime: MesaRuntime = MesaRuntime(\n",
" os.environ[\"BASE_URL\"], os.environ[\"USERNAME\"], os.environ[\"PASSWORD\"]\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b477ce37",
"metadata": {},
"outputs": [],
"source": [
"runtime.list_training_data()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7567abd5",
"metadata": {},
"outputs": [],
"source": [
"run_id: int = runtime.dispatch(\n",
" \"20260720-223834_paedawen-batch\",\n",
" model_name=\"paedawen\",\n",
" schema=\"paedacute\",\n",
" description=\"Extracting acute triage signs from paediatric triage notes\",\n",
" version=\"0.1.0\",\n",
" config=\"config.yaml\",\n",
" config_from_file=True\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ad3a0857",
"metadata": {},
"outputs": [],
"source": [
"runtime.get_run(run_id=run_id)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "paedawen (3.13.14.final.0)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.13.14"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
2 changes: 2 additions & 0 deletions pipelines/paedawen/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ dependencies = [
"londonaicentre-docsynth",
"londonaicentre-mesa-datagen",
"londonaicentre-paedacuteschema>=1.2.0",
"mesa-runtime",
]

[tool.uv.sources]
londonaicentre-docsynth = { git = "ssh://git@github.com/londonaicentre/MESA-Docsynth", branch = "spike/mesa-build-refactor" }
londonaicentre-mesa-datagen = { path = "../../lib/datagen", editable = true }
mesa-runtime = { git = "https://github.com/londonaicentre/mesa-runtime.git", subdirectory = "lib" }
16 changes: 15 additions & 1 deletion pipelines/paedawen/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.