Python · Training

Training

import uformfrom uform import ImageShape, VideoShape, AudioShape, … 4.0.0-rc.1 · 3ee5e534

Training is GPU-only. The configuration arrives as keyword-built structures mirroring the C ones field by field, so a field left out is zero, which the library derives:

executor = uform.Executor.for_vram(devices=[0, 1])
mesh = uform.Mesh.bootstrap(executor, uform.MeshOptions(host_domain_index=rank, host_domain_count=nodes,
                                                        directory="/shared/exchange", job="run-17"))
trainer = uform.Trainer.init_vram(executor, mesh=mesh, depth=12, hidden=512, objective=uform.Objective.JOINT,
                                  batch=uform.BatchShape(max_rows_per_device=64, max_segments_per_device=256,
                                                         max_columns_per_row=1024, max_bags_per_device=128,
                                                         image=uform.ImageShape(patch_side=16)),
                                  schedule=uform.Schedule(steps=100_000), seed=42)
stats = uform.TrainerStepStats()
trainer.step(modalities, contents, bags=bags, relations=uform.Relations(attract=(offsets, ids)), stats=stats)
trainer.save("checkpoint.safetensors")

BatchShape nests an ImageShape, a VideoShape and an AudioShape, each also taken as a tuple of its fields in order. Masking, Contrastive, LateInteraction, Choices and Schedule configure the objectives, and Relations holds three Edges sets of buffers: size_t offsets, uint32 IDs and optional float32 weights. Contrastive and LateInteraction take a uform.PairLossForm, and trainer.step takes each item’s uform.LateInteractionSide as sides. choices, taken as text_choose takes them, and choice_targets, a float32 tape shaped as the RowsTape it answers, train the calibrated choices within the batch’s max_choices_per_item, so (probabilities, probabilities.offsets) from one model can train another. Paths, like the mesh’s directory, cross as os.fsencode gives their bytes, while its job is a str name. trainer.step answers the pooled embeddings the loss scored when given an arena, and None otherwise. mesh.describe() answers a uform.MeshDescription, its multimem_tier a uform.MultimemTier and its gpu_class the uform.GPUClass every GPU of the run dispatches as.

API

Types

ModalityWhat the bytes of one training item hold, valued as uform_modality_t.
__init__.py:184 ↗
class Modality(IntEnum)

Values

TEXT0
IMAGE1
VIDEO2
AUDIO3
ObjectiveWhich losses a training step relaxes, valued as uform_objective_t.
__init__.py:192 ↗
class Objective(IntEnum)

Values

MASKED0
CONTRASTIVE1
JOINT2
NegativesWhich pairs the contrastive loss pushes apart, valued as uform_negatives_t.
__init__.py:199 ↗
class Negatives(IntEnum)

Values

AMBIENT0
NAMED1
PairLossFormHow a contrastive term turns a row of scores into forces, valued as uform_pair_loss_form_t.
__init__.py:205 ↗
class PairLossForm(IntEnum)

Values

DERIVED0
BALANCED1
RANKED2
SIGMOID3
LateInteractionSideWhich side of a late-interaction score an item takes, valued as uform_late_interaction_side_t.
__init__.py:213 ↗
class LateInteractionSide(IntEnum)

Values

