---
title: 'Sunum Kalıpları'
source: 'https://academia.sh/tr/kurslar/mlops-temelleri/sunum-kaliplari'
course: 'MLOps Temelleri'
language: tr
updated: '2026-08-17T18:08:53+00:00'
license: 'CC BY-SA 4.0'
---

# Sunum Kalıpları

Aynı paketin toplu, çevrimiçi ve akış tabanlı üç yerleşimde koşturulup üçünün gecikme sınıfı, tazeliği ve tahmin başına bedelinin ayrı ayrı sayılması: üç kalıp da aynı 600 isteğe aynı yanıtı verir ve isabet üçünde de 0,8067'dir, yani çıktıya bakan bir gözlem hangi kalıbın koştuğunu söyleyemez. Fark üç sütundadır: istek anında yapılan iş toplu ve akış kalıbında arama, çevrimiçi kalıpta 352 ile 550 satırlık tarama; yanıtın yaşı toplu kalıpta bir dönem, ötekilerde sıfır; tahmin başına okunan satır 11,00, 463,87 ve 3,67. Bayatlık süpürmesi altı döneme kadar 0 değişen tahmin verir ve bunun nedeni kalıp değil karar puanının eşiğe en az 7,6468 uzaklıkta durmasıdır. Bedel payda kararıdır: toplu ile çevrimiçi kalıp 4,74 kullanılan tahminde eşitlenir ve hangi görevin hangi kalıba dayandığı bu noktadan okunur.

Bir önceki ders modeli paketledi: çalışma zamanı sabitlendi, arayüz sözleşmesi yazıldı ve sözleşme
yazılmadığında kaç çağrının düştüğü sayıldı. Paketin ne kabul ettiği ve ne döndürdüğü artık
yazılıdır. Yazılmayan tek şey, bu paketin **ne zaman** çalıştığıdır. Aynı paket dönem başında bir kez
koşup iki yüz tahmini bir tabloya yazabilir, her istek geldiğinde bir kez koşabilir, ya da her yeni
okuma indiğinde kendini tazeleyebilir. Üçünde de ağırlıklar aynıdır.

Bu üç yerleşimin adı **sunum kalıbı (serving pattern)**. Aralarındaki fark modelde değil, **çıkarımın
(inference)** hangi anda ve hangi kapsamla yapıldığındadır. Bu ders üçünü aynı iş yükünde yan yana
koşturur ve tek bir isabet sayısı yerine üç sayıyı ayrı ayrı yazar: isteğin geldiği anda yapılan iş,
yanıtın dayandığı en yeni okumanın yaşı ve **tahmin başına maliyet (cost per prediction)**.

- **ED41.** Kaynak, hat ve model **kurgudur** ve ders içinde üretilir. Hiçbir sunum çatısı, çıkarım
  servisi, hızlandırıcı ya da bulut servisi çağrılmaz; üç kalıp da burada yazılır. Tohum 20260218.
- **ED42.** Etiket dengesizdir: dağılım `{0: 1752, 1: 448}`, **taban sınıf oranı 0,7964**. Hiçbir
  isabet bu oranın ne kadar üstünde olduğu yazılmadan okunmaz. Sınama kümesi 600 satırdır, yani
  isabetin en küçük adımı 0,0017'dir.
- **ED43.** Eğitim hattı bu kursta **tek makinede** ele alınır; bölüşüm ve karıştırma Dağıtık Veri
  İşleme kursunda ölçüldü ve tekrarlanmaz.
- **ED44.** Bedel **okunan satır** olarak sayılır; ham milisaniye yazılmaz. Gecikme **sınıf** olarak
  yazılır: `arama`, istek anında tek bir saklanmış kaydın okunmasıdır; `tarama`, istek anında
  abonenin ve bölgesinin geçmişinin okunmasıdır.
- **ED45.** Tazelik **dönem** olarak sayılır: yanıtın yaşı, en yeni okumanın tahmine yansıması için
  beklenen dönem sayısıdır.
