Instructions to use Efficient-Large-Model/Sol-H3-VAE with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use Efficient-Large-Model/Sol-H3-VAE with Diffusers:
pip install -U diffusers transformers accelerate
import torch from diffusers import DiffusionPipeline # switch to "mps" for apple devices pipe = DiffusionPipeline.from_pretrained("Efficient-Large-Model/Sol-H3-VAE", dtype=torch.bfloat16, device_map="cuda") prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" image = pipe(prompt).images[0] - Notebooks
- Google Colab
- Kaggle
Download code/spark_compat.py from Efficient-Large-Model/Sol-H3-VAE: direct link, hf CLI and curl.
- Browser
- Download file 3.37 kB
-
https://huggingface.co/Efficient-Large-Model/Sol-H3-VAE/resolve/main/code/spark_compat.py
- Command line
-
hf download hf://Efficient-Large-Model/Sol-H3-VAE/code/spark_compat.py
-
curl -L -o spark_compat.py https://huggingface.co/Efficient-Large-Model/Sol-H3-VAE/resolve/main/code/spark_compat.py
3.37 kB
| """Decoder template from the H3 VAE config (no H3 VAE weights needed). | |
| The checkpoint holds every decoder parameter: the template is built on meta, then the | |
| checkpoint is strictly assigned. QK normalization and rotary embedding follow the Diffusers | |
| H3 source (MiniMaxH3VideoAttnProcessor). | |
| """ | |
| from types import SimpleNamespace | |
| import torch | |
| from torch import nn | |
| from torch.nn import functional as F | |
| def _apply_qk_norm(norm, x): | |
| return norm(x.float()).to(x.dtype) | |
| def _apply_rotary_pos_emb_impl(x, emb): | |
| cos, sin = (t.to(x.dtype) for t in emb) | |
| dim = cos.shape[-1] | |
| a, tail = x[..., :dim], x[..., dim:] | |
| first, second = a.chunk(2, dim=-1) | |
| rotated = torch.cat((-second, first), dim=-1) | |
| return torch.cat((a * cos + rotated * sin, tail), dim=-1) | |
| class SwiGLU(nn.Module): | |
| def __init__(self, dim, hidden): | |
| super().__init__() | |
| self.w1 = nn.Linear(dim, 2 * hidden) | |
| self.w2 = nn.Linear(hidden, dim) | |
| def forward(self, x): | |
| gate, up = self.w1(x).chunk(2, dim=-1) | |
| return self.w2(F.silu(gate) * up) | |
| class RGBProcessor: | |
| def revert_tensor(self, x): | |
| # H3 returns ImageNet-normalized RGB, not pixels in [-1, 1]. | |
| mean = x.new_tensor((0.485, 0.456, 0.406)).view(1, 3, 1, 1, 1) | |
| std = x.new_tensor((0.229, 0.224, 0.225)).view(1, 3, 1, 1, 1) | |
| return x * std + mean | |
| def make_template(config): | |
| from diffusers.models.autoencoders.autoencoder_kl_minimax_h3 import MiniMaxH3VideoRotaryPosEmbed | |
| heads = config['decoder_num_attention_heads'] | |
| dh = config['decoder_attention_head_dim'] | |
| dim = heads * dh | |
| eps = config['decoder_norm_eps'] | |
| # These nonpersistent buffers must be real CPU tensors, not meta tensors. | |
| rope = MiniMaxH3VideoRotaryPosEmbed( | |
| int(dh * config['decoder_rope_dim_ratio']), theta=config['decoder_rope_theta']) | |
| mean = torch.tensor(config['latents_mean'], dtype=torch.float32) | |
| std = torch.tensor(config['latents_std'], dtype=torch.float32) | |
| with torch.device('meta'): | |
| dec = nn.Module() | |
| dec.x_embedder = nn.Linear(24, dim) | |
| dec.register_tokens = nn.Parameter(torch.empty(1, config['decoder_num_register_tokens'], dim)) | |
| dec.transformer_blocks = nn.ModuleList() | |
| for _ in range(config['decoder_num_layers']): | |
| block = nn.Module() | |
| block.norm1 = nn.RMSNorm(dim, eps=eps) | |
| block.norm2 = nn.RMSNorm(dim, eps=eps) | |
| block.scale1 = nn.Parameter(torch.empty(dim)) | |
| block.scale2 = nn.Parameter(torch.empty(dim)) | |
| block.attn = nn.Module() | |
| block.attn.heads, block.attn.dim_head = heads, dh | |
| block.attn.to_qkv = nn.Linear(dim, 3 * dim) | |
| block.attn.to_out = nn.Linear(dim, dim) | |
| block.attn.norm_q = nn.RMSNorm(dh, eps=eps, elementwise_affine=False) | |
| block.attn.norm_k = nn.RMSNorm(dh, eps=eps, elementwise_affine=False) | |
| block.ff = SwiGLU(dim, dim * config['decoder_ffn_mult']) | |
| dec.transformer_blocks.append(block) | |
| dec.norm_out = nn.LayerNorm(dim, eps=eps) | |
| dec.proj_out = nn.Linear(dim, 3 * 4 * 16 * 16) | |
| post_quant_conv = nn.Conv3d(24, 24, 1) | |
| dec.pos_embed = rope | |
| return SimpleNamespace(decoder=dec, post_quant_conv=post_quant_conv, | |
| latents_mean=mean, latents_std=std, processor=RGBProcessor()) | |