Skip to content

Commit c1ff439

Browse files
Create hf_model_loader.py
1 parent 5e8e356 commit c1ff439

1 file changed

Lines changed: 93 additions & 0 deletions

File tree

prototype/hf_model_loader.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# prototype/hf_model_loader.py (NEW)
2+
from transformers import AutoModelForCausalLM, AutoTokenizer
3+
import torch
4+
from typing import Dict, Optional, Tuple
5+
import numpy as np
6+
7+
class HuggingFaceModelLoader:
8+
"""Production-grade HF model loading with optimization."""
9+
10+
def __init__(
11+
self,
12+
model_id: str,
13+
device_map: Optional[Dict[int, str]] = None,
14+
load_in_8bit: bool = False,
15+
load_in_4bit: bool = False,
16+
quantization_config: Optional[dict] = None
17+
):
18+
self.model_id = model_id
19+
self.device_map = device_map
20+
self.load_in_8bit = load_in_8bit
21+
self.load_in_4bit = load_in_4bit
22+
23+
def load_model(self) -> Tuple[torch.nn.Module, AutoTokenizer]:
24+
"""Load HF model with optimal settings."""
25+
# Determine loading strategy
26+
if self.load_in_4bit:
27+
from bitsandbytes import AutoFloat8Quantizer
28+
from accelerate import dispatch_model
29+
30+
model = AutoModelForCausalLM.from_pretrained(
31+
self.model_id,
32+
load_in_4bit=True,
33+
quantization_config=quantization_config or {
34+
"llm_int8_has_fp16_weight": False,
35+
"llm_int8_threshold": 6.0,
36+
}
37+
)
38+
elif self.load_in_8bit:
39+
model = AutoModelForCausalLM.from_pretrained(
40+
self.model_id,
41+
load_in_8bit=True
42+
)
43+
else:
44+
# Full precision with device mapping for multi-GPU
45+
model = AutoModelForCausalLM.from_pretrained(
46+
self.model_id,
47+
torch_dtype=torch.float16 if self.device_map else torch.float32,
48+
device_map=self.device_map or "auto"
49+
)
50+
51+
tokenizer = AutoTokenizer.from_pretrained(self.model_id)
52+
return model.eval(), tokenizer
53+
54+
def slice_model_for_distribution(
55+
self,
56+
num_slices: int = 2,
57+
split_strategy: str = "layer_boundary"
58+
) -> List[Dict[str, Any]]:
59+
"""Partition HF model for distributed inference."""
60+
# For transformer models, split at attention/MLP block boundaries
61+
from transformers import AutoConfig
62+
63+
config = AutoConfig.from_pretrained(self.model_id)
64+
num_layers = getattr(config, 'num_hidden_layers', 8)
65+
66+
slices = []
67+
layers_per_slice = num_layers // num_slices
68+
69+
for i in range(num_slices):
70+
start_layer = i * layers_per_slice
71+
end_layer = (i + 1) * layers_per_slice if i < num_slices - 1 else num_layers
72+
73+
# Extract slice metadata
74+
slice_metadata = {
75+
"slice_id": f"hf_slice_{start_layer}_{end_layer}",
76+
"start_layer": start_layer,
77+
"end_layer": end_layer,
78+
"param_count": self._count_parameters(start_layer, end_layer),
79+
"compute_flops": self._estimate_compute(start_layer, end_layer)
80+
}
81+
slices.append(slice_metadata)
82+
83+
return slices
84+
85+
def _count_parameters(self, start: int, end: int) -> int:
86+
"""Count parameters in layer range."""
87+
# Implementation to count transformer weights
88+
pass
89+
90+
def _estimate_compute(self, start: int, end: int) -> float:
91+
"""Estimate FLOPs per token for slice."""
92+
# Implementation based on attention heads + MLP size
93+
pass

0 commit comments

Comments
 (0)