Jesse A. Green / notebook

Live demo: the DocCompiler guide library as a static, read-only snapshot (October 2026). No backend, no accounts, nothing to submit.

LLaMA Factory Administrator & Developer Guide

Generated May 2026 from hiyouga/LlamaFactory at e0bc3c1

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

LLaMA Factory is a unified framework for efficiently fine-tuning 100+ large language models. This guide covers architecture, configuration, deployment, security, and developer internals for administrators, operators, and contributors working with the system at a production level.

For everyday usage, CLI commands, and getting-started workflows, see the User Guide.


1. Architecture Overview

1.1 Dual-Engine Design

LLaMA Factory ships two complete training engines selectable at runtime. Both share the same CLI entry point (llamafactory-cli / lmf) and configuration surface, but differ fundamentally in extensibility and internal design.

Aspect Legacy Engine (default) V1 Engine (USE_V1=1)
Entry point cli.py → launcher.py cli.py → v1/launcher.py
Training loop HuggingFace Trainer subclasses Custom BaseTrainer.fit() with micro-batching
Extensibility Monolithic, modify source Plugin registry (BasePlugin pattern)
Distributed Accelerate / DeepSpeed via HF Native DeepSpeed, FSDP2, DDP
Supported stages SFT, DPO, KTO, PPO, RM, PT SFT, DPO, RM
Maturity Production-proven Newer, plugin-oriented

Important

The V1 engine is activated exclusively via the USE_V1=1 environment variable. There is no YAML flag or CLI switch. All V1-specific configuration (plugin configs, batching strategies) is ignored when V1 is not active.

1.2 Legacy Engine Module Map

src/llamafactory/
├── cli.py                  # Entry point, dispatches commands
├── launcher.py             # Command dispatch, torchrun auto-launch
├── train/
│   └── tuner.py            # Stage router → per-stage workflows
│       ├── sft/            # Supervised fine-tuning
│       ├── dpo/            # Direct preference optimization
│       ├── kto/            # KTO training
│       ├── ppo/            # Proximal policy optimization
│       ├── rm/             # Reward modeling
│       └── pt/             # Pretraining / continued pretraining
├── model/                  # Model loading, adapter mgmt, quantization
├── data/                   # Data loading, template system, multimodal, tool formatting
├── hparams/                # Argument dataclasses
├── chat/                   # ChatModel (HF, vLLM, SGLang, KTransformers engines)
├── webui/                  # Gradio-based LlamaBoard
├── api/                    # FastAPI OpenAI-compatible server
├── eval/                   # Evaluation (deprecated)
└── extras/                 # Constants, env detection, logging, misc, package checks

1.3 V1 Engine Module Map

src/llamafactory/v1/
├── launcher.py             # V1 command dispatch
├── core/
│   ├── data_engine.py      # torch Dataset from YAML/HF Hub/local
│   ├── model_engine.py     # Model init, PEFT, quantization, kernels
│   ├── base_trainer.py     # Training loop with micro-batch accumulation
│   ├── base_sampler.py     # Inference engine
│   └── utils/
│       ├── batching.py     # BatchGenerator with strategies
│       ├── checkpoint.py   # Distributed checkpoint save/resume
│       └── rendering.py    # ChatML message rendering
├── config/                 # OmegaConf + HfArgumentParser arg parsing
├── plugins/
│   ├── data_plugins/       # Data loading + conversion (alpaca, pair)
│   ├── model_plugins/      # Init, PEFT (LoRA), quant, kernels, templates, parallelization
│   ├── trainer_plugins/    # Optimizer, LR scheduler, distributed (DeepSpeed, FSDP2, Hub)
│   └── sampler_plugins/    # vLLM sampler
├── trainers/               # SFTTrainer, DPOTrainer, RMTrainer
├── samplers/               # CLISampler
├── accelerator/            # DistributedInterface, profiler
└── utils/                  # Types, logging, plugin system, helpers, constants

1.4 Command Dispatch Flow

llamafactory-cli <command>
        │
        ▼
    cli.py ─── USE_V1=1? ───► v1/launcher.py
        │ no                       │
        ▼                          ▼
    launcher.py              V1 dispatch
        │                    (train/chat)
        ▼
    Dispatch table:
      train   → train/tuner.py → stage-specific workflow
      api     → api/app.py (FastAPI + Uvicorn)
      chat    → chat/ChatModel (interactive CLI)
      export  → model export pipeline
      webchat → Gradio chat interface
      webui   → LlamaBoard (full Gradio UI)
      env     → print environment info
      version → print version

