|  | --- | 
					
						
						|  | 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() | 
					
						
						|  | ``` |