diff --git a/src/components/AssumptionsTab.jsx b/src/components/AssumptionsTab.jsx
index c91c344..c9fd7f8 100644
--- a/src/components/AssumptionsTab.jsx
+++ b/src/components/AssumptionsTab.jsx
@@ -1,6 +1,6 @@
import React, { useMemo, useState, useRef, useCallback, useEffect } from 'react';
import { ASSUMPTION_SEGMENTS, GLOBAL_PARAMS, TRANSLATION_INTENSITIES } from '../data/assumptions.js';
-import { formatNumber } from '../engine/calculations.js';
+import { formatNumber, softEfficiencyCap } from '../engine/calculations.js';
/* ── Brain equivalency constants ── */
const BRAIN = GLOBAL_PARAMS.brainEquivalency;
@@ -73,7 +73,7 @@ const BRAIN_COLUMNS = [
{ valueKey: 'cumulativeGain', label: 'Cumulative Eff. (x)', format: v => v < 1000 ? v.toFixed(1) + 'x' : (v / 1000).toFixed(1) + 'Kx' },
{ valueKey: 'wattsPerBrainEquiv', label: 'W per Brain-Equiv', format: v => v >= 1000 ? (v / 1000).toFixed(1) + ' kW' : v.toFixed(0) + ' W' },
{ valueKey: 'brainEfficiencyPct', label: '% of Brain Eff.', format: v => v < 1 ? v.toFixed(2) + '%' : v < 100 ? v.toFixed(1) + '%' : v.toFixed(0) + '%', help: `Human brain = ${GLOBAL_PARAMS.brainEquivalency.humanBrainWatts}W` },
- { valueKey: 'atAsymptote', label: 'Limit?', format: v => v ? 'AT LIMIT' : '\u2014' }
+ { valueKey: 'atAsymptote', label: 'Returns', format: v => v ? 'DIMINISHING' : 'linear' }
];
function AssumptionsTab({ assumptions, onAssumptionChange, onRunSimulation, isSimulating, results }) {
@@ -377,14 +377,15 @@ function AssumptionsTab({ assumptions, onAssumptionChange, onRunSimulation, isSi
const startingWatts = BRAIN.startingWattsPerBrainEquiv;
const brainWatts = BRAIN.humanBrainWatts;
- // Cap: AI can be at most 5× more efficient than the human brain (30W).
- // At 5× efficiency → 6W per brain-equiv. maxCumulativeGain = 10000 / 6 ≈ 1667×.
+ // Knee: gains above this level see logarithmic diminishing returns.
+ // maxCumulativeGain = 10000 / 3 ≈ 3333×. Beyond the knee, improvements
+ // continue but much slower — reflecting practical engineering limits.
const minWatts = BRAIN.minWattsPerBrainEquiv;
const maxCumulativeGain = startingWatts / minWatts;
- let cumulativeGain = 1.0;
- let asymptoteReached = false;
- let firstAsymptoteIdx = -1;
+ let rawCumulativeGain = 1.0;
+ let pastKnee = false;
+ let firstKneeIdx = -1;
const results = {};
@@ -392,33 +393,32 @@ function AssumptionsTab({ assumptions, onAssumptionChange, onRunSimulation, isSi
const years = BLOCK_YEARS[idx] || 1;
const annualGain = efficiencySummary[block.key]?.totalGain || 1;
- if (!asymptoteReached) {
- // Compound the annual gain over the block's duration
- const blockGain = Math.pow(annualGain, years);
- cumulativeGain *= blockGain;
+ // Always compound — gains never stop, just slow down past the knee
+ const blockGain = Math.pow(annualGain, years);
+ rawCumulativeGain *= blockGain;
- // Check if we hit the asymptote
- if (cumulativeGain >= maxCumulativeGain) {
- cumulativeGain = maxCumulativeGain;
- asymptoteReached = true;
- firstAsymptoteIdx = idx;
- }
+ // Soft cap: below the knee linear, above logarithmic diminishing returns
+ const effectiveGain = softEfficiencyCap(rawCumulativeGain, maxCumulativeGain);
+
+ if (!pastKnee && rawCumulativeGain >= maxCumulativeGain) {
+ pastKnee = true;
+ firstKneeIdx = idx;
}
- const wattsPerBrainEquiv = Math.max(startingWatts / cumulativeGain, minWatts);
+ const wattsPerBrainEquiv = Math.max(startingWatts / effectiveGain, minWatts);
const brainEfficiencyPct = (brainWatts / wattsPerBrainEquiv) * 100;
results[block.key] = {
- cumulativeGain,
+ cumulativeGain: effectiveGain,
wattsPerBrainEquiv,
brainEfficiencyPct,
- atAsymptote: asymptoteReached
+ atAsymptote: pastKnee
};
});
return {
perBlock: results,
- firstAsymptoteIdx
+ firstAsymptoteIdx: firstKneeIdx
};
}, [efficiencySummary, timeBlocks]);
@@ -500,14 +500,13 @@ function AssumptionsTab({ assumptions, onAssumptionChange, onRunSimulation, isSi
});
}, [impliedAIs, results]);
- /* ── Check if a row is past the asymptote (for greying out efficiency cells) ── */
+ /* ── Check if a row is past the efficiency knee (diminishing returns) ── */
const isRowPastAsymptote = useCallback((rowIdx) => {
- const { firstAsymptoteIdx } = brainEquivalency;
- if (firstAsymptoteIdx === -1) return false;
- // Grey out the row that hit the asymptote and all rows after it
- return rowIdx >= firstAsymptoteIdx;
- }, [brainEquivalency]);
+ // With the soft cap, cells are never fully disabled — gains continue,
+ // just slower. Return false so all rows stay editable.
+ return false;
+ }, []);
/* ── Render: table header row ── */
@@ -746,7 +745,7 @@ function AssumptionsTab({ assumptions, onAssumptionChange, onRunSimulation, isSi
W/Brain-Equiv
- floor {BRAIN.minWattsPerBrainEquiv}W
+ knee {BRAIN.minWattsPerBrainEquiv}W
|
Brain Equivalents
@@ -771,11 +770,12 @@ function AssumptionsTab({ assumptions, onAssumptionChange, onRunSimulation, isSi
{row.totalPowerGW.toFixed(1)}
|
-
+
{row.wattsPerBrainEquiv >= 1000
? (row.wattsPerBrainEquiv / 1000).toFixed(1) + ' kW'
- : row.wattsPerBrainEquiv.toFixed(0) + ' W'}
- {row.atEfficiencyLimit ? ' (LIMIT)' : ''}
+ : row.wattsPerBrainEquiv < 10
+ ? row.wattsPerBrainEquiv.toFixed(1) + ' W'
+ : row.wattsPerBrainEquiv.toFixed(0) + ' W'}
|
@@ -918,9 +918,9 @@ function AssumptionsTab({ assumptions, onAssumptionChange, onRunSimulation, isSi
Compares AI compute efficiency to the human brain ({BRAIN.humanBrainWatts}W).
Starting at {(BRAIN.startingWattsPerBrainEquiv / 1000).toFixed(0)}kW per brain-equivalent
of cognitive work, efficiency improvements compound over time.
- Asymptotes at {BRAIN.maxEfficiencyVsBrain}× brain efficiency
- ({BRAIN.minWattsPerBrainEquiv}W per brain-equiv). Once the
- asymptote is reached, further efficiency cells are locked.
+ Soft knee at {BRAIN.maxEfficiencyVsBrain}× brain efficiency
+ ({BRAIN.minWattsPerBrainEquiv}W per brain-equiv) — beyond this,
+ gains continue but with logarithmic diminishing returns.
{renderBrainEquivalencyTable()}
diff --git a/src/data/assumptions.js b/src/data/assumptions.js
index 9943926..6652a56 100644
--- a/src/data/assumptions.js
+++ b/src/data/assumptions.js
@@ -91,9 +91,9 @@ export const GLOBAL_PARAMS = {
brainEquivalency: {
humanBrainWatts: 30, // Human brain power consumption in watts
startingWattsPerBrainEquiv: 10000, // Starting AI watts per brain-equivalent of cognitive work
- maxEfficiencyVsBrain: 5, // Asymptote: AI can be at most 5x more efficient than the brain
- // At 5x efficiency, AI does brain-equivalent work at 30W / 5 = 6W
- minWattsPerBrainEquiv: 6 // = humanBrainWatts / maxEfficiencyVsBrain
+ maxEfficiencyVsBrain: 10, // Asymptote: AI can be at most 10x more efficient than the brain
+ // At 10x efficiency, AI does brain-equivalent work at 30W / 10 = 3W
+ minWattsPerBrainEquiv: 3 // = humanBrainWatts / maxEfficiencyVsBrain
}
};
diff --git a/src/engine/calculations.js b/src/engine/calculations.js
index 4eb6eb0..b62cf0e 100644
--- a/src/engine/calculations.js
+++ b/src/engine/calculations.js
@@ -150,13 +150,25 @@ function getNodeType(nodeId) {
const EPSILON = 1e-10;
-// Thermodynamic efficiency ceiling: shared across simulation engine and brain equivalency.
-// No matter how clever the algorithm or optimized the silicon, inference cannot go below
-// ~6W per operation (5× more efficient than the human brain at ~30W). Current GPU-class
-// accelerators draw ~700W, so max compound efficiency gain is bounded by 700W / 6W ≈ 117×.
+// Efficiency ceiling (soft knee): gains below the knee are linear; above, logarithmic
+// diminishing returns. The knee is set by the ratio of current GPU power to a practical
+// floor (~3W = 10× more efficient than the human brain at 30W). Beyond the knee,
+// improvements continue but at a dramatically slower pace — reflecting engineering
+// diminishing returns rather than a hard thermodynamic wall.
export const CURRENT_GPU_WATTS = 700;
-export const THERMODYNAMIC_FLOOR_WATTS = 6;
-export const MAX_EFFICIENCY_GAIN = CURRENT_GPU_WATTS / THERMODYNAMIC_FLOOR_WATTS;
+export const THERMODYNAMIC_FLOOR_WATTS = 3;
+export const MAX_EFFICIENCY_GAIN = CURRENT_GPU_WATTS / THERMODYNAMIC_FLOOR_WATTS; // ~233×
+
+/**
+ * Soft asymptotic efficiency cap with diminishing returns above the knee.
+ * Below the knee: gain = raw (linear, unchanged).
+ * Above the knee: gain = knee × (1 + ln(raw / knee)) — logarithmic.
+ * Continuous at the knee. Always increasing, but dramatically slower above it.
+ */
+export function softEfficiencyCap(raw, knee) {
+ if (raw <= knee) return raw;
+ return knee * (1 + Math.log(raw / knee));
+}
// Planning knobs
const CATCHUP_MONTHS = 6;
@@ -501,12 +513,11 @@ function computeRequiredGpus(month, trajectories, demandAssumptions, efficiencyA
// Efficiency gain: M decays (models get cheaper → more tok/s), S and H grow throughput.
// H_memory: inference is memory-bandwidth-bound (not compute-bound), so HBM generational
// improvements (H_memory) directly increase inference tok/s alongside general H gains.
- // Thermodynamic floor: no matter how clever the algorithm or how optimized the silicon,
- // inference cannot go below ~6W per operation (5× more efficient than the human brain
- // at ~30W). Current GPU-class accelerators draw ~700W, so the maximum compound
- // efficiency gain across all axes is bounded by 700W / 6W ≈ 117×.
+ // Soft efficiency ceiling: below ~233× (700W / 3W), gains are linear. Above the knee,
+ // diminishing returns kick in — improvements continue but at logarithmic pace,
+ // reflecting practical engineering limits rather than a hard thermodynamic wall.
const rawEfficiencyGain = (1 / Math.max(eff.M_inference, EPSILON)) * eff.S_inference * eff.H * eff.H_memory;
- const efficiencyGain = Math.min(rawEfficiencyGain, MAX_EFFICIENCY_GAIN);
+ const efficiencyGain = softEfficiencyCap(rawEfficiencyGain, MAX_EFFICIENCY_GAIN);
// Per-segment GPU demand (with demandScale applied to token volumes)
const consumerTokens = (inferenceDemand.consumer || 0) * demandScale;
@@ -533,11 +544,11 @@ function computeRequiredGpus(month, trajectories, demandAssumptions, efficiencyA
const totalTrainingHours = (frontierRuns * hoursFrontier) + (midtierRuns * hoursMidtier);
const denomTraining = hoursPerMonth * utilTrn * eff.S_training * eff.H;
- // Cap training efficiency the same way: M_training decays (numerator) while S*H grows
- // (denominator), so the effective reduction factor = M / (S*H). Floor it at 1/MAX.
- const rawTrainingFactor = eff.M_training / Math.max(denomTraining, EPSILON);
- const minTrainingFactor = 1 / (hoursPerMonth * utilTrn * MAX_EFFICIENCY_GAIN);
- const requiredTraining = totalTrainingHours * Math.max(rawTrainingFactor, minTrainingFactor);
+ // Soft cap training efficiency: compute raw gain = (S*H) / M, apply soft knee,
+ // then convert back to a cost factor. Gains continue past the knee but slow dramatically.
+ const rawTrainingGain = eff.S_training * eff.H / Math.max(eff.M_training, EPSILON);
+ const cappedTrainingGain = softEfficiencyCap(rawTrainingGain, MAX_EFFICIENCY_GAIN);
+ const requiredTraining = totalTrainingHours / (hoursPerMonth * utilTrn * cappedTrainingGain);
return {
requiredTotal: requiredInference + requiredTraining,
|