For the complete documentation index, see llms.txt. This page is also available as Markdown.

PEFT & RL Alignment Training

Parameter-efficient fine-tuning (12 methods), reinforcement learning alignment (9 trainers), mixed-precision training, knowledge distillation, and dataset curation

Deeplearning4j 1.0.0-rewrite adds a complete suite of tools for fine-tuning large pretrained models without retraining all parameters, aligning language model outputs using reinforcement learning feedback, training with reduced numerical precision, and curating datasets for domain adaptation.


1. Overview

The following capability groups are covered in this page:

Area
Key Classes
What It Provides

PEFT

PeftModel, PeftModelFactory, LoraLayer

13 adapter types; freeze base weights, train only adapter parameters

RL Alignment

GRPOTrainer, DPOTrainer, PPOTrainer, and 7 more

Human-preference and reward-signal alignment

Training Pipelines

SFTTrainingPipeline, RLAlignmentPipeline

End-to-end supervised and RLHF workflows

Mixed Precision

FP8ScaleManager, LossScaler

FP8 forward/backward, dynamic loss scaling

8-bit Adam

Adam8bit, Adam8bitUpdater

~4x optimizer-state memory reduction

Knowledge Distillation

DistillationTrainer

Teacher/student training with KL, attention, and feature losses

Dataset Curation

TextDeduplicator, SequencePacker, and 18 more

Deduplication, contamination removal, curriculum, bin-packing

Transfer Learning

TransferLearning, TransferLearningHelper

Layer freezing and head replacement on existing models

All SameDiff models gain these extension methods automatically:

sd.applyPeft(PeftConfig config);
sd.getTrainableParameters();
sd.printTrainableParameters();
sd.distillFrom(SameDiff teacher, DistillationConfig config);
sd.fitGRPO(GRPOConfig config, MultiDataSetIterator data);
sd.saveAdapters(Path dir);
sd.loadAdapters(Path dir);

2. Maven Dependencies


3. PEFT Methods

3.1 PeftType Enum

Every PEFT method is identified by a PeftType constant:

PeftType
Description

LORA

Low-Rank Adaptation — low-rank A/B matrices added to linear projections

QLORA

LoRA on NF4-quantized base weights

DORA

Weight-Decomposed LoRA with learned magnitude vector

LOHA

Low-rank Hadamard product adaptation

LOKR

Low-rank Kronecker product adaptation

IA3

Infused Adapter by Inhibiting and Amplifying Inner Activations

VERA

Vector-based Random Matrix Adaptation

PREFIX_TUNING

Trainable key/value prefix tokens prepended to each layer

PROMPT_TUNING

Soft prompt tokens prepended to the input embedding

ADAPTER

Small bottleneck feed-forward modules inserted between layers

LOFTQ

LoRA initialized to minimize NF4 quantization error

ADALORA

Adaptive rank allocation across layers

DYLORA

Dynamic rank search during training

3.2 PeftModel

PeftModel wraps an existing SameDiff base model and injects adapter layers without modifying the base graph:

Key PeftModel capabilities:

Method
Description

printTrainableParameters()

Logs trainable vs total parameter count and percentage

getTrainableParameterCount()

Returns the count of adapter (non-frozen) parameters

addAdapter(String name, PeftConfig config)

Inject an additional named adapter onto the same base model

setActiveAdapter(String name)

Switch which adapter is active for inference

mergeAndUnload()

Merge adapter weights into base weights and return a plain SameDiff

saveAdapters(Path dir)

Serialize only adapter weights (small files)

loadAdapters(Path dir)

Restore previously saved adapter weights

Base model parameters are automatically frozen when PeftModel is created. Only the adapter parameters listed in targetModules are in the computation graph as trainable variables.

3.3 PeftModelFactory

PeftModelFactory.fromConfig(SameDiff baseSd, PeftConfig config) inspects config.getPeftType() and dispatches to the correct adapter injection strategy:

3.4 LoraLayer

LoraLayer is the core adapter unit for all LoRA variants. It wraps an existing linear op (matrix multiply) with low-rank side-path A and B matrices:

Fields tracked per layer:

Field
Description

r

Rank of the factorization

alpha

Scaling factor; effective scale = alpha / r

dropout

Dropout probability applied to the adapter path