When the command is train and multiple GPUs are detected (or FORCE_TORCHRUN=1), launcher.py automatically re-launches the process under torchrun with appropriate distributed arguments.

1.5 Data Flow — Training Pipeline

YAML config ──► hparams parsing ──► DataEngine/DataLoader
                                         │
                Model loading ◄──────────┘
                     │
                     ▼
              Trainer.fit() / HF Trainer.train()
                     │
                     ├── Forward pass (micro-batch)
                     ├── Loss computation (stage-specific)
                     ├── Backward + gradient accumulation
                     ├── Optimizer step + LR schedule
                     └── Checkpoint save (every N steps)
                     │
                     ▼
              Output: adapter weights / merged model / checkpoints

2. System Requirements

2.1 Software Dependencies

Dependency Minimum Version Purpose
Python 3.9+ Runtime
PyTorch 2.x Training framework
Transformers 5.x+ Model loading, tokenizers
PEFT latest LoRA and adapter methods
DeepSpeed 0.14+ ZeRO optimization, offloading
Accelerate latest Distributed training orchestration
Gradio 4.x WebUI (LlamaBoard)
FastAPI latest API server
Uvicorn latest ASGI server
OmegaConf latest V1 config parsing
Pydantic 2.x API protocol models

2.2 Hardware Guidelines

Scenario GPU Memory Recommended Setup
QLoRA 7B model 8-16 GB Single consumer GPU (RTX 3090/4090)
LoRA 7B model 16-24 GB Single A100/H100 or RTX 4090/5090
Full fine-tune 7B 80+ GB Multi-GPU (2-4x A100 80GB)
Full fine-tune 70B 320+ GB 4-8x A100/H100, ZeRO-3 offload
LoRA 70B model 40-80 GB 1-2x A100 80GB with 4-bit quantization

Note

VRAM usage varies significantly with cutoff_len, micro_batch_size, and quantization settings. Use RECORD_VRAM=1 to profile actual consumption during a short test run before committing to long training jobs.

2.3 Docker Images

Three official Docker images target different accelerator stacks:

Image Path Base Target Hardware
CUDA docker/docker-cuda/ NVIDIA CUDA NVIDIA GPUs
ROCm docker/docker-rocm/ AMD ROCm AMD GPUs
NPU docker/docker-npu/ Ascend CANN Huawei Ascend NPUs

Each includes a Dockerfile with all dependencies pre-installed. Build with standard Docker commands from the respective directory.


3. Configuration Reference

3.1 Legacy Engine Arguments

The legacy engine uses six argument dataclasses parsed from YAML config files:

Dataclass Key Fields
ModelArguments model_name_or_path, adapter_name_or_path, quantization_bit, quantization_method
DataArguments dataset, dataset_dir, template, cutoff_len, max_samples, streaming
TrainingArguments Extends HF Seq2SeqTrainingArguments — output_dir, per_device_train_batch_size, learning_rate, num_train_epochs, bf16, deepspeed
FinetuningArgs stage (sft/dpo/kto/ppo/rm/pt), finetuning_type (lora/full/freeze), lora_rank, lora_target
GeneratingArgs temperature, top_p, top_k, max_new_tokens, repetition_penalty
EvaluationArgs task, n_shot, batch_size

Configuration is YAML-based. Example skeleton:

### model
model_name_or_path: meta-llama/Llama-2-7b-hf

### method
stage: sft
finetuning_type: lora
lora_rank: 8
lora_target: all

### dataset
dataset: alpaca_en
template: llama2
cutoff_len: 1024

### output
output_dir: saves/llama2-7b/lora/sft
logging_steps: 10
save_steps: 500

### train
per_device_train_batch_size: 2
gradient_accumulation_steps: 4
learning_rate: 1.0e-4
num_train_epochs: 3.0
bf16: true

3.2 V1 Engine Arguments

The V1 engine uses OmegaConf combined with HfArgumentParser, providing a cleaner configuration surface:

ModelArguments:

Field Default Description
model Qwen/Qwen3-4B-Instruct-2507 Model name or path
template qwen3_nothink Chat template name
trust_remote_code (False) Allow remote code execution
model_class llm Model class: llm, cls, or other
init_config (PluginConfig) Initialization plugin config
peft_config (PluginConfig) PEFT plugin config (LoRA, etc.)
kernel_config (PluginConfig) Kernel plugin config (NPU ops)
quant_config (PluginConfig) Quantization plugin config

TrainingArguments:

