C · Training

Training

#include <uform/train.h> 4.0.0-rc.1 · 3ee5e534

Training is GPU-only. uform_mesh_bootstrap joins this process to a run once, through files in a directory every host sees, and after it processes talk only over NVLink and InfiniBand. The mesh is the process-wide half of the transport, which every trainer borrows; uform_mesh_describe reports the topology every process agreed on, its multimem tier, and the gpu_class every GPU of the run dispatches as, the executor’s pin or the devices’ own. Every process bootstraps with the same count, multicast extent, directory, job and GPU class, or the call reports uform_status_config_mismatch_k.

uform_trainer_init_vram makes a trainer on a VRAM executor, owning one replica of the tower per device, its gradients, the Adafactor moments, the reconstruction heads and the learnable temperatures. One uform_trainer_step is one optimizer step over this process’s share of the global batch: forward, the losses, backward, the world gradient reduction, and the update. Items arrive tagged with a uform_modality_t, grouped into bags that travel together, with attract, repel and ignore relations indexing the step’s own items. Beside the masked and pooled contrastive losses, a trainer relaxes two optional terms, each read when its weight is positive:

  • late_interaction trains the token head with hard MaxSim scores between the items each step’s sides names a query, a document or both.
  • choices trains the byte decoder on the legal bytes each step’s choices tape gives, the tape uform_text_choose reads, and their target probabilities in the choice_targets tape, shaped as the probabilities it lands, within the batch’s max_choices_per_item.

uform_pair_loss_form_t picks how a contrastive term turns a row of scores into forces: balanced, ranked or SigLIP’s sigmoid, where derived keeps sigmoid for pooled embeddings and ranked for token vectors. The step’s stats report every loss as its world mean, with late_interaction_loss and choices_loss beside the contrastive and masked terms, the items truncated at a row’s width, and the segments dropped whole for want of room. A training call that fails after a GPU recorded a fault, such as a peer missing a multimem barrier or an InfiniBand round past its deadline, carries that fault as its outcome message. uform_trainer_save writes the safetensors checkpoint the model verbs load. Every path, the mesh’s directory, a resume checkpoint and a save’s path, arrives as the operating system’s own bytes, not necessarily UTF-8, and one holding a NUL byte is refused with uform_status_invalid_argument_k; the mesh’s job is a UTF-8 name.

uform_mesh_t mesh = NULL;
uform_mesh_bootstrap(&(uform_mesh_bootstrap_t){.mesh = &mesh, .executor = executor, .outcome = &outcome,
    .options = {.host_domain_index = node, .host_domain_count = nodes, .directory = {exchange, exchange_length},
                .job = {job, job_length}}});
uform_trainer_t trainer = NULL;
uform_trainer_init_vram(&(uform_trainer_init_vram_t){
    .trainer = &trainer, .executor = executor, .outcome = &outcome, .mesh = mesh, .depth = 12, .hidden = 512,
    .batch = {.max_rows_per_device = 64, .max_segments_per_device = 256, .max_columns_per_row = 1024,
              .max_bags_per_device = 128, .image = {.patch_side = 16}},
    .objective = uform_objective_joint_k, .schedule = {.steps = 100000}, .seed = 42});

API

Types

uform_modality_tWhat the bytes of one training item hold, in the order the engine packs a batch.
train.h:82 ↗
enum uform_modality_t

Values

uform_modality_text_k0UTF-8 text, a byte per token.
uform_modality_image_k1A JPEG, PNG or WebP file.
uform_modality_video_k2An MP4 or WebM file.
uform_modality_audio_k3A WAV, FLAC, MP3 or Opus file.

Spellings

char const * uform_modality_name(uform_modality_t modality);
uform_modality_t uform_modality_from_name(uform_bytes_view_t name);
uform_image_shape_tThe image slice of a batch envelope; a zero patch_side leaves images out of the run.
train.h:104 ↗
struct uform_image_shape_t

Fields

patch_sidesize_tThe square patch side images tile into, in pixels.
channelssize_tChannels every pixel carries; zero derives four, RGBA end to end.
uform_video_shape_tThe video slice of a batch envelope; a zero patch_side leaves video out of the run.
train.h:114 ↗
struct uform_video_shape_t

Fields

patch_sidesize_tThe square patch side one tube tiles into, in pixels.
tube_framessize_tFrames one tube folds ahead of its patch; zero derives two.
frame_stridesize_tSource frames between sampled ones; zero derives one, every frame.
channelssize_tChannels every pixel carries; zero derives three.
uform_audio_shape_tThe audio slice of a batch envelope; a zero chunk_samples leaves audio out of the run.
train.h:130 ↗
struct uform_audio_shape_t

