Speridlabs Idol

Speridlabs Idol is an image-to-3D model by Speridlabs. It takes one picture of an object and returns the whole object, including the sides the picture never showed, as 3D Gaussian splats. LibreYOLO ports it from the Speridlabs SDK and runs it through the LibreGen factory.

Tasks
3d generation
Install
pip install "libreyolo[gen]"
Support tier
Sibling tier, since v1.7.0. A separate product surface with its own factory and contract.
Upstream
Speridlabs Idol by Speridlabs, Apache-2.0. Paper, source
Licenses
Code MIT and Apache-2.0, weights Apache-2.0. Commercial use

Install

bash
pip install "libreyolo[gen]"

The gen extra installs diffusers, transformers and accelerate. Speridlabs Idol reads its DINOv3 encoder through transformers and its FLUX.2 VAE through diffusers. Importing LibreGen does not import either; they load on first use.

Predict

Python
from libreyolo import LibreGen # An example image from the Speridlabs Idol SDK. A local path, a PIL# image, a NumPy array or a folder of images works the same way.IMAGE = "https://raw.githubusercontent.com/speridlabs/idol-sdk/4702a7f00850e34b6e83a2170cc123c3e9570744/demo/examples/nb-armchair.webp" model = LibreGen("speridlabs-idol")   # weights download on first useresult = model(IMAGE, seed=0) result.save("armchair.ply")           # standard 3DGS layoutresult.save("armchair.splat")         # compact web formatprint(len(result.gaussians))          # 262144 at the defaults
CLI
# Saves the object as .ply under runs/generate/predict.libreyolo generate source=https://raw.githubusercontent.com/speridlabs/idol-sdk/4702a7f00850e34b6e83a2170cc123c3e9570744/demo/examples/nb-armchair.webp seed=0
Settings
from libreyolo import LibreGen IMAGE = "https://raw.githubusercontent.com/speridlabs/idol-sdk/4702a7f00850e34b6e83a2170cc123c3e9570744/demo/examples/nb-armchair.webp" model = LibreGen("speridlabs-idol") result = model(IMAGE, mode="real")             # photographs: a looser cropresult = model(IMAGE, gaussians=1_048_576)     # more detailresult = model(IMAGE, steps=25)                # faster, a little less detail # Two objects from one image, seeds 7 and 8, written to runs/generate/predict.results = model(IMAGE, seed=7, n=2, save=True)
Results
from libreyolo import LibreGen IMAGE = "https://raw.githubusercontent.com/speridlabs/idol-sdk/4702a7f00850e34b6e83a2170cc123c3e9570744/demo/examples/nb-armchair.webp" model = LibreGen("speridlabs-idol")result = model(IMAGE) g = result.gaussiansprint(g.xyz.shape, g.scales.shape, g.rotations.shape)   # (N, 3), (N, 3), (N, 4) wxyzprint(g.opacities.shape, g.colors.shape)                 # (N,), (N, 3) RGBprint(g.camera)                                          # the inferred input viewprint(g.seed, g.params)                                  # how to make it again g.input_image.save("crop.png")         # what the model saw after its cropresult.plot().save("preview.png")      # point-render previewg[g.opacities > 0.1].save("opaque.ply")

The source is anything predict takes: a path, URL, PIL.Image, NumPy array (BGR), tensor, a folder of images, or a list of them. An image file or PIL.Image with real transparency is used as the object's cutout. Any other input has its background removed first, by LibreYOLO's BiRefNet network with the BiRefNet weights from the Idol snapshot. The input resolution is fixed, so imgsz raises, and so does prompt=: the model has no text input.

The first call downloads about 5 GB at pinned revisions, with nothing gated and no Hugging Face login: Idol's own weights (about 3.1 GB) from Speridlabs' repository speridlabs/idol into weights/LibreSperidlabsIdol0.6b/, plus two image encoders into the Hugging Face cache, the DINOv3 ViT-H+/16 encoder (1.7 GB) and the FLUX.2 VAE (0.2 GB). LibreGen(path) loads a local directory that holds the snapshot files instead.

One source with n=1 returns a Results; several sources or n > 1 return a list, and stream=True a generator. result.gaussians holds the object in its own frame: z up, centered in the cube [-0.5, 0.5]^3. save() picks the format from the extension. A .ply is the standard 3D Gaussian Splatting layout, turned y-up the way splat viewers and trainers expect, with the seed, camera and settings stored in a header comment. A .splat is the compact web format, 32 bytes per Gaussian. result.plot() returns a point render from the inferred input view, a quick look rather than a Gaussian rasterization. The 3D generation task page describes the payload in full.

A seed, with the same model and settings, gives the same object. Object i of a source uses seed + i; without a seed, a fresh one is drawn and recorded in result.gaussians.seed. As in the SDK, the seed drives a random generator on the model's device, so one seed gives different objects on CUDA, MPS and CPU. On CUDA a seed gives the object the Speridlabs SDK gives for the same seed and settings. Rarely, part of the Gaussians land differently from one run to the next while the object stays the same: one attention step runs on a cuDNN kernel whose result depends on GPU memory history, in the SDK as in the port.

Objects generated from photos, with their source images, are in the article Speridlabs Idol in LibreYOLO: one image to a 3D object.

Settings

Every setting has a default, so all are optional. A name the model does not have raises and lists the supported ones.