Field Default Description
output_dir auto-generated UUID Output directory
micro_batch_size 1 Per-device micro-batch size
global_batch_size None (auto) Total batch across all devices
cutoff_len 2048 Maximum sequence length
learning_rate 1e-4 Initial learning rate
num_train_epochs 3 Number of training epochs
max_steps None Override epoch-based with step count
max_grad_norm 1.0 Gradient clipping threshold
bf16 True Use bfloat16 precision
batching_strategy normal One of: normal, padding_free, dynamic_batching, dynamic_padding_free
batching_workers 16 Data loading workers
enable_activation_checkpointing True Gradient checkpointing
dist_config (PluginConfig) Distributed training plugin
optim_config (PluginConfig) Optimizer plugin
lr_scheduler_config (PluginConfig) LR scheduler plugin
seed 42 Random seed
resume_from_checkpoint None Path or "auto" for latest
save_steps (None) Save every N steps
save_epochs (None) Save every N epochs
save_ckpt_as_hf False Convert checkpoints to HF format
save_total_limit None Max checkpoints to keep
logging_steps 1 Log every N steps

DataArguments:

Field Default Description
train_dataset (required) Training dataset specification
eval_dataset None Evaluation dataset specification

SampleArguments:

Field Default Description
sample_backend hf Inference backend: hf or vllm
max_new_tokens 128 Max generation length

Tip

V1 plugin configs use a nested structure with a mandatory name field. For example, to configure LoRA in V1:

peft_config:
  name: lora
  r: 16
  lora_alpha: 32
  target_modules: all

3.3 V1 Batching Strategies

Strategy Description Use Case
normal Standard padding to max length in batch Default, simplest
padding_free No padding, sequences concatenated Memory-efficient for variable-length data
dynamic_batching Batches adjusted by token budget Best throughput for diverse sequence lengths
dynamic_padding_free Dynamic batching + no padding Maximum memory efficiency

3.4 Environment Variable Reference

Complete list of environment variables that control runtime behavior:

Engine Selection:

Variable Default Description
USE_V1 0 Enable V1 engine (1 to activate)

API Server:

Variable Default Description
API_KEY None Bearer token for API authentication
API_PORT 8000 Server port
API_HOST 0.0.0.0 Server bind address
API_MODEL_NAME gpt-3.5-turbo Model name returned in API responses
FASTAPI_ROOT_PATH "" Root path prefix (for reverse proxies)
SAFE_MEDIA_PATH api/safe_media Allowed local file access path
ALLOW_LOCAL_FILES 1 Enable local file access in API
API_VERBOSE 1 Verbose request logging
MAX_CONCURRENT 1 Maximum concurrent inference requests

Logging & Debugging:

Variable Default Description
LLAMAFACTORY_VERBOSITY INFO Log level
DISABLE_VERSION_CHECK 0 Skip dependency version checks
RECORD_VRAM 0 Record VRAM usage during training
ALLOW_EXTRA_KEYS 0 Allow unknown keys in YAML configs

Distributed Training:

Variable Default Description
FORCE_TORCHRUN 0 Force torchrun launch even for single GPU
USE_MCA 0 Enable MCA (forces torchrun)
OPTIM_TORCH 1 Enable DDP optimizations (expandable_segments, NCCL)
NNODES 1 Number of training nodes
NODE_RANK 0 Current node rank in multi-node setup
NPROC_PER_NODE auto-detect GPUs per node
MASTER_ADDR 127.0.0.1 Master node address
MASTER_PORT auto Master node port

Elastic Training:

Variable Default Description
RDZV_ID None Rendezvous ID for elastic launch
MIN_NNODES None Minimum nodes for elastic training
MAX_NNODES None Maximum nodes for elastic training
MAX_RESTARTS 0 Maximum worker restarts

Model Hubs:

Variable Default Description
USE_MODELSCOPE_HUB 0 Download models from ModelScope
USE_OPENMIND_HUB 0 Download models from OpenMind

WebUI:

Variable Default Description
GRADIO_SERVER_NAME 0.0.0.0 Gradio server bind address

Warning

Setting ALLOW_EXTRA_KEYS=1 suppresses errors for unrecognized YAML keys. This is dangerous in production because typos in configuration fields will be silently ignored rather than caught at startup. Use only during development or migration.


4. Deployment & Scaling

4.1 Single-GPU Deployment

The simplest deployment for inference serving:

# Start API server with a LoRA adapter
llamafactory-cli api \
  --model_name_or_path meta-llama/Llama-2-7b-hf \
  --adapter_name_or_path saves/llama2-7b/lora/sft \
  --template llama2 \
  --finetuning_type lora

Or equivalently with a YAML config:

llamafactory-cli api path/to/config.yaml

4.2 Multi-GPU Training

