Hoppa till innehållet
AI-grafen
F· AI engineeringsprakmodeller· ca 90 min· volatil — kontrolleras ofta· verifierad 2026-09-21

Skalningslagar

Kunna läsa och tillämpa skalningslagar för att välja modellstorlek och datamängd för en beräkningsbudget.

Förkunskaper

Intuition

Skalningslagar säger att förlusten faller förutsägbart som en potenslag i tre storheter: antal parametrar NN, antal träningstokens DD, och beräkning CC.

L(N)≈L∞+(NcN)αL(N) \approx L_\infty + \left(\frac{N_c}{N}\right)^{\alpha}

I log-log-skala blir det en rak linje, och det är det anmärkningsvärda: man kan mäta på små modeller och extrapolera till stora, över flera tiopotenser.

Vad det används till: innan man spenderar miljoner på en träningskörning kör man en serie små modeller, anpassar kurvan, och förutsäger vad den stora kommer att ge. Det gör skalning till en ingenjörsdisciplin i stället för en gissning.

Två saker att hålla isär:

Betyder
Förlusten faller förutsägbartja, det är vad lagarna säger
Förmågor växer förutsägbartnej — det är en annan och mycket omdiskuterad fråga

Formellt

Chinchilla-resultatet (Hoffmann m.fl. 2022) är det mest praktiskt användbara. Med en fast beräkningsbudget C≈6NDC \approx 6ND FLOPs är förlusten minimerad när

D≈20⋅ND \approx 20 \cdot N

alltså cirka 20 träningstokens per parameter.

Det var en omvälvande slutsats, eftersom dåtidens största modeller var kraftigt underträade:

ModellParametrarTokensTokens/paramChinchilla-optimalt
GPT-3 (2020)175 B300 B1,73 500 B
Gopher (2021)280 B300 B1,15 600 B
Chinchilla (2022)70 B1 400 B20✓

Chinchilla slog Gopher trots att den var fyra gånger mindre — den hade tränats på rätt mängd data för sin storlek.

Men Chinchilla optimerar träningskostnaden, inte totalkostnaden. Ska modellen köras miljarder gånger dominerar inferensen, och då lönar det sig att träna en mindre modell längre än vad Chinchilla säger. Det är därför moderna öppna modeller ofta tränas på 100–1 000 tokens per parameter — långt bortom det «optimala» — eftersom en mindre modell är billigare att köra i evighet.

Hur man gör i praktiken:

  1. Träna 5–8 små modeller av olika storlek, alla till sin Chinchilla-optimala datamängd.
  2. Anpassa L=L∞+aN−αL = L_\infty + aN^{-\alpha} i log-log.
  3. Extrapolera till målstorleken.
  4. Kontrollera mot en punkt i mitten som inte användes i anpassningen.

Steg 4 är det som skiljer en användbar förutsägelse från en förhoppning.

Vad skalningslagar inte förutsäger:

FrågaSvar
Nedströmsprestanda på en specifik uppgiftnej — förlusten är inte träffsäkerheten
När en förmåga «dyker upp»omdiskuterat; Schaeffer m.fl. (2023) visade att många «emergenta» språng försvinner med kontinuerliga mått
Effekten av datakvalitetnej — lagarna antar samma datafördelning
Var kurvan planar utextrapolering bortom mätområdet är osäker

Den tredje raden är den mest praktiskt betydelsefulla: skalningslagarna säger ingenting om att bättre data kan flytta hela kurvan nedåt, vilket den gör. Att rensa och filtrera korpuset är ofta billigare än att tiodubbla beräkningen.

Kod

import numpy as np

def chinchilla_optimal(budget_flops):
    """C ≈ 6ND och D ≈ 20N ⟹ C ≈ 120N²."""
    N = (budget_flops / 120) ** 0.5
    return {"parametrar_md": round(N / 1e9, 2),
            "tokens_md": round(20 * N / 1e9, 1),
            "kontroll_flops": f"{6 * N * 20 * N:.2e}"}

for budget in (1e21, 1e22, 1e23, 1e24):
    print(f"{budget:.0e} FLOPs → {chinchilla_optimal(budget)}")
# 1e+21 FLOPs → {'parametrar_md': 2.89, 'tokens_md': 57.7, ...}
# 1e+23 FLOPs → {'parametrar_md': 28.87, 'tokens_md': 577.4, ...}

# Anpassa en potenslag till mätdata och extrapolera
def anpassa_potenslag(N, L, L_inf=1.6):
    """L = L_inf + a·N^(-alfa). Linjär regression i log-log på (L - L_inf)."""
    x = np.log(np.asarray(N, float))
    y = np.log(np.asarray(L, float) - L_inf)
    alfa_neg, log_a = np.polyfit(x, y, 1)
    return {"alfa": round(float(-alfa_neg), 4), "a": round(float(np.exp(log_a)), 2),
            "forutsag": lambda n: L_inf + np.exp(log_a) * n ** alfa_neg}

# Mätpunkter från små modeller
N = np.array([1e7, 3e7, 1e8, 3e8, 1e9])
L = 1.6 + 25.0 * N ** -0.30          # syntetisk «mätning»
f = anpassa_potenslag(N, L)
print(f"anpassad alfa {f['alfa']}, a {f['a']}")

for mal in (1e10, 1e11, 1e12):
    print(f"  N={mal:.0e}: förutsagd förlust {float(f['forutsag'](mal)):.4f}")

# Håll ut en punkt för kontroll — det är detta steg som oftast hoppas över
N_tr, L_tr = np.delete(N, 2), np.delete(L, 2)
f2 = anpassa_potenslag(N_tr, L_tr)
print(f"kontrollpunkt N=1e8: sant {L[2]:.4f}, förutsagt {float(f2['forutsag'](N[2])):.4f}")

# Chinchilla optimerar TRÄNING — räkna på totalkostnaden inklusive inferens
def total_kostnad(N, D, inferenstokens, kr_per_1e18_flops=50.0):
    traning = 6 * N * D
    inferens = 2 * N * inferenstokens
    return {"traning_flops": f"{traning:.2e}", "inferens_flops": f"{inferens:.2e}",
            "total_kr": round((traning + inferens) / 1e18 * kr_per_1e18_flops, 1),
            "inferensandel": round(inferens / (traning + inferens), 3)}

print(total_kostnad(7e9, 140e9, 1e15))       # liten modell, mycket inferens
print(total_kostnad(70e9, 1400e9, 1e15))     # stor modell, samma inferensvolym
#  ↑ vid hög inferensvolym lönar sig den mindre modellen även om den tränats längre

Behärskning innebär

  • Tolkar en potenslag i log-log-skala
  • Tillämpar Chinchilla-förhållandet
  • Vet vad skalningslagar inte förutsäger

Logga in för att göra övningarna och bygga upp din behärskning.

Källor

Alla källor och licenser