Kaplan Scaling Laws › Implementation: Scaling Law Calculator

Michael BrenndoerferJanuary 13, 20255 min read
Language AI HandbookAll chapters
Part 23 of 67Scaling Laws
Chapter 163Kaplan Scaling Laws › Implementation: Scaling Law Calculator
Reading section 11 of 15 · Implementation: Scaling Law Calculator · 5 minSection 11 of 15 · 5 min

Book contents

Section 11 of 15 · 5 min read

Kaplan Scaling Laws › Implementation: Scaling Law CalculatorOne section · Sections in this chapter11 / 15 ↓
Reading tools Definitions & inline links

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Article links

Make inline references clickable

Let's build a practical tool for working with Kaplan scaling laws. This implementation encapsulates all the key relationships we've discussed into a reusable class that can predict losses and compute optimal allocations:

In[20]:
Code
class KaplanScalingLaws:
    """Calculator for Kaplan et al. (2020) scaling laws."""

    # Fitted constants from the paper
    ALPHA_N = 0.076  # Parameter scaling exponent
    ALPHA_D = 0.095  # Data scaling exponent
    ALPHA_C = 0.050  # Compute scaling exponent

    N_C = 8.8e13  # Parameter scaling constant
    D_C = 5.4e13  # Data scaling constant
    C_C = 3.1e8  # Compute scaling constant

    # Optimal allocation exponents
    ALLOC_N = 0.73  # How parameters scale with compute
    ALLOC_D = 0.27  # How data scales with compute

    @classmethod
    def loss_from_params(cls, N: float) -> float:
        """Predict loss from non-embedding parameter count."""
        return (cls.N_C / N) ** cls.ALPHA_N

    @classmethod
    def loss_from_data(cls, D: float) -> float:
        """Predict loss from dataset size in tokens."""
        return (cls.D_C / D) ** cls.ALPHA_D

    @classmethod
    def loss_from_compute(cls, C: float) -> float:
        """Predict loss from compute in PetaFLOP-days."""
        return (cls.C_C / C) ** cls.ALPHA_C

    @classmethod
    def optimal_allocation(
        cls,
        C: float,
        N_base: float = 1e7,
        D_base: float = 1e9,
        C_base: float = 100,
    ) -> dict:
        """
        Calculate optimal model size and dataset for a compute budget.

        Args:
            C: Compute budget in PetaFLOP-days
            N_base: Baseline parameter count (for calibration)
            D_base: Baseline dataset size (for calibration)
            C_base: Baseline compute (for calibration)

        Returns:
            Dictionary with optimal N, D, and predicted loss
        """
        scale = C / C_base
        N_opt = N_base * (scale**cls.ALLOC_N)
        D_opt = D_base * (scale**cls.ALLOC_D)

        return {
            "parameters": N_opt,
            "tokens": D_opt,
            "predicted_loss": cls.loss_from_compute(C),
            "tokens_per_param": D_opt / N_opt,
        }
In[21]:
Code
# Test the calculator
calculator = KaplanScalingLaws()

# Predict losses at different scales
test_cases = [
    (125e6, "GPT-2 Small (125M)"),
    (1.5e9, "GPT-2 XL (1.5B)"),
    (175e9, "GPT-3 (175B)"),
]
Out[22]:
Console
Loss predictions from Kaplan scaling laws:
--------------------------------------------------
GPT-2 Small (125M)        → Predicted loss: 2.7824
GPT-2 XL (1.5B)           → Predicted loss: 2.3036
GPT-3 (175B)              → Predicted loss: 1.6044

The predicted losses demonstrate how the scaling law captures performance differences across model sizes. GPT-2 Small's higher loss compared to GPT-2 XL reflects the consistent power-law improvement. The much larger GPT-3 shows further gains that align with the α_N = 0.076 exponent. These predictions allow researchers to estimate whether building a larger model is worth the investment before committing the resources.

Now let's use the optimal allocation function to explore different compute budgets:

In[23]:
Code
# Explore optimal allocations across compute budgets
compute_budgets = [100, 1000, 10000, 100000, 1000000]  # PetaFLOP-days
allocations = [calculator.optimal_allocation(C) for C in compute_budgets]
Out[24]:
Console
Kaplan optimal allocation across compute scales:
----------------------------------------------------------------------
Compute (PF-d)  Parameters      Tokens          Loss       Tok/Param
----------------------------------------------------------------------
100             0.01           B 1.0            B 2.1114     100.0
1,000           0.05           B 1.9            B 1.8818     34.7
10,000          0.29           B 3.5            B 1.6771     12.0
100,000         1.55           B 6.5            B 1.4947     4.2
1,000,000       8.32           B 12.0           B 1.3322     1.4

This table shows how Kaplan's optimal allocation shifts the balance toward larger models as compute increases. At 1 million PetaFLOP-days, the recommended model has over 100 billion parameters but trains on only about 20 billion tokens, a ratio that seemed counterintuitive before scaling laws were established. The conventional wisdom had been that models needed many examples per parameter to avoid overfitting, but Kaplan's analysis showed that for language models, the optimal strategy is the opposite: build very large models and train them for relatively few steps.

The tokens-per-parameter ratio remains stable across scales, hovering around 3-4 tokens per parameter. This is far below what many practitioners assumed was necessary before scaling laws were established.

Out[25]:
Visualization
Bar chart showing tokens-per-parameter ratio staying constant around 3-4.
Tokens-per-parameter ratio across compute scales under Kaplan optimal allocation. The ratio remains stable around 3-4 tokens per parameter regardless of scale, contradicting traditional intuitions that larger models need proportionally more data.