LLaMA Factory auto-detects available GPUs and launches torchrun automatically. Manual control is available via environment variables:

# 4 GPUs on a single node
NPROC_PER_NODE=4 llamafactory-cli train config.yaml

# Force torchrun even on single GPU (useful for debugging distributed code)
FORCE_TORCHRUN=1 llamafactory-cli train config.yaml

4.3 Multi-Node Training

# Node 0 (master)
NNODES=2 NODE_RANK=0 MASTER_ADDR=10.0.0.1 MASTER_PORT=29500 \
  NPROC_PER_NODE=8 llamafactory-cli train config.yaml

# Node 1
NNODES=2 NODE_RANK=1 MASTER_ADDR=10.0.0.1 MASTER_PORT=29500 \
  NPROC_PER_NODE=8 llamafactory-cli train config.yaml

4.4 Elastic Training

For fault-tolerant training that can scale nodes dynamically:

RDZV_ID=my_job MIN_NNODES=2 MAX_NNODES=4 MAX_RESTARTS=3 \
  NPROC_PER_NODE=8 llamafactory-cli train config.yaml

4.5 DeepSpeed Configurations

Pre-built DeepSpeed configs are provided in examples/deepspeed/:

Config File ZeRO Stage Features
ds_z0_config.json 0 No sharding (baseline)
ds_z2_config.json 2 Optimizer + gradient sharding with auto tensor parallelism
ds_z2_offload_config.json 2 Stage 2 + CPU offloading
ds_z3_config.json 3 Full parameter sharding
ds_z3_offload_config.json 3 Stage 3 + CPU offloading
ds_z3_fp8_config.json 3 Stage 3 + FP8 precision

Usage in legacy engine YAML:

deepspeed: examples/deepspeed/ds_z3_config.json

Usage in V1 engine:

dist_config:
  name: deepspeed
  config_file: examples/deepspeed/ds_z3_config.json

4.6 FSDP Configurations

Available FSDP configs in examples/accelerate/:

Config Description
fsdp_config.yaml Standard FSDP
fsdp2_config.yaml FSDP2 (newer PyTorch native)
fsdp_config_offload.yaml FSDP with CPU offloading
fsdp_config_multiple_nodes.yaml Multi-node FSDP

4.7 Docker Deployment

# Build CUDA image
cd docker/docker-cuda
docker build -t llamafactory:cuda .

# Run training
docker run --gpus all -v /data/models:/models -v /data/output:/output \
  llamafactory:cuda llamafactory-cli train /config/train.yaml

# Run API server
docker run --gpus all -p 8000:8000 \
  -e API_KEY=your-secret-key \
  -e API_MODEL_NAME=my-fine-tuned-model \
  llamafactory:cuda llamafactory-cli api /config/api.yaml

Important

When running the API server in Docker, always set API_KEY to a strong secret. The default configuration has no authentication, and CORS allows all origins.

4.8 Reverse Proxy Setup

When deploying behind a reverse proxy (nginx, Traefik), set the FASTAPI_ROOT_PATH environment variable to match the proxy's path prefix:

# If proxied at /llm/v1/
FASTAPI_ROOT_PATH=/llm API_PORT=8000 llamafactory-cli api config.yaml

5. Operations

5.1 Checkpoint Management

Legacy engine: Uses HuggingFace Trainer checkpointing. Checkpoints are saved to output_dir/checkpoint-{step}/.

V1 engine: Uses TrainingCheckpointCoordinator for distributed-safe checkpointing:

  • Saves model state, optimizer state, LR scheduler state, batch generator state, and RNG states
  • resume_from_checkpoint: "auto" scans output_dir for the latest checkpoint
  • save_total_limit rotates old checkpoints to control disk usage
  • save_ckpt_as_hf: true converts distributed checkpoints to HuggingFace format (requires approximately 2x memory during save)
# V1 checkpoint config example
output_dir: /output/my-training-run
save_steps: 500
save_total_limit: 3
resume_from_checkpoint: auto
save_ckpt_as_hf: false

Caution

Setting save_ckpt_as_hf: true roughly doubles memory usage during checkpoint saves because the full model must be materialized in HuggingFace format. On memory-constrained setups, save in native format and convert post-training using the checkpoint conversion scripts.

5.2 Checkpoint Conversion Scripts

Located in scripts/convert_ckpt/:

Script Purpose
llamafy_baichuan2.py Convert Baichuan2 to LLaMA format
llamafy_qwen.py Convert Qwen to LLaMA format
tiny_llama4.py Create tiny LLaMA4 for testing
tiny_qwen3.py Create tiny Qwen3 for testing

5.3 Dataset Registry

