Skip to content

Model Fine-Tuning

Provon can train adapters and small models from project Datasets and serve the resulting checkpoints behind the AI Gateway. The Node runtime owns job scheduling, checkpoint trackin

View as Markdown Open the plain-text version of this page.

Node does not spawn Python child processes for training. It calls the Python service over HTTP, which keeps PyTorch, Transformers, and PEFT dependencies out of the Node process.

When To Use It#

Use model fine-tuning when you have curated Dataset examples and want to:

  • improve model behavior on a recurring task shape seen in traces;
  • produce a project-specific checkpoint that stays inside your infrastructure;
  • compare a fine-tuned checkpoint against the base model in the Playground.

Fine-tuning is a follow-up step after Dataset collection. See Datasets for how training examples are produced and validated.

Architecture#

flowchart LR
  dataset["Dataset examples"] --> node["Node runtime"]
  node --> manifest["Dataset manifest"]
  manifest --> python["services/python-fine-tuning"]
  python --> checkpoint["Checkpoint artifact"]
  checkpoint --> runtime["Model runtime"]
  runtime --> gateway["AI Gateway self/ target"]

The Node runtime:

  • validates the Dataset schema and example count;
  • materializes a training manifest from the Dataset;
  • submits the job to services/python-fine-tuning;
  • polls for status and stores checkpoint metadata;
  • registers completed checkpoints for inference and optionally auto-deploys them.

Supported Training Configuration#

Dimension Supported values
Engine transformers
Method sft (API/CLI current); dpo, orpo, kto implemented in Python service only
Adapter lora, qlora, full
Output format safetensors, gguf
GGUF quantization q4_0, q4_k_m, q4_k_s, q5_0, q5_k_m, q6_k, q8_0, f16, bf16, f32
Compressed quantization fp8, fp8_dynamic, fp8_static, int8

Output format determines the default inference engine when the checkpoint is deployed: Safetensors checkpoints are typically served by vLLM or SGLang; GGUF checkpoints are served by llama.cpp. Compressed quantization produces safetensors checkpoints with compressed-tensor metadata for efficient vLLM/SGLang serving; static FP8 requires a calibration dataset.

  • sft uses chat-formatted examples.
  • dpo, orpo, and kto use preference-format examples (prompt/chosen/rejected for DPO/ORPO, prompt/completion/label for KTO). These methods are implemented in services/python-fine-tuning but are not yet exposed through the API or CLI; create jobs with method: "sft" for now.

Create A Fine-Tuning Job#

A job references a base model and a Dataset:

bash
curl -X POST "$PROVON_API_URL/projects/$PROJECT_ID/fine-tuning/jobs" \
  -H "Authorization: Bearer $PROVON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "baseModelId": "<base-model-id>",
    "datasetId": "<dataset-id>",
    "engine": "transformers",
    "method": "sft",
    "adapter": "lora",
    "hyperparameters": {
      "learningRate": 0.0001,
      "numTrainEpochs": 3,
      "perDeviceTrainBatchSize": 1
    },
    "output": {
      "format": "safetensors"
    }
  }'

The base model must already be known to the runtime. The Dataset must use the chat schema with at least one example.

Job Lifecycle#

Jobs move through queued, running, completed, failed, and cancelled. Poll status:

bash
curl "$PROVON_API_URL/projects/$PROJECT_ID/fine-tuning/jobs/$JOB_ID" \
  -H "Authorization: Bearer $PROVON_API_KEY"

Cancel a running job:

bash
curl -X POST "$PROVON_API_URL/projects/$PROJECT_ID/fine-tuning/jobs/$JOB_ID/cancel" \
  -H "Authorization: Bearer $PROVON_API_KEY"

Tuning Configs#

A tuning config is a reusable recipe that binds a base model, a Dataset, hyperparameters, and an output format. You can create configs through the API and reuse them to start jobs, or enable automatic triggers and deployment.

bash
curl -X POST "$PROVON_API_URL/projects/$PROJECT_ID/fine-tuning/tuning-configs" \
  -H "Authorization: Bearer $PROVON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "baseModelId": "<base-model-id>",
    "datasetId": "<dataset-id>",
    "engine": "transformers",
    "method": "sft",
    "adapter": "lora",
    "hyperparameters": {
      "learningRate": 0.0001,
      "numTrainEpochs": 3
    },
    "output": {
      "format": "safetensors"
    },
    "autoTrigger": {
      "enabled": true,
      "minExampleCount": 10
    },
    "autoDeploy": {
      "enabled": true
    }
  }'
  • autoTrigger starts a new job automatically when the Dataset reaches minExampleCount new examples.
  • autoDeploy deploys the resulting checkpoint to the model runtime when the job completes successfully.

