neo_dragon / README.md
jegly's picture
Upload 17 files
4a0d16e verified
|
Raw
History Blame Contribute Delete
5.03 kB
---
license: bsd-3-clause-clear
base_model: Qualcomm-AI-Research/Neodragon
tags:
- text-to-video
- litert
- tflite
- on-device
- android
library_name: litert
---
# Neodragon β€” LiteRT (.tflite) conversions for on-device text-to-video
LiteRT conversions of [Qualcomm-AI-Research/Neodragon](https://huggingface.co/Qualcomm-AI-Research/Neodragon),
prepared for [Box](https://github.com/jegly/Box) β€” an open-source, fully offline
on-device AI app for Android.
These are **converted artifacts only**. The models, research and original weights
are Qualcomm AI Research's work; see the
[upstream repo](https://huggingface.co/Qualcomm-AI-Research/Neodragon) and
[paper](https://qualcomm-ai-research.github.io/neodragon).
Generates a 320Γ—512 clip entirely on-device β€” no network, no server, no account.
## Licence β€” please read before use
The weights are released by Qualcomm under **two** licences, and both carry over
to these conversions:
1. **[BSD 3-Clause Clear](https://spdx.org/licenses/BSD-3-Clause-Clear.html)** β€”
permits redistribution and derivative works (a conversion is a derivative)
with notices retained. Note the "Clear" variant grants **no patent licence**.
2. **[Qualcomm Responsible AI License](https://www.qualcomm.com/site/responsible-ai-license)** β€”
adds use restrictions. It is not a grant licence; it sits on top of the BSD
grant and **flows down to you**. Prohibited uses include military use,
criminal/predictive-policing applications, social scoring, biometric
categorisation, emotion recognition in workplaces or education, and
distributing generated content without disclosing that it is machine
generated. Read the full text before using these files.
Box surfaces these restrictions in a consent screen before download and marks
generated output as AI-generated.
## What's here
Fixed-shape LiteRT graphs. Filenames are deliberately **flat** β€” Box's downloader
flattens remote paths into a single directory.
### Video pipeline (picture β†’ video)
| file | size | shape |
|---|---|---|
| `dt5_text_encoder.tflite` | 495 MB | `(1,128)` ids + mask β†’ `(1,128,4096)` |
| `context_adapter_dynamic_int8.tflite` | 124 MB | `(1,128,4096)` β†’ `(1,128,1536)` |
| `clip_l_text_encoder.tflite` | 472 MB | `(1,77)` β†’ pooled 768 |
| `clip_g_text_encoder_int8.tflite` | 670 MB | `(1,77)` β†’ pooled 1280 |
| `dit_stage0_10x16_int4.tflite` | 816 MB | pyramid stage 0 |
| `dit_stage1_20x32_int4.tflite` | 817 MB | pyramid stage 1 |
| `dit_stage2_40x64_int4.tflite` | 822 MB | pyramid stage 2 |
| `causal_video_vae_encoder_320x512.tflite` | 419 MB | `(1,3,1,320,512)` β†’ `(1,16,1,40,64)` |
| `causal_video_vae_decoder.tflite` | 38 MB | `(1,16,2,40,64)` β†’ `(1,3,9,320,512)` |
The three DiT graphs are the same 1.5B weights at three input resolutions; the
pipeline calls one per pyramid stage. Each accepts **exactly two** conditioning
latents, which is what limits this set to 9-frame clips.
### First-frame pipeline (text β†’ picture, SSD1B at 640Γ—1024)
| file | size | shape |
|---|---|---|
| `ssd_1b_clip_l.tflite` | 443 MB | `(1,77)` β†’ `(1,77,768)` `hidden_states[-2]` |
| `ssd_1b_clip_g.tflite` | 2.65 GB | `(1,77)` β†’ `(1,1280)` + `(1,77,1280)` |
| `ssd_1b_unet_640x1024.tflite` | 5.07 GB | `(1,4,80,128)` + t + ehs + text_embeds + time_ids |
| `ssd_1b_vae_decoder_640x1024.tflite` | 189 MB | `(1,4,80,128)` β†’ `(1,3,640,1024)` |
### Tokenizer assets
| file | note |
|---|---|
| `clip_vocab.json`, `clip_merges.txt` | CLIP BPE, shared by all four CLIP encoders |
| `t5_spiece.model` | DT5 unigram SentencePiece |
`clip_merges.txt` retains its `#version: 0.2` header line β€” **skip it when
loading**, or every merge rank shifts by one and tokenization silently corrupts.
## Notes for anyone reusing these
- **CPU only.** The LiteRT GPU delegate supports at most rank-4 tensors, and
Neodragon's latents are 5D `(b,c,t,h,w)`. On a Tensor G5, `--gpu` places 256 of
3402 ops on the GPU and then segfaults (`RESHAPE: Tensor dimensions must be
less than 5`). This is structural, not a configuration problem.
- **Two different CLIP pairs.** `clip_*` are Neodragon's own encoders (for the
DiT's pooled vector); `ssd_1b_clip_*` are SSD1B's (for SDXL conditioning).
Their weights differ. The tokenizer vocabularies are identical, so one
tokenizer serves both.
- **SDXL uses `hidden_states[-2]`**, not `last_hidden_state`, from both CLIP
encoders. Using the last layer does not crash β€” it quietly degrades output.
- **The SSD1B UNet is fp32** because int8 quantisation fails in
`ai_edge_quantizer` 0.8.0 on one layer
(`CrossAttnDownBlock2D_2/ResnetBlock2D_0/conv2`: *"input operand has more
dimensions than allowed by the axis remapping"*).
- Measured on a Pixel 10 Pro Fold (Tensor G5), CPU: DiT stages β‰ˆ 1.1 / 3.9 /
17.3 s per call.
## Credit
All credit for the model and research to **Qualcomm AI Research** β€” Animesh
Karnewar and the Neodragon authors. These conversions exist only to make that
work runnable on more devices.