Datasets are registered in data/dataset_info.json. Each entry specifies:

{
  "dataset_name": {
    "file_name": "path/to/data.json",
    "formatting": "alpaca",
    "columns": {
      "prompt": "instruction",
      "query": "input",
      "response": "output"
    }
  }
}

The V1 engine uses YAML-based dataset definitions with DatasetInfo objects supporting:

Field Description
path Local path or HF Hub dataset ID
source hf_hub, ms_hub, or local
split Dataset split name
converter Data converter plugin (alpaca, pair)
size Dataset size hint
weight Sampling weight for dataset mixing
streaming Enable streaming mode

Note

In the V1 engine, all datasets in a training run must be either all streaming or all non-streaming. Mixing modes produces the error: "All datasets must be streaming or non-streaming."

5.4 Monitoring & Logging

Log levels: Controlled via LLAMAFACTORY_VERBOSITY (values: DEBUG, INFO, WARNING, ERROR, CRITICAL).

VRAM profiling: Set RECORD_VRAM=1 to track GPU memory allocation throughout training.

Training metrics: Both engines log loss, learning rate, and throughput at intervals set by logging_steps.

External loggers: The legacy engine supports integration with MLflow, WandB, and TensorBoard via HuggingFace Trainer's reporting infrastructure.

5.5 Utility Scripts

Located in scripts/stat_utils/:

Script Purpose Usage
cal_flops.py Calculate model FLOPs Pre-training capacity planning
cal_mfu.py Calculate model FLU utilization Measure hardware efficiency
cal_ppl.py Calculate perplexity Evaluate model quality
cal_lr.py Calculate learning rate schedule Visualize LR warmup/decay
length_cdf.py Dataset length CDF Choose appropriate cutoff_len

5.6 Batch Size Constraints

The V1 engine enforces strict batch size relationships:

global_batch_size must be divisible by (data_parallel_size × micro_batch_size)

If global_batch_size is not set, it is computed automatically as micro_batch_size × data_parallel_size. Violations produce: "Global batch size must be divisible by DP size and micro batch size."


6. Performance

6.1 Memory Optimization Ladder

Listed from least to most aggressive, apply cumulatively as needed:

Technique Memory Savings Config
BF16 training ~50% vs FP32 bf16: true
Gradient checkpointing ~30-50% activation memory V1: enable_activation_checkpointing: true; Legacy: gradient_checkpointing: true
LoRA ~90% trainable params finetuning_type: lora / V1: peft_config.name: lora
QLoRA (4-bit) ~75% model memory quantization_bit: 4 + LoRA
DeepSpeed ZeRO-2 Shard optimizer + gradients deepspeed: ds_z2_config.json
DeepSpeed ZeRO-3 Shard everything deepspeed: ds_z3_config.json
ZeRO-3 + CPU offload Offload to system RAM deepspeed: ds_z3_offload_config.json
Padding-free batching Eliminate padding waste V1: batching_strategy: padding_free

6.2 Throughput Optimization

Batching strategy selection (V1):

  • normal: Safe default. Pads all sequences to the longest in the batch.
  • padding_free: Concatenates sequences without padding. Best for datasets with high length variance. No wasted compute on pad tokens.
  • dynamic_batching: Groups sequences by similar length into token-budget batches. Maximizes GPU utilization.
  • dynamic_padding_free: Combines both strategies for maximum efficiency.

Data loading: batching_workers: 16 (V1 default) controls parallel data preprocessing. Increase on CPU-rich nodes; decrease if CPU is the bottleneck.

DDP optimization: OPTIM_TORCH=1 (default) enables PyTorch DDP optimizations including CUDA expandable memory segments and NCCL optimizations.

6.3 V1 Training Loop Internals

The BaseTrainer.fit() loop operates as follows:

  1. BatchGenerator initialization — creates batches according to the configured batching_strategy
  2. Optimizer creation — default AdamW, overridable via optim_config plugin
  3. LR scheduler creation — configurable via lr_scheduler_config plugin
  4. Training loop per step:
    • Accumulate N micro-batches (where N = global_batch_size / (micro_batch_size × dp_size))
    • Each micro-batch: forward → loss → backward
    • Loss scaling uses valid-token weighting (not naive averaging)
    • If DeepSpeed: engine handles backward pass and optimizer step
    • If FSDP2/DDP: manual clip_grad_norm_ → optimizer.step() → scheduler.step()
  5. Checkpoint save at configured intervals
  6. Callbacks fire at each logging step (LoggingCallback built-in, custom TrainerCallback supported)

6.4 Sequence Parallelism

