Squidiff 1.0.8
repository·main·Indexed 41 days ago
https://github.com/siyuh/squidiffA diffusion model-based generative framework designed to predict transcriptomic changes across diverse cell types in response to environmental changes, drug treatments, cell differentiation, or gene perturbations. It features a specialized MLPModel architecture for single-cell RNA-seq data, supporting semantic latent embeddings and drug structural information.
What's inside Squidiff
- Squidiff is a generative framework based on diffusion models. It is designed to predict transcriptomic changes across diverse cell types when they are subjected to various environmental perturbations or changes.
Model Input Requirements
mainSquidiff requires an
.h5adfile containing the following information:- Single-cell count matrix
- Meta data
- (Optional) Additional drug compounds
Install Squidiff via pip
mainInstall the Squidiff package using pip to begin using the diffusion model-based generative framework for predicting transcriptomic changes.
pip install SquidiffHow ScheduleSampler works and its subclasses
mainA
ScheduleSamplerdefines a distribution over timesteps in the diffusion process to reduce objective variance.Core Logic
By default, samplers use unbiased importance sampling. The
sample()method calculates probabilities based onweights(), then returns weights calculated as1 / (len(p) * p[indices])to ensure the expected value of the loss remains unchanged.Subclasses
UniformSampler: Provides a constant weight for all timesteps.LossAwareSampler: An abstract base for samplers that can update their weights based on model loss. It provides the synchronization logic viaupdate_with_local_losses.LossSecondMomentResampler: A concrete implementation ofLossAwareSampler. It tracks a history of losses for each timestep and uses the square root of the mean squared loss (second moment) to prioritize timesteps with higher variance/error. It includes auniform_probto ensure all timesteps retain a minimum probability of being sampled.
How TimestepBlock and TimestepEmbedSequential work
mainThe project uses a specialized hierarchy for modules that need to be aware of diffusion timesteps.
TimestepBlock: An abstract base class (interface) for any module whoseforwardmethod accepts(x, emb, z_sem).x: The input tensor.emb: Timestep embeddings.z_sem: Semantic latent embeddings.
MLPBlock: A concrete implementation ofTimestepBlock. It uses two linear layers with LayerNorm and SiLU activation. It conditionally addsembandz_semto the hidden state via learned linear projections (time_denseandzsem_dense).TimestepEmbedSequential: A specialized version ofnn.Sequential. When iterating through its layers, it checks if a layer is an instance ofTimestepBlock. If so, it passesx,emb, andz_sem. Otherwise, it passes onlyx. This allows mixing standard PyTorch layers with timestep-aware layers in a single sequence.
# Conceptual usage of TimestepEmbedSequential # It automatically handles the distribution of embeddings to compatible layers from Squidiff.MLPModel import TimestepEmbedSequential, MLPBlock layers = TimestepEmbedSequential( MLPBlock(128, 128, time_embed_dim=64, latent_dim=32), MLPBlock(128, 128, time_embed_dim=64, latent_dim=32) ) # The call passes emb and z_sem to both MLPBlocks output = layers(x=input_tensor, emb=time_emb, z_sem=semantic_emb)Train the Squidiff model via CLI
mainThe
train_squidiff.pyscript is the primary entrypoint for training the perturbation-conditioned generative diffusion model. It uses a command-line interface to configure model architecture, diffusion parameters, and training hyperparameters.To run training, you must provide at least
--logger_pathand--data_pathvia the CLI. The script supports distributed training and can resume from a checkpoint using--resume_checkpoint.# Example command to start training python train_squidiff.py \ --data_path "/path/to/adata/" \ --logger_path "/path/to/logs/" \ --batch_size 128 \ --lr 1e-4 \ --use_fp16 TrueSample transcriptomics using sample_squidiff.sampler
mainUse the
sample_squidiff.samplerto generate predicted transcriptomics. The process involves initializing a sampler with a model path, gene size, output dimension, and drug structure preference, then encoding test data through the model's encoder before calling.pred()to get the predictions.sampler = sample_squidiff.sampler( model_path = 'simu_results/model.pt', gene_size = 100, output_dim = 100, use_drug_structure = False ) test_adata_scrna = sc.read_h5ad('datasets/sc_simu_test.h5ad') z_sem_scrna = sampler.model.encoder(torch.tensor(test_adata_scrna.X).to('cuda')) scrnas_pred = sampler.pred(z_sem_scrna, gene_size = test_adata_scrna.shape[1])Dump logged metrics to files
mainTo write the currently buffered key-value metrics to the output files (CSV, JSON, etc.), call
dumpkvs(). This operation clears the internal buffer and returns the dictionary of values that were just written.from Squidiff import dumpkvs # Inside a training loop metrics = dumpkvs() # Writes to files and clears bufferLog key-value pairs and running means
mainThe logger allows tracking metrics using key-value pairs. These metrics are aggregated and can be dumped to the configured output formats (like CSV or JSON).
logkv(key, val): Records a single value for a specific key. Subsequent calls to the same key will overwrite the previous value in the current buffer.logkv_mean(key, val): Calculates a running average for the specified key. This is useful for tracking epoch-level losses or accuracies.logkvs(d): A convenience function to log multiple key-value pairs from a dictionaryd.
from Squidiff import logkv, logkv_mean, logkvs # Log a single metric logkv("learning_rate", 0.001) # Log a running average (e.g., loss) logkv_mean("loss", 0.5) # Log multiple metrics at once logkvs({"accuracy": 0.95, "step": 100})Configure the global logger
mainUse
configure(dir, format_strs=None, log_suffix="")to initialize the globalLoggerinstance. This sets up where logs are stored and which output formats are used.dir: The directory where log files will be created.format_strs: A list or comma-separated string of formats. Supported formats arestdout,log,json, andcsv.log_suffix: An optional string to append to filenames.
If
configureis not called, callingget_current()will trigger a default configuration using theOPENAI_LOG_FORMATenvironment variable.from Squidiff import configure configure(dir="./logs", format_strs=["stdout", "csv", "json"], log_suffix="_experiment1")Use standard logging levels
mainThe module provides standard logging functions to print messages to the configured output formats (e.g.,
stdoutor a.txtlog file).Available levels:
debug(args)info(args)warn(args)error(args)
Constants for levels:
DEBUG=10,INFO=20,WARN=30,ERROR=40,DISABLED=50.from Squidiff import info, warn, error info("Starting training...") warn("Loss is diverging!") error("Failed to load checkpoint.")Default configuration dictionaries
mainThe following functions return dictionaries of default parameters for different components of the system:
diffusion_defaults(): Returns defaults for diffusion training (e.g.,learn_sigma,diffusion_steps,noise_schedule,timestep_respacing,use_kl,predict_xstart,rescale_timesteps,rescale_learned_sigmas).classifier_defaults(): Returns defaults for classifier models (e.g.,gene_size,classifier_use_fp16,classifier_width,classifier_depth,classifier_attention_resolutions,classifier_use_scale_shift_norm,classifier_pool).model_and_diffusion_defaults(): Returns a combined dictionary for training a standard model, includingoutput_dim,num_layers,gene_size,num_channels,dropout,class_cond,use_checkpoint,use_scale_shift_norm,use_fp16,use_encoder,use_drug_structure,drug_dimension, andcomb_num, merged withdiffusion_defaults().classifier_and_diffusion_defaults(): Returns a combined dictionary for classifier training, mergingclassifier_defaults()withdiffusion_defaults().sr_model_and_diffusion_defaults(): Returns defaults specifically for Super Resolution, includinglarge_sizeandsmall_size, filtered to match the arguments required bysr_create_model_and_diffusion.