mergeWeights() adds (lora_B @ lora_A) * (alpha / r) directly into the base weight matrix, eliminating the side path and returning a standard linear op with no inference overhead.

3.5 LoraAdapterCache

LoraAdapterCache provides thread-safe, LRU-evicted in-memory caching of adapter weights for multi-adapter serving scenarios:

The LRU policy evicts the least-recently-used adapter when the cache is full, making it suitable for serving many fine-tuned variants from a single base model without loading all adapters into GPU memory simultaneously.

3.6 LoftQInitializer

LoftQInitializer produces LoRA A/B initializations that specifically minimize the error introduced by NF4 quantization:

Use initLoraWeights(InitLoraWeights.LOFTQ) in LoraConfig to apply this automatically via PeftModelFactory.


4. LoRA Deep Dive

4.1 LoraConfig

biasMode controls which bias vectors receive gradients:

BiasMode
Effect

NONE

No bias vectors are trained (default)

ALL

All bias vectors (base + adapter layers) are trained

LORA_ONLY

Only bias vectors in LoRA-targeted layers are trained

4.2 QLoraConfig

QLoraConfig extends LoraConfig and adds NF4 quantization of the base weights. The base model loads in 4-bit and stays frozen; only the LoRA adapter trains in full precision:

4.3 AdaLoraConfig — Adaptive Rank Allocation

AdaLoRA starts all adapters at initR and iteratively prunes ranks toward targetR using singular value decomposition-based importance scoring. Orthogonal regularization keeps the A/B decomposition valid:

4.4 DyLoraConfig — Dynamic Rank

DyLoRA trains a single adapter that can serve any rank in [minR, maxR] by randomly sampling a rank each forward pass. This produces an adapter where you pick the serving rank at inference time based on latency vs. quality trade-offs:

4.5 Other Adapter Configs

Config Class
Key Parameters

DoraConfig

useDoraDecomposition, magnitudeLr (learning rate for the magnitude vector)

LohaConfig

Hadamard rank r, lohaAlpha, targetModules

LokrConfig

Kronecker factor sizes, alpha, targetModules

IA3Config

targetModulesForFeedforward, scales feedforward activations only

VeraConfig

projectionRank, per-layer scaling vectors; shared random projection matrices are not stored per-layer

LoftQConfig

numBits, numIter for quantization error minimization

PrefixTuningConfig

numVirtualTokens, encoderHiddenSize

PromptTuningConfig

numVirtualTokens, promptTuningInit (RANDOM or TEXT)

AdapterConfig

bottleneckDim, nonLinearity, placement (AFTER_ATTN, AFTER_FF, BOTH)

4.6 VeRA — Vector-based Random Matrix Adaptation

VeRA (ADR 0077) shares a single pair of frozen random projection matrices across all targeted layers. Only per-layer learned scaling vectors d and b are trained, making it dramatically more parameter-efficient than standard LoRA.

The update formula per layer is:

where A_shared and B_shared are the same frozen random matrices for every layer. Only d and b (one scalar per row/column) are trainable.

VeRA requires orders of magnitude fewer trainable parameters than LoRA at the same rank, making it well suited for scenarios where adapter storage or communication is a bottleneck.

4.7 DyLoRA — Dynamic Rank Training

DyLoRA (ADR 0077) trains a single adapter with a rank range [minRank, maxR]. During each forward pass a rank is sampled uniformly from the range. After training, the same adapter checkpoint can be served at any rank in the range, letting you trade quality against latency at deployment time.

4.8 LoRA+ — Differential Learning Rates

LoRA+ (ADR 0077) applies a higher learning rate to the B matrix than to the A matrix. The B matrix lies closer to the output and benefits from faster updates; keeping A at the base learning rate stabilises training. Set loraLrRatioB in LoraConfig and register the multiplier in TrainingConfig:

4.9 PiSSA and OLoRA Initialization

Both PiSSA and OLoRA (ADR 0077) produce better starting points for LoRA adapters than random initialization by exploiting the structure of the base weight matrix.

PiSSA (Principal Singular-value and Singular-vector Adaptation) runs a truncated SVD on the base weight and initialises A and B from the top-r singular triplets. The base weight is then replaced by its residual W_residual = W - B @ A, so the adapter begins training with zero initial error.

OLoRA performs the same residual correction but uses QR decomposition instead of SVD, which is cheaper for wide matrices.

