Instructions to use PerRing/InternVL-MoonViT-V2-MiniCPM5-2B-HF with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use PerRing/InternVL-MoonViT-V2-MiniCPM5-2B-HF with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="PerRing/InternVL-MoonViT-V2-MiniCPM5-2B-HF", trust_remote_code=True) 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)# pip install -U transformers accelerate # Load model directly from transformers import AutoModelForImageTextToText model = AutoModelForImageTextToText.from_pretrained("PerRing/InternVL-MoonViT-V2-MiniCPM5-2B-HF", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use PerRing/InternVL-MoonViT-V2-MiniCPM5-2B-HF with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "PerRing/InternVL-MoonViT-V2-MiniCPM5-2B-HF" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "PerRing/InternVL-MoonViT-V2-MiniCPM5-2B-HF", "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/PerRing/InternVL-MoonViT-V2-MiniCPM5-2B-HF
- SGLang
How to use PerRing/InternVL-MoonViT-V2-MiniCPM5-2B-HF 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 "PerRing/InternVL-MoonViT-V2-MiniCPM5-2B-HF" \ --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": "PerRing/InternVL-MoonViT-V2-MiniCPM5-2B-HF", "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 "PerRing/InternVL-MoonViT-V2-MiniCPM5-2B-HF" \ --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": "PerRing/InternVL-MoonViT-V2-MiniCPM5-2B-HF", "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 PerRing/InternVL-MoonViT-V2-MiniCPM5-2B-HF with Docker Model Runner:
docker model run hf.co/PerRing/InternVL-MoonViT-V2-MiniCPM5-2B-HF
Download image_processing_moonvit.py from PerRing/InternVL-MoonViT-V2-MiniCPM5-2B-HF: direct link, hf CLI and curl.
- Browser
- Download file 5.8 kB
-
https://huggingface.co/PerRing/InternVL-MoonViT-V2-MiniCPM5-2B-HF/resolve/main/image_processing_moonvit.py
- Command line
-
hf download hf://PerRing/InternVL-MoonViT-V2-MiniCPM5-2B-HF/image_processing_moonvit.py
-
curl -L -o image_processing_moonvit.py https://huggingface.co/PerRing/InternVL-MoonViT-V2-MiniCPM5-2B-HF/resolve/main/image_processing_moonvit.py
5.8 kB
| # MoonViT native-resolution image processor (port of the moonshotai/MoonViT-SO-400M and | |
| # AI4Industry/MoonViT-V2 processors, which differ only in their limits). | |
| # | |
| # Output: | |
| # pixel_values (total_patches, 3, patch_size, patch_size) | |
| # image_grid_thws (num_images, 3) as (frames, height, width) in patches; frames is 1 for images | |
| # | |
| # `in_token_limit` counts ViT input tokens (14x14 patches, before the 2x2 merge), so the number of | |
| # tokens the LLM sees is at most in_token_limit / 4. | |
| import math | |
| import numpy as np | |
| import torch | |
| from PIL import Image | |
| from torchvision.transforms import functional as TF | |
| from transformers.image_processing_utils import BaseImageProcessor, BatchFeature | |
| from transformers.image_utils import ImageInput, make_flat_list_of_images | |
| class MoonViTImageProcessor(BaseImageProcessor): | |
| model_input_names = ["pixel_values", "image_grid_thws"] | |
| def __init__( | |
| self, | |
| patch_size: int = 14, | |
| merge_kernel_size: int | list[int] | tuple[int, int] = (2, 2), | |
| in_token_limit: int = 4096, | |
| patch_limit_on_one_side: int | None = None, | |
| max_num_frames: int = 1, | |
| pad_input: bool = True, | |
| image_mean: list[float] | tuple[float, ...] = (0.5, 0.5, 0.5), | |
| image_std: list[float] | tuple[float, ...] = (0.5, 0.5, 0.5), | |
| **kwargs, | |
| ): | |
| super().__init__(**kwargs) | |
| self.patch_size = patch_size | |
| if isinstance(merge_kernel_size, int): | |
| merge_kernel_size = (merge_kernel_size, merge_kernel_size) | |
| self.merge_kernel_size = list(merge_kernel_size) | |
| # Max ViT tokens (14x14 patches before the 2x2 merge) per image; the image is downscaled to fit. | |
| self.in_token_limit = in_token_limit | |
| # Max patches along one side (MoonViT-V2: 512, i.e. 7168px); None disables the per-side cap. | |
| self.patch_limit_on_one_side = patch_limit_on_one_side | |
| # Video frames covered by the temporal position embedding (MoonViT-V2: 4). | |
| self.max_num_frames = max_num_frames | |
| # True: pad right/bottom to a multiple of patch_size * merge_kernel_size; False: center-crop to it. | |
| self.pad_input = pad_input | |
| self.image_mean = list(image_mean) | |
| self.image_std = list(image_std) | |
| def resize_and_align(self, image: Image.Image) -> Image.Image: | |
| w, h = image.size | |
| p = self.patch_size | |
| scale = min(1.0, math.sqrt(self.in_token_limit / (max(1, w // p) * max(1, h // p)))) | |
| if self.patch_limit_on_one_side is not None: | |
| side = self.patch_limit_on_one_side * p | |
| scale = min(scale, side / w, side / h) | |
| if scale < 1.0: | |
| image = image.resize((max(1, int(w * scale)), max(1, int(h * scale))), Image.Resampling.BICUBIC) | |
| w, h = image.size | |
| unit_h, unit_w = self.merge_kernel_size[0] * p, self.merge_kernel_size[1] * p | |
| if self.pad_input: | |
| image = TF.pad(image, [0, 0, (unit_w - w % unit_w) % unit_w, (unit_h - h % unit_h) % unit_h]) | |
| else: | |
| image = TF.center_crop(image, [max(h - h % unit_h, unit_h), max(w - w % unit_w, unit_w)]) | |
| return image | |
| def get_grid_thw(self, height: int, width: int, num_frames: int = 1) -> tuple[int, int, int]: | |
| """Grid (in patches) that `resize_and_align` produces for an image of this size.""" | |
| w, h = self.resize_and_align(Image.new("RGB", (width, height))).size | |
| return num_frames, h // self.patch_size, w // self.patch_size | |
| def _to_pil(self, image) -> Image.Image: | |
| if isinstance(image, Image.Image): | |
| return image.convert("RGB") | |
| if isinstance(image, torch.Tensor): | |
| image = image.cpu().numpy() | |
| image = np.asarray(image) | |
| if image.ndim == 3 and image.shape[0] in (1, 3) and image.shape[-1] not in (1, 3): | |
| image = image.transpose(1, 2, 0) | |
| if image.dtype != np.uint8: | |
| image = (image * 255 if image.max() <= 1.0 else image).clip(0, 255).astype(np.uint8) | |
| return Image.fromarray(image).convert("RGB") | |
| def _patchify(self, frames: list[Image.Image]) -> tuple[torch.Tensor, list[int]]: | |
| p = self.patch_size | |
| x = torch.stack([TF.normalize(TF.to_tensor(f), self.image_mean, self.image_std) for f in frames]) | |
| t, c, h, w = x.shape | |
| patches = x.reshape(t, c, h // p, p, w // p, p).permute(0, 2, 4, 1, 3, 5).reshape(-1, c, p, p) | |
| return patches, [t, h // p, w // p] | |
| def preprocess(self, images: ImageInput, return_tensors=None, **kwargs) -> BatchFeature: | |
| pixel_values, grid_thws = [], [] | |
| for image in make_flat_list_of_images(images): | |
| patches, grid = self._patchify([self.resize_and_align(self._to_pil(image))]) | |
| pixel_values.append(patches) | |
| grid_thws.append(grid) | |
| data = {"pixel_values": torch.cat(pixel_values), "image_grid_thws": torch.tensor(grid_thws, dtype=torch.long)} | |
| return BatchFeature(data=data, tensor_type=return_tensors) | |
| def preprocess_video(self, frames, return_tensors=None) -> BatchFeature: | |
| """One video = one sample with T frames; all frames share the first frame's resize/pad.""" | |
| frames = [self._to_pil(f) for f in frames] | |
| if not 1 <= len(frames) <= self.max_num_frames: | |
| raise ValueError(f"Got {len(frames)} frames, but max_num_frames={self.max_num_frames}") | |
| w, h = frames[0].size | |
| target = self.resize_and_align(frames[0]).size | |
| frames = [self.resize_and_align(f) if f.size == (w, h) else f.resize(target) for f in frames] | |
| patches, grid = self._patchify(frames) | |
| data = {"pixel_values": patches, "image_grid_thws": torch.tensor([grid], dtype=torch.long)} | |
| return BatchFeature(data=data, tensor_type=return_tensors) | |
| __all__ = ["MoonViTImageProcessor"] | |