Fields

chunk_samplessize_tRaw samples per frame, the fan-in of the learned frontend.
sample_ratesize_tThe mono rate every recording is resampled to; zero derives 16000.
uform_batch_shape_tWhat one device's step carries at most, whatever the modality mix: capacity fixed at creation, with padding through the data.
train.h:142 ↗
struct uform_batch_shape_t

Text always takes part; a media modality takes part when its slice is live.

Fields

max_rows_per_devicesize_tRows one device's step packs.
max_segments_per_devicesize_tItems one device's step carries across all its rows, which is also its pooling axis.
max_columns_per_rowsize_tPositions one row spans, the sequence length.
max_bags_per_devicesize_tBags one device's step carries; zero keeps every item its own routing unit.
max_choices_per_itemsize_tLegal bytes one item offers to choose from at most; zero makes no choices.
imageuform_image_shape_tThe image geometry.
videouform_video_shape_tThe video geometry.
audiouform_audio_shape_tThe audio geometry.
uform_objective_tWhich losses a step relaxes, one enumerator per combination the engine trains.
train.h:170 ↗
enum uform_objective_t

Values

uform_objective_masked_k0Masked reconstruction alone, as the Base pretrains.
uform_objective_contrastive_k1The pairwise contrastive loss alone, as the Embedder trains.
uform_objective_joint_k2Both, joined at the final-norm states.

Spellings

char const * uform_objective_name(uform_objective_t objective);
uform_objective_t uform_objective_from_name(uform_bytes_view_t name);
uform_masking_tHow the masked objective corrupts a batch and weighs its heads; every zero derives the default named.
train.h:190 ↗
struct uform_masking_t

Fields

token_mask_probabilityfloatFraction of text positions covered by spans; 0.15.
token_mean_spanfloatMean geometric span length in bytes; 16.
replace_fractionfloatOf covered positions, the share shown as MASK; 0.8.
random_fractionfloatOf covered positions, the share replaced by a random byte, the rest kept clean; 0.1.
image_mask_ratiofloatFraction of image patches masked; 0.75.
video_mask_ratiofloatFraction of video tubes masked, tubed across time; 0.75.
audio_mask_ratiofloatFraction of audio frames masked; 0.75.
text_weightfloatThe weight λ of the text head; 1.
image_weightfloatThe weight λ of the image head; 1.
video_weightfloatThe weight λ of the video head; 1.
audio_weightfloatThe weight λ of the audio head; 1.
uform_negatives_tWhich pairs the contrastive loss pushes apart.
train.h:227 ↗
enum uform_negatives_t

Values

uform_negatives_ambient_k0Repel edges, and every pair no edge names, at ambient_repulsion_weight.
uform_negatives_named_k1Repel edges alone.

Spellings

char const * uform_negatives_name(uform_negatives_t negatives);
uform_negatives_t uform_negatives_from_name(uform_bytes_view_t name);
uform_pair_loss_form_tHow a contrastive term turns a row of scores into forces, mirroring the trainer's pair-loss forms; zero keeps the term's own form: sigmoid for pooled vertices, ranked for token vectors.
train.h:244 ↗
enum uform_pair_loss_form_t

Values

uform_pair_loss_form_derived_k0The term's own form.
uform_pair_loss_form_balanced_k1The sigmoid cross-entropy of every cell, its attract and repel halves normalized apart.
uform_pair_loss_form_ranked_k2The sigmoid cross-entropy of every positive's score over every negative's, where the bias cancels.
uform_pair_loss_form_sigmoid_k3SigLIP's sigmoid cross-entropy of every cell, each repel weighed like an attract.
uform_contrastive_tHow the contrastive loss scores the pooled embeddings; every zero derives the default named.
train.h:261 ↗
struct uform_contrastive_t

Fields

matryoshka_dimensionssize_t const *The optional Matryoshka prefix widths, strictly ascending, each a multiple of 8, at most 8 of them, every one scored; NULL scores the full width alone.
matryoshka_dimensions_countsize_tEntries in matryoshka_dimensions.
temperature_groupssize_tLearnable (inverse temperature, bias) pairs, one per group a step's items select; one.
inverse_temperaturefloatThe starting inverse temperature of every group; 10 under the sigmoid form, SigLIP's, else 1.
biasfloatThe starting logit bias of every group; −10 under the sigmoid form, SigLIP's, else zero.
negativesuform_negatives_tWhich pairs repel.
ambient_repulsion_weightfloatThe weight of every pair no edge names, under uform_negatives_ambient_k; 1.
max_edges_per_devicesize_tEdges one device's step names per edge set at most; zero derives it from the segments and the largest bag.
pair_lossuform_pair_loss_form_tThe pair loss over each anchor's row; sigmoid.
uform_late_interaction_tHow the late-interaction loss scores the per-token vectors of query and document segments; every zero derives the default named.
train.h:296 ↗
struct uform_late_interaction_t