- **ED46.** Sunum ufku sınama dönemleridir — `2026-10`, `2026-11`, `2026-12` — ve her dönem iki yüz
  abone için bir istek gelir. Toplam 600 istek.
- **ED47.** Toplu kalıp her dönem bir kez koşar. Bu bir **seçimdir** ve aşağıda süpürülür.

## Üç Kalıp Yan Yana

İlk blok kaynağı, hattın tüketime kadarki üç aşamasını, öznitelik yolunu ve kurgu modeli kurar; sonra
üç kalıbı aynı ağırlıklarla koşturur. Öznitelikler **bir kez** hesaplanır ve ağırlıktan bağımsızdır.

```python
# KURGUDUR. Olcum aginin sayac okumalari , hattin ilk uc asamasi , oznitelik
# yolu ve uc agirlikli esik modeli ders icinde uretilir; hicbir ogrenme
# kitapligi , sunum catisi ya da cikarim servisi cagrilmaz. Tohum 20260218.
TOHUM, M32 = 20260218, 0xFFFFFFFF


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


BOLGE = ["dogu", "bati", "kuzey", "guney", "merkez"]
TIP = ["mesken", "isyeri"]
DONEM = [f"2026-{a:02d}" for a in range(1, 13)]
ABONE = {}
for i in range(200):
    r = uretec(TOHUM + 37 * i)
    ABONE[f"A{i + 1:03d}"] = {"bolge": BOLGE[int(r() * 5)], "tip": TIP[int(r() * 2)],
                              "baslangic": 10000 + int(r() * 60000)}


def kaynak_uret():
    kayit = []
    for i, (ab, a) in enumerate(ABONE.items()):
        e = a["baslangic"]
        for d in DONEM:
            r = uretec(TOHUM + 101 * i + 7 * DONEM.index(d))
            e += 4 + int(r() * 46)
            kayit.append({"abone": ab, "donem": d, "bolge": a["bolge"], "tip": a["tip"],
                          "endeks": e, "birim": "m3"})
    return kayit


def a3_tuketim(kayit):
    tablo = {(k["abone"], k["donem"]): k for k in kayit}
    cikti = []
    for k in kayit:
        i = DONEM.index(k["donem"])
        onceki = tablo.get((k["abone"], DONEM[i - 1])) if i else None
        if onceki is not None:
            cikti.append(dict(k, m3=int(k["endeks"]) - int(onceki["endeks"])))
    return cikti


EGITIM, SINAMA, ESIK = DONEM[1:9], DONEM[9:], 40


def etiket(k):
    return 1 if k["m3"] > ESIK else 0


def oznitelikler(kayitlar, pencere=None, basamak=4):
    """Egitim yolu tam gecmisi gorur. Agirliktan bagimsiz , bir kez hesaplanir."""
    sirali = sorted(kayitlar, key=lambda k: DONEM.index(k["donem"]))
    ab, bo = {}, {}
    for k in sirali:
        ab.setdefault(k["abone"], []).append((DONEM.index(k["donem"]), k["m3"]))
        bo.setdefault(k["bolge"], []).append((DONEM.index(k["donem"]), k["m3"]))

    def ortalama(dizi, i):
        secili = [v for d, v in dizi if (d < i and (pencere is None or d >= i - pencere))]
        return round(sum(secili) / len(secili), basamak) if secili else 0.0

    return {(k["abone"], k["donem"]): {
        "abone_ort": ortalama(ab[k["abone"]], DONEM.index(k["donem"])),
        "bolge_ort": ortalama(bo[k["bolge"]], DONEM.index(k["donem"])),
        "isyeri": 1 if k["tip"] == "isyeri" else 0} for k in kayitlar}


IZGARA = [(a, b, c) for a in (0.6, 0.8, 1.0) for b in (0.0, 0.2, 0.4) for c in (0, 4, 8)]


def puan(o, w):
    return w[0] * o["abone_ort"] + w[1] * o["bolge_ort"] + w[2] * o["isyeri"]


def egit(kayitlar, oz):
    kume = [k for k in kayitlar if k["donem"] in EGITIM]
    en_iyi, en_iyi_w = -1.0, None
    for w in IZGARA:
        d = sum(1 for k in kume
                if (1 if puan(oz[(k["abone"], k["donem"])], w) > ESIK else 0) == etiket(k))
        if d / len(kume) > en_iyi:
            en_iyi, en_iyi_w = d / len(kume), w
    return {"agirlik": en_iyi_w, "egitim_satiri": len(kume), "aday": len(IZGARA)}


TUM = a3_tuketim(kaynak_uret())
OZ = oznitelikler(TUM)
M = egit(TUM, OZ)
W = M["agirlik"]
SUNUM, ISTEK = SINAMA, sorted(ABONE)


def toplu_kosum(kayitlar, donem, w):
    """Butun gecmis bir kez taranir , butun tahminler uretilip saklanir."""
    oz = oznitelikler(kayitlar)
    return ({k["abone"]: (1 if puan(oz[(k["abone"], k["donem"])], w) > ESIK else 0)
             for k in kayitlar if k["donem"] == donem}, len(kayitlar))


def cevrimici_istek(dz, abone, donem, w):
    """Istek aninda abonenin ve bolgesinin gecmisi taranir."""
    ab, bo = dz
    i, b = DONEM.index(donem), ab[abone][0]["bolge"]
    sa = [k["m3"] for k in ab[abone] if DONEM.index(k["donem"]) < i]
    sb = [k["m3"] for k in bo[b] if DONEM.index(k["donem"]) < i]
    o = {"abone_ort": round(sum(sa) / len(sa), 4) if sa else 0.0,
         "bolge_ort": round(sum(sb) / len(sb), 4) if sb else 0.0,
         "isyeri": 1 if ab[abone][0]["tip"] == "isyeri" else 0}
    return (1 if puan(o, w) > ESIK else 0), len(ab[abone]) + len(bo[b])


def akis_kosum(kayitlar, w):
    """Her okuma geldiginde durum artimli guncellenir ve tahmin tazelenir."""
    da, db, tah, okunan, tazeleme = {}, {}, {}, 0, 0
    for k in sorted(kayitlar, key=lambda k: (DONEM.index(k["donem"]), k["abone"])):
        okunan += 1
        a, b = k["abone"], k["bolge"]
        o = {"abone_ort": round(da[a][0] / da[a][1], 4) if a in da else 0.0,
             "bolge_ort": round(db[b][0] / db[b][1], 4) if b in db else 0.0,
             "isyeri": 1 if k["tip"] == "isyeri" else 0}
        tah[(a, k["donem"])] = 1 if puan(o, w) > ESIK else 0
        da.setdefault(a, [0, 0]); db.setdefault(b, [0, 0])
        da[a][0] += k["m3"]; da[a][1] += 1
        db[b][0] += k["m3"]; db[b][1] += 1
        tazeleme += 1
    return tah, okunan, tazeleme, len(da) + len(db)


ab, bo = {}, {}
for k in TUM:
    ab.setdefault(k["abone"], []).append(k)
    bo.setdefault(k["bolge"], []).append(k)
DZ = (ab, bo)

GERCEK = {(k["abone"], k["donem"]): etiket(k) for k in TUM if k["donem"] in SUNUM}
N = len(ISTEK) * len(SUNUM)


def isabet(t):
    return round(sum(1 for c in GERCEK if t[c] == GERCEK[c]) / N, 4)


TOPLU, ok_t = {}, 0
for d in SUNUM:
    t, o = toplu_kosum(TUM, d, W)
    ok_t += o
    for a in ISTEK:
        TOPLU[(a, d)] = t[a]

CEV, ok_c, en_az, en_cok = {}, 0, 10 ** 9, 0
for d in SUNUM:
    for a in ISTEK:
        p, o = cevrimici_istek(DZ, a, d, W)
        CEV[(a, d)], ok_c = p, ok_c + o
        en_az, en_cok = min(en_az, o), max(en_cok, o)

AKIS, ok_a, taz, durum = akis_kosum(TUM, W)
print(f"egitim satiri {M['egitim_satiri']} , agirlik {W} , aday {M['aday']}")
print(f"sunum ufku {len(SUNUM)} donem x {len(ISTEK)} abone = {N} istek")
print("kalip      istek aninda  yanit yasi  okunan satir  tahmin basina  isabet")
for adi, yas, ok, ia in (("toplu", 1, ok_t, isabet(TOPLU)),
                         ("cevrimici", 0, ok_c, isabet(CEV)),
                         ("akis", 0, ok_a, isabet(AKIS))):
    print(f"{adi:<9}  {'tarama' if adi == 'cevrimici' else 'arama':>12}  {yas:>10}"
          f"  {ok:>12}  {ok / N:>13.2f}  {ia}")
print(f"cevrimici istek basina okunan: en az {en_az} , en cok {en_cok}")
print(f"akis: tazeleme {taz} , kullanilan {N} , tutulan durum girdisi {durum}")
```