The V1 engine supports Ulysses sequence parallelism for extremely long sequences via the model plugin system. Note the limitation: "Sequence parallel is not supported for qwen3.5 model."

6.5 NPU Kernel Optimizations

For Huawei Ascend NPUs, the V1 kernel plugin provides fused operations:

Kernel Operation
fused_moe Fused Mixture-of-Experts
swiglu Fused SwiGLU activation
rms_norm Fused RMS normalization
rope Fused rotary position embedding

Configure via:

kernel_config:
  name: npu

7. Security

7.1 API Authentication

The API server authenticates requests via Bearer token:

Authorization: Bearer <API_KEY>

Set via the API_KEY environment variable. When API_KEY is not set, the API operates without authentication.

Caution

Running the API server without API_KEY set exposes the model to unauthenticated access. Always set a strong API key in production deployments.

7.2 CORS Policy

The API server allows all origins (*) by default. For production deployments behind a reverse proxy, configure CORS restrictions at the proxy level.

7.3 Local File Injection (LFI) Protection

The check_lfi_path() function in api/common.py restricts local file access to the directory specified by SAFE_MEDIA_PATH. Any request attempting to access files outside this boundary is rejected.

  • Default SAFE_MEDIA_PATH: api/safe_media (relative to working directory)
  • ALLOW_LOCAL_FILES=0 disables all local file access through the API

7.4 Server-Side Request Forgery (SSRF) Protection

The check_ssrf_url() function in api/common.py prevents the API from making requests to internal network resources:

  • Blocks private IP ranges (10.x, 172.16-31.x, 192.168.x, 127.x, etc.)
  • Blocks reserved/link-local addresses
  • Validates HTTP and HTTPS schemes only
  • Rejects URLs targeting internal services

7.5 Remote Code Execution

The trust_remote_code parameter (both engines) allows execution of arbitrary Python code bundled with model repositories. This is required by some models but represents a significant security risk.

Warning

Only enable trust_remote_code for models from trusted sources. Malicious model repositories can execute arbitrary code during model loading. In production, prefer models that do not require remote code.

7.6 Security Hardening Checklist

Item Action
API authentication Set API_KEY to a strong random secret
Local file access Set ALLOW_LOCAL_FILES=0 unless required
SAFE_MEDIA_PATH Restrict to a dedicated media directory
Remote code Set trust_remote_code: false unless model requires it
CORS Restrict at reverse proxy level
Network exposure Bind API to localhost (API_HOST=127.0.0.1) behind reverse proxy
Container isolation Run containers with --read-only filesystem where possible
GPU isolation Use NVIDIA_VISIBLE_DEVICES to restrict GPU access

8. Developer Internals

8.1 V1 Plugin System

The V1 engine's extensibility is built on the BasePlugin registry pattern in v1/utils/plugin.py.

Registration:

@InitPlugin("custom_init").register("load_model")
def custom_load_model(model_args, ...):
    # Custom model loading logic
    pass

Invocation:

InitPlugin("custom_init")()  # Calls the registered method

Plugin hierarchy:

Plugin Base Class Purpose Methods
InitPlugin Model initialization load_model, load_tokenizer
PeftPlugin Parameter-efficient fine-tuning apply_peft, save_peft
QuantizationPlugin Model quantization quantize_model
KernelPlugin Custom compute kernels apply_kernels
DataLoaderPlugin Data loading customization load_data
DataConverterPlugin Data format conversion convert (alpaca, pair formats)
OptimizerPlugin Custom optimizers create_optimizer
LRSchedulerPlugin Learning rate schedules create_scheduler
DistributedPlugin Distributed training backends setup, teardown

Plugin configs use PluginConfig — a dict-like object requiring a name field that maps to the registered plugin. Missing the name field produces: "Plugin configuration must have a 'name' field."

8.2 V1 DataEngine Internals

DataEngine (v1/core/data_engine.py) implements a torch.utils.data.Dataset:

  1. Parses dataset YAML config into DatasetInfo objects
  2. Each dataset can come from HuggingFace Hub, ModelScope, OpenMind, or local files
  3. Data converters transform raw records into the internal message format (ChatML)
  4. Builds a flat data_index for efficient random access across multiple datasets
  5. Supports dataset mixing via weight field
  6. Streaming mode for datasets too large to fit in memory (disables random access — "Streaming dataset does not support index access.")

8.3 V1 ModelEngine Internals

ModelEngine (v1/core/model_engine.py) orchestrates model setup:

  1. Load base model via InitPlugin
  2. Apply quantization via QuantizationPlugin (if configured)
  3. Apply PEFT via PeftPlugin (if configured)
  4. Apply custom kernels via KernelPlugin (if configured)
  5. Apply distributed wrapping (DDP, FSDP2, or DeepSpeed)