Fields

weightfloatThe loss weight; zero trains no token head.
widthsize_tThe token vectors' width, a multiple of 8; 128.
inverse_temperaturefloatThe starting inverse temperature of every contrastive group; 1.
biasfloatThe starting logit bias of every contrastive group; zero is zero.
max_query_spansize_tTokens one query segment contributes at most, its first past the prefix; 64.
max_query_tokens_per_devicesize_tQuery token rows one device's step holds at most; max_query_span of every segment.
max_documents_per_devicesize_tDocument segments one device's step holds at most; max_segments_per_device.
max_document_tokens_per_devicesize_tDocument token rows one device's step holds at most; the batch's tokens per device.
pair_lossuform_pair_loss_form_tThe pair loss over each query's row of hard MaxSim scores; ranked.
uform_late_interaction_side_tWhich side of a late-interaction score an item takes, mirroring the trainer's sides: a query's tokens score a document's, and a symmetric pair plays both.
train.h:328 ↗
enum uform_late_interaction_side_t

Values

uform_late_interaction_side_none_k0The item takes no part in late interaction.
uform_late_interaction_side_query_k1The item's tokens score the documents it attracts and repels.
uform_late_interaction_side_document_k2The item's tokens are scored by the queries naming it.
uform_late_interaction_side_query_and_document_k3The item plays both sides.
uform_schedule_tThe learning-rate schedule: a linear warmup to the peak, then a cosine decay to the floor.
train.h:357 ↗
struct uform_schedule_t

Fields

learning_ratefloatThe peak learning rate; zero derives 5e-4.
min_learning_ratefloatThe floor the cosine settles at; zero derives 1e-5.
warmup_stepssize_tSteps from zero to the peak; zero derives a tenth of steps, at most 400.
stepssize_tSteps the run takes across resumes, which the cosine spans; zero is refused.
uform_trainer_tA training run: the tower replicas, gradients, optimizer moments, heads, temperatures and the collectives sized by them, on the executor's devices.
train.h:499 ↗
typedef struct uform_trainer_handle_t * uform_trainer_t;
uform_edges_view_tOne edge set over a step's items, as compressed sparse rows.
train.h:567 ↗
struct uform_edges_view_t

Fields

offsetssize_t const *The step's count + 1 non-decreasing offsets into ids, in host memory; NULL names no edges.
idsuint32_t const *Item i links to items ids[offsets[i]] up to ids[offsets[i+1]], indices into the step's items, ascending within each run.
weightsfloat const *The optional weight of each edge, paired with ids; NULL weighs every edge one.
uform_relations_view_tThe contrastive targets of one step, resolved per pair in this order: a pair ignore names is skipped, one attract names pulls together, one repel names pushes apart, and every other pair follows the run's negatives.
train.h:584 ↗
struct uform_relations_view_t

Fields

attractuform_edges_view_tPairs pulled together.
repeluform_edges_view_tPairs pushed apart.
ignoreuform_edges_view_tPairs skipped, like known false negatives; weights is not read.
uform_trainer_step_stats_tWhat a step reports, every loss its world mean.
train.h:597 ↗
struct uform_trainer_step_stats_t

Fields

stepsize_tThe optimizer step the call applied, counted from one across resumes.
learning_ratefloatThe learning rate it applied.
lossfloatThe total loss the step minimized.
contrastive_lossfloatThe contrastive term; zero when the objective is masked alone.
masked_text_lossfloatThe text reconstruction term, before its weight; zero when absent.
masked_image_lossfloatThe image reconstruction term, before its weight; zero when absent.
masked_video_lossfloatThe video reconstruction term, before its weight; zero when absent.
masked_audio_lossfloatThe audio reconstruction term, before its weight; zero when absent.
late_interaction_lossfloatThe late-interaction term, weighted; zero when absent.
choices_lossfloatThe choices term over the items that made a choice, before its weight; zero when absent.
truncatedsize_tItems cut at a row's width.
droppedsize_tSegments dropped whole because the batch had no room for them, since the last step that read its stats.

Functions

uform_trainer_init_vramBuilds one replica per device, the NVLink domain its consumers reserve over the mesh, and starts or resumes the run; every process of the run calls it with the same geometry, objective and seed.
train.h:564 ↗
void uform_trainer_init_vram(uform_trainer_init_vram_t *arguments);