```
egitim satiri 1600 , agirlik (0.6, 0.4, 0) , aday 27
sunum ufku 3 donem x 200 abone = 600 istek
kalip      istek aninda  yanit yasi  okunan satir  tahmin basina  isabet
toplu             arama           1          6600          11.00  0.8067
cevrimici        tarama           0        278322         463.87  0.8067
akis              arama           0          2200           3.67  0.8067
cevrimici istek basina okunan: en az 352 , en cok 550
akis: tazeleme 2200 , kullanilan 600 , tutulan durum girdisi 205
```

Son sütun üç satırda da **0,8067**. Aynı ağırlıklar, aynı öznitelik yolu, aynı 600 istek; üç kalıp da
aynı yanıtları verir. Etiket dengesizdir ve taban sınıf oranı 0,7964'tür; sınama kümesinin kendi
taban oranı da 0,8067'dir, yani bu kurulum kursun ilk dersinde yazıldığı gibi tabanın **0,0000**
üstünde durur. Kalıp seçimi de onu değiştirmez ve çıktıya bakan bir gözlem hangi kalıbın koştuğunu
söyleyemez.

Fark öbür sütunlarda durur. Çevrimiçi kalıp istek başına 352 ile 550 satır okur, ortalaması 463,87.
Bunun neredeyse tamamı **bölge geçmişidir**; abonenin kendi geçmişi on bir satırdır. `bolge_ort`
özniteliği tek bir abone için hesaplanamaz, bölgenin bütün abonelerini ister. **Çevrimiçi çıkarımın
(online inference) pahalı oluşu modelden değil, özniteliğin kapsamından gelir** — bir tahmin başına
kırk iki kat fazla satır okunmasının nedeni budur.