Note

When using LoRA with the V1 engine, loading the model by meta device (lazy initialization) is not supported. Attempting this produces: "Currently lora stage does not support loading model by meta."

8.4 V1 Distributed Training

The DistributedInterface in v1/accelerator/ abstracts distributed backends:

DeepSpeed: Uses the DeepSpeed engine to manage backward pass, optimizer step, and gradient accumulation. Configured via JSON config files (ZeRO stages 0/2/3).

FSDP2: Uses PyTorch's native FSDP2. Manages parameter sharding and gradient synchronization. Configured via YAML accelerate configs.

DDP: Standard PyTorch DistributedDataParallel. The default when no distributed config is specified with multiple GPUs.

The V1 engine requires drop_last=True for distributed training to ensure even batch distribution across ranks. Violating this produces: "Drop last must be True."

8.5 Legacy Engine ChatModel

The ChatModel class in chat/ supports four inference backends:

Backend Engine Use Case
HuggingFace transformers generate Default, broadest compatibility
vLLM vllm High-throughput serving
SGLang sglang Structured generation
KTransformers ktransformers Specialized inference

8.6 API Server Internals

The FastAPI server (api/app.py) exposes three endpoints:

Method Path Handler Description
GET /v1/models list_models Returns loaded model info
POST /v1/chat/completions create_chat_completion OpenAI-compatible chat completion
POST /v1/score/evaluation create_score_evaluation Score/evaluate responses

Request/response models are defined in api/protocol.py using Pydantic v2. The API follows the OpenAI chat completions specification for maximum compatibility with existing client libraries.

Concurrency is controlled by MAX_CONCURRENT (default 1), which limits simultaneous inference requests to prevent GPU OOM.

8.7 Template System

Both engines use a template system to format conversations for different model families. Templates define:

  • System message handling
  • Turn delimiters and role tokens
  • Tool/function call formatting
  • Stop sequences

The V1 engine ships with built-in templates including qwen3 and qwen3_nothink (the default, which suppresses chain-of-thought tokens).

8.8 Test Infrastructure

Two independent test suites:

Suite Path Coverage
Legacy tests tests/ Data processing, model loading, templates, training, evaluation
V1 tests tests_v1/ V1 data engine, model engine, training, plugins

Run with pytest:

# All legacy tests
pytest tests/

# All V1 tests
pytest tests_v1/

# Specific test
pytest tests_v1/test_data_engine.py -v

8.9 Project File Structure

hiyouga/LlamaFactory/
├── src/llamafactory/          # Main package
│   ├── cli.py                 # Entry point
│   ├── launcher.py            # Legacy command dispatch
│   ├── train/                 # Training stages (sft, dpo, kto, ppo, rm, pt)
│   ├── model/                 # Model loading & adapters
│   ├── data/                  # Data loading & templates
│   ├── hparams/               # Argument dataclasses
│   ├── chat/                  # Interactive chat (multi-backend)
│   ├── api/                   # FastAPI server
│   ├── webui/                 # LlamaBoard (Gradio)
│   ├── eval/                  # Evaluation (deprecated)
│   ├── extras/                # Utilities
│   └── v1/                    # V1 plugin-based engine
│       ├── core/              # DataEngine, ModelEngine, BaseTrainer
│       ├── config/            # OmegaConf argument parsing
│       ├── plugins/           # All plugin implementations
│       ├── trainers/          # SFT, DPO, RM trainers
│       ├── samplers/          # CLI sampler
│       ├── accelerator/       # Distributed interface
│       └── utils/             # Plugin system, helpers
├── data/                      # Demo datasets + dataset_info.json
├── examples/                  # YAML configs for all scenarios
│   ├── deepspeed/             # DeepSpeed JSON configs
│   ├── accelerate/            # FSDP YAML configs
│   └── ...                    # Per-stage example configs
├── docker/                    # Dockerfiles (CUDA, ROCm, NPU)
├── scripts/                   # Utilities (FLOPs, MFU, PPL, checkpoint conversion)
├── tests/                     # Legacy test suite
└── tests_v1/                  # V1 test suite

9. Integration Points

9.1 OpenAI API Compatibility

The API server implements the OpenAI chat completions protocol, making it a drop-in replacement for applications using the OpenAI client library:

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="your-api-key"
)

response = client.chat.completions.create(
    model="my-model",
    messages=[{"role": "user", "content": "Hello!"}]
)

The API_MODEL_NAME environment variable controls what model name the server reports. Clients can use any model name in their requests; the server always uses the loaded model.

