Imputation, denoising, generation, and perturbation#
A trained UniVI model is a generative model: its decoders map any latent point to every modality. This notebook uses that to
denoise measured expression, from one modality or several
evaluate cross-modal prediction feature by feature
generate new cells, unconditionally or for a chosen cell type, in all modalities at once
probe the model with an in-silico perturbation of one input feature
RNA is kept as log-normalized expression without z-scoring here, so that zero means “not expressed” and decoded values are on a familiar scale.
import sys
if "google.colab" in sys.modules:
%pip install -q "univi[tutorials]>=1.0" "pandas==2.2.3"
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import scanpy as sc
import scipy.sparse as sp
import torch
import univi.datasets as uds
from univi import ModalityConfig, TrainingConfig, UniVIConfig, UniVIMultiModalVAE, UniVITrainer
from univi.evaluation import (denoise_adata, encode_adata, evaluate_cross_reconstruction,
fit_label_latent_gaussians, generate_from_latent, sample_latent_by_label)
from univi.perturbation import predict_feature_perturbation
from univi.plotting import compare_raw_vs_denoised_umap_features, plot_featurewise_reconstruction_scatter
from univi.preprocessing import ATACPreprocessor, RNAPreprocessor, split_by_label
from univi.utils.seed import set_seed
from univi.workflows import make_loader
device = "cuda" if torch.cuda.is_available() else ("mps" if torch.backends.mps.is_available() else "cpu")
set_seed(0)
dense = lambda x: x.toarray() if sp.issparse(x) else np.asarray(x)
C:\Users\ashfo\micromamba\envs\univi-release-050\Lib\site-packages\tqdm\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
from .autonotebook import tqdm as notebook_tqdm
N_EPOCHS = 400
BATCH_SIZE = 256
N_HVG = 2000
N_LSI = 101
N_GENERATED = 2000
Train#
data = uds.pbmc_multiome_10k()
rna, atac = data["rna"], data["atac"]
splits = split_by_label(rna.obs["cell_type"], train_fraction=0.8, val_fraction=0.1, seed=0)
rna_prep = RNAPreprocessor(n_hvg=N_HVG, scale=False).fit(rna[splits["train"]]) # log1p, not z-scored
atac_prep = ATACPreprocessor(n_components=N_LSI, drop_first=True, scale=True).fit(atac[splits["train"]])
parts = {k: {"rna": rna_prep.transform(rna[i]), "atac": atac_prep.transform(atac[i])} for k, i in splits.items()}
train, val, test = parts["train"], parts["val"], parts["test"]
cfg = UniVIConfig(
latent_dim=30, beta=1.25, gamma=4.35, encoder_dropout=0.10, decoder_dropout=0.05,
kl_anneal_start=50, kl_anneal_end=85, align_anneal_start=75, align_anneal_end=110,
modalities=[ModalityConfig("rna", train["rna"].n_vars, [512, 256, 128], [128, 256, 512]),
ModalityConfig("atac", train["atac"].n_vars, [128, 64], [64, 128])],
)
model = UniVIMultiModalVAE(cfg, loss_mode="v1", v1_recon="avg", normalize_v1_terms=True)
UniVITrainer(model, make_loader(train, batch_size=BATCH_SIZE, shuffle=True, drop_last=True),
make_loader(val, batch_size=1024),
TrainingConfig(n_epochs=N_EPOCHS, batch_size=BATCH_SIZE, lr=1e-3, weight_decay=1e-4, device=device,
early_stopping=True, patience=50, best_epoch_warmup=110, log_every=50)).fit();
rna_test, atac_test = test["rna"], test["atac"]
rna_test.obsm["X_univi"] = encode_adata(model, rna_test, modality="rna", device=device, latent="modality_mean")
sc.pp.neighbors(rna_test, use_rep="X_univi")
sc.tl.umap(rna_test, random_state=0)
markers = [g for g in ["MS4A1", "CD79A", "CD3D", "IL7R", "NKG7", "GNLY", "LYZ", "FCGR3A"] if g in rna_test.var_names]
[2026-09-21 00:58:52,478] [UniVITrainer] [INFO] TrainingConfig:
[2026-09-21 00:58:52,478] [UniVITrainer] [INFO] n_epochs: 400
[2026-09-21 00:58:52,479] [UniVITrainer] [INFO] batch_size: 256
[2026-09-21 00:58:52,479] [UniVITrainer] [INFO] lr: 0.001
[2026-09-21 00:58:52,479] [UniVITrainer] [INFO] weight_decay: 0.0001
[2026-09-21 00:58:52,480] [UniVITrainer] [INFO] device: 'cuda'
[2026-09-21 00:58:52,480] [UniVITrainer] [INFO] log_every: 50
[2026-09-21 00:58:52,480] [UniVITrainer] [INFO] grad_clip: None
[2026-09-21 00:58:52,480] [UniVITrainer] [INFO] num_workers: 0
[2026-09-21 00:58:52,481] [UniVITrainer] [INFO] seed: 0
[2026-09-21 00:58:52,481] [UniVITrainer] [INFO] early_stopping: True
[2026-09-21 00:58:52,481] [UniVITrainer] [INFO] patience: 50
[2026-09-21 00:58:52,482] [UniVITrainer] [INFO] min_delta: 0.0
[2026-09-21 00:58:52,482] [UniVITrainer] [INFO] best_epoch_warmup: 110
Training UniVI: 0%| | 0/400 [00:00<?, ?it/s]
[2026-09-21 00:58:54,148] [UniVITrainer] [INFO] [Epoch 001] Train loss=925.2269 (beta=0.000, gamma=0.000)
[2026-09-21 00:58:54,238] [UniVITrainer] [INFO] [Epoch 001] Val loss=940.4916 (beta=1.250, gamma=4.350)
Training UniVI: 0%| | 0/400 [00:01<?, ?it/s, beta=0.000, gamma=0.000, train_loss=925.2269, val_loss=940.4916]
Training UniVI: 0%| | 1/400 [00:01<11:40, 1.76s/it, beta=0.000, gamma=0.000, train_loss=925.2269, val_loss=940.4916]
Training UniVI: 0%| | 1/400 [00:03<11:40, 1.76s/it, beta=0.000, gamma=0.000, train_loss=739.9063, val_loss=909.4086]
Training UniVI: 0%| | 2/400 [00:03<10:43, 1.62s/it, beta=0.000, gamma=0.000, train_loss=739.9063, val_loss=909.4086]
Training UniVI: 0%| | 2/400 [00:04<10:43, 1.62s/it, beta=0.000, gamma=0.000, train_loss=696.6504, val_loss=930.3757]
Training UniVI: 1%| | 3/400 [00:04<10:29, 1.59s/it, beta=0.000, gamma=0.000, train_loss=696.6504, val_loss=930.3757]
Training UniVI: 1%| | 3/400 [00:06<10:29, 1.59s/it, beta=0.000, gamma=0.000, train_loss=678.9952, val_loss=962.8282]
Training UniVI: 1%| | 4/400 [00:06<10:19, 1.57s/it, beta=0.000, gamma=0.000, train_loss=678.9952, val_loss=962.8282]
Training UniVI: 1%| | 4/400 [00:07<10:19, 1.57s/it, beta=0.000, gamma=0.000, train_loss=652.7454, val_loss=1042.4561]
Training UniVI: 1%|▏ | 5/400 [00:07<10:12, 1.55s/it, beta=0.000, gamma=0.000, train_loss=652.7454, val_loss=1042.4561]
Training UniVI: 1%|▏ | 5/400 [00:09<10:12, 1.55s/it, beta=0.000, gamma=0.000, train_loss=631.2725, val_loss=1120.4171]
Training UniVI: 2%|▏ | 6/400 [00:09<10:07, 1.54s/it, beta=0.000, gamma=0.000, train_loss=631.2725, val_loss=1120.4171]
Training UniVI: 2%|▏ | 6/400 [00:10<10:07, 1.54s/it, beta=0.000, gamma=0.000, train_loss=622.6380, val_loss=1189.5018]
Training UniVI: 2%|▏ | 7/400 [00:10<10:07, 1.54s/it, beta=0.000, gamma=0.000, train_loss=622.6380, val_loss=1189.5018]
Training UniVI: 2%|▏ | 7/400 [00:12<10:07, 1.54s/it, beta=0.000, gamma=0.000, train_loss=615.0681, val_loss=1249.0157]
Training UniVI: 2%|▏ | 8/400 [00:12<10:02, 1.54s/it, beta=0.000, gamma=0.000, train_loss=615.0681, val_loss=1249.0157]
Training UniVI: 2%|▏ | 8/400 [00:14<10:02, 1.54s/it, beta=0.000, gamma=0.000, train_loss=609.7046, val_loss=1330.4464]
Training UniVI: 2%|▏ | 9/400 [00:14<09:59, 1.53s/it, beta=0.000, gamma=0.000, train_loss=609.7046, val_loss=1330.4464]
Training UniVI: 2%|▏ | 9/400 [00:15<09:59, 1.53s/it, beta=0.000, gamma=0.000, train_loss=605.8420, val_loss=1537.4929]
Training UniVI: 2%|▎ | 10/400 [00:15<09:56, 1.53s/it, beta=0.000, gamma=0.000, train_loss=605.8420, val_loss=1537.4929]
Training UniVI: 2%|▎ | 10/400 [00:17<09:56, 1.53s/it, beta=0.000, gamma=0.000, train_loss=601.0171, val_loss=1593.3953]
Training UniVI: 3%|▎ | 11/400 [00:17<09:57, 1.54s/it, beta=0.000, gamma=0.000, train_loss=601.0171, val_loss=1593.3953]
Training UniVI: 3%|▎ | 11/400 [00:18<09:57, 1.54s/it, beta=0.000, gamma=0.000, train_loss=597.4898, val_loss=1569.3445]
Training UniVI: 3%|▎ | 12/400 [00:18<09:53, 1.53s/it, beta=0.000, gamma=0.000, train_loss=597.4898, val_loss=1569.3445]
Training UniVI: 3%|▎ | 12/400 [00:20<09:53, 1.53s/it, beta=0.000, gamma=0.000, train_loss=594.7605, val_loss=1670.6594]
Training UniVI: 3%|▎ | 13/400 [00:20<09:52, 1.53s/it, beta=0.000, gamma=0.000, train_loss=594.7605, val_loss=1670.6594]
Training UniVI: 3%|▎ | 13/400 [00:21<09:52, 1.53s/it, beta=0.000, gamma=0.000, train_loss=592.3143, val_loss=1708.5619]
Training UniVI: 4%|▎ | 14/400 [00:21<09:50, 1.53s/it, beta=0.000, gamma=0.000, train_loss=592.3143, val_loss=1708.5619]
Training UniVI: 4%|▎ | 14/400 [00:23<09:50, 1.53s/it, beta=0.000, gamma=0.000, train_loss=590.6109, val_loss=1868.3799]
Training UniVI: 4%|▍ | 15/400 [00:23<09:48, 1.53s/it, beta=0.000, gamma=0.000, train_loss=590.6109, val_loss=1868.3799]
Training UniVI: 4%|▍ | 15/400 [00:24<09:48, 1.53s/it, beta=0.000, gamma=0.000, train_loss=589.2301, val_loss=2005.8770]
Training UniVI: 4%|▍ | 16/400 [00:24<09:49, 1.54s/it, beta=0.000, gamma=0.000, train_loss=589.2301, val_loss=2005.8770]
Training UniVI: 4%|▍ | 16/400 [00:26<09:49, 1.54s/it, beta=0.000, gamma=0.000, train_loss=587.5677, val_loss=2173.3894]
Training UniVI: 4%|▍ | 17/400 [00:26<09:48, 1.54s/it, beta=0.000, gamma=0.000, train_loss=587.5677, val_loss=2173.3894]
Training UniVI: 4%|▍ | 17/400 [00:27<09:48, 1.54s/it, beta=0.000, gamma=0.000, train_loss=586.1759, val_loss=2250.8472]
Training UniVI: 4%|▍ | 18/400 [00:27<09:51, 1.55s/it, beta=0.000, gamma=0.000, train_loss=586.1759, val_loss=2250.8472]
Training UniVI: 4%|▍ | 18/400 [00:29<09:51, 1.55s/it, beta=0.000, gamma=0.000, train_loss=585.3079, val_loss=2509.9011]
Training UniVI: 5%|▍ | 19/400 [00:29<09:59, 1.57s/it, beta=0.000, gamma=0.000, train_loss=585.3079, val_loss=2509.9011]
Training UniVI: 5%|▍ | 19/400 [00:30<09:59, 1.57s/it, beta=0.000, gamma=0.000, train_loss=583.7703, val_loss=2664.2834]
Training UniVI: 5%|▌ | 20/400 [00:30<09:50, 1.55s/it, beta=0.000, gamma=0.000, train_loss=583.7703, val_loss=2664.2834]
Training UniVI: 5%|▌ | 20/400 [00:32<09:50, 1.55s/it, beta=0.000, gamma=0.000, train_loss=582.7419, val_loss=2600.6580]
Training UniVI: 5%|▌ | 21/400 [00:32<09:44, 1.54s/it, beta=0.000, gamma=0.000, train_loss=582.7419, val_loss=2600.6580]
Training UniVI: 5%|▌ | 21/400 [00:34<09:44, 1.54s/it, beta=0.000, gamma=0.000, train_loss=581.5339, val_loss=2923.3806]
Training UniVI: 6%|▌ | 22/400 [00:34<09:43, 1.54s/it, beta=0.000, gamma=0.000, train_loss=581.5339, val_loss=2923.3806]
Training UniVI: 6%|▌ | 22/400 [00:35<09:43, 1.54s/it, beta=0.000, gamma=0.000, train_loss=580.4578, val_loss=3062.8464]
Training UniVI: 6%|▌ | 23/400 [00:35<09:47, 1.56s/it, beta=0.000, gamma=0.000, train_loss=580.4578, val_loss=3062.8464]
Training UniVI: 6%|▌ | 23/400 [00:37<09:47, 1.56s/it, beta=0.000, gamma=0.000, train_loss=579.1981, val_loss=3143.5354]
Training UniVI: 6%|▌ | 24/400 [00:37<09:43, 1.55s/it, beta=0.000, gamma=0.000, train_loss=579.1981, val_loss=3143.5354]
Training UniVI: 6%|▌ | 24/400 [00:38<09:43, 1.55s/it, beta=0.000, gamma=0.000, train_loss=578.2092, val_loss=3451.9287]
Training UniVI: 6%|▋ | 25/400 [00:38<09:40, 1.55s/it, beta=0.000, gamma=0.000, train_loss=578.2092, val_loss=3451.9287]
Training UniVI: 6%|▋ | 25/400 [00:40<09:40, 1.55s/it, beta=0.000, gamma=0.000, train_loss=577.5278, val_loss=3715.1768]
Training UniVI: 6%|▋ | 26/400 [00:40<09:37, 1.54s/it, beta=0.000, gamma=0.000, train_loss=577.5278, val_loss=3715.1768]
Training UniVI: 6%|▋ | 26/400 [00:41<09:37, 1.54s/it, beta=0.000, gamma=0.000, train_loss=576.4642, val_loss=3968.1199]
Training UniVI: 7%|▋ | 27/400 [00:41<09:36, 1.55s/it, beta=0.000, gamma=0.000, train_loss=576.4642, val_loss=3968.1199]
Training UniVI: 7%|▋ | 27/400 [00:43<09:36, 1.55s/it, beta=0.000, gamma=0.000, train_loss=575.6019, val_loss=4292.6929]
Training UniVI: 7%|▋ | 28/400 [00:43<09:33, 1.54s/it, beta=0.000, gamma=0.000, train_loss=575.6019, val_loss=4292.6929]
Training UniVI: 7%|▋ | 28/400 [00:44<09:33, 1.54s/it, beta=0.000, gamma=0.000, train_loss=574.5837, val_loss=4668.5850]
Training UniVI: 7%|▋ | 29/400 [00:44<09:29, 1.54s/it, beta=0.000, gamma=0.000, train_loss=574.5837, val_loss=4668.5850]
Training UniVI: 7%|▋ | 29/400 [00:46<09:29, 1.54s/it, beta=0.000, gamma=0.000, train_loss=573.9729, val_loss=5186.9058]
Training UniVI: 8%|▊ | 30/400 [00:46<09:26, 1.53s/it, beta=0.000, gamma=0.000, train_loss=573.9729, val_loss=5186.9058]
Training UniVI: 8%|▊ | 30/400 [00:47<09:26, 1.53s/it, beta=0.000, gamma=0.000, train_loss=572.8237, val_loss=5815.6777]
Training UniVI: 8%|▊ | 31/400 [00:47<09:24, 1.53s/it, beta=0.000, gamma=0.000, train_loss=572.8237, val_loss=5815.6777]
Training UniVI: 8%|▊ | 31/400 [00:49<09:24, 1.53s/it, beta=0.000, gamma=0.000, train_loss=572.0747, val_loss=5942.7363]
Training UniVI: 8%|▊ | 32/400 [00:49<09:22, 1.53s/it, beta=0.000, gamma=0.000, train_loss=572.0747, val_loss=5942.7363]
Training UniVI: 8%|▊ | 32/400 [00:50<09:22, 1.53s/it, beta=0.000, gamma=0.000, train_loss=571.1481, val_loss=6767.5635]
Training UniVI: 8%|▊ | 33/400 [00:50<09:18, 1.52s/it, beta=0.000, gamma=0.000, train_loss=571.1481, val_loss=6767.5635]
Training UniVI: 8%|▊ | 33/400 [00:52<09:18, 1.52s/it, beta=0.000, gamma=0.000, train_loss=570.4176, val_loss=7668.3345]
Training UniVI: 8%|▊ | 34/400 [00:52<09:16, 1.52s/it, beta=0.000, gamma=0.000, train_loss=570.4176, val_loss=7668.3345]
Training UniVI: 8%|▊ | 34/400 [00:54<09:16, 1.52s/it, beta=0.000, gamma=0.000, train_loss=569.6985, val_loss=8068.1196]
Training UniVI: 9%|▉ | 35/400 [00:54<09:30, 1.56s/it, beta=0.000, gamma=0.000, train_loss=569.6985, val_loss=8068.1196]
Training UniVI: 9%|▉ | 35/400 [00:55<09:30, 1.56s/it, beta=0.000, gamma=0.000, train_loss=569.1615, val_loss=10374.4326]
Training UniVI: 9%|▉ | 36/400 [00:55<09:25, 1.55s/it, beta=0.000, gamma=0.000, train_loss=569.1615, val_loss=10374.4326]
Training UniVI: 9%|▉ | 36/400 [00:57<09:25, 1.55s/it, beta=0.000, gamma=0.000, train_loss=568.3247, val_loss=10761.4268]
Training UniVI: 9%|▉ | 37/400 [00:57<09:25, 1.56s/it, beta=0.000, gamma=0.000, train_loss=568.3247, val_loss=10761.4268]
Training UniVI: 9%|▉ | 37/400 [00:58<09:25, 1.56s/it, beta=0.000, gamma=0.000, train_loss=567.9129, val_loss=11535.0811]
Training UniVI: 10%|▉ | 38/400 [00:58<09:23, 1.56s/it, beta=0.000, gamma=0.000, train_loss=567.9129, val_loss=11535.0811]
Training UniVI: 10%|▉ | 38/400 [01:00<09:23, 1.56s/it, beta=0.000, gamma=0.000, train_loss=567.0075, val_loss=12653.2656]
Training UniVI: 10%|▉ | 39/400 [01:00<09:20, 1.55s/it, beta=0.000, gamma=0.000, train_loss=567.0075, val_loss=12653.2656]
Training UniVI: 10%|▉ | 39/400 [01:01<09:20, 1.55s/it, beta=0.000, gamma=0.000, train_loss=566.3805, val_loss=14082.3701]
Training UniVI: 10%|█ | 40/400 [01:01<09:15, 1.54s/it, beta=0.000, gamma=0.000, train_loss=566.3805, val_loss=14082.3701]
Training UniVI: 10%|█ | 40/400 [01:03<09:15, 1.54s/it, beta=0.000, gamma=0.000, train_loss=566.0262, val_loss=15776.8379]
Training UniVI: 10%|█ | 41/400 [01:03<09:11, 1.54s/it, beta=0.000, gamma=0.000, train_loss=566.0262, val_loss=15776.8379]
Training UniVI: 10%|█ | 41/400 [01:04<09:11, 1.54s/it, beta=0.000, gamma=0.000, train_loss=565.5368, val_loss=14502.5410]
Training UniVI: 10%|█ | 42/400 [01:04<09:11, 1.54s/it, beta=0.000, gamma=0.000, train_loss=565.5368, val_loss=14502.5410]
Training UniVI: 10%|█ | 42/400 [01:06<09:11, 1.54s/it, beta=0.000, gamma=0.000, train_loss=565.1992, val_loss=16459.5488]
Training UniVI: 11%|█ | 43/400 [01:06<09:09, 1.54s/it, beta=0.000, gamma=0.000, train_loss=565.1992, val_loss=16459.5488]
Training UniVI: 11%|█ | 43/400 [01:07<09:09, 1.54s/it, beta=0.000, gamma=0.000, train_loss=564.5358, val_loss=17407.3164]
Training UniVI: 11%|█ | 44/400 [01:07<09:08, 1.54s/it, beta=0.000, gamma=0.000, train_loss=564.5358, val_loss=17407.3164]
Training UniVI: 11%|█ | 44/400 [01:09<09:08, 1.54s/it, beta=0.000, gamma=0.000, train_loss=564.0448, val_loss=18088.8574]
Training UniVI: 11%|█▏ | 45/400 [01:09<09:03, 1.53s/it, beta=0.000, gamma=0.000, train_loss=564.0448, val_loss=18088.8574]
Training UniVI: 11%|█▏ | 45/400 [01:11<09:03, 1.53s/it, beta=0.000, gamma=0.000, train_loss=563.4700, val_loss=20426.2793]
Training UniVI: 12%|█▏ | 46/400 [01:11<09:04, 1.54s/it, beta=0.000, gamma=0.000, train_loss=563.4700, val_loss=20426.2793]
Training UniVI: 12%|█▏ | 46/400 [01:12<09:04, 1.54s/it, beta=0.000, gamma=0.000, train_loss=563.0944, val_loss=20343.2051]
Training UniVI: 12%|█▏ | 47/400 [01:12<09:01, 1.53s/it, beta=0.000, gamma=0.000, train_loss=563.0944, val_loss=20343.2051]
Training UniVI: 12%|█▏ | 47/400 [01:14<09:01, 1.53s/it, beta=0.000, gamma=0.000, train_loss=563.2148, val_loss=21798.1953]
Training UniVI: 12%|█▏ | 48/400 [01:14<09:00, 1.53s/it, beta=0.000, gamma=0.000, train_loss=563.2148, val_loss=21798.1953]
Training UniVI: 12%|█▏ | 48/400 [01:15<09:00, 1.53s/it, beta=0.000, gamma=0.000, train_loss=562.4736, val_loss=23146.6523]
Training UniVI: 12%|█▏ | 49/400 [01:15<08:56, 1.53s/it, beta=0.000, gamma=0.000, train_loss=562.4736, val_loss=23146.6523]
[2026-09-21 01:00:09,553] [UniVITrainer] [INFO] [Epoch 050] Train loss=562.1614 (beta=0.000, gamma=0.000)
[2026-09-21 01:00:09,649] [UniVITrainer] [INFO] [Epoch 050] Val loss=26081.9082 (beta=1.250, gamma=4.350)
Training UniVI: 12%|█▏ | 49/400 [01:17<08:56, 1.53s/it, beta=0.000, gamma=0.000, train_loss=562.1614, val_loss=26081.9082]
Training UniVI: 12%|█▎ | 50/400 [01:17<08:56, 1.53s/it, beta=0.000, gamma=0.000, train_loss=562.1614, val_loss=26081.9082]
Training UniVI: 12%|█▎ | 50/400 [01:18<08:56, 1.53s/it, beta=0.036, gamma=0.000, train_loss=565.0509, val_loss=20405.1875]
Training UniVI: 13%|█▎ | 51/400 [01:18<08:52, 1.53s/it, beta=0.036, gamma=0.000, train_loss=565.0509, val_loss=20405.1875]
Training UniVI: 13%|█▎ | 51/400 [01:20<08:52, 1.53s/it, beta=0.071, gamma=0.000, train_loss=567.6949, val_loss=10759.2568]
Training UniVI: 13%|█▎ | 52/400 [01:20<08:49, 1.52s/it, beta=0.071, gamma=0.000, train_loss=567.6949, val_loss=10759.2568]
Training UniVI: 13%|█▎ | 52/400 [01:21<08:49, 1.52s/it, beta=0.107, gamma=0.000, train_loss=569.2496, val_loss=4566.3027]
Training UniVI: 13%|█▎ | 53/400 [01:21<08:46, 1.52s/it, beta=0.107, gamma=0.000, train_loss=569.2496, val_loss=4566.3027]
Training UniVI: 13%|█▎ | 53/400 [01:23<08:46, 1.52s/it, beta=0.143, gamma=0.000, train_loss=570.2328, val_loss=2327.6846]
Training UniVI: 14%|█▎ | 54/400 [01:23<08:45, 1.52s/it, beta=0.143, gamma=0.000, train_loss=570.2328, val_loss=2327.6846]
Training UniVI: 14%|█▎ | 54/400 [01:24<08:45, 1.52s/it, beta=0.179, gamma=0.000, train_loss=570.9169, val_loss=1457.9457]
Training UniVI: 14%|█▍ | 55/400 [01:24<08:43, 1.52s/it, beta=0.179, gamma=0.000, train_loss=570.9169, val_loss=1457.9457]
Training UniVI: 14%|█▍ | 55/400 [01:26<08:43, 1.52s/it, beta=0.214, gamma=0.000, train_loss=571.2664, val_loss=1105.2592]
Training UniVI: 14%|█▍ | 56/400 [01:26<08:41, 1.52s/it, beta=0.214, gamma=0.000, train_loss=571.2664, val_loss=1105.2592]
Training UniVI: 14%|█▍ | 56/400 [01:27<08:41, 1.52s/it, beta=0.250, gamma=0.000, train_loss=571.9915, val_loss=956.1557]
Training UniVI: 14%|█▍ | 57/400 [01:27<08:43, 1.53s/it, beta=0.250, gamma=0.000, train_loss=571.9915, val_loss=956.1557]
Training UniVI: 14%|█▍ | 57/400 [01:29<08:43, 1.53s/it, beta=0.286, gamma=0.000, train_loss=573.1311, val_loss=876.0720]
Training UniVI: 14%|█▍ | 58/400 [01:29<09:00, 1.58s/it, beta=0.286, gamma=0.000, train_loss=573.1311, val_loss=876.0720]
Training UniVI: 14%|█▍ | 58/400 [01:31<09:00, 1.58s/it, beta=0.321, gamma=0.000, train_loss=573.6634, val_loss=837.0106]
Training UniVI: 15%|█▍ | 59/400 [01:31<08:54, 1.57s/it, beta=0.321, gamma=0.000, train_loss=573.6634, val_loss=837.0106]
Training UniVI: 15%|█▍ | 59/400 [01:32<08:54, 1.57s/it, beta=0.357, gamma=0.000, train_loss=574.2770, val_loss=792.8387]
Training UniVI: 15%|█▌ | 60/400 [01:32<08:50, 1.56s/it, beta=0.357, gamma=0.000, train_loss=574.2770, val_loss=792.8387]
Training UniVI: 15%|█▌ | 60/400 [01:34<08:50, 1.56s/it, beta=0.393, gamma=0.000, train_loss=574.8395, val_loss=767.6216]
Training UniVI: 15%|█▌ | 61/400 [01:34<08:45, 1.55s/it, beta=0.393, gamma=0.000, train_loss=574.8395, val_loss=767.6216]
Training UniVI: 15%|█▌ | 61/400 [01:35<08:45, 1.55s/it, beta=0.429, gamma=0.000, train_loss=575.6789, val_loss=745.4875]
Training UniVI: 16%|█▌ | 62/400 [01:35<08:49, 1.57s/it, beta=0.429, gamma=0.000, train_loss=575.6789, val_loss=745.4875]
Training UniVI: 16%|█▌ | 62/400 [01:37<08:49, 1.57s/it, beta=0.464, gamma=0.000, train_loss=576.2234, val_loss=741.8503]
Training UniVI: 16%|█▌ | 63/400 [01:37<08:46, 1.56s/it, beta=0.464, gamma=0.000, train_loss=576.2234, val_loss=741.8503]
Training UniVI: 16%|█▌ | 63/400 [01:38<08:46, 1.56s/it, beta=0.500, gamma=0.000, train_loss=576.8146, val_loss=727.1196]
Training UniVI: 16%|█▌ | 64/400 [01:38<08:40, 1.55s/it, beta=0.500, gamma=0.000, train_loss=576.8146, val_loss=727.1196]
Training UniVI: 16%|█▌ | 64/400 [01:40<08:40, 1.55s/it, beta=0.536, gamma=0.000, train_loss=576.8060, val_loss=713.1837]
Training UniVI: 16%|█▋ | 65/400 [01:40<08:38, 1.55s/it, beta=0.536, gamma=0.000, train_loss=576.8060, val_loss=713.1837]
Training UniVI: 16%|█▋ | 65/400 [01:41<08:38, 1.55s/it, beta=0.571, gamma=0.000, train_loss=577.4569, val_loss=708.2587]
Training UniVI: 16%|█▋ | 66/400 [01:41<08:34, 1.54s/it, beta=0.571, gamma=0.000, train_loss=577.4569, val_loss=708.2587]
Training UniVI: 16%|█▋ | 66/400 [01:43<08:34, 1.54s/it, beta=0.607, gamma=0.000, train_loss=578.3580, val_loss=704.6484]
Training UniVI: 17%|█▋ | 67/400 [01:43<08:31, 1.54s/it, beta=0.607, gamma=0.000, train_loss=578.3580, val_loss=704.6484]
Training UniVI: 17%|█▋ | 67/400 [01:44<08:31, 1.54s/it, beta=0.643, gamma=0.000, train_loss=578.5693, val_loss=692.8246]
Training UniVI: 17%|█▋ | 68/400 [01:44<08:29, 1.53s/it, beta=0.643, gamma=0.000, train_loss=578.5693, val_loss=692.8246]
Training UniVI: 17%|█▋ | 68/400 [01:46<08:29, 1.53s/it, beta=0.679, gamma=0.000, train_loss=578.9652, val_loss=686.1740]
Training UniVI: 17%|█▋ | 69/400 [01:46<08:27, 1.53s/it, beta=0.679, gamma=0.000, train_loss=578.9652, val_loss=686.1740]
Training UniVI: 17%|█▋ | 69/400 [01:47<08:27, 1.53s/it, beta=0.714, gamma=0.000, train_loss=579.1409, val_loss=678.9684]
Training UniVI: 18%|█▊ | 70/400 [01:47<08:24, 1.53s/it, beta=0.714, gamma=0.000, train_loss=579.1409, val_loss=678.9684]
Training UniVI: 18%|█▊ | 70/400 [01:49<08:24, 1.53s/it, beta=0.750, gamma=0.000, train_loss=579.4756, val_loss=669.6049]
Training UniVI: 18%|█▊ | 71/400 [01:49<08:23, 1.53s/it, beta=0.750, gamma=0.000, train_loss=579.4756, val_loss=669.6049]
Training UniVI: 18%|█▊ | 71/400 [01:51<08:23, 1.53s/it, beta=0.786, gamma=0.000, train_loss=580.1237, val_loss=675.8754]
Training UniVI: 18%|█▊ | 72/400 [01:51<08:21, 1.53s/it, beta=0.786, gamma=0.000, train_loss=580.1237, val_loss=675.8754]
Training UniVI: 18%|█▊ | 72/400 [01:52<08:21, 1.53s/it, beta=0.821, gamma=0.000, train_loss=580.4073, val_loss=665.6043]
Training UniVI: 18%|█▊ | 73/400 [01:52<08:17, 1.52s/it, beta=0.821, gamma=0.000, train_loss=580.4073, val_loss=665.6043]
Training UniVI: 18%|█▊ | 73/400 [01:54<08:17, 1.52s/it, beta=0.857, gamma=0.000, train_loss=580.4204, val_loss=660.1317]
Training UniVI: 18%|█▊ | 74/400 [01:54<08:16, 1.52s/it, beta=0.857, gamma=0.000, train_loss=580.4204, val_loss=660.1317]
Training UniVI: 18%|█▊ | 74/400 [01:55<08:16, 1.52s/it, beta=0.893, gamma=0.000, train_loss=580.5357, val_loss=665.8461]
Training UniVI: 19%|█▉ | 75/400 [01:55<08:18, 1.53s/it, beta=0.893, gamma=0.000, train_loss=580.5357, val_loss=665.8461]
Training UniVI: 19%|█▉ | 75/400 [01:57<08:18, 1.53s/it, beta=0.929, gamma=0.124, train_loss=583.3665, val_loss=614.7459]
Training UniVI: 19%|█▉ | 76/400 [01:57<08:18, 1.54s/it, beta=0.929, gamma=0.124, train_loss=583.3665, val_loss=614.7459]
Training UniVI: 19%|█▉ | 76/400 [01:58<08:18, 1.54s/it, beta=0.964, gamma=0.249, train_loss=584.9337, val_loss=601.5826]
Training UniVI: 19%|█▉ | 77/400 [01:58<08:22, 1.56s/it, beta=0.964, gamma=0.249, train_loss=584.9337, val_loss=601.5826]
Training UniVI: 19%|█▉ | 77/400 [02:00<08:22, 1.56s/it, beta=1.000, gamma=0.373, train_loss=586.3592, val_loss=594.5400]
Training UniVI: 20%|█▉ | 78/400 [02:00<08:20, 1.55s/it, beta=1.000, gamma=0.373, train_loss=586.3592, val_loss=594.5400]
Training UniVI: 20%|█▉ | 78/400 [02:01<08:20, 1.55s/it, beta=1.036, gamma=0.497, train_loss=587.3823, val_loss=588.3367]
Training UniVI: 20%|█▉ | 79/400 [02:01<08:15, 1.54s/it, beta=1.036, gamma=0.497, train_loss=587.3823, val_loss=588.3367]
Training UniVI: 20%|█▉ | 79/400 [02:03<08:15, 1.54s/it, beta=1.071, gamma=0.621, train_loss=588.6284, val_loss=584.6346]
Training UniVI: 20%|██ | 80/400 [02:03<08:10, 1.53s/it, beta=1.071, gamma=0.621, train_loss=588.6284, val_loss=584.6346]
Training UniVI: 20%|██ | 80/400 [02:04<08:10, 1.53s/it, beta=1.107, gamma=0.746, train_loss=589.4200, val_loss=582.4034]
Training UniVI: 20%|██ | 81/400 [02:04<08:14, 1.55s/it, beta=1.107, gamma=0.746, train_loss=589.4200, val_loss=582.4034]
Training UniVI: 20%|██ | 81/400 [02:06<08:14, 1.55s/it, beta=1.143, gamma=0.870, train_loss=590.1598, val_loss=578.0100]
Training UniVI: 20%|██ | 82/400 [02:06<08:11, 1.55s/it, beta=1.143, gamma=0.870, train_loss=590.1598, val_loss=578.0100]
Training UniVI: 20%|██ | 82/400 [02:07<08:11, 1.55s/it, beta=1.179, gamma=0.994, train_loss=590.3864, val_loss=577.1531]
Training UniVI: 21%|██ | 83/400 [02:07<08:07, 1.54s/it, beta=1.179, gamma=0.994, train_loss=590.3864, val_loss=577.1531]
Training UniVI: 21%|██ | 83/400 [02:09<08:07, 1.54s/it, beta=1.214, gamma=1.119, train_loss=590.8575, val_loss=574.8228]
Training UniVI: 21%|██ | 84/400 [02:09<08:07, 1.54s/it, beta=1.214, gamma=1.119, train_loss=590.8575, val_loss=574.8228]
Training UniVI: 21%|██ | 84/400 [02:11<08:07, 1.54s/it, beta=1.250, gamma=1.243, train_loss=591.5443, val_loss=573.5441]
Training UniVI: 21%|██▏ | 85/400 [02:11<08:19, 1.59s/it, beta=1.250, gamma=1.243, train_loss=591.5443, val_loss=573.5441]
Training UniVI: 21%|██▏ | 85/400 [02:12<08:19, 1.59s/it, beta=1.250, gamma=1.367, train_loss=591.6175, val_loss=572.0430]
Training UniVI: 22%|██▏ | 86/400 [02:12<08:13, 1.57s/it, beta=1.250, gamma=1.367, train_loss=591.6175, val_loss=572.0430]
Training UniVI: 22%|██▏ | 86/400 [02:14<08:13, 1.57s/it, beta=1.250, gamma=1.491, train_loss=591.8157, val_loss=572.3853]
Training UniVI: 22%|██▏ | 87/400 [02:14<08:07, 1.56s/it, beta=1.250, gamma=1.491, train_loss=591.8157, val_loss=572.3853]
Training UniVI: 22%|██▏ | 87/400 [02:15<08:07, 1.56s/it, beta=1.250, gamma=1.616, train_loss=591.9002, val_loss=571.0907]
Training UniVI: 22%|██▏ | 88/400 [02:15<08:01, 1.54s/it, beta=1.250, gamma=1.616, train_loss=591.9002, val_loss=571.0907]
Training UniVI: 22%|██▏ | 88/400 [02:17<08:01, 1.54s/it, beta=1.250, gamma=1.740, train_loss=591.8035, val_loss=569.0499]
Training UniVI: 22%|██▏ | 89/400 [02:17<08:00, 1.55s/it, beta=1.250, gamma=1.740, train_loss=591.8035, val_loss=569.0499]
Training UniVI: 22%|██▏ | 89/400 [02:18<08:00, 1.55s/it, beta=1.250, gamma=1.864, train_loss=591.8622, val_loss=569.6931]
Training UniVI: 22%|██▎ | 90/400 [02:18<07:56, 1.54s/it, beta=1.250, gamma=1.864, train_loss=591.8622, val_loss=569.6931]
Training UniVI: 22%|██▎ | 90/400 [02:20<07:56, 1.54s/it, beta=1.250, gamma=1.989, train_loss=591.8622, val_loss=569.4761]
Training UniVI: 23%|██▎ | 91/400 [02:20<07:53, 1.53s/it, beta=1.250, gamma=1.989, train_loss=591.8622, val_loss=569.4761]
Training UniVI: 23%|██▎ | 91/400 [02:21<07:53, 1.53s/it, beta=1.250, gamma=2.113, train_loss=591.9935, val_loss=568.9213]
Training UniVI: 23%|██▎ | 92/400 [02:21<07:51, 1.53s/it, beta=1.250, gamma=2.113, train_loss=591.9935, val_loss=568.9213]
Training UniVI: 23%|██▎ | 92/400 [02:23<07:51, 1.53s/it, beta=1.250, gamma=2.237, train_loss=592.1414, val_loss=568.5129]
Training UniVI: 23%|██▎ | 93/400 [02:23<07:48, 1.53s/it, beta=1.250, gamma=2.237, train_loss=592.1414, val_loss=568.5129]
Training UniVI: 23%|██▎ | 93/400 [02:24<07:48, 1.53s/it, beta=1.250, gamma=2.361, train_loss=592.0294, val_loss=567.1006]
Training UniVI: 24%|██▎ | 94/400 [02:24<07:47, 1.53s/it, beta=1.250, gamma=2.361, train_loss=592.0294, val_loss=567.1006]
Training UniVI: 24%|██▎ | 94/400 [02:26<07:47, 1.53s/it, beta=1.250, gamma=2.486, train_loss=592.0440, val_loss=567.1113]
Training UniVI: 24%|██▍ | 95/400 [02:26<07:47, 1.53s/it, beta=1.250, gamma=2.486, train_loss=592.0440, val_loss=567.1113]
Training UniVI: 24%|██▍ | 95/400 [02:28<07:47, 1.53s/it, beta=1.250, gamma=2.610, train_loss=591.9583, val_loss=566.6970]
Training UniVI: 24%|██▍ | 96/400 [02:28<07:50, 1.55s/it, beta=1.250, gamma=2.610, train_loss=591.9583, val_loss=566.6970]
Training UniVI: 24%|██▍ | 96/400 [02:29<07:50, 1.55s/it, beta=1.250, gamma=2.734, train_loss=592.5014, val_loss=567.6807]
Training UniVI: 24%|██▍ | 97/400 [02:29<07:53, 1.56s/it, beta=1.250, gamma=2.734, train_loss=592.5014, val_loss=567.6807]
Training UniVI: 24%|██▍ | 97/400 [02:31<07:53, 1.56s/it, beta=1.250, gamma=2.859, train_loss=592.3454, val_loss=566.1569]
Training UniVI: 24%|██▍ | 98/400 [02:31<07:49, 1.55s/it, beta=1.250, gamma=2.859, train_loss=592.3454, val_loss=566.1569]
Training UniVI: 24%|██▍ | 98/400 [02:32<07:49, 1.55s/it, beta=1.250, gamma=2.983, train_loss=592.5273, val_loss=565.2050]
Training UniVI: 25%|██▍ | 99/400 [02:32<07:44, 1.54s/it, beta=1.250, gamma=2.983, train_loss=592.5273, val_loss=565.2050]
[2026-09-21 01:01:26,661] [UniVITrainer] [INFO] [Epoch 100] Train loss=592.2073 (beta=1.250, gamma=3.107)
[2026-09-21 01:01:26,750] [UniVITrainer] [INFO] [Epoch 100] Val loss=565.8599 (beta=1.250, gamma=4.350)
Training UniVI: 25%|██▍ | 99/400 [02:34<07:44, 1.54s/it, beta=1.250, gamma=3.107, train_loss=592.2073, val_loss=565.8599]
Training UniVI: 25%|██▌ | 100/400 [02:34<07:41, 1.54s/it, beta=1.250, gamma=3.107, train_loss=592.2073, val_loss=565.8599]
Training UniVI: 25%|██▌ | 100/400 [02:35<07:41, 1.54s/it, beta=1.250, gamma=3.231, train_loss=591.9524, val_loss=565.7328]
Training UniVI: 25%|██▌ | 101/400 [02:35<07:39, 1.54s/it, beta=1.250, gamma=3.231, train_loss=591.9524, val_loss=565.7328]
Training UniVI: 25%|██▌ | 101/400 [02:37<07:39, 1.54s/it, beta=1.250, gamma=3.356, train_loss=592.8247, val_loss=564.9425]
Training UniVI: 26%|██▌ | 102/400 [02:37<07:40, 1.55s/it, beta=1.250, gamma=3.356, train_loss=592.8247, val_loss=564.9425]
Training UniVI: 26%|██▌ | 102/400 [02:38<07:40, 1.55s/it, beta=1.250, gamma=3.480, train_loss=592.3044, val_loss=565.0009]
Training UniVI: 26%|██▌ | 103/400 [02:38<07:37, 1.54s/it, beta=1.250, gamma=3.480, train_loss=592.3044, val_loss=565.0009]
Training UniVI: 26%|██▌ | 103/400 [02:40<07:37, 1.54s/it, beta=1.250, gamma=3.604, train_loss=592.1323, val_loss=565.2573]
Training UniVI: 26%|██▌ | 104/400 [02:40<07:35, 1.54s/it, beta=1.250, gamma=3.604, train_loss=592.1323, val_loss=565.2573]
Training UniVI: 26%|██▌ | 104/400 [02:42<07:35, 1.54s/it, beta=1.250, gamma=3.729, train_loss=592.5538, val_loss=564.5836]
Training UniVI: 26%|██▋ | 105/400 [02:42<07:36, 1.55s/it, beta=1.250, gamma=3.729, train_loss=592.5538, val_loss=564.5836]
Training UniVI: 26%|██▋ | 105/400 [02:43<07:36, 1.55s/it, beta=1.250, gamma=3.853, train_loss=592.1316, val_loss=563.9470]
Training UniVI: 26%|██▋ | 106/400 [02:43<07:33, 1.54s/it, beta=1.250, gamma=3.853, train_loss=592.1316, val_loss=563.9470]
Training UniVI: 26%|██▋ | 106/400 [02:45<07:33, 1.54s/it, beta=1.250, gamma=3.977, train_loss=592.7560, val_loss=564.5496]
Training UniVI: 27%|██▋ | 107/400 [02:45<07:31, 1.54s/it, beta=1.250, gamma=3.977, train_loss=592.7560, val_loss=564.5496]
Training UniVI: 27%|██▋ | 107/400 [02:46<07:31, 1.54s/it, beta=1.250, gamma=4.101, train_loss=592.5773, val_loss=563.7704]
Training UniVI: 27%|██▋ | 108/400 [02:46<07:28, 1.54s/it, beta=1.250, gamma=4.101, train_loss=592.5773, val_loss=563.7704]
Training UniVI: 27%|██▋ | 108/400 [02:48<07:28, 1.54s/it, beta=1.250, gamma=4.226, train_loss=592.4919, val_loss=562.8469]
[2026-09-21 01:01:40,597] [UniVITrainer] [INFO] [Epoch 109] Best tracking warmup ends next epoch (best_epoch_warmup=110).
Training UniVI: 27%|██▋ | 109/400 [02:48<07:25, 1.53s/it, beta=1.250, gamma=4.226, train_loss=592.4919, val_loss=562.8469]
Training UniVI: 27%|██▋ | 109/400 [02:49<07:25, 1.53s/it, beta=1.250, gamma=4.350, train_loss=592.4761, val_loss=563.8130]
[2026-09-21 01:01:42,113] [UniVITrainer] [INFO] [Epoch 110] New best val loss: 563.8130
Training UniVI: 28%|██▊ | 110/400 [02:49<07:22, 1.53s/it, beta=1.250, gamma=4.350, train_loss=592.4761, val_loss=563.8130]
Training UniVI: 28%|██▊ | 110/400 [02:51<07:22, 1.53s/it, beta=1.250, gamma=4.350, train_loss=592.4321, val_loss=564.0607]
Training UniVI: 28%|██▊ | 111/400 [02:51<07:23, 1.54s/it, beta=1.250, gamma=4.350, train_loss=592.4321, val_loss=564.0607]
Training UniVI: 28%|██▊ | 111/400 [02:52<07:23, 1.54s/it, beta=1.250, gamma=4.350, train_loss=592.2151, val_loss=563.5482]
[2026-09-21 01:01:45,188] [UniVITrainer] [INFO] [Epoch 112] New best val loss: 563.5482
Training UniVI: 28%|██▊ | 112/400 [02:52<07:20, 1.53s/it, beta=1.250, gamma=4.350, train_loss=592.2151, val_loss=563.5482]
Training UniVI: 28%|██▊ | 112/400 [02:54<07:20, 1.53s/it, beta=1.250, gamma=4.350, train_loss=592.4882, val_loss=563.3478]
[2026-09-21 01:01:46,768] [UniVITrainer] [INFO] [Epoch 113] New best val loss: 563.3478
Training UniVI: 28%|██▊ | 113/400 [02:54<07:23, 1.55s/it, beta=1.250, gamma=4.350, train_loss=592.4882, val_loss=563.3478]
Training UniVI: 28%|██▊ | 113/400 [02:55<07:23, 1.55s/it, beta=1.250, gamma=4.350, train_loss=591.6003, val_loss=564.1714]
Training UniVI: 28%|██▊ | 114/400 [02:55<07:22, 1.55s/it, beta=1.250, gamma=4.350, train_loss=591.6003, val_loss=564.1714]
Training UniVI: 28%|██▊ | 114/400 [02:57<07:22, 1.55s/it, beta=1.250, gamma=4.350, train_loss=591.9966, val_loss=563.5090]
Training UniVI: 29%|██▉ | 115/400 [02:57<07:20, 1.55s/it, beta=1.250, gamma=4.350, train_loss=591.9966, val_loss=563.5090]
Training UniVI: 29%|██▉ | 115/400 [02:58<07:20, 1.55s/it, beta=1.250, gamma=4.350, train_loss=591.9016, val_loss=563.2977]
[2026-09-21 01:01:51,381] [UniVITrainer] [INFO] [Epoch 116] New best val loss: 563.2977
Training UniVI: 29%|██▉ | 116/400 [02:58<07:16, 1.54s/it, beta=1.250, gamma=4.350, train_loss=591.9016, val_loss=563.2977]
Training UniVI: 29%|██▉ | 116/400 [03:00<07:16, 1.54s/it, beta=1.250, gamma=4.350, train_loss=591.7722, val_loss=563.6526]
Training UniVI: 29%|██▉ | 117/400 [03:00<07:15, 1.54s/it, beta=1.250, gamma=4.350, train_loss=591.7722, val_loss=563.6526]
Training UniVI: 29%|██▉ | 117/400 [03:01<07:15, 1.54s/it, beta=1.250, gamma=4.350, train_loss=591.4247, val_loss=563.5334]
Training UniVI: 30%|██▉ | 118/400 [03:01<07:14, 1.54s/it, beta=1.250, gamma=4.350, train_loss=591.4247, val_loss=563.5334]
Training UniVI: 30%|██▉ | 118/400 [03:03<07:14, 1.54s/it, beta=1.250, gamma=4.350, train_loss=591.3850, val_loss=563.2593]
[2026-09-21 01:01:55,993] [UniVITrainer] [INFO] [Epoch 119] New best val loss: 563.2593
Training UniVI: 30%|██▉ | 119/400 [03:03<07:11, 1.54s/it, beta=1.250, gamma=4.350, train_loss=591.3850, val_loss=563.2593]
Training UniVI: 30%|██▉ | 119/400 [03:05<07:11, 1.54s/it, beta=1.250, gamma=4.350, train_loss=591.0233, val_loss=563.6340]
Training UniVI: 30%|███ | 120/400 [03:05<07:12, 1.54s/it, beta=1.250, gamma=4.350, train_loss=591.0233, val_loss=563.6340]
Training UniVI: 30%|███ | 120/400 [03:06<07:12, 1.54s/it, beta=1.250, gamma=4.350, train_loss=591.1945, val_loss=563.1671]
[2026-09-21 01:01:59,108] [UniVITrainer] [INFO] [Epoch 121] New best val loss: 563.1671
Training UniVI: 30%|███ | 121/400 [03:06<07:11, 1.55s/it, beta=1.250, gamma=4.350, train_loss=591.1945, val_loss=563.1671]
Training UniVI: 30%|███ | 121/400 [03:08<07:11, 1.55s/it, beta=1.250, gamma=4.350, train_loss=591.0008, val_loss=563.4450]
Training UniVI: 30%|███ | 122/400 [03:08<07:08, 1.54s/it, beta=1.250, gamma=4.350, train_loss=591.0008, val_loss=563.4450]
Training UniVI: 30%|███ | 122/400 [03:09<07:08, 1.54s/it, beta=1.250, gamma=4.350, train_loss=590.5717, val_loss=562.3444]
[2026-09-21 01:02:02,222] [UniVITrainer] [INFO] [Epoch 123] New best val loss: 562.3444
Training UniVI: 31%|███ | 123/400 [03:09<07:10, 1.55s/it, beta=1.250, gamma=4.350, train_loss=590.5717, val_loss=562.3444]
Training UniVI: 31%|███ | 123/400 [03:11<07:10, 1.55s/it, beta=1.250, gamma=4.350, train_loss=590.4162, val_loss=562.8185]
Training UniVI: 31%|███ | 124/400 [03:11<07:13, 1.57s/it, beta=1.250, gamma=4.350, train_loss=590.4162, val_loss=562.8185]
Training UniVI: 31%|███ | 124/400 [03:12<07:13, 1.57s/it, beta=1.250, gamma=4.350, train_loss=590.3469, val_loss=563.3680]
Training UniVI: 31%|███▏ | 125/400 [03:12<07:08, 1.56s/it, beta=1.250, gamma=4.350, train_loss=590.3469, val_loss=563.3680]
Training UniVI: 31%|███▏ | 125/400 [03:14<07:08, 1.56s/it, beta=1.250, gamma=4.350, train_loss=590.5577, val_loss=563.5060]
Training UniVI: 32%|███▏ | 126/400 [03:14<07:03, 1.54s/it, beta=1.250, gamma=4.350, train_loss=590.5577, val_loss=563.5060]
Training UniVI: 32%|███▏ | 126/400 [03:15<07:03, 1.54s/it, beta=1.250, gamma=4.350, train_loss=590.3604, val_loss=563.1414]
Training UniVI: 32%|███▏ | 127/400 [03:15<07:00, 1.54s/it, beta=1.250, gamma=4.350, train_loss=590.3604, val_loss=563.1414]
Training UniVI: 32%|███▏ | 127/400 [03:17<07:00, 1.54s/it, beta=1.250, gamma=4.350, train_loss=590.4595, val_loss=563.3854]
Training UniVI: 32%|███▏ | 128/400 [03:17<06:58, 1.54s/it, beta=1.250, gamma=4.350, train_loss=590.4595, val_loss=563.3854]
Training UniVI: 32%|███▏ | 128/400 [03:18<06:58, 1.54s/it, beta=1.250, gamma=4.350, train_loss=590.0556, val_loss=562.9994]
Training UniVI: 32%|███▏ | 129/400 [03:18<06:55, 1.53s/it, beta=1.250, gamma=4.350, train_loss=590.0556, val_loss=562.9994]
Training UniVI: 32%|███▏ | 129/400 [03:20<06:55, 1.53s/it, beta=1.250, gamma=4.350, train_loss=590.2075, val_loss=563.4799]
Training UniVI: 32%|███▎ | 130/400 [03:20<06:52, 1.53s/it, beta=1.250, gamma=4.350, train_loss=590.2075, val_loss=563.4799]
Training UniVI: 32%|███▎ | 130/400 [03:22<06:52, 1.53s/it, beta=1.250, gamma=4.350, train_loss=590.2020, val_loss=562.7233]
Training UniVI: 33%|███▎ | 131/400 [03:22<06:50, 1.52s/it, beta=1.250, gamma=4.350, train_loss=590.2020, val_loss=562.7233]
Training UniVI: 33%|███▎ | 131/400 [03:23<06:50, 1.52s/it, beta=1.250, gamma=4.350, train_loss=589.4321, val_loss=563.3311]
Training UniVI: 33%|███▎ | 132/400 [03:23<06:48, 1.52s/it, beta=1.250, gamma=4.350, train_loss=589.4321, val_loss=563.3311]
Training UniVI: 33%|███▎ | 132/400 [03:25<06:48, 1.52s/it, beta=1.250, gamma=4.350, train_loss=589.8997, val_loss=564.0758]
Training UniVI: 33%|███▎ | 133/400 [03:25<06:48, 1.53s/it, beta=1.250, gamma=4.350, train_loss=589.8997, val_loss=564.0758]
Training UniVI: 33%|███▎ | 133/400 [03:26<06:48, 1.53s/it, beta=1.250, gamma=4.350, train_loss=589.1749, val_loss=563.0874]
Training UniVI: 34%|███▎ | 134/400 [03:26<06:46, 1.53s/it, beta=1.250, gamma=4.350, train_loss=589.1749, val_loss=563.0874]
Training UniVI: 34%|███▎ | 134/400 [03:28<06:46, 1.53s/it, beta=1.250, gamma=4.350, train_loss=589.8703, val_loss=562.7892]
Training UniVI: 34%|███▍ | 135/400 [03:28<06:48, 1.54s/it, beta=1.250, gamma=4.350, train_loss=589.8703, val_loss=562.7892]
Training UniVI: 34%|███▍ | 135/400 [03:29<06:48, 1.54s/it, beta=1.250, gamma=4.350, train_loss=589.3388, val_loss=563.6404]
Training UniVI: 34%|███▍ | 136/400 [03:29<06:53, 1.57s/it, beta=1.250, gamma=4.350, train_loss=589.3388, val_loss=563.6404]
Training UniVI: 34%|███▍ | 136/400 [03:31<06:53, 1.57s/it, beta=1.250, gamma=4.350, train_loss=589.1556, val_loss=562.9666]
Training UniVI: 34%|███▍ | 137/400 [03:31<06:49, 1.56s/it, beta=1.250, gamma=4.350, train_loss=589.1556, val_loss=562.9666]
Training UniVI: 34%|███▍ | 137/400 [03:32<06:49, 1.56s/it, beta=1.250, gamma=4.350, train_loss=589.4346, val_loss=562.9344]
Training UniVI: 34%|███▍ | 138/400 [03:32<06:55, 1.59s/it, beta=1.250, gamma=4.350, train_loss=589.4346, val_loss=562.9344]
Training UniVI: 34%|███▍ | 138/400 [03:34<06:55, 1.59s/it, beta=1.250, gamma=4.350, train_loss=589.1638, val_loss=562.6082]
Training UniVI: 35%|███▍ | 139/400 [03:34<06:50, 1.57s/it, beta=1.250, gamma=4.350, train_loss=589.1638, val_loss=562.6082]
Training UniVI: 35%|███▍ | 139/400 [03:36<06:50, 1.57s/it, beta=1.250, gamma=4.350, train_loss=589.3590, val_loss=562.5450]
Training UniVI: 35%|███▌ | 140/400 [03:36<06:49, 1.58s/it, beta=1.250, gamma=4.350, train_loss=589.3590, val_loss=562.5450]
Training UniVI: 35%|███▌ | 140/400 [03:37<06:49, 1.58s/it, beta=1.250, gamma=4.350, train_loss=589.1050, val_loss=563.5695]
Training UniVI: 35%|███▌ | 141/400 [03:37<06:43, 1.56s/it, beta=1.250, gamma=4.350, train_loss=589.1050, val_loss=563.5695]
Training UniVI: 35%|███▌ | 141/400 [03:39<06:43, 1.56s/it, beta=1.250, gamma=4.350, train_loss=588.5941, val_loss=562.1112]
[2026-09-21 01:02:31,635] [UniVITrainer] [INFO] [Epoch 142] New best val loss: 562.1112
Training UniVI: 36%|███▌ | 142/400 [03:39<06:39, 1.55s/it, beta=1.250, gamma=4.350, train_loss=588.5941, val_loss=562.1112]
Training UniVI: 36%|███▌ | 142/400 [03:40<06:39, 1.55s/it, beta=1.250, gamma=4.350, train_loss=588.5826, val_loss=562.6511]
Training UniVI: 36%|███▌ | 143/400 [03:40<06:37, 1.55s/it, beta=1.250, gamma=4.350, train_loss=588.5826, val_loss=562.6511]
Training UniVI: 36%|███▌ | 143/400 [03:42<06:37, 1.55s/it, beta=1.250, gamma=4.350, train_loss=588.1487, val_loss=563.5067]
Training UniVI: 36%|███▌ | 144/400 [03:42<06:35, 1.54s/it, beta=1.250, gamma=4.350, train_loss=588.1487, val_loss=563.5067]
Training UniVI: 36%|███▌ | 144/400 [03:43<06:35, 1.54s/it, beta=1.250, gamma=4.350, train_loss=588.6915, val_loss=562.8868]
Training UniVI: 36%|███▋ | 145/400 [03:43<06:31, 1.54s/it, beta=1.250, gamma=4.350, train_loss=588.6915, val_loss=562.8868]
Training UniVI: 36%|███▋ | 145/400 [03:45<06:31, 1.54s/it, beta=1.250, gamma=4.350, train_loss=588.2909, val_loss=563.2031]
Training UniVI: 36%|███▋ | 146/400 [03:45<06:29, 1.53s/it, beta=1.250, gamma=4.350, train_loss=588.2909, val_loss=563.2031]
Training UniVI: 36%|███▋ | 146/400 [03:46<06:29, 1.53s/it, beta=1.250, gamma=4.350, train_loss=588.4942, val_loss=562.6237]
Training UniVI: 37%|███▋ | 147/400 [03:46<06:29, 1.54s/it, beta=1.250, gamma=4.350, train_loss=588.4942, val_loss=562.6237]
Training UniVI: 37%|███▋ | 147/400 [03:48<06:29, 1.54s/it, beta=1.250, gamma=4.350, train_loss=588.6310, val_loss=563.2789]
Training UniVI: 37%|███▋ | 148/400 [03:48<06:29, 1.54s/it, beta=1.250, gamma=4.350, train_loss=588.6310, val_loss=563.2789]
Training UniVI: 37%|███▋ | 148/400 [03:49<06:29, 1.54s/it, beta=1.250, gamma=4.350, train_loss=588.1923, val_loss=563.5789]
Training UniVI: 37%|███▋ | 149/400 [03:49<06:31, 1.56s/it, beta=1.250, gamma=4.350, train_loss=588.1923, val_loss=563.5789]
[2026-09-21 01:02:43,913] [UniVITrainer] [INFO] [Epoch 150] Train loss=588.4368 (beta=1.250, gamma=4.350)
[2026-09-21 01:02:44,003] [UniVITrainer] [INFO] [Epoch 150] Val loss=563.2269 (beta=1.250, gamma=4.350)
Training UniVI: 37%|███▋ | 149/400 [03:51<06:31, 1.56s/it, beta=1.250, gamma=4.350, train_loss=588.4368, val_loss=563.2269]
Training UniVI: 38%|███▊ | 150/400 [03:51<06:28, 1.55s/it, beta=1.250, gamma=4.350, train_loss=588.4368, val_loss=563.2269]
Training UniVI: 38%|███▊ | 150/400 [03:53<06:28, 1.55s/it, beta=1.250, gamma=4.350, train_loss=588.3859, val_loss=563.1212]
Training UniVI: 38%|███▊ | 151/400 [03:53<06:26, 1.55s/it, beta=1.250, gamma=4.350, train_loss=588.3859, val_loss=563.1212]
Training UniVI: 38%|███▊ | 151/400 [03:54<06:26, 1.55s/it, beta=1.250, gamma=4.350, train_loss=588.3397, val_loss=562.6656]
Training UniVI: 38%|███▊ | 152/400 [03:54<06:23, 1.55s/it, beta=1.250, gamma=4.350, train_loss=588.3397, val_loss=562.6656]
Training UniVI: 38%|███▊ | 152/400 [03:56<06:23, 1.55s/it, beta=1.250, gamma=4.350, train_loss=588.1694, val_loss=563.5648]
Training UniVI: 38%|███▊ | 153/400 [03:56<06:20, 1.54s/it, beta=1.250, gamma=4.350, train_loss=588.1694, val_loss=563.5648]
Training UniVI: 38%|███▊ | 153/400 [03:57<06:20, 1.54s/it, beta=1.250, gamma=4.350, train_loss=588.1359, val_loss=562.8400]
Training UniVI: 38%|███▊ | 154/400 [03:57<06:18, 1.54s/it, beta=1.250, gamma=4.350, train_loss=588.1359, val_loss=562.8400]
Training UniVI: 38%|███▊ | 154/400 [03:59<06:18, 1.54s/it, beta=1.250, gamma=4.350, train_loss=588.4912, val_loss=563.3677]
Training UniVI: 39%|███▉ | 155/400 [03:59<06:16, 1.54s/it, beta=1.250, gamma=4.350, train_loss=588.4912, val_loss=563.3677]
Training UniVI: 39%|███▉ | 155/400 [04:00<06:16, 1.54s/it, beta=1.250, gamma=4.350, train_loss=588.2675, val_loss=563.3976]
Training UniVI: 39%|███▉ | 156/400 [04:00<06:13, 1.53s/it, beta=1.250, gamma=4.350, train_loss=588.2675, val_loss=563.3976]
Training UniVI: 39%|███▉ | 156/400 [04:02<06:13, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.9288, val_loss=563.0774]
Training UniVI: 39%|███▉ | 157/400 [04:02<06:12, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.9288, val_loss=563.0774]
Training UniVI: 39%|███▉ | 157/400 [04:03<06:12, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.6100, val_loss=563.4537]
Training UniVI: 40%|███▉ | 158/400 [04:03<06:11, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.6100, val_loss=563.4537]
Training UniVI: 40%|███▉ | 158/400 [04:05<06:11, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.4532, val_loss=562.8994]
Training UniVI: 40%|███▉ | 159/400 [04:05<06:12, 1.54s/it, beta=1.250, gamma=4.350, train_loss=587.4532, val_loss=562.8994]
Training UniVI: 40%|███▉ | 159/400 [04:06<06:12, 1.54s/it, beta=1.250, gamma=4.350, train_loss=587.9470, val_loss=562.7375]
Training UniVI: 40%|████ | 160/400 [04:06<06:10, 1.54s/it, beta=1.250, gamma=4.350, train_loss=587.9470, val_loss=562.7375]
Training UniVI: 40%|████ | 160/400 [04:08<06:10, 1.54s/it, beta=1.250, gamma=4.350, train_loss=587.8138, val_loss=563.4728]
Training UniVI: 40%|████ | 161/400 [04:08<06:06, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.8138, val_loss=563.4728]
Training UniVI: 40%|████ | 161/400 [04:09<06:06, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.6317, val_loss=563.4167]
Training UniVI: 40%|████ | 162/400 [04:09<06:03, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.6317, val_loss=563.4167]
Training UniVI: 40%|████ | 162/400 [04:11<06:03, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.2909, val_loss=564.2297]
Training UniVI: 41%|████ | 163/400 [04:11<06:02, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.2909, val_loss=564.2297]
Training UniVI: 41%|████ | 163/400 [04:12<06:02, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.2202, val_loss=562.2927]
Training UniVI: 41%|████ | 164/400 [04:12<06:00, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.2202, val_loss=562.2927]
Training UniVI: 41%|████ | 164/400 [04:14<06:00, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.8414, val_loss=563.6866]
Training UniVI: 41%|████▏ | 165/400 [04:14<06:00, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.8414, val_loss=563.6866]
Training UniVI: 41%|████▏ | 165/400 [04:16<06:00, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.6000, val_loss=563.0455]
Training UniVI: 42%|████▏ | 166/400 [04:16<05:58, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.6000, val_loss=563.0455]
Training UniVI: 42%|████▏ | 166/400 [04:17<05:58, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.2424, val_loss=563.3159]
Training UniVI: 42%|████▏ | 167/400 [04:17<05:59, 1.54s/it, beta=1.250, gamma=4.350, train_loss=587.2424, val_loss=563.3159]
Training UniVI: 42%|████▏ | 167/400 [04:19<05:59, 1.54s/it, beta=1.250, gamma=4.350, train_loss=587.2845, val_loss=563.1484]
Training UniVI: 42%|████▏ | 168/400 [04:19<05:56, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.2845, val_loss=563.1484]
Training UniVI: 42%|████▏ | 168/400 [04:20<05:56, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.5021, val_loss=563.7892]
Training UniVI: 42%|████▏ | 169/400 [04:20<05:53, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.5021, val_loss=563.7892]
Training UniVI: 42%|████▏ | 169/400 [04:22<05:53, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.6455, val_loss=563.5106]
Training UniVI: 42%|████▎ | 170/400 [04:22<05:52, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.6455, val_loss=563.5106]
Training UniVI: 42%|████▎ | 170/400 [04:23<05:52, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.8624, val_loss=564.3004]
Training UniVI: 43%|████▎ | 171/400 [04:23<05:49, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.8624, val_loss=564.3004]
Training UniVI: 43%|████▎ | 171/400 [04:25<05:49, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.6509, val_loss=563.8875]
Training UniVI: 43%|████▎ | 172/400 [04:25<05:49, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.6509, val_loss=563.8875]
Training UniVI: 43%|████▎ | 172/400 [04:26<05:49, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.4847, val_loss=563.3040]
Training UniVI: 43%|████▎ | 173/400 [04:26<05:48, 1.53s/it, beta=1.250, gamma=4.350, train_loss=587.4847, val_loss=563.3040]
Training UniVI: 43%|████▎ | 173/400 [04:28<05:48, 1.53s/it, beta=1.250, gamma=4.350, train_loss=586.9467, val_loss=563.4670]
Training UniVI: 44%|████▎ | 174/400 [04:28<05:53, 1.57s/it, beta=1.250, gamma=4.350, train_loss=586.9467, val_loss=563.4670]
Training UniVI: 44%|████▎ | 174/400 [04:30<05:53, 1.57s/it, beta=1.250, gamma=4.350, train_loss=587.0496, val_loss=564.0400]
Training UniVI: 44%|████▍ | 175/400 [04:30<05:54, 1.57s/it, beta=1.250, gamma=4.350, train_loss=587.0496, val_loss=564.0400]
Training UniVI: 44%|████▍ | 175/400 [04:31<05:54, 1.57s/it, beta=1.250, gamma=4.350, train_loss=586.9175, val_loss=563.4199]
Training UniVI: 44%|████▍ | 176/400 [04:31<05:50, 1.56s/it, beta=1.250, gamma=4.350, train_loss=586.9175, val_loss=563.4199]
Training UniVI: 44%|████▍ | 176/400 [04:33<05:50, 1.56s/it, beta=1.250, gamma=4.350, train_loss=586.4289, val_loss=563.0624]
Training UniVI: 44%|████▍ | 177/400 [04:33<05:47, 1.56s/it, beta=1.250, gamma=4.350, train_loss=586.4289, val_loss=563.0624]
Training UniVI: 44%|████▍ | 177/400 [04:34<05:47, 1.56s/it, beta=1.250, gamma=4.350, train_loss=586.7579, val_loss=564.5703]
Training UniVI: 44%|████▍ | 178/400 [04:34<05:42, 1.54s/it, beta=1.250, gamma=4.350, train_loss=586.7579, val_loss=564.5703]
Training UniVI: 44%|████▍ | 178/400 [04:36<05:42, 1.54s/it, beta=1.250, gamma=4.350, train_loss=586.5503, val_loss=563.9557]
Training UniVI: 45%|████▍ | 179/400 [04:36<05:42, 1.55s/it, beta=1.250, gamma=4.350, train_loss=586.5503, val_loss=563.9557]
Training UniVI: 45%|████▍ | 179/400 [04:37<05:42, 1.55s/it, beta=1.250, gamma=4.350, train_loss=586.6799, val_loss=563.6429]
Training UniVI: 45%|████▌ | 180/400 [04:37<05:40, 1.55s/it, beta=1.250, gamma=4.350, train_loss=586.6799, val_loss=563.6429]
Training UniVI: 45%|████▌ | 180/400 [04:39<05:40, 1.55s/it, beta=1.250, gamma=4.350, train_loss=586.7406, val_loss=563.6834]
Training UniVI: 45%|████▌ | 181/400 [04:39<05:37, 1.54s/it, beta=1.250, gamma=4.350, train_loss=586.7406, val_loss=563.6834]
Training UniVI: 45%|████▌ | 181/400 [04:40<05:37, 1.54s/it, beta=1.250, gamma=4.350, train_loss=586.2413, val_loss=563.8001]
Training UniVI: 46%|████▌ | 182/400 [04:40<05:35, 1.54s/it, beta=1.250, gamma=4.350, train_loss=586.2413, val_loss=563.8001]
Training UniVI: 46%|████▌ | 182/400 [04:42<05:35, 1.54s/it, beta=1.250, gamma=4.350, train_loss=586.6578, val_loss=563.6293]
Training UniVI: 46%|████▌ | 183/400 [04:42<05:33, 1.54s/it, beta=1.250, gamma=4.350, train_loss=586.6578, val_loss=563.6293]
Training UniVI: 46%|████▌ | 183/400 [04:43<05:33, 1.54s/it, beta=1.250, gamma=4.350, train_loss=586.5840, val_loss=564.9703]
Training UniVI: 46%|████▌ | 184/400 [04:43<05:30, 1.53s/it, beta=1.250, gamma=4.350, train_loss=586.5840, val_loss=564.9703]
Training UniVI: 46%|████▌ | 184/400 [04:45<05:30, 1.53s/it, beta=1.250, gamma=4.350, train_loss=586.8725, val_loss=563.4805]
Training UniVI: 46%|████▋ | 185/400 [04:45<05:28, 1.53s/it, beta=1.250, gamma=4.350, train_loss=586.8725, val_loss=563.4805]
Training UniVI: 46%|████▋ | 185/400 [04:46<05:28, 1.53s/it, beta=1.250, gamma=4.350, train_loss=586.5367, val_loss=564.2125]
Training UniVI: 46%|████▋ | 186/400 [04:46<05:27, 1.53s/it, beta=1.250, gamma=4.350, train_loss=586.5367, val_loss=564.2125]
Training UniVI: 46%|████▋ | 186/400 [04:48<05:27, 1.53s/it, beta=1.250, gamma=4.350, train_loss=586.6665, val_loss=563.4631]
Training UniVI: 47%|████▋ | 187/400 [04:48<05:32, 1.56s/it, beta=1.250, gamma=4.350, train_loss=586.6665, val_loss=563.4631]
Training UniVI: 47%|████▋ | 187/400 [04:50<05:32, 1.56s/it, beta=1.250, gamma=4.350, train_loss=586.3489, val_loss=563.3010]
Training UniVI: 47%|████▋ | 188/400 [04:50<05:28, 1.55s/it, beta=1.250, gamma=4.350, train_loss=586.3489, val_loss=563.3010]
Training UniVI: 47%|████▋ | 188/400 [04:51<05:28, 1.55s/it, beta=1.250, gamma=4.350, train_loss=586.2512, val_loss=563.4144]
Training UniVI: 47%|████▋ | 189/400 [04:51<05:26, 1.55s/it, beta=1.250, gamma=4.350, train_loss=586.2512, val_loss=563.4144]
Training UniVI: 47%|████▋ | 189/400 [04:53<05:26, 1.55s/it, beta=1.250, gamma=4.350, train_loss=586.1596, val_loss=563.6163]
Training UniVI: 48%|████▊ | 190/400 [04:53<05:24, 1.54s/it, beta=1.250, gamma=4.350, train_loss=586.1596, val_loss=563.6163]
Training UniVI: 48%|████▊ | 190/400 [04:54<05:24, 1.54s/it, beta=1.250, gamma=4.350, train_loss=586.0810, val_loss=563.8258]
Training UniVI: 48%|████▊ | 191/400 [04:54<05:20, 1.53s/it, beta=1.250, gamma=4.350, train_loss=586.0810, val_loss=563.8258]
Training UniVI: 48%|████▊ | 191/400 [04:56<05:20, 1.53s/it, beta=1.250, gamma=4.350, train_loss=586.1165, val_loss=563.3881]
[2026-09-21 01:03:48,690] [UniVITrainer] [INFO] Early stopping at epoch 192 (best val loss=562.1112, best epoch=142)
Training UniVI: 48%|████▊ | 191/400 [04:56<05:24, 1.55s/it, beta=1.250, gamma=4.350, train_loss=586.1165, val_loss=563.3881]
[2026-09-21 01:03:48,723] [UniVITrainer] [INFO] Restored best model from epoch 142 (val loss=562.1112)
Denoise#
denoise_adata encodes cells and decodes the same modality into a new layer. With adata_by_mod, the encoding uses every modality supplied (the fused posterior), so accessibility also informs the denoised expression.
denoise_adata(model, rna_test, modality="rna", device=device, out_layer="denoised_rna_only")
denoise_adata(model, rna_test, modality="rna", device=device, out_layer="denoised_rna_atac", adata_by_mod=test)
compare_raw_vs_denoised_umap_features(rna_test, obsm_key="X_univi", features=markers[:4],
denoised_layer="denoised_rna_atac")
Denoised values are model estimates: good for visualization and for spotting marker patterns, but they are smoother than real biology and should not replace measured counts in differential-expression tests.
Cross-modal prediction, feature by feature#
rep = evaluate_cross_reconstruction(model, atac_test, rna_test, src_mod="atac", tgt_mod="rna", device=device)
print({k: round(float(v), 3) for k, v in rep["summary"].items()})
plot_featurewise_reconstruction_scatter(rep, features=markers[:4], title="ATAC to RNA: observed vs predicted")
{'mse_mean': 0.536, 'mse_median': 0.207, 'pearson_mean': 0.301, 'pearson_median': 0.278, 'per_cell_mean': 0.536}
Generate cells#
From the prior#
Sampling latent points from the standard-normal prior and decoding them produces synthetic cells. With no target_mod, every modality is decoded from the same latent points, so the generated RNA and ATAC profiles belong together.
generated = generate_from_latent(model, n=N_GENERATED, device=device, z_source="prior")
{mod: x.shape for mod, x in generated.items()}
{'rna': (2000, 2000), 'atac': (2000, 100)}
A quick check: encode the generated RNA and look at it next to real test cells. Prior samples cover the whole region the model has learned, including the space between cell types, so they are useful for exploring the model but are not a substitute for a specific population. For that, sample per cell type (next section).
import anndata as ad
genes = pd.DataFrame(index=rna_test.var_names)
real = ad.AnnData(dense(rna_test.X), obs=rna_test.obs[["cell_type"]].copy(), var=genes)
fake = ad.AnnData(generated["rna"].astype(np.float32), var=genes)
fake.obs_names = [f"generated-{i}" for i in range(fake.n_obs)]
fake.obs["cell_type"] = "generated"
both = ad.concat({"real": real, "generated": fake}, label="source")
both.obsm["X_univi"] = encode_adata(model, both, modality="rna", device=device, latent="modality_mean")
sc.pp.neighbors(both, use_rep="X_univi")
sc.tl.umap(both, random_state=0)
sc.pl.umap(both, color=["source", "cell_type"], wspace=0.45, legend_fontsize=7)
For a chosen cell type#
To generate a specific population, fit a Gaussian to each cell type’s latent embeddings and sample from it.
z_train = encode_adata(model, train["rna"], modality="rna", device=device, latent="modality_mean")
gauss = fit_label_latent_gaussians(z_train, train["rna"].obs["cell_type"].astype(str).to_numpy())
counts = train["rna"].obs["cell_type"].value_counts()
chosen = [c for c in counts.index if c in gauss][:4]
rows = {}
for cell_type in chosen:
z = sample_latent_by_label(gauss, label=cell_type, n=500, random_state=0)
fake = generate_from_latent(model, z=z, target_mod="rna", device=device)
real = dense(rna_test[rna_test.obs["cell_type"] == cell_type].X)
rows[cell_type] = {"generated": pd.Series(fake.mean(0), index=rna_test.var_names)[markers],
"real": pd.Series(real.mean(0), index=rna_test.var_names)[markers]}
fig, axes = plt.subplots(1, len(chosen), figsize=(3.2 * len(chosen), 3), sharey=True)
for ax, (cell_type, r) in zip(np.atleast_1d(axes), rows.items()):
ax.bar(np.arange(len(markers)) - 0.2, r["real"], 0.4, label="real")
ax.bar(np.arange(len(markers)) + 0.2, r["generated"], 0.4, label="generated")
ax.set_xticks(range(len(markers)), markers, rotation=90)
ax.set_title(cell_type)
np.atleast_1d(axes)[0].set_ylabel("mean log-normalized expression")
np.atleast_1d(axes)[0].legend(frameon=False, fontsize=8)
plt.tight_layout()
plt.show()
In-silico perturbation#
predict_feature_perturbation edits one or more input features (set to zero, set to a value, add, or scale), runs the edited and original inputs through the model, and returns the change in the decoded output. Here we switch off a marker gene in the RNA input of the cells that express it most and ask which decoded genes move with it.
This measures what the model has learned to associate with the gene. It is a hypothesis generator, not evidence of causal regulation.
gene = markers[0]
by_type = pd.Series(dense(rna_test[:, gene].X).ravel(), index=rna_test.obs_names).groupby(
rna_test.obs["cell_type"].astype(str)).mean()
target_type = by_type.idxmax()
cells = rna_test[rna_test.obs["cell_type"] == target_type].copy()
result = predict_feature_perturbation(model, cells, source_modality="rna", target_modality="rna",
features=[gene], mode="off", device=device)
effect = pd.Series(result["delta"].mean(0), index=cells.var_names).drop(gene)
print(f"switched off {gene} in {cells.n_obs} {target_type} cells")
pd.concat({"largest decrease": effect.nsmallest(8), "largest increase": effect.nlargest(8)}).round(4)
switched off MS4A1 in 30 Intermediate B cells
genes
largest decrease TBC1D9 -0.0177
AL355076.2 -0.0174
ANK3 -0.0172
SNED1 -0.0149
AIM2 -0.0149
OSBPL10 -0.0142
COL4A3 -0.0126
CSGALNACT1 -0.0115
largest increase IGHD 0.0232
TCL1A 0.0218
IGHM 0.0191
CAMK2D 0.0180
BACH2 0.0163
PCDH9 0.0151
COL19A1 0.0145
MARCH3 0.0132
dtype: float32