Select either via initLoraWeights:

Because the base weight is modified in place during initialization, mergeAndUnload() is mandatory before saving if you want a standalone model file. The residual base weight and the adapter must be kept together.

4.10 BitFit — Bias-Only Fine-Tuning

BitFit (ADR 0077) is the simplest PEFT method: every parameter in the base model is frozen except the bias vectors. It is implemented as a method on PeftModel rather than a separate config:

BitFit is appropriate for small datasets where larger adapters overfit, and for establishing a low-cost baseline before committing to a full PEFT experiment.

4.11 Multi-Adapter Serving

Multiple adapters may be attached to the same base model simultaneously. Switch between them without reloading the base weights:

LoraAdapterCache manages hot-swapping in multi-tenant serving: the cache holds pre-loaded adapter weight maps and swaps them into the model graph on demand with LRU eviction.

4.12 Merge and Unload

After training, merge the adapter into the base weights to get a standard model with no inference overhead:

Under the hood, mergeAndUnload() calls LoraLayer.mergeWeights() on every adapted layer, which adds (B @ A) * (alpha / r) to the base weight in place, then removes the adapter variables from the graph.


5. RL Alignment Trainers

All RL alignment trainers operate on a SameDiff policy model and are configured with builder-pattern config objects. They implement a common interface that exposes a train(MultiDataSetIterator) method.

5.1 GRPOTrainer — Group Relative Policy Optimization

For each prompt, GRPO generates groupSize completions, scores them with a reward function, computes z-score normalized advantages within the group, and optimizes a clipped surrogate objective:

where ratio = pi(token) / pi_old(token).

SameDiff placeholders used by GRPOTrainer:

Placeholder
Shape
Description

_grpo_tokens

[batch, seq]

Token IDs for generated completions

_grpo_old_log_probs

[batch, seq]

Log probabilities from the old policy

_grpo_advantages

[batch]

Z-score normalized group advantages

_grpo_ref_log_probs

[batch, seq]

Log probabilities from the frozen reference model

5.2 DPOTrainer — Direct Preference Optimization

DPO eliminates the need for a separate reward model by directly optimizing on preference pairs (chosen vs. rejected):

5.3 PPOTrainer — Proximal Policy Optimization

PPO uses a value network to estimate baselines and clips the policy update ratio:

5.4 DAPOTrainer — Decoupled Clip and Dynamic Sampling Policy Optimization

DAPO decouples the clip range for chosen vs. rejected samples and uses dynamic sampling to focus the rollout budget on difficult prompts:

5.5 DrGRPOTrainer — Variance-Reduced GRPO

DrGRPO adds advantage whitening (zero mean, unit variance across the full batch rather than per-group) to reduce gradient variance:

5.6 KTOTrainer — Kahneman-Tversky Optimization

KTO applies prospect theory loss functions that model asymmetric human preferences (losses are felt more strongly than gains):

5.7 ORPOTrainer — Odds Ratio Preference Optimization

ORPO eliminates the reference model by adding an odds-ratio penalty directly to the SFT cross-entropy loss:

5.8 SimPOTrainer — Simple Preference Optimization

SimPO removes the reference model and uses length-normalized rewards to avoid verbosity bias:

5.9 GSPOTrainer — Grouped Sampling Policy Optimization

GSPO uses sampling-based grouping of completions and optimizes group-level preference signals:

5.10 VlmGRPOTrainer — GRPO for Vision-Language Models

VlmGRPOTrainer extends GRPO for multimodal models. The reward function receives both the generated text and the conditioning image:

5.11 RewardModelTrainer

RewardModelTrainer trains a scalar reward model from preference data. It supports three reward function implementations:

Class
Description

CompositeRewardFunction

Weighted sum of multiple reward signals

RuleBasedRewardFunction

Hand-crafted heuristics (format compliance, length penalties)

SameDiffRewardFunction

Trainable neural reward model implemented as a SameDiff graph


6. Training Pipelines

6.1 SFTTrainingPipeline

SFTTrainingPipeline handles the full supervised fine-tuning loop: data loading, loss computation, gradient accumulation, optimizer stepping, checkpointing, and optional evaluation:

Internally, SFTTrainingPipeline uses GradientAccumulator to split each logical batch into micro-batches, accumulating gradients across accumulationSteps calls to SameDiff.execBackwards() before applying the optimizer update.