NONE0
QUERY1
DOCUMENT2
QUERY_AND_DOCUMENT3
ClassImageShapeThe image slice of a BatchShape; a zero patch_side leaves images out of the run.3
lib.pyi:707 ↗
class ImageShape
ImageShape
lib.pyi:713 ↗
ImageShape(*, patch_side: int = 0, channels: int = 0)
patch_side
lib.pyi:711 ↗
patch_side: Final[int]
channels
lib.pyi:712 ↗
channels: Final[int]
ClassVideoShapeThe video slice of a BatchShape; a zero patch_side leaves video out of the run.5
lib.pyi:715 ↗
class VideoShape
VideoShape
lib.pyi:723 ↗
VideoShape(
    *,
    patch_side: int = 0,
    tube_frames: int = 0,
    frame_stride: int = 0,
    channels: int = 0,
)
patch_side
lib.pyi:719 ↗
patch_side: Final[int]
tube_frames
lib.pyi:720 ↗
tube_frames: Final[int]
frame_stride
lib.pyi:721 ↗
frame_stride: Final[int]
channels
lib.pyi:722 ↗
channels: Final[int]
ClassAudioShapeThe audio slice of a BatchShape; a zero chunk_samples leaves audio out of the run.3
lib.pyi:727 ↗
class AudioShape
AudioShape
lib.pyi:733 ↗
AudioShape(*, chunk_samples: int = 0, sample_rate: int = 0)
chunk_samples
lib.pyi:731 ↗
chunk_samples: Final[int]
sample_rate
lib.pyi:732 ↗
sample_rate: Final[int]
ClassBatchShapeWhat one device's step carries at most, whatever the modality mix, fixed at creation.9
lib.pyi:735 ↗
class BatchShape
BatchShape
lib.pyi:747 ↗
BatchShape(
    *,
    max_rows_per_device: int = 0,
    max_segments_per_device: int = 0,
    max_columns_per_row: int = 0,
    max_bags_per_device: int = 0,
    max_choices_per_item: int = 0,
    image: ImageShape | tuple[int, ...] | None = None,
    video: VideoShape | tuple[int, ...] | None = None,
    audio: AudioShape | tuple[int, ...] | None = None,
)
max_rows_per_device
lib.pyi:739 ↗
max_rows_per_device: Final[int]
max_segments_per_device
lib.pyi:740 ↗
max_segments_per_device: Final[int]
max_columns_per_row
lib.pyi:741 ↗
max_columns_per_row: Final[int]
max_bags_per_device
lib.pyi:742 ↗
max_bags_per_device: Final[int]
max_choices_per_item
lib.pyi:743 ↗
max_choices_per_item: Final[int]
image
lib.pyi:744 ↗
image: Final[ImageShape | None]
video
lib.pyi:745 ↗
video: Final[VideoShape | None]
audio
lib.pyi:746 ↗
audio: Final[AudioShape | None]
ClassMaskingHow the masked objective corrupts a batch and weighs its heads; every zero derives.12
lib.pyi:760 ↗
class Masking
Masking
lib.pyi:775 ↗
Masking(
    *,
    token_mask_probability: float = 0.0,
    token_mean_span: float = 0.0,
    replace_fraction: float = 0.0,
    random_fraction: float = 0.0,
    image_mask_ratio: float = 0.0,
    video_mask_ratio: float = 0.0,
    audio_mask_ratio: float = 0.0,
    text_weight: float = 0.0,
    image_weight: float = 0.0,
    video_weight: float = 0.0,
    audio_weight: float = 0.0,
)
token_mask_probability
lib.pyi:764 ↗
token_mask_probability: Final[float]
token_mean_span
lib.pyi:765 ↗
token_mean_span: Final[float]
replace_fraction
lib.pyi:766 ↗
replace_fraction: Final[float]
random_fraction
lib.pyi:767 ↗
random_fraction: Final[float]
image_mask_ratio
lib.pyi:768 ↗
image_mask_ratio: Final[float]
video_mask_ratio
lib.pyi:769 ↗
video_mask_ratio: Final[float]
audio_mask_ratio
lib.pyi:770 ↗
audio_mask_ratio: Final[float]
text_weight
lib.pyi:771 ↗
text_weight: Final[float]
image_weight
lib.pyi:772 ↗
image_weight: Final[float]
video_weight
lib.pyi:773 ↗
video_weight: Final[float]
audio_weight
lib.pyi:774 ↗
audio_weight: Final[float]
ClassContrastiveHow the contrastive loss scores the pooled embeddings; every zero derives.9
lib.pyi:791 ↗
class Contrastive
Contrastive
lib.pyi:803 ↗
Contrastive(
    *,
    matryoshka_dimensions: Sequence[int] | None = None,
    temperature_groups: int = 0,
    inverse_temperature: float = 0.0,
    bias: float = 0.0,
    negatives: Negatives = ...,
    ambient_repulsion_weight: float = 0.0,
    max_edges_per_device: int = 0,
    pair_loss: PairLossForm = ...,
)
matryoshka_dimensions
lib.pyi:795 ↗
matryoshka_dimensions: Final[Sequence[int] | None]
temperature_groups
lib.pyi:796 ↗
temperature_groups: Final[int]
inverse_temperature
lib.pyi:797 ↗
inverse_temperature: Final[float]
bias
lib.pyi:798 ↗
bias: Final[float]
negatives
lib.pyi:799 ↗
negatives: Final[Negatives]
ambient_repulsion_weight
lib.pyi:800 ↗
ambient_repulsion_weight: Final[float]
max_edges_per_device
lib.pyi:801 ↗
max_edges_per_device: Final[int]
pair_loss
lib.pyi:802 ↗
pair_loss: Final[PairLossForm]
ClassLateInteractionHow the late-interaction loss scores the token vectors of queries and documents; every zero derives.10
lib.pyi:816 ↗
class LateInteraction
LateInteraction
lib.pyi:829 ↗
LateInteraction(
    *,
    weight: float = 0.0,
    width: int = 0,
    inverse_temperature: float = 0.0,
    bias: float = 0.0,
    max_query_span: int = 0,
    max_query_tokens_per_device: int = 0,
    max_documents_per_device: int = 0,
    max_document_tokens_per_device: int = 0,
    pair_loss: PairLossForm = ...,
)
weight
lib.pyi:820 ↗
weight: Final[float]
width
lib.pyi:821 ↗
width: Final[int]
inverse_temperature
lib.pyi:822 ↗
inverse_temperature: Final[float]
bias
lib.pyi:823 ↗
bias: Final[float]
max_query_span
lib.pyi:824 ↗
max_query_span: Final[int]
max_query_tokens_per_device
lib.pyi:825 ↗
max_query_tokens_per_device: Final[int]
max_documents_per_device
lib.pyi:826 ↗
max_documents_per_device: Final[int]
max_document_tokens_per_device
lib.pyi:827 ↗
max_document_tokens_per_device: Final[int]
pair_loss
lib.pyi:828 ↗
pair_loss: Final[PairLossForm]
ClassScheduleThe learning-rate schedule: a linear warmup to the peak, then a cosine decay to the floor.5
lib.pyi:851 ↗
class Schedule
Schedule
lib.pyi:859 ↗
Schedule(
    *,
    learning_rate: float = 0.0,
    min_learning_rate: float = 0.0,
    warmup_steps: int = 0,
    steps: int = 0,
)
learning_rate
lib.pyi:855 ↗
learning_rate: Final[float]
min_learning_rate
lib.pyi:856 ↗
min_learning_rate: Final[float]
warmup_steps
lib.pyi:857 ↗
warmup_steps: Final[int]
steps
lib.pyi:858 ↗
steps: Final[int]
ClassEdgesOne edge set over a step's items, as compressed sparse rows of buffers borrowed until the step is final.4
lib.pyi:884 ↗
class Edges
Edges
lib.pyi:891 ↗
Edges(
    *,
    offsets: Buffer | None = None,
    ids: Buffer | None = None,
    weights: Buffer | None = None,
)
offsets
lib.pyi:888 ↗
offsets: Final[Buffer | None]
ids
lib.pyi:889 ↗
ids: Final[Buffer | None]
weights
lib.pyi:890 ↗
weights: Final[Buffer | None]
ClassRelationsThe contrastive targets of one step: ignored, attracted, repelled, then the run's negatives.4
lib.pyi:897 ↗
class Relations
Relations
lib.pyi:904 ↗
Relations(
    *,
    attract: _EdgesLike = None,
    repel: _EdgesLike = None,
    ignore: _EdgesLike = None,
)
attract
lib.pyi:901 ↗
attract: Final[Edges | None]
repel
lib.pyi:902 ↗
repel: Final[Edges | None]
ignore
lib.pyi:903 ↗
ignore: Final[Edges | None]
ClassTrainerStepStatsWhat step reports, overwritten by every call it is passed to, every loss its world mean.12
lib.pyi:969 ↗
class TrainerStepStats
stepThe optimizer step the call applied, counted from one.
lib.pyi:975 ↗
step: int
learning_rateThe learning rate it applied.
lib.pyi:980 ↗
learning_rate: float
lossThe total loss the step minimized, its world mean.
lib.pyi:985 ↗
loss: float
contrastive_lossThe contrastive term; 0 when absent.
lib.pyi:990 ↗
contrastive_loss: float
masked_text_lossThe text reconstruction term, unweighted.
lib.pyi:995 ↗
masked_text_loss: float
masked_image_lossThe image reconstruction term, unweighted.
lib.pyi:1000 ↗
masked_image_loss: float
masked_video_lossThe video reconstruction term, unweighted.
lib.pyi:1005 ↗
masked_video_loss: float
masked_audio_lossThe audio reconstruction term, unweighted.
lib.pyi:1010 ↗
masked_audio_loss: float
late_interaction_lossThe late-interaction term, weighted.
lib.pyi:1015 ↗
late_interaction_loss: float
choices_lossThe choices term over the items that made a choice, unweighted.
lib.pyi:1020 ↗
choices_loss: float
truncatedItems cut at a row's width.
lib.pyi:1025 ↗
truncated: int
droppedSegments dropped whole because the batch had no room for them, since the last stats read.
lib.pyi:1030 ↗
dropped: int
ClassTrainerA training run on the devices of the executor it was created on, which its own verbs block on.5
lib.pyi:1034 ↗
class Trainer
init_vramBuilds one replica per device and starts or resumes the run.
lib.pyi:1039 ↗
@classmethod
def init_vram(
    executor: Executor,
    /,
    *,
    mesh: Mesh | None = None,
    resume: _PathLike | None = None,
    depth: int = 0,
    hidden: int = 0,
    batch: BatchShape | None = None,
    objective: Objective = ...,
    masking: Masking | None = None,
    contrastive: Contrastive | None = None,
    late_interaction: LateInteraction | None = None,
    choices: Choices | None = None,
    schedule: Schedule | None = None,
    seed: int = 0,
    progress: _Progress | None = None,
    progress_steps: int = 0,
) -> Trainer

Calls uform_trainer_init_vram.

onA receiver whose verbs block on executor.
lib.pyi:1063 ↗
def on(executor: Executor, /) -> On[Trainer]

Python-only.

deferredA receiver whose verbs submit to executor and answer a Deferred.
lib.pyi:1067 ↗
def deferred(executor: Executor, /) -> DeferredOn[Trainer]

Python-only.

stepApplies one optimizer step over this process's items and every peer's.
lib.pyi:1071 ↗
def step(
    modalities: Sequence[Modality],
    contents: _Texts,
    /,
    *,
    bags: _Words | None = None,
    temperature_groups: _Words | None = None,
    sides: Sequence[LateInteractionSide] | None = None,
    choices: _Texts | None = None,
    choice_targets: Sequence[Buffer] | _Tape | None = None,
    relations: Relations | None = None,
    arena: Arena | None = None,
    outputs_scalar: Scalar = ...,
    stats: TrainerStepStats | None = None,
) -> ArenaBuffer | None

Calls uform_trainer_step.

saveWrites the weights and the step as a checkpoint.
lib.pyi:1090 ↗
def save(
    path: _PathLike,
    /,
    *,
    progress: _Progress | None = None,
    progress_steps: int = 0,
) -> None

Calls uform_trainer_save.