|
|
|
""" |
|
Test script to verify DotsVLMForCausalLM model loading |
|
""" |
|
import os |
|
import json |
|
import shutil |
|
import torch |
|
from transformers import AutoConfig, AutoProcessor |
|
from .configuration_dots_vlm import DotsVLMConfig, DotsVLMProcessor |
|
from .modeling_dots_vlm import DotsVLMForCausalLM |
|
import traceback |
|
|
|
def create_debug_model_path(original_path, debug_layers=3): |
|
""" |
|
创建一个debug版本的模型路径,只包含指定层数的配置和权重 |
|
|
|
Args: |
|
original_path: 原始模型路径 |
|
debug_layers: debug模式下使用的层数 |
|
|
|
Returns: |
|
debug模型的临时路径 |
|
""" |
|
debug_path = original_path + "_debug_temp" |
|
|
|
|
|
|
|
|
|
|
|
|
|
os.makedirs(debug_path, exist_ok=True) |
|
|
|
|
|
files_to_copy = [ |
|
'tokenizer_config.json', |
|
'tokenizer.json', |
|
'special_tokens_map.json', |
|
'preprocessor_config.json', |
|
'modeling_deepseek.py', |
|
'configuration_deepseek.py' |
|
] |
|
|
|
for file in files_to_copy: |
|
src = os.path.join(original_path, file) |
|
dst = os.path.join(debug_path, file) |
|
if os.path.exists(src): |
|
if not os.path.exists(dst): |
|
print(f"📁 Copying basefile {file}... from {src} to {dst}") |
|
shutil.copy2(src, dst) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
config_src = os.path.join(original_path, 'config.json') |
|
config_dst = os.path.join(debug_path, 'config.json') |
|
|
|
with open(config_src, 'r') as f: |
|
config = json.load(f) |
|
|
|
|
|
original_layers = config['num_hidden_layers'] |
|
config['num_hidden_layers'] = debug_layers |
|
print(f"🔧 DEBUG: Reducing num_hidden_layers from {original_layers} to {debug_layers}") |
|
|
|
with open(config_dst, 'w') as f: |
|
json.dump(config, f, indent=2) |
|
|
|
|
|
index_src = os.path.join(original_path, 'model.safetensors.index.json') |
|
|
|
with open(index_src, 'r') as f: |
|
index_data = json.load(f) |
|
|
|
original_weight_map = index_data['weight_map'] |
|
|
|
|
|
|
|
front_files = [f"model-{i:05d}-of-00316.safetensors" for i in range(1, 9)] |
|
|
|
layer2_files = ["model-00056-of-00316.safetensors"] |
|
|
|
back_files = ["model-00315-of-00316.safetensors", "model-00316-of-00316.safetensors"] |
|
|
|
norm_files = ["model-00314-of-00316.safetensors"] |
|
|
|
needed_files = set(front_files + layer2_files + back_files + norm_files) |
|
|
|
print(f"🔧 DEBUG: Will load {len(needed_files)} safetensor files instead of 316:") |
|
for f in sorted(needed_files): |
|
print(f" - {f}") |
|
|
|
|
|
new_weight_map = {} |
|
|
|
|
|
for key, file in original_weight_map.items(): |
|
|
|
if any(key.startswith(prefix) for prefix in [ |
|
'model.embed_tokens', |
|
'model.norm', |
|
'lm_head' |
|
]): |
|
if file in needed_files: |
|
new_weight_map[key] = file |
|
|
|
|
|
elif key.startswith('vision_tower.'): |
|
if file in needed_files: |
|
new_weight_map[key] = file |
|
|
|
|
|
elif key.startswith('model.layers.'): |
|
|
|
layer_parts = key.split('.') |
|
if len(layer_parts) >= 3 and layer_parts[2].isdigit(): |
|
layer_num = int(layer_parts[2]) |
|
if layer_num < debug_layers and file in needed_files: |
|
new_weight_map[key] = file |
|
|
|
print(f"🔧 DEBUG: Filtered weight map from {len(original_weight_map)} to {len(new_weight_map)} entries") |
|
|
|
|
|
copied_files = set() |
|
for file in new_weight_map.values(): |
|
if file not in copied_files: |
|
src_file = os.path.join(original_path, file) |
|
dst_file = os.path.join(debug_path, file) |
|
if os.path.exists(src_file): |
|
|
|
if not os.path.exists(dst_file): |
|
print(f"📁 Copying Safetensor {file}... from {src_file} to {dst_file}") |
|
shutil.copy2(src_file, dst_file) |
|
copied_files.add(file) |
|
else: |
|
print(f"⚠️ File not found: {src_file}") |
|
|
|
|
|
new_index_data = { |
|
"metadata": index_data.get("metadata", {}), |
|
"weight_map": new_weight_map |
|
} |
|
|
|
index_dst = os.path.join(debug_path, 'model.safetensors.index.json') |
|
with open(index_dst, 'w') as f: |
|
json.dump(new_index_data, f, indent=2) |
|
|
|
print(f"✅ DEBUG: Created debug model at {debug_path}") |
|
return debug_path |
|
|
|
|
|
def test_model_loading(): |
|
"""Test loading the model from pretrained weights""" |
|
|
|
model_path = "." |
|
|
|
|
|
debug_minimal_layers = os.getenv('DEBUG_MINIMAL_LAYERS', '0') == '1' |
|
|
|
|
|
if debug_minimal_layers: |
|
print("🔧 DEBUG MINIMAL LAYERS: Using only 3 layers and minimal safetensors") |
|
|
|
model_path = create_debug_model_path(model_path, debug_layers=3) |
|
|
|
print("Loading model configuration...") |
|
try: |
|
config = AutoConfig.from_pretrained(model_path) |
|
print(f"✓ Config loaded successfully: {config.__class__.__name__}") |
|
print(f" Model type: {config.model_type}") |
|
print(f" Architecture: {config.architectures}") |
|
print(f" Number of hidden layers: {config.num_hidden_layers}") |
|
|
|
|
|
if hasattr(config, 'quantization_config') and config.quantization_config is not None: |
|
quant_config = config.quantization_config |
|
if isinstance(quant_config, dict) and quant_config.get('quant_method') == 'fp8': |
|
print(" Detected FP8 quantization configuration") |
|
print(f" Format: {quant_config.get('fmt', 'unknown')}") |
|
print(f" Weight block size: {quant_config.get('weight_block_size', 'unknown')}") |
|
print(f" Activation scheme: {quant_config.get('activation_scheme', 'unknown')}") |
|
except Exception as e: |
|
print(f"✗ Error loading config: {e}") |
|
return False |
|
|
|
print("\nTesting processor loading...") |
|
try: |
|
|
|
try: |
|
processor = AutoProcessor.from_pretrained(model_path) |
|
print(f"✓ AutoProcessor loaded successfully: {processor.__class__.__name__}") |
|
except Exception as e: |
|
print(f"⚠️ AutoProcessor failed, trying direct import: {e}") |
|
|
|
processor = DotsVLMProcessor.from_pretrained(model_path) |
|
print(f"✓ Direct processor loaded successfully: {processor.__class__.__name__}") |
|
|
|
|
|
if hasattr(processor, 'image_token'): |
|
print(f" Image token: {processor.image_token}") |
|
if hasattr(processor, 'tokenizer'): |
|
print(f" Tokenizer type: {processor.tokenizer.__class__.__name__}") |
|
if hasattr(processor, 'image_processor'): |
|
print(f" Image processor type: {processor.image_processor.__class__.__name__}") |
|
|
|
except Exception as e: |
|
print(f"⚠️ Processor loading failed (this is OK for now): {e}") |
|
processor = None |
|
|
|
|
|
print("\nLoading model with auto-fixing vision_tower quantization...") |
|
try: |
|
|
|
model = DotsVLMForCausalLM.from_pretrained( |
|
model_path, |
|
config=config, |
|
torch_dtype="auto", |
|
device_map="auto", |
|
trust_remote_code=True |
|
) |
|
print(f"✓ Model loaded successfully: {model.__class__.__name__}") |
|
print(f" Number of parameters: {model.num_parameters():,}") |
|
|
|
|
|
if hasattr(model, 'vision_tower') and model.vision_tower is not None: |
|
vision_sample_param = list(model.vision_tower.parameters())[0] |
|
print(f" Vision tower dtype: {vision_sample_param.dtype}") |
|
|
|
except Exception as e: |
|
traceback.print_exc() |
|
print(f"✗ Error loading model: {e}") |
|
return False |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print("\nTesting model forward pass...") |
|
try: |
|
|
|
|
|
batch_size = 1 |
|
seq_len = 10 |
|
input_ids = torch.randint(0, 1000, (batch_size, seq_len)) |
|
|
|
|
|
if hasattr(model, 'device'): |
|
device = next(model.parameters()).device |
|
input_ids = input_ids.to(device) |
|
|
|
with torch.no_grad(): |
|
outputs = model(input_ids=input_ids) |
|
|
|
print(f"✓ Forward pass successful") |
|
print(f" Output shape: {outputs.logits.shape}") |
|
print(f" Output dtype: {outputs.logits.dtype}") |
|
|
|
except Exception as e: |
|
print(f"✗ Error in forward pass: {e}") |
|
traceback.print_exc() |
|
return False |
|
|
|
|
|
if debug_minimal_layers and model_path.endswith("_debug_temp"): |
|
try: |
|
|
|
print(f"🧹 Cleaned up temporary debug directory: {model_path}") |
|
except Exception as e: |
|
print(f"⚠️ Failed to clean up debug directory: {e}") |
|
|
|
elif debug_minimal_layers: |
|
print("\n🎉 DEBUG MINIMAL LAYERS: 3-layer model test completed!") |
|
print("💡 To test with full 61-layer model, run without DEBUG_MINIMAL_LAYERS=1") |
|
else: |
|
print("\n🎉 All tests passed! Model is working correctly.") |
|
|
|
return True |
|
|
|
|
|
if __name__ == "__main__": |
|
test_model_loading() |