6.2 RLAlignmentPipeline

RLAlignmentPipeline coordinates the full RLHF loop:

  1. Freeze reference model (copy of base policy before RL training)

  2. Rollout generation — sample completions from current policy

  3. Reward scoring — score with RewardModelTrainer or a RewardFunction

  4. Advantage computation — normalize per group or globally

  5. Trainer update — call the configured RL trainer (GRPO, PPO, DPO, etc.)

6.3 GradientAccumulator

6.4 CheckpointManager

6.5 ContinuedPretrainingWorkflow

For domain-specific continued pretraining, ContinuedPretrainingWorkflow mixes a domain dataset with a general-purpose dataset at a configurable ratio:


7. Mixed Precision Training

7.1 FP8ScaleManager

FP8ScaleManager tracks per-tensor absolute maximums and updates dynamic scales for FP8 forward and backward passes:

Tensor direction
FP8 format
Max representable value

Forward activations

E4M3

448.0

Backward gradients

E5M2

57344.0

7.2 LossScaler — Dynamic Loss Scaling

LossScaler prevents underflow in FP16/BF16 training by scaling the loss up before the backward pass and scaling gradients back down before the optimizer step:

7.3 Gradient Checkpointing

Gradient checkpointing trades compute for memory by not storing all intermediate activations during the forward pass. Activations are recomputed during the backward pass as needed:

7.4 LossScaleConfig — TrainingConfig Integration (ADR 0057)

The core of the mixed precision system is LossScaleConfig, which is embedded directly in TrainingConfig. Three modes are available:

Mode
Behaviour

NONE

No loss scaling (default; pure FP32 training)

STATIC

Fixed scale factor; use when you already know a safe scale for your model

DYNAMIC

Adaptive scaling that automatically grows on stable steps and backs off on overflow

TrainingConfig carries two additional data-type fields:

  • computeDataType — the dtype used for forward and backward passes (e.g., FLOAT16 or BFLOAT16)

  • masterWeightDataType — the dtype used to store the authoritative weight copy (almost always FLOAT)

For a known-stable scale (e.g., after a dry-run sweep), use static mode:

A convenience factory method covers the most common case:

7.5 Gradient Accumulation via TrainingConfig (ADR 0057)

Gradient accumulation is configured directly on TrainingConfig via gradientAccumulationSteps. Gradients are always accumulated in FP32 regardless of computeDataType, which prevents precision loss when summing many small gradients:

The GradientAccumulator (see section 6.3) is used by SFTTrainingPipeline internally when gradientAccumulationSteps > 1. It stores accumulated gradients per named variable and averages them before applying the optimizer update. You may also use it directly in a custom training loop (see section 6.3).

Data type memory tradeoffs (for reference):

Component
FP32-only
Mixed Precision (FP16 compute)

Weights

W bytes

W/2 (FP16) + W (master FP32) = 1.5W

Gradients

W bytes

W/2 bytes

Optimizer state (Adam)

2W bytes

2W bytes

Activations

A bytes

A/2 bytes

For models where activations dominate GPU memory (most large transformers), mixed precision provides a significant net reduction despite the FP32 master weight copy.


8. 8-bit Adam Optimizer

Adam8bit stores the first and second moment vectors (m and v) in INT8 with per-block absolute maximum quantization, reducing optimizer state memory by approximately 4x:

Precision
Memory for 7B parameter model

BF16 Adam (standard)

~56 GB optimizer state

Adam8bit

~14 GB optimizer state

Default block size is 2048 elements per quantization block (DEFAULT_BLOCK_SIZE = 2048).

Internally, Adam8bitUpdater performs per-block updates:

  1. Dequantize INT8 m and v blocks to float using stored absmax values

  2. Apply the standard Adam moment update in float

  3. Compute the parameter update

  4. Requantize updated m and v back to INT8

BlockQuantizationUtils provides the low-level INT8 quantize/dequantize operations used by the updater.


9. Knowledge Distillation

DistillationTrainer trains a smaller student model to mimic a larger teacher model. Three loss components are available and can be combined:

Loss Class
What It Minimizes

DistillationKLLoss

KL divergence between teacher and student output distributions at temperature T

AttentionDistillationLoss

