|
Download integrations/transformers/usage.md from hf-internal-testing/mic-internvl-integration: direct link, hf CLI and curl.
- Browser
- Download file 5.14 kB
-
https://huggingface.co/hf-internal-testing/mic-internvl-integration/resolve/main/integrations/transformers/usage.md
- Command line
-
hf download hf://hf-internal-testing/mic-internvl-integration/integrations/transformers/usage.md
-
curl -L -o usage.md https://huggingface.co/hf-internal-testing/mic-internvl-integration/resolve/main/integrations/transformers/usage.md
5.14 kB
InternVL3-1B: multimodal image+text with Transformers
This page is the Transformers contract of the InternVL3-1B MIC and also a usage example. doc-builder renders the runnable blocks below as documentation, and its pytest plugin runs them as written against OpenGVLab/InternVL3-1B-hf. The MIC runner runs the same blocks against each slim fixture and each checkpoint in integration.json. Lines marked # doc-builder: hide only matter there: they swap in the pinned checkpoint or variant and print the result record.
Image+text inference
import torch
from transformers import AutoProcessor, AutoModelForImageTextToText, set_seed
from PIL import Image
import json # doc-builder: hide
import os # doc-builder: hide
import numpy as np # doc-builder: hide
model_id = "OpenGVLab/InternVL3-1B-hf"
model_id = os.environ.get("MIC_MODEL", model_id) # doc-builder: hide
variant = json.loads(os.environ.get("MIC_MODEL_KWARGS", "{}")) # doc-builder: hide
device = "cuda" if torch.cuda.is_available() else "cpu"
set_seed(0)
processor = AutoProcessor.from_pretrained(model_id)
load_kwargs = dict(variant) # doc-builder: hide
if "dtype" in load_kwargs: # doc-builder: hide
load_kwargs["torch_dtype"] = getattr(torch, load_kwargs.pop("dtype")) # doc-builder: hide
model = AutoModelForImageTextToText.from_pretrained(model_id, **load_kwargs).to(device) # doc-builder: hide
# Two distinct synthetic images matching the model's expected input size (448x448)
img1 = Image.fromarray(np.random.randint(0, 255, (448, 448, 3), dtype=np.uint8))
img2 = Image.fromarray(np.random.randint(0, 255, (448, 448, 3), dtype=np.uint8))
# Prompt-only conversations for inference
prompts = [
[{"role": "user", "content": [{"type": "image"}, {"type": "text", "text": "Describe this image briefly."}]}],
[{"role": "user", "content": [{"type": "image"}, {"type": "text", "text": "What do you see?"}]}],
]
prompt_texts = [processor.apply_chat_template(p, tokenize=False, add_generation_prompt=True) for p in prompts]
inputs = processor(images=[img1, img2], text=prompt_texts, return_tensors="pt", padding=True).to(device)
model.eval()
with torch.no_grad():
out = model(**inputs)
logits = out.logits
# Compact probe: last 5 positions, first 5 vocab entries of sequence 0
probe = logits[0, -5:, :5].float().tolist()
print(f"logits probe: {probe}")
One training step
# Full conversations (user + assistant) for supervised training
full_convs = [
[
{"role": "user", "content": [{"type": "image"}, {"type": "text", "text": "Describe this image briefly."}]},
{"role": "assistant", "content": [{"type": "text", "text": "A colorful abstract pattern."}]},
],
[
{"role": "user", "content": [{"type": "image"}, {"type": "text", "text": "What do you see?"}]},
{"role": "assistant", "content": [{"type": "text", "text": "A random noise image."}]},
],
]
full_texts = [processor.apply_chat_template(c, tokenize=False) for c in full_convs]
train_inputs = processor(images=[img1, img2], text=full_texts, return_tensors="pt", padding=True).to(device)
# Labels: -100 for prompt positions, token ids for response positions
prompt_enc = processor(images=[img1, img2], text=prompt_texts, return_tensors="pt", padding=True)
prompt_lens = prompt_enc["input_ids"].ne(processor.tokenizer.pad_token_id).sum(dim=-1).to(device)
labels = train_inputs["input_ids"].clone()
for i in range(labels.shape[0]):
labels[i, :prompt_lens[i]] = -100
if processor.tokenizer.pad_token_id is not None:
labels[i, train_inputs["input_ids"][i] == processor.tokenizer.pad_token_id] = -100
model.train()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
loss = model(**train_inputs, labels=labels).loss
loss.backward()
before = {n: p.detach().clone() for n, p in model.named_parameters()} # doc-builder: hide
optimizer.step()
print(f"loss: {loss.item():.4f}")
if os.environ.get("MIC_RUNNER"): # doc-builder: hide
named = dict(model.named_parameters())
all_names = list(named.keys())
vis_params = [n for n in all_names if "vision" in n and "layers.0" in n]
lang_params = [n for n in all_names if "language" in n and "layers.0" in n and "q_proj" in n]
checked = (vis_params[0] if vis_params else all_names[0], lang_params[0] if lang_params else all_names[-1])
result = {
"runtime": {
"device": device,
"dtype": str(next(model.parameters()).dtype).removeprefix("torch."),
"attn_implementation": model.config._attn_implementation,
},
"logits_probe": probe,
"training": {
"loss": loss.item(),
"gradients": {
n: bool(named[n].grad is not None and torch.count_nonzero(named[n].grad) > 0 and torch.isfinite(named[n].grad).all())
for n in checked
},
"updated": any(not torch.equal(p, before[n]) for n, p in named.items()),
},
}
print(json.dumps(result))