**Toplu çıkarım (batch inference)** aynı bölge ortalamasını bir kez hesaplayıp bölgedeki bütün
abonelere paylaştırır: 6600 satır, 600 tahmin, tahmin başına 11,00. Karşılığında yanıtı bir dönem
yaşlanır, çünkü iki koşum arasında gelen hiçbir okuma tahmine giremez. Akış kalıbı her satırı bir kez
okur ve durumu artımlı günceller: 2200 satır, tahmin başına 3,67. Tablo onun bedelini **göstermez**;
2200 tazelemenin yalnız 600'ü kullanılır, 205 durum girdisi sürekli tutulur ve durum kaybolduğunda
yeniden kurmak 2200 satırı baştan okumak demektir. Okunan satır sütunu akışın en ucuz göründüğü
sütundur ve akışın bedeli tam olarak o sütunda yazmaz.

## Bedel Hangi Paydayla Bölünüyor

Yanıtın bir dönem yaşlanması bir bedel gibi durur. İkinci blok önce onu ölçer: aynı istekleri gitgide
daha eski bir koşumdan yanıtlar. Sonra tahmin başına maliyetin paydasını değiştirir.

```python
# Bu blok ilk bloktaki TUM , OZ , W , SUNUM , ISTEK , CEV , ok_c , N ,
# puan , ESIK , DONEM ve isabet tanimlarini surdurur.
print("yanit yasi (donem)  degisen tahmin  isabet")
for g in range(0, 7):
    t = {}
    for d in SUNUM:
        j = max(DONEM.index(d) - g, 1)
        for a in ISTEK:
            t[(a, d)] = 1 if puan(OZ[(a, DONEM[j])], W) > ESIK else 0
    deg = sum(1 for c in t if t[c] != CEV[c])
    print(f"{g:>18}  {deg:>14}  {isabet(t)}")

uz = sorted(abs(puan(OZ[c], W) - ESIK) for c in CEV)
print(f"esik {ESIK} , karar puaninin esige uzakligi: en az {uz[0]:.4f}"
      f" , medyan {uz[len(uz) // 2]:.4f}")

print("\nkullanilan tahmin    toplu  cevrimici    akis  en ucuz  toplu kullanilmayan")
ort_c = ok_c / N
for u in (1, 2, 5, 20, 50, 200):
    s = [len(TUM) / u, ort_c, len(ISTEK) / u]
    print(f"{u:>17}  {s[0]:>7.2f}  {s[1]:>9.2f}  {s[2]:>6.2f}"
          f"  {('toplu', 'cevrimici', 'akis')[s.index(min(s))]:>7}  {len(ISTEK) - u:>19}")
print(f"toplu ile cevrimici {len(TUM) / ort_c:.2f} kullanilan tahminde esitlenir")
```