MSE between teacher and student attention weight matrices

FeatureDistillationLoss

MSE between intermediate hidden state representations

The temperature parameter scales logits before the softmax: higher values produce softer probability distributions that expose more information about inter-class similarities.

Alternatively, use the SameDiff extension:

9.1 Native Distillation Loss Ops (ADR 0077)

Each of the three Java loss classes is backed by a C++ op (CPU and CUDA) registered in libnd4j. You can invoke them directly via SameDiff if you want to compose a custom distillation loss:

Op Name
SameDiff call
Formula

distillation_kl_loss

sd.math.distillationKLLoss(student, teacher, labels, T, alpha)

alpha * T^2 * KL(softmax(s/T) || softmax(t/T)) + (1-alpha) * CE(s, labels)

feature_distillation_loss

sd.math.featureDistillationLoss(studentHidden, teacherHidden)

MSE(projection(studentHidden), teacherHidden)

attention_distillation_loss

sd.math.attentionDistillationLoss(studentAttn, teacherAttn)

MSE(studentAttn, teacherAttn) with head-count alignment

Each op ships with a gradient (backward) implementation so they participate automatically in sd.execBackwards().

Example — custom combined loss in a SameDiff graph:

9.2 Self-Distillation with EMA Teacher

DistillationTrainer also supports self-distillation, where the teacher is an Exponential Moving Average (EMA) of the student's own weights. This stabilises training when no external large teacher is available:


10. Dataset Curation Toolkit

The dataset curation package provides 20 utilities for preparing high-quality training data.

10.1 Deduplication

TextDeduplicator uses MinHash Locality-Sensitive Hashing to detect and remove near-duplicate documents efficiently:

10.2 Benchmark Contamination Removal

NGramDecontaminator removes documents containing n-gram overlaps with benchmark evaluation sets:

10.3 Quality Filtering

TextQualityFilter applies heuristics to remove low-quality text:

10.4 Curriculum Learning

CurriculumIterator wraps a dataset iterator and yields examples in order of difficulty, starting with easier examples and progressing to harder ones:

10.5 Sequence Packing

SequencePacker bin-packs variable-length sequences into fixed-size windows, minimizing padding tokens and maximizing GPU utilization:

10.6 Domain Mixing

WeightedDataMixer samples from multiple domain iterators with configurable weights:

10.7 Padding-Free Batching

LengthBucketingIterator groups sequences into length buckets before batching, reducing within-batch padding. PaddingFreeBatch represents a batch where all padding has been eliminated by packing:

10.8 Instruction Formatting and Chat Templates

InstructionDataFormatter and ChatTemplate apply model-specific chat templates to raw instruction datasets:

10.9 Stratified Splitting

StratifiedSplitter creates train/validation/test splits that preserve category distributions:

10.10 Package Reference and Full Class List

All curation classes live under org.nd4j.linalg.dataset.curation in the nd4j-api artifact, not org.deeplearning4j.data. Use these imports in your code:

Sub-package
Classes

.dedup

MinHasher, TextDeduplicator

.decontamination

NGramDecontaminator, DecontaminationResult

.curriculum

CurriculumIterator, DifficultyScorer

.packing

SequencePacker, PackedSequence

.mixing

WeightedDataMixer

.batching

LengthBucketingIterator, PaddingFreeBatch, PaddingFreeBatchCollator

.filtering

TextQualityFilter, FilterResult

.format

ChatTemplate, InstructionDataFormatter, ConversationTurn, ConversationExtension, FormattedExample

.splitting

StratifiedSplitter, SplitResult

(top-level)

RawTextDatasetIterator, TokenizedTextDataIterator

The correct imports for the examples in sections 10.1–10.9 follow this pattern:

MinHasher constructor signature (exact from source):

NGramDecontaminator works in two steps — index benchmarks first, then decontaminate:

CurriculumIterator API (exact from source):

SequencePacker uses First-Fit Decreasing bin packing and produces block-diagonal attention masks (one block per packed document) to prevent cross-document attention leakage:

WeightedDataMixer is a generic Iterator<T> that accepts any Iterator<T> sources. It supports optional temperature scaling (values < 1 sharpen the distribution toward the highest-weight source; values > 1 flatten it):


11. Transfer Learning API