9.2 HuggingFace Hub Integration

  • Models: Loaded directly from HuggingFace Hub via model_name_or_path / model
  • Datasets: Referenced by Hub ID in dataset configs
  • Adapters: Saved to and loaded from Hub-compatible format
  • Checkpoints: save_ckpt_as_hf converts to Hub format

9.3 ModelScope and OpenMind Hubs

Alternative model/dataset sources activated via environment variables:

# Use ModelScope for model downloads
USE_MODELSCOPE_HUB=1 llamafactory-cli train config.yaml

# Use OpenMind for model downloads
USE_OPENMIND_HUB=1 llamafactory-cli train config.yaml

9.4 Gradio WebUI (LlamaBoard)

The WebUI provides a browser-based interface for:

  • Training configuration and launch
  • Model chat/evaluation
  • Dataset preview
# Start WebUI
llamafactory-cli webui

# Or with custom binding
GRADIO_SERVER_NAME=0.0.0.0 llamafactory-cli webui

9.5 Tool Calling

The API supports tool/function calling in the OpenAI format. Example scripts are provided in scripts/api_example/ demonstrating tool calling and image input.


Appendix A: Troubleshooting

A.1 "can't start new thread" (RuntimeError)

Error: RuntimeError: can't start new thread

Cause: System thread limit reached, commonly when batching_workers is too high or the system ulimit for threads is restrictive.

Solution: Reduce batching_workers in training config. Increase the system thread limit: ulimit -u 65536.

Prevention: Set batching_workers proportional to available CPU cores, not arbitrarily high.

A.2 "backward through graph twice" with Unsloth + ZeRO-3

Error: RuntimeError about backward through the graph a second time, occurring with unsloth_gc enabled alongside Gemma4 and DeepSpeed ZeRO-3.

Cause: Incompatibility between Unsloth's gradient checkpointing and ZeRO-3's parameter partitioning for certain model architectures.

Solution: Disable unsloth_gc when using ZeRO-3 with affected models (Gemma4). Use standard gradient checkpointing instead.

Prevention: Test new model + optimizer + distributed combinations on small datasets before committing to full training runs.

A.3 "ignore_mismatched_sizes" breaking model loading

Error: Model loading fails or produces incorrect results when ignore_mismatched_sizes is enabled in the loader.

Cause: Silently loading mismatched tensor shapes corrupts the model rather than failing loudly.

Solution: Remove ignore_mismatched_sizes and fix the root cause (wrong model path, incompatible adapter, architecture mismatch).

Prevention: Always verify model and adapter compatibility before loading.

A.4 MLflow external logger failing

Error: MLflow integration produces errors or fails to log metrics.

Cause: MLflow configuration or connectivity issues with the tracking server.

Solution: Verify MLflow tracking URI is accessible. Check MLflow version compatibility with the HuggingFace Trainer version in use.

Prevention: Test MLflow connectivity independently before integrating with training.

A.5 GPU 0 barrier warning in distributed training

Error: Warning about GPU 0 waiting at a barrier during distributed training.

Cause: Uneven workload distribution or a process on one rank taking significantly longer.

Solution: Ensure all ranks have equal data. Check for CPU bottlenecks on specific nodes. Verify network connectivity between nodes.

Prevention: Use drop_last=True (mandatory in V1) to ensure even batch distribution.

A.6 Data packing error in SFT with multimodal models

Error: Data packing fails during SFT with models like Qwen3VL.

Cause: Packing (concatenating multiple examples into one sequence) conflicts with multimodal token handling.

Solution: Disable packing when training multimodal models.

Prevention: Review model-specific documentation for known training limitations.

A.7 "Plugin configuration must have a 'name' field"

Error: Raised during V1 engine config parsing.

Cause: A plugin config block (e.g., peft_config, dist_config) is specified without the required name field.

Solution: Add the name field identifying which plugin implementation to use:

peft_config:
  name: lora     # This field is mandatory
  r: 16

A.8 "Global batch size must be divisible by DP size and micro batch size"

Error: Raised at training start in V1 engine.

Cause: The global_batch_size is not evenly divisible by the product of data parallel size and micro_batch_size.

Solution: Either remove global_batch_size (let it auto-compute) or set it to a valid multiple. For example, with 4 GPUs and micro_batch_size: 2, valid global_batch_size values are 8, 16, 24, etc.

Tip

When troubleshooting distributed training issues, set LLAMAFACTORY_VERBOSITY=DEBUG and NPROC_PER_NODE=1 to isolate whether the issue is distributed-specific or a general training problem.