```
yanit yasi (donem)  degisen tahmin  isabet
                 0               0  0.8067
                 1               0  0.8067
                 2               0  0.8067
                 3               0  0.8067
                 4               0  0.8067
                 5               0  0.8067
                 6               0  0.8067
esik 40 , karar puaninin esige uzakligi: en az 7.6468 , medyan 13.6826

kullanilan tahmin    toplu  cevrimici    akis  en ucuz  toplu kullanilmayan
                1  2200.00     463.87  200.00     akis                  199
                2  1100.00     463.87  100.00     akis                  198
                5   440.00     463.87   40.00     akis                  195
               20   110.00     463.87   10.00     akis                  180
               50    44.00     463.87    4.00     akis                  150
              200    11.00     463.87    1.00     akis                    0
toplu ile cevrimici 4.74 kullanilan tahminde esitlenir
```

Bayatlık süpürmesinin sonucu tek bir sayıdır: yanıtın yaşı sıfırdan altı döneme çıkarken **değişen
tahmin 0** ve isabet 0,8067'de kalır. Bu iş yükünde bayatlığın ölçülebilir bir karşılığı yoktur ve
buradan "toplu kalıp bedelsizdir" **çıkarılmaz**. Nedeni bir alt satırdadır: karar puanının eşiğe en
yakın uzaklığı 7,6468, medyanı 13,6826. Kararlar eşikten uzak durur ve bir dönemlik ek geçmiş, on
bir dönemlik kümülatif ortalamayı bu uzaklığı kapatacak kadar oynatmaz. Kararlar eşiğe yaklaştığında
aynı bayatlık tahmini oynatır. **Ölçülemeyen bedel yok sayılmaz; ölçülemediği ve hangi koşulda
görüneceği yazılır** — kursun ikinci iddiası burada bedel tarafından okunmuş hâlidir.

