Image-Text-to-Text
Transformers
Safetensors
English
visionpsynano
feature-extraction
vision-language-model
nanovlm
chart-understanding
ocr
crypto
launchpad
stable-mainnet
fefer
pegd-fun
conversational
custom_code
Instructions to use feferai/FEFER-AI-460M with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use feferai/FEFER-AI-460M with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="feferai/FEFER-AI-460M", 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)# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("feferai/FEFER-AI-460M", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use feferai/FEFER-AI-460M with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "feferai/FEFER-AI-460M" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "feferai/FEFER-AI-460M", "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/feferai/FEFER-AI-460M
- SGLang
How to use feferai/FEFER-AI-460M 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 "feferai/FEFER-AI-460M" \ --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": "feferai/FEFER-AI-460M", "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 "feferai/FEFER-AI-460M" \ --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": "feferai/FEFER-AI-460M", "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 feferai/FEFER-AI-460M with Docker Model Runner:
docker model run hf.co/feferai/FEFER-AI-460M
| """HuggingFace PreTrainedModel wrapper for VisionPsyNano.""" | |
| from __future__ import annotations | |
| import os | |
| from typing import Optional | |
| import torch | |
| from transformers import PreTrainedModel | |
| try: | |
| from .configuration_visionpsynano import VisionPsyNanoConfig | |
| except ImportError: | |
| from configuration_visionpsynano import VisionPsyNanoConfig | |
| try: | |
| from .processors import get_tokenizer | |
| from .language_model import LanguageModel | |
| from .modality_projector import ModalityProjector | |
| from .vision_language_model import VisionLanguageModel | |
| from .vision_transformer import ViT | |
| except ImportError as exc: | |
| raise ImportError( | |
| "Failed to import VisionPsyNano core modules (models/, data/). " | |
| "For Hub packages use scripts/package_hub_repo.py so imports are flattened." | |
| ) from exc | |
| class VisionPsyNanoForConditionalGeneration(PreTrainedModel): | |
| config_class = VisionPsyNanoConfig | |
| base_model_prefix = "" | |
| _no_split_modules = ["ViTBlock", "LanguageModelBlock", "ModalityProjector"] | |
| main_input_name = "input_ids" | |
| supports_gradient_checkpointing = False | |
| def __init__(self, config: VisionPsyNanoConfig): | |
| super().__init__(config) | |
| self.cfg = config.to_vlm_config() | |
| self.vision_encoder = ViT(self.cfg) | |
| self.decoder = LanguageModel(self.cfg) | |
| self.MP = ModalityProjector(self.cfg) | |
| self.tokenizer = get_tokenizer( | |
| self.cfg.lm_tokenizer, | |
| self.cfg.vlm_extra_tokens, | |
| self.cfg.lm_chat_template, | |
| ) | |
| self._sync_image_token_id() | |
| self._compiled_decoder = None | |
| self._compiled_vision_encoder = None | |
| self.load_backbone = False | |
| self.post_init() | |
| self.tie_weights() | |
| def _sync_image_token_id(self) -> None: | |
| tok = self.tokenizer | |
| if hasattr(tok, "image_token"): | |
| tok.image_token_id = tok.convert_tokens_to_ids(tok.image_token) | |
| elif "<|image|>" in getattr(tok, "get_vocab", lambda: {})(): | |
| tok.image_token = "<|image|>" | |
| tok.image_token_id = tok.convert_tokens_to_ids("<|image|>") | |
| def set_tokenizer(self, tokenizer) -> None: | |
| self.tokenizer = tokenizer | |
| self._sync_image_token_id() | |
| def _reinit_rotary_cache(self) -> None: | |
| re = getattr(self.decoder, "rotary_embd", None) | |
| if re is None or not hasattr(re, "extend_cache"): | |
| return | |
| cos = getattr(re, "cos_cached", None) | |
| if cos is None or getattr(cos, "is_meta", False) or cos.device.type == "meta": | |
| return | |
| length = int(getattr(re, "original_max_seq_len", None) or re.max_seq_len) | |
| re.extend_cache(max(length, 1)) | |
| if bool(torch.isnan(re.cos_cached).any()) or bool(torch.isnan(re.sin_cached).any()): | |
| device = re.inv_freq.device | |
| positions = torch.arange(length, dtype=torch.float, device=device) | |
| freqs = positions.unsqueeze(-1) * re.inv_freq.unsqueeze(0) | |
| emb = torch.cat([freqs, freqs], dim=-1) | |
| re.cos_cached = emb.cos() * re.attention_scaling | |
| re.sin_cached = emb.sin() * re.attention_scaling | |
| re.original_max_seq_len = length | |
| def tie_weights(self, recompute_mapping: bool = True, **kwargs): | |
| _ = recompute_mapping, kwargs | |
| if not getattr(self.cfg, "lm_tie_weights", True): | |
| return | |
| head_w = self.decoder.head.weight | |
| emb_w = self.decoder.token_embedding.weight | |
| if head_w.data_ptr() != emb_w.data_ptr(): | |
| with torch.no_grad(): | |
| emb_w.copy_(head_w) | |
| self.decoder.head.weight = self.decoder.token_embedding.weight | |
| def _tie_weights(self): | |
| self.tie_weights() | |
| def _repair_legacy_checkpoint_weights( | |
| self, pretrained_model_name_or_path, *, revision: Optional[str] = None | |
| ) -> None: | |
| weights_path = None | |
| if os.path.isdir(pretrained_model_name_or_path): | |
| candidate = os.path.join(pretrained_model_name_or_path, "model.safetensors") | |
| if os.path.isfile(candidate): | |
| weights_path = candidate | |
| else: | |
| try: | |
| from huggingface_hub import hf_hub_download | |
| weights_path = hf_hub_download( | |
| pretrained_model_name_or_path, | |
| "model.safetensors", | |
| revision=revision, | |
| ) | |
| except Exception: | |
| return | |
| if not weights_path: | |
| return | |
| from safetensors import safe_open | |
| with safe_open(weights_path, framework="pt", device="cpu") as f: | |
| keys = set(f.keys()) | |
| for i, block in enumerate(self.decoder.blocks): | |
| gate_key = f"decoder.blocks.{i}.mlp.gate_proj.weight" | |
| up_key = f"decoder.blocks.{i}.mlp.up_proj.weight" | |
| fused_key = f"decoder.blocks.{i}.mlp.gate_up_proj.weight" | |
| if gate_key in keys and up_key in keys and fused_key not in keys: | |
| fused = torch.cat([f.get_tensor(gate_key), f.get_tensor(up_key)], dim=0) | |
| param = block.mlp.gate_up_proj.weight | |
| param.data.copy_(fused.to(device=param.device, dtype=param.dtype)) | |
| if ( | |
| "decoder.token_embedding.weight" not in keys | |
| and "decoder.head.weight" in keys | |
| ): | |
| head = f.get_tensor("decoder.head.weight") | |
| emb = self.decoder.token_embedding.weight | |
| emb.data.copy_(head.to(device=emb.device, dtype=emb.dtype)) | |
| def _vision_encoder_for_prefill(self): | |
| return VisionLanguageModel._vision_encoder_for_prefill(self) | |
| def _decoder_for_decode(self): | |
| return VisionLanguageModel._decoder_for_decode(self) | |
| def _replace_img_tokens_with_embd(self, input_ids, token_embd, image_embd): | |
| return VisionLanguageModel._replace_img_tokens_with_embd( | |
| self, input_ids, token_embd, image_embd | |
| ) | |
| def _process_images(self, images, device): | |
| return VisionLanguageModel._process_images(self, images, device) | |
| def apply_deploy_profile(self, device: Optional[torch.device] = None) -> None: | |
| try: | |
| from .runtime_profile import apply_deploy_profile | |
| except ImportError: | |
| from runtime_profile import apply_deploy_profile | |
| apply_deploy_profile(self, device or next(self.parameters()).device) | |
| def apply_eager_profile(self) -> None: | |
| try: | |
| from .runtime_profile import apply_eager_profile | |
| except ImportError: | |
| from runtime_profile import apply_eager_profile | |
| apply_eager_profile(self) | |
| def forward( | |
| self, | |
| input_ids: Optional[torch.LongTensor] = None, | |
| images=None, | |
| pixel_values=None, | |
| attention_mask: Optional[torch.Tensor] = None, | |
| labels: Optional[torch.LongTensor] = None, | |
| targets: Optional[torch.LongTensor] = None, | |
| **kwargs, | |
| ): | |
| images = images if images is not None else pixel_values | |
| targets = targets if targets is not None else labels | |
| return VisionLanguageModel.forward( | |
| self, input_ids, images, attention_mask=attention_mask, targets=targets | |
| ) | |
| def generate( | |
| self, | |
| input_ids: Optional[torch.LongTensor] = None, | |
| images=None, | |
| pixel_values=None, | |
| attention_mask: Optional[torch.Tensor] = None, | |
| max_new_tokens: int = 5, | |
| top_k: int = 50, | |
| top_p: float = 0.9, | |
| temperature: float = 0.5, | |
| greedy: bool = False, | |
| **kwargs, | |
| ): | |
| images = images if images is not None else pixel_values | |
| _ = kwargs | |
| return VisionLanguageModel.generate( | |
| self, | |
| input_ids, | |
| images, | |
| attention_mask=attention_mask, | |
| max_new_tokens=max_new_tokens, | |
| top_k=top_k, | |
| top_p=top_p, | |
| temperature=temperature, | |
| greedy=greedy, | |
| ) | |
| def from_pretrained(cls, pretrained_model_name_or_path, *model_args, **kwargs): | |
| model = super().from_pretrained(pretrained_model_name_or_path, *model_args, **kwargs) | |
| model._repair_legacy_checkpoint_weights( | |
| pretrained_model_name_or_path, revision=kwargs.get("revision") | |
| ) | |
| model.tie_weights() | |
| model._reinit_rotary_cache() | |
| try: | |
| from transformers import AutoTokenizer | |
| try: | |
| from .processing_visionpsynano import VisionPsyNanoProcessor | |
| except ImportError: | |
| from processing_visionpsynano import VisionPsyNanoProcessor | |
| tok = AutoTokenizer.from_pretrained( | |
| pretrained_model_name_or_path, | |
| trust_remote_code=kwargs.get("trust_remote_code", False), | |
| ) | |
| VisionPsyNanoProcessor._attach_extra_token_attrs(tok, model.config.vlm_extra_tokens) | |
| model.set_tokenizer(tok) | |
| except Exception: | |
| model._sync_image_token_id() | |
| return model | |
| def from_legacy_pretrained( | |
| cls, | |
| repo_id_or_path: str, | |
| *, | |
| is_flash: Optional[bool] = None, | |
| variant: Optional[str] = None, | |
| revision: Optional[str] = None, | |
| **kwargs, | |
| ) -> "VisionPsyNanoForConditionalGeneration": | |
| import json | |
| from huggingface_hub import hf_hub_download | |
| from safetensors.torch import load_model | |
| if os.path.isdir(repo_id_or_path): | |
| config_path = os.path.join(repo_id_or_path, "config.json") | |
| weights_path = os.path.join(repo_id_or_path, "model.safetensors") | |
| else: | |
| config_path = hf_hub_download( | |
| repo_id=repo_id_or_path, filename="config.json", revision=revision | |
| ) | |
| weights_path = hf_hub_download( | |
| repo_id=repo_id_or_path, filename="model.safetensors", revision=revision | |
| ) | |
| with open(config_path, "r") as f: | |
| raw = json.load(f) | |
| config = VisionPsyNanoConfig.from_legacy_dict( | |
| raw, is_flash=is_flash, variant=variant | |
| ) | |
| model = cls(config) | |
| load_model(model, weights_path) | |
| model.tie_weights() | |
| model._reinit_rotary_cache() | |
| tok_dir = repo_id_or_path if os.path.isdir(repo_id_or_path) else os.path.dirname(config_path) | |
| if any( | |
| os.path.exists(os.path.join(tok_dir, n)) | |
| for n in ("tokenizer.json", "tokenizer_config.json") | |
| ): | |
| from transformers import AutoTokenizer | |
| try: | |
| from .processing_visionpsynano import VisionPsyNanoProcessor | |
| except ImportError: | |
| from processing_visionpsynano import VisionPsyNanoProcessor | |
| tok = AutoTokenizer.from_pretrained(tok_dir) | |
| VisionPsyNanoProcessor._attach_extra_token_attrs(tok, config.vlm_extra_tokens) | |
| model.set_tokenizer(tok) | |
| return model | |
| try: | |
| from transformers import AutoConfig, AutoModel, AutoModelForImageTextToText | |
| AutoConfig.register("visionpsynano", VisionPsyNanoConfig) | |
| AutoModel.register(VisionPsyNanoConfig, VisionPsyNanoForConditionalGeneration) | |
| AutoModelForImageTextToText.register(VisionPsyNanoConfig, VisionPsyNanoForConditionalGeneration) | |
| except Exception: | |
| pass | |