DeepFellow DOCS
Finetuning

How DF-Finetune Works

Training data flow, key design decisions, and how the worker integrates with DeepFellow Server.

DF-Finetune trains LoRA adapters for causal language models on top of the Hugging Face Trainer and PEFT libraries. It runs in two modes: as a standalone command line tool against a local dataset, and as a long-running worker that processes fine-tuning jobs submitted through DeepFellow Server's API.

Training Data Flow

  1. Load the JSONL dataset with LLMInstructionDataset, validating each line and skipping malformed entries.
  2. Format each prompt-response pair with format_instruction(), using the template ### Instruction:\n{prompt}\n\n### Response:\n{response}.
  3. Tokenize each example and mask instruction and padding tokens with -100 in labels, so cross-entropy loss counts only response tokens. See Response-only loss.
  4. Train with Hugging Face Trainer, using a LoRA adapter applied through PEFT.
  5. Save the adapter, tokenizer, and a metadata.json provenance file to adapters/MODEL_NAME/.
  6. Convert the adapter to GGUF format with convert_to_gguf.py, when requested, for use with llama.cpp.

Two Ways to Run DF-Finetune

  • Local CLI: run train.py, run.py, generate.py, and convert_to_gguf.py directly against a config file and a local dataset. See the CLI reference.
  • DeepFellow fine-tuning worker: run worker.py as a background service. It polls a MongoDB fine_tuning_jobs collection for queued jobs, claims them in FIFO order, downloads the training file from DeepFellow Server, and trains with the same LLMTrainer class the local CLI path uses.

Both paths converge on the same trainer, so a job submitted through DeepFellow Server trains identically to one submitted through the CLI with an equivalent configuration.

Key Design Decisions

Response-Only Loss

DF-Finetune masks instruction (prompt) tokens and padding with -100 in the training labels, so the loss penalizes errors in response tokens only. This keeps the model focused on generating better responses instead of memorizing prompts.

Device Selection

DF-Finetune selects a compute device automatically, in this priority order: CUDA, then Apple Silicon MPS, then CPU.

Quantization

Set architecture.quantization in the config to reduce memory usage during training.

ValueDescription
4bit4-bit quantization through bitsandbytes (NF4). Requires CUDA.
8bit8-bit quantization through bitsandbytes.
fp32Full precision.
null or omittedfp16, the default.

Idempotent Orchestration

run.py checks for existing artifacts before running expensive steps. It treats an adapter as trained once adapter_config.json and adapter_model.safetensors exist, and treats an adapter as converted once gguf/adapter.gguf exists. Use --force-retrain or --force-convert to rerun a step anyway.

Adapter Metadata

Every trained adapter includes a metadata.json file recording the base model, LoRA configuration, training hyperparameters, dataset info, and environment details such as device, quantization mode, timestamp, and git commit. Use this file to trace which configuration produced a given adapter.

LoRA Target Modules by Model

LoRA attaches to different module names depending on the model architecture. Set architecture.lora.target_modules in the config accordingly.

Model FamilyTarget Modules
GPT-2c_attn, c_proj
Llama, Mistralq_proj, k_proj, v_proj, o_proj
Phiq_proj, k_proj, v_proj, dense

How the Worker Integrates with DeepFellow Server

upload_job.py and worker.py connect DF-Finetune to a running DeepFellow Server.

  1. upload_job.py logs into DeepFellow Server, sets up an organization, project, and API key when none are provided, uploads the training file to POST /v1/files, and creates a job with POST /v1/fine_tuning/jobs.
  2. worker.py polls DeepFellow Server's MongoDB fine_tuning_jobs collection for jobs with status: "queued", and claims the oldest one.
  3. worker.py downloads the training file from GET /v1/files/{file_id}/content, using the job's dfft_ token for authorization.
  4. worker.py builds a training config from the job's hyperparameters, auto-detecting the prompt and response field names in the training file, and trains with LLMTrainer.
  5. worker.py updates the job's status to succeeded or failed, and appends progress events, which DeepFellow Server exposes through GET /v1/fine_tuning/jobs/{job_id}/events.

DF-Finetune calls DeepFellow Server's existing fine-tuning API. It does not implement those endpoints. See the API reference for /v1/fine_tuning/jobs and related endpoints.

worker.py reads its MongoDB and server connection settings from environment variables shared with DeepFellow Server, so both processes point at the same MongoDB instance. See worker.py in the CLI reference for the full list.

Module Map

PathRole
train.pyTrains a single adapter from a config file.
run.pyTrains and converts to GGUF, idempotently.
generate.pyCompares base and fine-tuned model output.
convert_to_gguf.pyConverts a trained adapter to GGUF format.
worker.pyPolls MongoDB and trains queued jobs.
upload_job.pyUploads a file and creates a job through DeepFellow Server's API.
trainers/llm_trainer.pyLLMTrainer, the core training class wrapping Hugging Face Trainer.
trainers/finetuning_strategies.pyBuilds and applies the LoRA configuration.
data_loaders/llm_dataset.pyLoads and tokenizes the JSONL dataset, with response-only masking.
utils/device.pySelects the compute device.

We use cookies on our website. We use them to ensure proper functioning of the site and, if you agree, for purposes such as analytics, marketing, and targeting ads.