Image-Text-to-Text
Transformers
Safetensors
English
Chinese
Korean
internvl
internvl3.5
vision-language
multimodal
vllm
compressed-tensors
awq
int4
w4a16
ampere
wsl2
conversational
Instructions to use hsmin92/internvl35-4b-awq-w4a16-g128 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use hsmin92/internvl35-4b-awq-w4a16-g128 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="hsmin92/internvl35-4b-awq-w4a16-g128") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# Load model directly from transformers import AutoProcessor, AutoModelForMultimodalLM processor = AutoProcessor.from_pretrained("hsmin92/internvl35-4b-awq-w4a16-g128") model = AutoModelForMultimodalLM.from_pretrained("hsmin92/internvl35-4b-awq-w4a16-g128", device_map="auto") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] inputs = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=40) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use hsmin92/internvl35-4b-awq-w4a16-g128 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "hsmin92/internvl35-4b-awq-w4a16-g128" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "hsmin92/internvl35-4b-awq-w4a16-g128", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker
docker model run hf.co/hsmin92/internvl35-4b-awq-w4a16-g128
- SGLang
How to use hsmin92/internvl35-4b-awq-w4a16-g128 with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "hsmin92/internvl35-4b-awq-w4a16-g128" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "hsmin92/internvl35-4b-awq-w4a16-g128", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "hsmin92/internvl35-4b-awq-w4a16-g128" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "hsmin92/internvl35-4b-awq-w4a16-g128", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }' - Docker Model Runner
How to use hsmin92/internvl35-4b-awq-w4a16-g128 with Docker Model Runner:
docker model run hf.co/hsmin92/internvl35-4b-awq-w4a16-g128
Update model card with right-sized 8 GB serving config and measured tuning data
Browse files
README.md
CHANGED
|
@@ -95,19 +95,19 @@ calibration and does not carry this caveat.
|
|
| 95 |
| Quantization backend | compressed-tensors 0.17.0 |
|
| 96 |
| Attention backend | FlashAttention (auto-selected) |
|
| 97 |
|
| 98 |
-
|
| 99 |
-
--max-num-seqs 1 --max-num-batched-tokens 4096 --dtype bfloat16`:
|
| 100 |
|
| 101 |
```text
|
| 102 |
-
Model loading took 3.84 GiB memory
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
Graph capturing finished in 1 secs, took 0.00 GiB
|
| 107 |
```
|
| 108 |
|
| 109 |
-
|
| 110 |
-
|
|
|
|
|
|
|
| 111 |
|
| 112 |
## Serving with vLLM
|
| 113 |
|
|
@@ -118,20 +118,26 @@ vllm serve hsmin92/internvl35-4b-awq-w4a16-g128 \
|
|
| 118 |
--served-model-name internvl35-awq \
|
| 119 |
--dtype bfloat16 \
|
| 120 |
--max-model-len 8192 \
|
| 121 |
-
--max-num-seqs
|
| 122 |
--max-num-batched-tokens 4096 \
|
| 123 |
--limit-mm-per-prompt '{"image":2,"video":0}' \
|
| 124 |
-
--gpu-memory-utilization 0.
|
| 125 |
-
--
|
|
|
|
|
|
|
|
|
|
| 126 |
```
|
| 127 |
|
| 128 |
Then use the OpenAI-compatible endpoint at `http://127.0.0.1:8000/v1`.
|
| 129 |
|
|
|
|
|
|
|
|
|
|
| 130 |
### Do not use `--dtype half`
|
| 131 |
|
| 132 |
On this checkpoint family `--dtype half` produces a server that starts
|
| 133 |
-
normally, returns HTTP 200 from `/health`, reports a healthy
|
| 134 |
-
|
| 135 |
overflows the FP16 range, the logits become NaN, and argmax selects token 0.
|
| 136 |
It fails silently, so a liveness probe will not catch it.
|
| 137 |
|
|
@@ -139,18 +145,80 @@ The checkpoint declares `bfloat16` in `config.json` and Ampere supports BF16
|
|
| 139 |
natively at the same memory cost. Always send a real request after a
|
| 140 |
configuration change, not just a health check.
|
| 141 |
|
| 142 |
-
### `--
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 143 |
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 147 |
|
| 148 |
```text
|
| 149 |
image item with 2816 embedding tokens, which exceeds the
|
| 150 |
pre-allocated encoder cache size 2048
|
| 151 |
```
|
| 152 |
|
| 153 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
|
| 155 |
### Image token cost is driven by aspect ratio, not size
|
| 156 |
|
|
@@ -162,35 +230,45 @@ resolution. Measured on this model:
|
|
| 162 |
| 448×448 | 257 | 1 |
|
| 163 |
| 896×448 | 769 | 3 |
|
| 164 |
| 960×544 | 769 | 3 |
|
| 165 |
-
| 200×150 | **3,329** | **13** |
|
| 166 |
| 800×450 | 769 | 3 |
|
| 167 |
-
|
|
|
|
|
|
|
|
| 168 |
|
| 169 |
A 200×150 crop costs **4.3× more** than an 800×450 image, because 4:3 maps
|
| 170 |
exactly onto a 4×3 tile grid and the crop is upscaled to 1792×1344 for no
|
| 171 |
-
added information.
|
| 172 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 173 |
|
| 174 |
## Choosing between the FP8 and AWQ builds
|
| 175 |
|
| 176 |
-
Measured on the same RTX 3070, same vLLM version,
|
|
|
|
| 177 |
|
| 178 |
| | FP8 Dynamic | **AWQ W4A16 G128** |
|
| 179 |
|---|---|---|
|
| 180 |
| Weights on GPU | 5.51 GiB | **3.84 GiB** |
|
| 181 |
-
| KV cache
|
| 182 |
-
| KV cache capacity | 8,928 tokens | **19,344 tokens** |
|
| 183 |
-
| Max concurrency @ 8192 ctx | 1.09× | **2.36×** |
|
| 184 |
| KV cache dtype needed for 8192 ctx | fp8 (compromise) | **fp16** |
|
| 185 |
| CUDA graphs on 8 GB | not possible | **yes** |
|
| 186 |
-
|
|
|
|
|
|
|
|
| 187 |
| Calibration data required | **no** | yes (see above) |
|
| 188 |
| Weight precision | 8-bit | 4-bit |
|
| 189 |
|
| 190 |
-
AWQ is decisively better on memory and speed
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
|
|
|
|
|
|
|
|
|
| 194 |
|
| 195 |
## Limitations
|
| 196 |
|
|
@@ -198,12 +276,11 @@ first on hard inputs. Benchmark both on your own data before choosing.
|
|
| 198 |
- **No accuracy benchmark has been published for this checkpoint.** Functional
|
| 199 |
validation only: text generation, a 7k-token context, and multi-image
|
| 200 |
(full frame + crop) requests all produce coherent, correct answers on simple
|
| 201 |
-
synthetic probes.
|
| 202 |
- Calibration is general-purpose photography; see [Calibration](#calibration).
|
| 203 |
- The vision tower and output head remain BF16 and are a meaningful share of
|
| 204 |
the loaded weights, so the size reduction is smaller than 4/16 would suggest.
|
| 205 |
-
- The bundled `chat_template.jinja` has no tool-calling support.
|
| 206 |
-
`tools=[...]` is silently ignored regardless of vLLM's tool-parser flags.
|
| 207 |
- VRAM figures depend on driver, desktop applications, context length,
|
| 208 |
multimodal limits, and vLLM version.
|
| 209 |
|
|
|
|
| 95 |
| Quantization backend | compressed-tensors 0.17.0 |
|
| 96 |
| Attention backend | FlashAttention (auto-selected) |
|
| 97 |
|
| 98 |
+
Startup with the command below:
|
|
|
|
| 99 |
|
| 100 |
```text
|
| 101 |
+
Model loading took 3.84 GiB memory and 5.08 seconds
|
| 102 |
+
GPU KV cache size: 12,288 tokens
|
| 103 |
+
Maximum concurrency for 8,192 tokens per request: 1.50x
|
| 104 |
+
Graph capturing finished in 1 secs, took 0.09 GiB
|
|
|
|
| 105 |
```
|
| 106 |
|
| 107 |
+
Total process footprint is about **6.6 GB**, leaving roughly 0.9 GB free on an
|
| 108 |
+
8 GB card that is also driving a desktop. CUDA graphs capture successfully and
|
| 109 |
+
a full FP16 KV cache is used at an 8,192-token context — neither is possible
|
| 110 |
+
with the FP8 build on the same card.
|
| 111 |
|
| 112 |
## Serving with vLLM
|
| 113 |
|
|
|
|
| 118 |
--served-model-name internvl35-awq \
|
| 119 |
--dtype bfloat16 \
|
| 120 |
--max-model-len 8192 \
|
| 121 |
+
--max-num-seqs 8 \
|
| 122 |
--max-num-batched-tokens 4096 \
|
| 123 |
--limit-mm-per-prompt '{"image":2,"video":0}' \
|
| 124 |
+
--gpu-memory-utilization 0.79 \
|
| 125 |
+
--kv-cache-memory-bytes 1728M \
|
| 126 |
+
--trust-remote-code \
|
| 127 |
+
--enable-auto-tool-choice \
|
| 128 |
+
--tool-call-parser hermes
|
| 129 |
```
|
| 130 |
|
| 131 |
Then use the OpenAI-compatible endpoint at `http://127.0.0.1:8000/v1`.
|
| 132 |
|
| 133 |
+
Each flag is explained below — several of them are not obvious, and two of
|
| 134 |
+
them fail in ways that a health check will not catch.
|
| 135 |
+
|
| 136 |
### Do not use `--dtype half`
|
| 137 |
|
| 138 |
On this checkpoint family `--dtype half` produces a server that starts
|
| 139 |
+
normally, returns HTTP 200 from `/health`, reports a healthy container
|
| 140 |
+
health check — and answers every request with `!!!!!!!!`. Dequantization
|
| 141 |
overflows the FP16 range, the logits become NaN, and argmax selects token 0.
|
| 142 |
It fails silently, so a liveness probe will not catch it.
|
| 143 |
|
|
|
|
| 145 |
natively at the same memory cost. Always send a real request after a
|
| 146 |
configuration change, not just a health check.
|
| 147 |
|
| 148 |
+
### Pin the KV cache instead of raising `--gpu-memory-utilization`
|
| 149 |
+
|
| 150 |
+
Without `--kv-cache-memory-bytes`, vLLM expands the KV cache to fill whatever
|
| 151 |
+
`--gpu-memory-utilization` allows. On this model that wastes VRAM for no gain
|
| 152 |
+
and makes the cache size drift between restarts with whatever the desktop
|
| 153 |
+
happens to be using:
|
| 154 |
+
|
| 155 |
+
| | utilization only (0.86) | pinned KV (0.79 + 1728M) |
|
| 156 |
+
|---|---|---|
|
| 157 |
+
| KV cache | 16,128 – 19,344 tokens (varies per restart) | **12,288 tokens (fixed)** |
|
| 158 |
+
| Process VRAM | 7.9 GB | **6.6 GB** |
|
| 159 |
+
| Throughput, 16 concurrent | 126.1 tok/s | 124.4 tok/s |
|
| 160 |
+
|
| 161 |
+
1.3 GB is recovered for a throughput difference inside measurement noise.
|
| 162 |
+
Size the cache from the workload instead: 12,288 tokens holds one full-length
|
| 163 |
+
8,192-token request with room to spare, or about 11 typical requests of a
|
| 164 |
+
960×544 frame plus a normalized crop (~1,084 tokens each).
|
| 165 |
|
| 166 |
+
**`--gpu-memory-utilization` is a fraction of the free memory the process can
|
| 167 |
+
see, which is not what host `nvidia-smi` reports.** Under WSL2 the container
|
| 168 |
+
saw 6.93 GiB while the Windows host reported 7.48 GiB free, so the effective
|
| 169 |
+
ceiling was 0.866, and 0.87 was rejected outright:
|
| 170 |
+
|
| 171 |
+
```text
|
| 172 |
+
Free memory on device cuda:0 (6.93/8.0 GiB) on startup is less than
|
| 173 |
+
desired GPU memory utilization (0.87, 6.96 GiB)
|
| 174 |
+
```
|
| 175 |
+
|
| 176 |
+
### `--max-num-seqs`: leaving it at the default costs throughput
|
| 177 |
+
|
| 178 |
+
The vLLM default is 128. When more concurrent requests arrive than the KV
|
| 179 |
+
cache can hold, vLLM preempts and recomputes, and throughput collapses below
|
| 180 |
+
what a smaller limit achieves. Measured at ~1,084 prompt tokens per request
|
| 181 |
+
with a 16,128-token cache:
|
| 182 |
+
|
| 183 |
+
| Concurrent | `--max-num-seqs 128` | `--max-num-seqs 8` |
|
| 184 |
+
|---|---|---|
|
| 185 |
+
| 1 | 0.84 s / 63.3 tok/s | 0.84 s / 63.4 tok/s |
|
| 186 |
+
| 2 | 1.19 s / 87.4 tok/s | 1.18 s / 88.2 tok/s |
|
| 187 |
+
| 4 | 1.87 s / 105.8 tok/s | 1.19 s / 167.2 tok/s |
|
| 188 |
+
| 8 | 3.26 s / 119.7 tok/s | 3.22 s / 120.5 tok/s |
|
| 189 |
+
| **16** | **11.82 s / 68.9 tok/s** | **6.54 s / 126.1 tok/s** |
|
| 190 |
+
|
| 191 |
+
Pick a limit the cache can actually sustain. Do **not** derive it from the
|
| 192 |
+
`Maximum concurrency for 8,192 tokens per request` line in the startup log —
|
| 193 |
+
that figure assumes every request fills the full context window, which real
|
| 194 |
+
requests rarely do.
|
| 195 |
+
|
| 196 |
+
### `--max-num-batched-tokens` also sizes the multimodal encoder cache
|
| 197 |
+
|
| 198 |
+
This is not a VRAM tuning knob. The vLLM default of 2048 rejects large images
|
| 199 |
+
outright, on any card:
|
| 200 |
|
| 201 |
```text
|
| 202 |
image item with 2816 embedding tokens, which exceeds the
|
| 203 |
pre-allocated encoder cache size 2048
|
| 204 |
```
|
| 205 |
|
| 206 |
+
InternVL dynamic tiling allows up to 12 patches plus a thumbnail, so a single
|
| 207 |
+
image can reach **3,329 embedding tokens**. Use at least 4096.
|
| 208 |
+
|
| 209 |
+
### Tool-call flags are needed even without tool calling
|
| 210 |
+
|
| 211 |
+
`--enable-auto-tool-choice` and `--tool-call-parser` are required for the
|
| 212 |
+
server to *accept* requests that carry a `tool_choice` field. Open WebUI sends
|
| 213 |
+
`tool_choice: "auto"` by default, so omitting the flags makes it fail with:
|
| 214 |
+
|
| 215 |
+
```text
|
| 216 |
+
"auto" tool choice requires --enable-auto-tool-choice and
|
| 217 |
+
--tool-call-parser to be set
|
| 218 |
+
```
|
| 219 |
+
|
| 220 |
+
Actual tool calling still does not work: the bundled `chat_template.jinja` has
|
| 221 |
+
no tool rendering, so `tools=[...]` is silently ignored.
|
| 222 |
|
| 223 |
### Image token cost is driven by aspect ratio, not size
|
| 224 |
|
|
|
|
| 230 |
| 448×448 | 257 | 1 |
|
| 231 |
| 896×448 | 769 | 3 |
|
| 232 |
| 960×544 | 769 | 3 |
|
|
|
|
| 233 |
| 800×450 | 769 | 3 |
|
| 234 |
+
| 2048×2048 | 2,561 | 10 |
|
| 235 |
+
| **200×150** | **3,329** | **13** |
|
| 236 |
+
| 4000×300 | 3,329 | 13 |
|
| 237 |
|
| 238 |
A 200×150 crop costs **4.3× more** than an 800×450 image, because 4:3 maps
|
| 239 |
exactly onto a 4×3 tile grid and the crop is upscaled to 1792×1344 for no
|
| 240 |
+
added information. Across randomly sized crops of a 960×544 frame, the total
|
| 241 |
+
prompt cost swung between 1,040 and 4,112 tokens.
|
| 242 |
+
|
| 243 |
+
When sending region crops, letterbox them into a fixed 448×448 canvas
|
| 244 |
+
(preserving aspect ratio, no upscaling) to make cost constant at ~1,065 tokens
|
| 245 |
+
per request. On a small-text reading task this was 4× faster than sending the
|
| 246 |
+
raw crop, with no loss of accuracy down to 14 px glyphs.
|
| 247 |
|
| 248 |
## Choosing between the FP8 and AWQ builds
|
| 249 |
|
| 250 |
+
Measured on the same RTX 3070, same vLLM version, each tuned to its own best
|
| 251 |
+
settings on this card:
|
| 252 |
|
| 253 |
| | FP8 Dynamic | **AWQ W4A16 G128** |
|
| 254 |
|---|---|---|
|
| 255 |
| Weights on GPU | 5.51 GiB | **3.84 GiB** |
|
| 256 |
+
| KV cache | 9,088 tokens (fp8 KV) | **12,288 tokens (fp16 KV)** |
|
|
|
|
|
|
|
| 257 |
| KV cache dtype needed for 8192 ctx | fp8 (compromise) | **fp16** |
|
| 258 |
| CUDA graphs on 8 GB | not possible | **yes** |
|
| 259 |
+
| `--gpu-memory-utilization` needed | 0.85 (near the 0.866 ceiling) | **0.79** |
|
| 260 |
+
| Process VRAM | 7.8 GB | **6.6 GB** |
|
| 261 |
+
| Text generation, single request | 12–18 tok/s | **~2–4× faster** (18–63 tok/s, varies with warm-up) |
|
| 262 |
| Calibration data required | **no** | yes (see above) |
|
| 263 |
| Weight precision | 8-bit | 4-bit |
|
| 264 |
|
| 265 |
+
AWQ is decisively better on memory and speed, and it is the only one of the
|
| 266 |
+
two that fits comfortably on an 8 GB card without compromises.
|
| 267 |
+
|
| 268 |
+
**Accuracy has not been compared between the two builds, or against the BF16
|
| 269 |
+
base model.** 4-bit weights and out-of-domain calibration are both reasons to
|
| 270 |
+
expect the AWQ build to degrade first on hard inputs. Benchmark both on your
|
| 271 |
+
own data before choosing.
|
| 272 |
|
| 273 |
## Limitations
|
| 274 |
|
|
|
|
| 276 |
- **No accuracy benchmark has been published for this checkpoint.** Functional
|
| 277 |
validation only: text generation, a 7k-token context, and multi-image
|
| 278 |
(full frame + crop) requests all produce coherent, correct answers on simple
|
| 279 |
+
synthetic probes, both from a local directory and downloaded from this repo.
|
| 280 |
- Calibration is general-purpose photography; see [Calibration](#calibration).
|
| 281 |
- The vision tower and output head remain BF16 and are a meaningful share of
|
| 282 |
the loaded weights, so the size reduction is smaller than 4/16 would suggest.
|
| 283 |
+
- The bundled `chat_template.jinja` has no tool-calling support.
|
|
|
|
| 284 |
- VRAM figures depend on driver, desktop applications, context length,
|
| 285 |
multimodal limits, and vLLM version.
|
| 286 |
|