mlops/dih.py

126 lines
3.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import time
import joblib
import pandas as pd
import numpy as np
import random
from sklearn.base import BaseEstimator, TransformerMixin
# ===== КРИТИЧЕСКИ ВАЖНО =====
# Эти классы ДОЛЖНЫ существовать до joblib.load()
class TextExtractor(BaseEstimator, TransformerMixin):
def fit(self, X, y=None):
return self
def transform(self, X):
return X['full_text'].fillna('')
class NumberExtractor(BaseEstimator, TransformerMixin):
def fit(self, X, y=None):
return self
def transform(self, X):
return X[['amount']].fillna(0)
# ============================
MODEL_PATH = "mcc_model.pkl"
BASE_TX = {
"transaction_id": "TX00001116",
"terminal_name": "STORE001",
"terminal_description": "common common common thing",
"city": "NYC",
"amount": 272.80,
"items": [
{"name": "basic loyalty", "price": 58.20},
{"name": "Bringiong item lifes", "price": 28.99},
{"name": "regular item basic item", "price": 56.91}
]
}
def json_to_df(data_list):
rows = []
for d in data_list:
items = d.get("items", [])
item_text = " ".join(str(i.get("name","")) for i in items)
full_text = f"{d.get('terminal_name','')} {d.get('terminal_description','')} {item_text}".lower()
rows.append({
"full_text": full_text,
"amount": float(d.get("amount", 0))
})
return pd.DataFrame(rows)
def make_batch(n=100):
batch = []
for i in range(n):
tx = BASE_TX.copy()
tx["transaction_id"] = f"TX{i:06d}"
tx["amount"] = round(random.uniform(3, 500), 2)
batch.append(tx)
return batch
# ============================
# BENCH
# ============================
print("\n[1] LOADING MODEL (cold start)...")
t0 = time.perf_counter()
model = joblib.load(MODEL_PATH)
t1 = time.perf_counter()
print(f"Cold load time: {t1 - t0:.4f} sec")
# warmup
print("\n[2] WARMUP...")
warm_df = json_to_df([BASE_TX])
for _ in range(5):
model.predict(warm_df)
# single inference benchmark
print("\n[3] SINGLE REQUEST BENCH (1000 runs)...")
times = []
for _ in range(1000):
df = json_to_df([BASE_TX])
t0 = time.perf_counter()
model.predict_proba(df)
times.append(time.perf_counter() - t0)
times = np.array(times)
print(f"avg : {times.mean()*1000:.2f} ms")
print(f"p95 : {np.percentile(times,95)*1000:.2f} ms")
print(f"max : {times.max()*1000:.2f} ms")
# batch benchmark
print("\n[4] BATCH 100 BENCH...")
batch = make_batch(100)
df_batch = json_to_df(batch)
t0 = time.perf_counter()
model.predict_proba(df_batch)
dt = time.perf_counter() - t0
print(f"Batch 100 time: {dt:.3f} sec")
# verdict
print("\n[5] VERDICT")
if np.percentile(times,95) < 0.2:
print("✅ /predict проходит по latency (<200ms p95)")
else:
print("❌ /predict НЕ проходит по latency")
if dt < 5:
print("✅ /predict/batch проходит (<5s)")
else:
print("❌ /predict/batch НЕ проходит")