İkinci tablo tahmin başına maliyetin bir **payda kararı** olduğunu gösterir. Toplu kalıp bir koşumda
2200 satır okur ve iki yüz tahmin üretir; o tahminlerin kaçının gerçekten okunduğu kalıbın değil
işin sorusudur. Tek tahmin kullanılıyorsa toplu kalıbın tahmin başına maliyeti **2200,00**'dir ve
çevrimiçi kalıbın 463,87'sinin dört katından fazladır; iki kalıp **4,74 kullanılan tahminde**
eşitlenir. Son sütun toplu kalıbın bedelinin adıdır: bir tahmin kullanıldığında 199 tahmin üretilip
hiç okunmaz.

Hangi görevin hangi kalıba dayandığı bu iki tablodan okunur. Dönem başında bütün abonelerin
listelendiği iş toplu kalıba dayanır: payda 200'dür, bayatlık ölçülemez ve maliyet 11,00'e iner.
Önceden bilinmeyen tek abonelik bir sorgu çevrimiçi kalıba dayanır: payda 1'dir ve toplu kalıp orada
dört kattan fazla pahalıdır, üstelik listede olmayan bir anahtarı hiç yanıtlayamaz. Okumanın **geldiği anda**
tetiklenmesi gereken iş yalnız akışla yapılır: akış 2200 tetikleme üretir, çevrimiçi kalıp yalnız
istek geldiğinde 600 üretir ve hiç istek gelmezse hiç tetiklenmez, toplu kalıp ise 600'ü dönem
başında ve bir dönem gecikmeli üretir.

## Özet

- Üç sunum kalıbı aynı 600 isteğe **aynı yanıtları** verir ve isabet üçünde de **0,8067**'dir; taban
  sınıf oranı 0,7964, sınama kümesinin taban oranı 0,8067 ve bu kurulum onun **0,0000** üstünde.
  Kalıp seçimi bir isabet kararı değildir ve çıktıya bakan bir gözlem hangi kalıbın koştuğunu
  söyleyemez.
- Fark üç sütundadır: istek anındaki gecikme sınıfı toplu ve akış kalıbında `arama`, çevrimiçi
  kalıpta 352 ile 550 satırlık `tarama`; yanıtın yaşı 1, 0 ve 0 dönem; tahmin başına okunan satır
  **11,00**, **463,87** ve **3,67**.
- Çevrimiçi kalıbın kırk iki katlık farkı modelden değil `bolge_ort` özniteliğinin kapsamından gelir;
  abonenin kendi geçmişi on bir satır, bölgesininki 341 ile 539 satır arasındadır.
- Yanıtın yaşı altı döneme çıkarıldığında değişen tahmin **0**'dır; bunun nedeni kalıp değil, karar
  puanının eşiğe en az **7,6468** uzaklıkta durmasıdır. Ölçülemeyen bedel, ölçülmüş bir güvence
  değildir.
- Tahmin başına maliyet paydaya bağlıdır: toplu kalıp bir tahmin kullanıldığında **2200,00**, iki yüz
  tahmin kullanıldığında **11,00** verir ve çevrimiçi kalıpla **4,74** kullanılan tahminde eşitlenir.
- Akış kalıbı okunan satırda en ucuzudur, ama 2200 tazelemenin 1600'ü kullanılmaz ve 205 durum
  girdisi sürekli tutulur; bu bedel okunan satır sütununda hiç görünmez.

## Sonraki Adım

Kalıp seçildi, ama her kalıp içinde hâlâ tek bir soru yanıtsızdır: bir çağrı kaç isteği **birlikte**
taşımalıdır. Toplu kalıpta bu, koşumun kaç tahmin ürettiğidir; çevrimiçi kalıpta ise gelen istekleri
biriktirip bir arada işlemek demektir ve biriktirmenin bedeli, ilk gelen isteğin **beklemesidir**.
Sonraki ders aynı istekleri toplu boyut bir ile altmış dört arasında koşturur, tahmin başına
maliyetin düşüşünü bekleyen isteğin gecikmesiyle yan yana sayar ve aynı süpürmeyi iki hızlandırıcı
sınıfında tekrarlar.
