tekno25 / handler.py
Huseyin's picture
Update handler.py
4d9cf87 verified
"""
Custom Inference Handler for Huseyin/tekno25 Model
Hugging Face Inference Endpoints için özelleştirilmiş handler
"""
import torch
from typing import Dict, List, Any
from transformers import AutoModelForCausalLM, AutoTokenizer
import logging
# Logger ayarla
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class EndpointHandler:
def __init__(self, path=""):
"""
Model ve tokenizer'ı yükle
Args:
path: Model dosyalarının bulunduğu dizin
"""
logger.info(f"Model yükleniyor: {path}")
# Tokenizer'ı yükle
self.tokenizer = AutoTokenizer.from_pretrained(
path,
trust_remote_code=True
)
# Modeli yükle
self.model = AutoModelForCausalLM.from_pretrained(
path,
torch_dtype=torch.float16, # Bellek optimizasyonu için
device_map="auto", # Otomatik cihaz ataması
trust_remote_code=True
)
# Eğer tokenizer'da pad_token yoksa ekle
if self.tokenizer.pad_token is None:
self.tokenizer.pad_token = self.tokenizer.eos_token
logger.info("Model başarıyla yüklendi!")
def __call__(self, data: Dict[str, Any]) -> List[Dict[str, Any]]:
"""
Inference endpoint'i için ana fonksiyon
Args:
data: İstek verisi
- inputs (str veya List[str]): Giriş metni/metinleri
- parameters (dict, optional): Generasyon parametreleri
Returns:
List[Dict]: Üretilen metin(ler)
"""
try:
# Giriş verilerini al
inputs = data.get("inputs", "")
parameters = data.get("parameters", {})
# Eğer inputs bir string ise listeye çevir
if isinstance(inputs, str):
inputs = [inputs]
# Varsayılan parametreler
default_params = {
"max_new_tokens": 512,
"temperature": 0.7,
"top_p": 0.9,
"top_k": 50,
"do_sample": True,
"repetition_penalty": 1.1,
"return_full_text": False
}
# Kullanıcı parametrelerini varsayılanlarla birleştir
generation_params = {**default_params, **parameters}
# return_full_text parametresini ayır
return_full_text = generation_params.pop("return_full_text", False)
# Batch işleme için sonuçları topla
results = []
for text_input in inputs:
# Tokenize et
encoded_inputs = self.tokenizer(
text_input,
return_tensors="pt",
padding=True,
truncation=True,
max_length=2048
).to(self.model.device)
# Çıktı üret
with torch.no_grad():
output_ids = self.model.generate(
**encoded_inputs,
**generation_params
)
# Decode et
if return_full_text:
# Tam metni döndür (giriş + üretilen)
generated_text = self.tokenizer.decode(
output_ids[0],
skip_special_tokens=True
)
else:
# Sadece üretilen kısmı döndür
input_length = encoded_inputs.input_ids.shape[1]
generated_text = self.tokenizer.decode(
output_ids[0][input_length:],
skip_special_tokens=True
)
results.append({
"generated_text": generated_text
})
return results
except Exception as e:
logger.error(f"Inference sırasında hata: {str(e)}")
return [{
"error": str(e),
"error_type": type(e).__name__
}]
# Alternatif: Pipeline kullanımı için handler
class PipelineHandler:
"""
Transformers pipeline kullanarak daha basit bir handler
"""
def __init__(self, path=""):
from transformers import pipeline
logger.info(f"Pipeline yükleniyor: {path}")
self.pipeline = pipeline(
"text-generation",
model=path,
torch_dtype=torch.float16,
device_map="auto",
trust_remote_code=True
)
logger.info("Pipeline başarıyla yüklendi!")
def __call__(self, data: Dict[str, Any]) -> List[Dict[str, Any]]:
"""
Pipeline tabanlı inference
"""
try:
inputs = data.get("inputs", "")
parameters = data.get("parameters", {})
# Varsayılan parametreler
default_params = {
"max_new_tokens": 512,
"temperature": 0.7,
"top_p": 0.9,
"do_sample": True,
"return_full_text": False
}
generation_params = {**default_params, **parameters}
# Pipeline'ı çalıştır
outputs = self.pipeline(
inputs,
**generation_params
)
return outputs
except Exception as e:
logger.error(f"Pipeline inference hatası: {str(e)}")
return [{
"error": str(e),
"error_type": type(e).__name__
}]