The classical transfer learning API (TransferLearning / TransferLearningHelper) applies to MultiLayerNetwork and ComputationGraph models. For large generative models, prefer the PeftModel API described in sections 3–4.

11.1 Freeze Layers by Name Pattern

11.2 SameDiff-Based Freezing

For SameDiff models, freeze parameters by converting them to constants:

11.3 TransferLearningHelper — Pre-computed Feature Cache

For large frozen feature extractors, pre-computing activations at the freeze boundary dramatically reduces training time:


12. Configuration Reference

LoraConfig

Parameter
Type
Default
Description

r

int

8

Adapter rank

loraAlpha

int

16

Scaling numerator; effective_scale = loraAlpha / r

loraDropout

double

0.0

Dropout on adapter input

targetModules

List<String>

[]

Layer name substrings to target

bias

String

"none"

Which bias vectors to train: "none", "all", "lora_only"

initLoraWeights

String

"kaiming_uniform"

Init strategy: "kaiming_uniform", "gaussian", "pissa", "olora"

loraLrRatioB

double

1.0

LR multiplier for B matrix relative to A matrix (LoRA+ feature)

useRsLora

boolean

false

Use rank-stabilized scaling α/√r instead of α/r

VeraConfig

Parameter
Type
Default
Description

projectionRank

int

64

Rank of the shared random projection matrices

targetModules

List<String>

[]

Layer name substrings to target

loraDropout

double

0.0

Dropout applied to the adapter path

DyLoraConfig

Parameter
Type
Default
Description

r

int

16

Maximum rank (upper bound of dynamic range)

minRank

int

1

Minimum rank sampled during training

loraAlpha

int

16

Scaling factor

targetModules

List<String>

[]

Layer name substrings to target

LossScaleConfig

Parameter
Type
Default
Description

mode

Mode

NONE

NONE, STATIC, or DYNAMIC

initialScale

double

65536.0

Starting loss scale (2^16)

minScale

double

1.0

Floor for dynamic scaling

maxScale

double

65536.0

Ceiling for dynamic scaling

growthFactor

double

2.0

Multiplier applied to scale after stable run

backoffFactor

double

0.5

Multiplier applied to scale on overflow

growthInterval

int

2000

Consecutive finite-gradient steps before scale grows

GRPOConfig

Parameter
Type
Default
Description

groupSize

int

8

Completions generated per prompt

clipEpsilon

double

0.2

Policy ratio clipping threshold

klCoeff

double

0.04

KL divergence penalty weight

maxNewTokens

int

256

Maximum tokens generated per completion

temperature

double

1.0

Sampling temperature

SFTConfig

Parameter
Type
Default
Description

maxSeqLength

int

2048

Maximum input sequence length

batchSize

int

8

Micro-batch size per step

gradientAccumulationSteps

int

1

Steps before optimizer update

numEpochs

int

3

Training epochs

learningRate

double

2e-4

Peak learning rate

warmupSteps

int

0

Linear warmup steps

saveEveryNSteps

int

500

Checkpoint frequency

FP8ScaleManager

Parameter
Type
Default
Description

rollingWindowSize

int

16

Steps in the rolling absmax window

forwardFormat

FP8Format

E4M3

FP8 format for forward activations

backwardFormat

FP8Format

E5M2

FP8 format for backward gradients

forwardMaxValue

double

448.0

Saturation value for E4M3

backwardMaxValue

double

57344.0

Saturation value for E5M2

LossScaler

Parameter
Type
Default
Description

initialScale

double

65536.0

Starting loss scale

scaleWindow

int

2000

Steps before doubling the scale

scaleFactor

double

2.0

Factor used to halve (on overflow) or double

Adam8bit

Parameter
Type
Default
Description

lr

double

1e-3

Learning rate

beta1

double

0.9

First moment decay

beta2

double

0.999

Second moment decay

epsilon

double

1e-8

Numerical stability constant

blockSize

int

2048

Elements per quantization block

DistillationConfig

Parameter
Type
Default
Description

temperature

double

4.0

Softmax temperature for teacher logits

klLossWeight

double

1.0

Weight for KL divergence loss component

attentionLossWeight

double

0.0

Weight for attention map distillation

featureLossWeight

double

0.0

Weight for hidden state distillation

hardLabelWeight

double

0.0

Weight for ground-truth cross-entropy


See Also

Last updated

Was this helpful?