Table of Contents

Class LoraFinetuning

Namespace
LMKit.Finetuning
Assembly
LM-Kit.NET.dll

Fine-tunes a base model with the LoRA (Low-Rank Adaptation) technique, producing a small adapter or a merged model, entirely on the local machine.

public sealed class LoraFinetuning : IDisposable
Inheritance
LoraFinetuning
Implements
Inherited Members

Examples

using LMKit.Model;
using LMKit.Finetuning;
using LMKit.TextGeneration.Chat;

LM model = LM.LoadFromModelID("qwen3.5:0.8b");

using var finetuning = new LoraFinetuning(model);
finetuning.Parameters.Rank = 8;
finetuning.Parameters.Epochs = 3;
finetuning.Parameters.LearningRate = 2e-4f;

finetuning.FinetuningProgress += (s, e) =>
    Console.WriteLine($"epoch {e.Epoch + 1}/{e.TotalEpochs}  step {e.Step}/{e.TotalSteps}  loss {e.Loss:F4}");

var data = new ChatHistory(model);
data.AddMessage(AuthorRole.User, "Who are you?");
data.AddMessage(AuthorRole.Assistant, "I am a local assistant running entirely on your machine.");
finetuning.AddTrainingData(data);

finetuning.TrainToAdapter("my-adapter.gguf");

Remarks

LoRA freezes the base weights and trains a small pair of low-rank matrices on the selected modules, which makes it possible to adapt large models on consumer hardware. Training runs on the same GGUF model files used for inference and produces GGUF artifacts: an adapter that can be applied at load time, or a merged model.

Typical workflow

  1. Create a LoraFinetuning over a base model.
  2. Configure Parameters (rank, target modules, epochs, learning rate).
  3. Load training data with AddTrainingData(ChatHistory) or AddRawText(string).
  4. Subscribe to FinetuningProgress for live loss and accuracy.
  5. Call TrainToAdapter(string) or TrainToModel(string, float).

Constructors

LoraFinetuning(LM)

Initializes a new fine-tuning engine over an already-loaded model.

LoraFinetuning(string)

Initializes a new fine-tuning engine, loading the base model from a file path.

Properties

CheckpointDirectory

Directory where step checkpoints are written when CheckpointSaveSteps is positive. A checkpoint holds the adapter, optimizer state, and metadata for resuming.

CheckpointSaveSteps

Save a checkpoint every N optimizer steps. 0 (the default) disables checkpointing.

ContextSize

Token window used to build training samples. Samples longer than this are skipped. Defaults to the model's context length capped at 2048.

MicroBatchSize

Tokens evaluated per training micro-batch. Activation memory scales linearly with this, so it is the first lever when a run does not fit device memory; larger values run faster when memory allows. 0 (the default) picks 512 or 256 to divide the window. The value snaps down to the nearest power of two that divides the resolved window.

Parameters

Training hyperparameters. Configure before calling a training method.

ResolvedWindow

The training window the run resolved (tokens per training sequence): the explicit ContextSize, or the data-sized window. Set when training starts; 0 before that.

ResumeOptimizerPath

Path of a checkpoint's optimizer state file to resume from. The runtime restores the optimizer moments and the adapter weights the checkpoint captured, validating that the adapter identity (rank, alpha, target modules) matches this run's parameters. Null or empty (the default) starts a fresh run.

ResumeStep

Global optimizer step the resumed run continues from, as recorded by the checkpoint being restored. Ignored when ResumeOptimizerPath is not set.

SampleCount

Number of training samples currently loaded.

SampleMaxLength

Length, in tokens, of the longest loaded sample.

SampleMinLength

Length, in tokens, of the shortest loaded sample.

UnmaskedSampleCount

Number of chat samples whose assistant span could not be located, so the whole sample was supervised instead. A non-zero value while AssistantLossOnly is enabled signals a chat-template mismatch: masking degraded to full-sequence loss on those samples, which weakens instruction tuning.

Methods

AddDataset(TrainingDataset)

Adds every sample from a TrainingDataset (chat conversations and raw-text samples), loaded from any supported file format or archive.

AddDatasetFile(string)

Loads a dataset file (JSONL, ShareGPT, Alpaca, plain text, or a ZIP archive of these) and adds all of its samples. Format is auto-detected.

AddRawText(string)

Adds a single raw-text sample, tokenized as-is, with every token supervised. Use for continued-pretraining-style data.

AddTrainingData(ChatHistory)

Adds a conversation to the training set. Assistant turns are supervised; system and user turns are masked when AssistantLossOnly is enabled. Use BeginOfNewConversation markers to pack several conversations into one history.

ClearTrainingData()

Removes all loaded training samples.

CountSamplesLongerThan(int)

Number of loaded samples whose token length exceeds tokenCount. Samples longer than the training window are skipped at training time, so this is the count a given window (or cutoff) would leave out.

Dispose()

Releases the engine and, if it owns the model, the model.

RequestStop()

Requests a cooperative stop of the in-progress training run. Training halts after the current batch; the adapter trained so far is saved.

TrainToAdapter(string)

Runs fine-tuning and writes the trained LoRA adapter as a GGUF file.

TrainToModel(string, float)

Runs fine-tuning, then merges the trained adapter into the base model and writes the result as a standalone GGUF model.

TrySaveAdapterSnapshot(string)

Saves the adapter's CURRENT weights to a GGUF file while training runs. Valid only from inside a FinetuningProgress handler (the trainer's own thread, between steps), which is exactly where best-checkpoint policies live. Returns false outside a run.

Events

FinetuningProgress

Raised after every optimizer step and validation batch with live metrics. Set Stop to request a cooperative stop.

Share