--- library_name: transformers pipeline_tag: image-text-to-text inference: true widget: - text: Hello! example_title: Hello world group: Python base_model: - openbmb/MiniCPM-V-4 --- This tiny model is for debugging. It is randomly initialized with the config adapted from [openbmb/MiniCPM-V-4](https://huggingface.co/openbmb/MiniCPM-V-4). ### Example usage: ```python import numpy as np import torch from PIL import Image from transformers import AutoModel, AutoTokenizer model_id = "yujiepan/minicpm-v-4-tiny-random" model = AutoModel.from_pretrained(model_id, trust_remote_code=True, attn_implementation='sdpa', torch_dtype=torch.bfloat16) model = model.eval().cuda() tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True) image = Image.fromarray(np.random.randint(0, 255, (224, 224, 3), dtype=np.uint8), 'RGB') question = "What is the landform in the picture?" msgs = [{'role': 'user', 'content': [image, question]}] answer = model.chat( msgs=msgs, image=image, tokenizer=tokenizer, max_new_tokens=32, ) print(answer) # Second round chat, pass history context of multi-turn conversation msgs.append({"role": "assistant", "content": [answer]}) msgs.append({"role": "user", "content": [ "What should I pay attention to when traveling here?"]}) answer = model.chat( msgs=msgs, image=None, tokenizer=tokenizer, max_new_tokens=32, ) print(answer) ``` ### Codes to create this repo: ```python import json from pathlib import Path import accelerate import torch from huggingface_hub import hf_hub_download from transformers import ( AutoConfig, AutoModel, AutoModelForCausalLM, AutoProcessor, AutoTokenizer, GenerationConfig, set_seed, ) source_model_id = "openbmb/MiniCPM-V-4" save_folder = "/tmp/yujiepan/minicpm-v-4-tiny-random" processor = AutoProcessor.from_pretrained(source_model_id, trust_remote_code=True) processor.save_pretrained(save_folder) with open(hf_hub_download(source_model_id, filename='config.json', repo_type='model',), 'r', encoding='utf-8') as f: config_json = json.load(f) for k, v in config_json['auto_map'].items(): config_json['auto_map'][k] = f'{source_model_id}--{v}' automap = config_json['auto_map'] config_json['head_dim'] = 32 config_json["hidden_size"] = 128 # required by Sampler -- num_heads=embed_dim // 128 config_json['intermediate_size'] = 128 config_json['num_attention_heads'] = 2 config_json['num_key_value_heads'] = 1 config_json['num_hidden_layers'] = 2 config_json['tie_word_embeddings'] = True factor = config_json['rope_scaling']['long_factor'] config_json['rope_scaling']['long_factor'] = factor[:16] config_json['rope_scaling']['short_factor'] = factor[:16] config_json['vision_config']['intermediate_size'] = 128 config_json['vision_config']['hidden_size'] = 64 config_json['vision_config']['num_attention_heads'] = 2 config_json['vision_config']['num_hidden_layers'] = 2 with open(f"{save_folder}/config.json", "w", encoding='utf-8') as f: json.dump(config_json, f, indent=2) config = AutoConfig.from_pretrained( save_folder, trust_remote_code=True, ) print(config) torch.set_default_dtype(torch.bfloat16) model = AutoModel.from_config(config, trust_remote_code=True) torch.set_default_dtype(torch.float32) model.generation_config = GenerationConfig.from_pretrained( source_model_id, trust_remote_code=True, ) set_seed(42) num_params = sum(p.numel() for p in model.parameters()) with torch.no_grad(): for name, p in sorted(model.named_parameters()): torch.nn.init.normal_(p, 0, 0.1) print(name, p.shape, p.dtype, p.device, f'{p.numel() / num_params * 100: .2f}%') pass model.save_pretrained(save_folder) def modify_automap(path, source_model_id): import json with open(path, 'r', encoding='utf-8') as f: content = json.load(f) automap = {} if content.get('auto_map', None) is not None: for key, value in content.get('auto_map').items(): if isinstance(value, str): value = source_model_id + '--' + value.split('--')[-1] else: value = [(source_model_id + '--' + v.split('--')[-1]) for v in value] automap[key] = value with open(path, 'w', encoding='utf-8') as f: json.dump({**content, 'auto_map': automap}, f, indent=2) modify_automap(f"{save_folder}/config.json", source_model_id) modify_automap(f'{save_folder}/processor_config.json', source_model_id) modify_automap(f'{save_folder}/preprocessor_config.json', source_model_id) modify_automap(f'{save_folder}/tokenizer_config.json', source_model_id) for f in Path(save_folder).glob('*.py'): f.unlink() ```