Parameters

traineruform_trainer_t *Output for the new trainer, written once the call completes.
executoruform_executor_tA VRAM executor, every device of which holds one replica.
outcomeuform_outcome_t *Output for the outcome, final once its status leaves uform_status_deferred_k.
completionuform_completion_tWhether the call blocks or returns once queued; zero blocks.
resumeuform_bytes_view_tThe optional path of the checkpoint to continue from, at its saved step; empty starts from seed.
depthsize_tTransformer blocks stacked.
hiddensize_tEmbedding width, a multiple of 128.
batchuform_batch_shape_tWhat one device's step carries at most.
objectiveuform_objective_tWhich losses a step relaxes.
maskinguform_masking_tThe masked objective's corruption and weights, read unless the objective is contrastive alone.
contrastiveuform_contrastive_tThe contrastive loss's scoring, read unless the objective is masked alone.
late_interactionuform_late_interaction_tThe late-interaction loss beside the pooled one, read when its weight is positive.
choicesuform_choices_tThe calibrated choices beside every other term, read when its weight is positive, which needs the batch's max_choices_per_item.
scheduleuform_schedule_tThe learning-rate schedule.
meshuform_mesh_tThe optional mesh, borrowed until the trainer is freed and made over this same executor; NULL runs this process alone.
seeduint64_tThe base of every keyed draw: initialization, corruption and the shuffle.
progressuform_progress_tThe optional handler, called with tensors placed on a resume.
uform_trainer_stepApplies one optimizer step over this process's items and every peer's; every process of the run calls it once per step.
train.h:709 ↗
void uform_trainer_step(uform_trainer_step_t *arguments);

Parameters

traineruform_trainer_tThe run to advance.
executoruform_executor_tThe executor the trainer was created on.
outcomeuform_outcome_t *Output for the outcome, final once its status leaves uform_status_deferred_k.
completionuform_completion_tWhether the call blocks or returns once queued; zero blocks.
countsize_tItems in this process's share of the step; more than its devices' envelopes hold reports uform_status_shape_mismatch_k.
modalitiesuform_modality_t const *The modality of each item, count of them in host memory; a modality the run left out reports uform_status_unsupported_k.
contentsuform_tape_view_tThe items' bytes, one entry each, of uform_scalar_u8_k: UTF-8 text or an encoded file, as modalities tags it.
bagsuint32_t const *The optional bag of each item, count of them in host memory; items sharing a bag land on one device.
temperature_groupsuint32_t const *The optional temperature group of each item, count of them in host memory, each below the run's temperature_groups; NULL puts every item in group zero.
sidesuform_late_interaction_side_t const *The optional late-interaction side of each item, count of them in host memory; NULL makes every item uform_late_interaction_side_none_k.
choicesuform_tape_view_tThe optional legal choices of each item, one byte each, uform_scalar_u8_k, as uform_text_choose_t reads them; NULL offsets make no choices, and an item offering none makes none.
choice_targetsuform_tape_view_tThe target probability of each choice, uform_scalar_f32_k, in choices order, as uform_text_choose_t lands its probabilities: each item's entry as long as its entry of choices, summing to one.
relationsuform_relations_view_tThe contrastive targets, read unless the objective is masked alone; a contrastive step naming no attract edge reports uform_status_invalid_argument_k.
embeddingsuform_rows_view_t *The optional output for the pooled embedding of every item, as the contrastive loss scored it before the update, inside arena; NULL skips the copy.
arenauform_arena_tMemory for embeddings, rewound by the call.
outputs_scalaruform_scalar_tThe scalar type embeddings lands as.
statsuform_trainer_step_stats_t *The optional report; NULL skips it, and with it the readback of the losses.
uform_trainer_saveWrites the weights and the step, which uform_model_load_vram and its siblings serve and uform_trainer_init_vram resumes; only the process of index zero writes, the rest return at once.
train.h:736 ↗
void uform_trainer_save(uform_trainer_save_t *arguments);

Parameters

traineruform_trainer_tThe run to save.
executoruform_executor_tThe executor the trainer was created on.
outcomeuform_outcome_t *Output for the outcome, final once its status leaves uform_status_deferred_k.
completionuform_completion_tWhether the call blocks or returns once queued; zero blocks.
pathuform_bytes_view_tDestination path of the safetensors checkpoint, written whole and renamed into place.
progressuform_progress_tThe optional handler, called with tensors written.
uform_trainer_freeFrees a trainer and leaves the mesh; NULL is safe, and it cannot fail, so takes no outcome.
train.h:740 ↗
void uform_trainer_free(uform_trainer_t trainer);

Every call using it must be final.