loopvl / README.md
multimodalart's picture
multimodalart HF Staff
Upload folder using huggingface_hub
58785a2 verified
|
Raw History Blame Contribute Delete
2.24 kB
metadata
title: LoopVL
emoji: 🔁
colorFrom: purple
colorTo: yellow
sdk: gradio
sdk_version: 6.30.0
app_file: app.py
short_description: Recurrent VLM with a controllable compute budget
python_version: '3.12'
startup_duration_timeout: 30m

LoopVL: Recurrent Vision-Language Model

LoopVL (TierFlow/LoopVL) is a ~1.6B vision-language model that reuses its 16-layer transformer stack in nested loops instead of stacking 128 layers. The distinctive control this demo exposes is the recurrent inference budget: the H (high) and L (low) cycle counts decide how many times the stack is applied per forward pass — unrolled depth 16 × H × (L+1) effective layers. The schedule can be changed at runtime without reloading weights.

Ask any question about an image, pick a schedule, and compare answers across compute budgets.

  • Model: TierFlow/LoopVL (BF16 vision/language cores + FP32 projector, visual gate and anchor)
  • Code: Tier-Flow/LoopVL — the inference runtime (hrm_penguin, penguin_encoder, modeling_loopvl.py, metadata.py) is vendored here from that Apache-2.0 repository; the Penguin vision encoder keeps its Tencent LICENSE.txt alongside.
  • Examples: images from linoyts/repo-to-space-example-inputs (free to use, CC0-style).

How it works

  1. The image is resized under a dynamic-resolution policy (256–2048 visual tokens) and patched by the PenguinVL vision encoder.
  2. Visual tokens are injected into the text sequence; the HRM-Text recurrent LM loops its stack H × (L+1) times per forward pass, re-injecting an anchored version of the visual tokens after each high cycle, gated by a learned saturation-aware gate.
  3. Decoding is greedy, recomputing the full sequence per token (no KV cache).

Reproducing the reference

The answer endpoint follows the authors' runtime/infer.py one-to-one: same prompt template (condition\nImage:\n + placeholders + \nInstruction:\n…), same greedy decode, same decode(skip_special_tokens=True).strip() postprocess.