List, update, and delete configs with the same path pattern. Exact request and response shapes are in the Fine-Tuning API.

Checkpoints#

When a job completes, it produces a checkpoint stored in the project checkpoint registry. List checkpoints:

bash
curl "$PROVON_API_URL/projects/$PROJECT_ID/fine-tuning/checkpoints" \
  -H "Authorization: Bearer $PROVON_API_KEY"

Deploy a checkpoint to the model runtime:

bash
curl -X POST "$PROVON_API_URL/projects/$PROJECT_ID/fine-tuning/checkpoints/$CHECKPOINT_ID/deploy" \
  -H "Authorization: Bearer $PROVON_API_KEY"

Deployment loads the checkpoint into the model runtime and makes it available as a self/ Gateway target. The checkpoint must have a registered inference profile.

Lineage#

Trace the provenance of a model:

bash
curl "$PROVON_API_URL/projects/$PROJECT_ID/fine-tuning/lineage/$ROOT_MODEL_ID" \
  -H "Authorization: Bearer $PROVON_API_KEY"

Lineage records the chain of base models, fine-tuning jobs, and checkpoints.

Export Checkpoints#

Export a checkpoint or a Hugging Face model to the Hugging Face Hub:

bash
curl -X POST "$PROVON_API_URL/projects/$PROJECT_ID/fine-tuning/export" \
  -H "Authorization: Bearer $PROVON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sourceType": "checkpoint",
    "checkpointId": "<checkpoint-id>",
    "format": "gguf",
    "quantMethod": "q4_k_m",
    "destination": "huggingface-hub",
    "hfRepoId": "owner/repo"
  }'

Supported export formats are gguf and merged-16bit. lora-adapter export is not currently supported by the API.

Export requires a configured Hugging Face connector with a valid access token. The token is resolved from the project connector and passed to the export worker securely; it is not persisted on the job record.

Configuration#

Node runtime variables that control the fine-tuning and export background loops:

Variable Default Purpose
PROVON_PYTHON_FINE_TUNING_URL http://127.0.0.1:8001 Base URL of services/python-fine-tuning
PROVON_PYTHON_FINE_TUNING_API_KEY none Bearer token shared with Node
PROVON_MODEL_FINE_TUNING_WORK_DIR none Root for training temporary files and manifests
PROVON_MODEL_EXPORT_WORK_DIR none Root for export temporary files
PROVON_MODEL_FINE_TUNING_INTERVAL_MS 5000 Poll interval for the fine-tuning consumer
PROVON_MODEL_FINE_TUNING_LOCK_MS 1,800,000 (30 min) Lease duration for a fine-tuning job
PROVON_MODEL_EXPORT_INTERVAL_MS 5000 Poll interval for the export consumer
PROVON_MODEL_EXPORT_LOCK_MS 3,600,000 (1 hour) Lease duration for an export job

The Python fine-tuning service is configured separately from Node:

Variable Default Purpose
PROVON_HOST 0.0.0.0 Bind host
PROVON_PORT 8001 Bind port
PROVON_API_KEY none Bearer token shared with Node
PROVON_LOG_LEVEL info Service log level
PROVON_LLAMA_CPP_PATH llama.cpp Path to llama.cpp checkout for GGUF export

Node and the Python service must see the training work directory at the same absolute path, because training requests pass filesystem paths for the Dataset manifest and checkpoint output. When running on different hosts, mount or replicate the configured PROVON_MODEL_FINE_TUNING_WORK_DIR so both processes resolve the same paths.

Capability Requirements#

The project API key needs:

  • workspace:read or project:data:read to list jobs, checkpoints, and lineage;
  • models:manage or project:data:write to create jobs, cancel jobs, and export checkpoints;
  • models:manage or project:models:manage to deploy checkpoints.

Limitations#

  • Fine-tuning is only available in the Node runtime. Cloudflare Workers do not provide local training or checkpoint storage.
  • The current supported engine set is transformers; others may be added over time.
  • GGUF export requires a local checkout of llama.cpp with convert_hf_to_gguf.py and the llama-quantize binary.
  • Compressed quantization (FP8/INT8) requires the compressed optional dependency (llm-compressor) in the Python fine-tuning service.