SettingDefaultMeaning
steps50Sampling steps. Fewer run faster and lose some detail.
guidance3.0Classifier-free guidance; 0 turns it off.
shift3.0Flow time shift toward high noise.
gaussians262144Gaussians in the output, from 32,768 to 1,048,576, rounded down to a multiple of 32.
mode"synthetic""synthetic" for renders and generated images, "real" for photographs. Sets how much room the crop leaves around the object: a crop side of 1.2 or 1.7 times the object size.
marginNoneAn explicit crop side over object size, at least 1. Overrides mode.

The constructor takes device ("auto" picks CUDA, then MPS, then CPU) and compile. compile=True needs CUDA: it compiles the denoiser blocks, runs the guided and unguided passes in one batch, and uses cuDNN attention and TF32 matmuls while sampling, the same path as the SDK's optimized sampling. It reproduces that compiled path; against the eager path it gives the same object, not the same Gaussians. The model runs in its published mixed precision (fp16 transformer blocks, bf16 encoders), so dtype accepts only "auto".

Speed and memory

Time per object at the default settings, one object per call, in the published mixed precision:

DeviceRuntimeTime per object (s)
NVIDIA H100CUDA, eager9.8
NVIDIA H100CUDA, compile=True, after the first call6.4
Apple M4 ProMPS, eager464 to 467

The M4 Pro figures are two objects on one machine, the first including the model load from local disk. Speridlabs Idol runs in under 8 GB of GPU memory. Speridlabs publishes request times for its SDK on ten GPUs, from 3.4 s on a B300 to 54.6 s on an L4, on the Idol research page.

Export

TaskONNXTorchScriptExecuTorchTensorRTOpenVINOPaddleMNNRKNNncnnTFLiteCoreMLCore AI
3D generation3D generation to ONNX: not supported3D generation to TorchScript: not supported3D generation to ExecuTorch: not supported3D generation to TensorRT: not supported3D generation to OpenVINO: not supported3D generation to Paddle: not supported3D generation to MNN: not supported3D generation to RKNN: not supported3D generation to ncnn: not supported3D generation to TFLite: not supported3D generation to CoreML: not supported3D generation to Core AI: not supported

Export is not implemented: the model is a sampling loop over several networks, and LibreYOLO has no exportable graph contract for that yet (ADR 0031 in the library). export(), train() and val() raise NotImplementedError. train(data=...) is reserved for fine-tuning on image and 3D object pairs, and val(data=...) for rendered-view metrics.

Licensing

Check the license on the Hugging Face repository of the specific weights you download. Every checkpoint in the LibreYOLO org carries one, and they are not always the same across a family. That repository is the authoritative source; the summary below describes what applied when this page was last verified.

This is a description of the licenses involved, not legal advice. If the answer matters commercially, read the licenses yourself and take your own counsel.

Original work
Speridlabs Idol, Speridlabs
Upstream license
Apache-2.0
LibreYOLO code
MIT
Weights
Apache-2.0, distributed by their authors. LibreYOLO does not host or mirror them.
Interpretation
Apache-2.0 is a permissive license, so the Speridlabs Idol code and weights can be used in commercial and closed-source products. Redistributing them means keeping the license text and notices, and the license grants a patent license. LibreYOLO's adapter is MIT; the Idol networks it ports from the Speridlabs SDK keep Apache-2.0, alongside the MIT code from TripoSplat that Idol builds on, with their notices in libreyolo/models/gen/speridlabs_idol/NOTICE. Idol's own weights download from Speridlabs' Hugging Face repository, speridlabs/idol, and the FLUX.2 VAE from black-forest-labs/FLUX.2-klein-4B, both Apache-2.0. The DINOv3 image encoder is the exception: it is Meta's, under the DINOv3 License, a custom agreement that is not OSI-approved. It permits redistribution with a copy of the agreement and passes through trade-control and end-use restrictions (military, weapons, espionage and nuclear uses among them). LibreYOLO mirrors that encoder in bfloat16 at LibreYOLO/LibreDINOv3vith16plus together with the agreement, so nothing is gated; read the agreement before shipping a product on it.

Speridlabs Idol is the work of Alejandro Cañada and Chema Garabito at Speridlabs. Its code is the Idol SDK and its weights are speridlabs/idol, both Apache-2.0. LibreYOLO does not mirror those weights: they download from Speridlabs' repository, so the downloads count for its authors.

The DINOv3 encoder is the one file LibreYOLO hosts for this model, at LibreYOLO/LibreDINOv3vith16plus. It is Meta's checkpoint cast to bfloat16, the precision Idol runs it in: all 615 tensors equal the upstream ones loaded in bfloat16, so outputs do not change. Meta's own copy sits behind a manually reviewed access form; the mirror ships the DINOv3 License agreement and has no gate. The FLUX.2 VAE downloads from black-forest-labs/FLUX.2-klein-4B under Apache-2.0. LibreYOLO logs this license summary once per process, when it loads the weights.

Citation

@misc{canada2026idol,
  title  = {Idol: Single Image to 3D Gaussian Splats},
  author = {Ca{\~n}ada, Alejandro and Garabito, Chema},
  year   = {2026},
  url    = {https://speridlabs.com/research/idol}
}

Copied from the authors' citation block at speridlabs.com/research/idol#citation.

Verified against LibreYOLO v1.7.0. Support tables, checkpoints and benchmark numbers on this page are generated from the released library and the published weights, not written by hand.