Lens / Lens-Turbo Loader
The Lens loader that squeezes a 40 GB text encoder onto a 24 GB card
- pipeline
Microsoft's Lens-Turbo is a weird beast, and this loader exists for one reason: getting its enormous text encoder to fit on a normal consumer GPU. Lens itself is a modest 3.8B diffusion transformer, but its text encoder - GPT-OSS-20B - dequantizes to roughly 40 GB of bf16, more than most cards hold. This node's party trick is a hybrid placement mode that parks that encoder on CPU, runs the transformer and VAE on the GPU, and monkey-patches the pipeline so the two halves can talk across the gap. Measured on an RTX 3090: ~11 GB peak VRAM and ~11–15 s per 1024² image at 4 steps. That headline is the whole reason you're reading this page.
LensTurboLoader is the first half of a two-node pack - load it, then hand the result to LensTurboSampler for the actual T2I. It builds the pipeline once, holds it in a module-level cache, and returns a single pipeline output (a custom LENS_PIPELINE type). Wire that straight into the sampler. Classic ComfyUI loader→sampler pattern, just with an unusually heavy load.
The inputs that matter
Most of the required fields have sane defaults and you should leave them alone. The two worth your attention:
repo_id- defaults tomicrosoft/Lens-Turbo, and also acceptsmicrosoft/Lens(the RL-tuned variant, 20 steps) ormicrosoft/Lens-Base(the 50-step research baseline), or an absolute local path to a snapshot you already downloaded. Given Microsoft's record of pulling releases, a local path is arguably the safest choice - more on that in a second.offload_mode- the one knob that matters.cpu_text_encoder(the default) is the whole point: ~11 GB peak VRAM.modelandnoneexpect 48 GB+ of VRAM because the full dequantized encoder has to fit while active.sequentialis listed in the dropdown and is known broken with Lens on accelerate ≥1.x (a meta-tensor bug in layer-level offload). It's there for completeness. Don't touch it.
The rest is cache plumbing: force_reload bypasses the cache and rebuilds, evict_others (on by default) frees any other cached pipeline first, and cpu_construct (also on) builds under torch.device('cpu') so giant RoPE caches and position tables don't OOM you at init. device (cuda:0) and dtype (bf16) are fine as-is. hf_cache_dir only matters if you want a different HF_HOME for this load.
The first load is slow - around two minutes on a 3090 - and it prints a running commentary into comfy.log while it works. After that, the cache keys on (repo, dtype, device, offload, cpu_construct), so subsequent loads are instant. This is exactly why the batch CLI exists: amortize the cold load once, then cruise at ~12 s/image.
How to install it - the honest version
This is not a drop-in custom node. ComfyUI Manager can clone the repo, but the README's real install runs four bash scripts:
cd $COMFY_ROOT/custom_nodes
git clone https://github.com/aadebuger/ComfyUI-LensTurbo
cd ComfyUI-LensTurbo
# 1. Vendor the upstream `lens` Python package (required - LensPipeline won't import without it)
bash scripts/fetch_upstream.sh
# 2. Install Python deps (uv pip; handles Py3.13 overrides, uninstalls broken `kernels`)
bash scripts/install_deps.sh
# 3. Check HF gated access
bash scripts/hf_login_check.sh
hf auth login # if needed
# 4. Pre-download weights (~58 GB, resumable - run in tmux)
bash scripts/download_models.sh
Then restart ComfyUI and confirm the banner:
grep ComfyUI-LensTurbo comfy.log
Non-negotiables before you start: the model repos are gated, so click "Agree" on the HF pages for microsoft/Lens-Turbo and black-forest-labs/FLUX.2-dev (the VAE). The pipeline wants ~48 GB of system RAM even though it only needs 11 GB of VRAM - the encoder lives in host memory. Plus 80 GB of disk for the HF cache. Beefy setup, full stop.
The availability caveat
Microsoft published Lens and Lens-Turbo on Hugging Face in May 2026, gated, and then deleted them days later - the same move it pulled with VibeVoice the year before. The community's standing rule applies here: download interesting Microsoft releases immediately and mirror them. The pack's scripts point at the official repos, so if you hit a 404 or a "repo not found," find a community mirror and point repo_id at the local snapshot instead. It's the most likely thing to trip up a new user - and it has nothing to do with the node.
Troubleshooting
The README's pitfall table is worth a skim, but the top three:
[ComfyUI-LensTurbo/nodes] ... lens_source=MISSINGin the log -fetch_upstream.shdidn't run. Thelenspackage must sit inlens_source/for the import to work.httpx.LocalProtocolError: Illegal header value b'kernels/0.14.0; ...'- thekernelspackage is broken and unused on Ampere anyway (it needs sm_90+ for MXFP4).install_deps.shuninstalls it; if you skipped the scripts, do it manually.- OOM during sampling - you're on the wrong
offload_mode. Usecpu_text_encoderand keepevict_otherson; a 24 GB card holds exactly one of these pipelines.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| repo_id | STRING | microsoft/Lens-Turbo | HF repo id (e.g. microsoft/Lens-Turbo) OR an absolute local path to a downloaded snapshot. |
| device | COMBO | cuda:0 | 3 options: cuda:0, cuda:1, cpu |
| dtype | COMBO | bf16 | 3 options: bf16, fp16, fp32 |
| offload_mode | COMBO | cpu_text_encoder | VRAM strategy: cpu_text_encoder = text_encoder on CPU, transformer+vae on GPU. ~11 GB peak VRAM, ~10-15 s/image @ 1024² on RTX 3090. DEFAULT, recommended for 24 GB cards. sequential = layer-level (KNOWN BROKEN with Lens on accelerate >=1.x meta tensor bug). model = sub-model offload (needs ≥48 GB). none = pipe.to(device), needs ≥48 GB VRAM. |
| cpu_constructopt | BOOLEAN | true | Construct under `with torch.device('cpu')` to avoid OOM at __init__ time when RoPE caches / position tables would otherwise allocate on GPU. |
| force_reloadopt | BOOLEAN | false | Bypass cache, rebuild. |
| evict_othersopt | BOOLEAN | true | Free other cached pipelines before loading. |
| hf_cache_diropt | STRING | Override HF_HOME for this load. Empty = use env. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| pipeline | LENS_PIPELINE | — |