@tokcalc/mcp-server 0.1.3 → 0.2.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/README.md +86 -406
  2. package/dist/http.js +23504 -0
  3. package/dist/index.js +21290 -0
  4. package/package.json +36 -92
  5. package/.zscripts/build.sh +0 -175
  6. package/.zscripts/database-runtime-build.sh +0 -33
  7. package/.zscripts/dev.pid +0 -1
  8. package/.zscripts/dev.sh +0 -154
  9. package/.zscripts/mini-services-build.sh +0 -78
  10. package/.zscripts/mini-services-install.sh +0 -65
  11. package/.zscripts/mini-services-start.sh +0 -123
  12. package/.zscripts/python-runtime-build.sh +0 -120
  13. package/.zscripts/start.sh +0 -145
  14. package/CAPACITY_STUDY.md +0 -283
  15. package/CODE_OF_CONDUCT.md +0 -55
  16. package/CONTRIBUTING.md +0 -177
  17. package/Caddyfile +0 -23
  18. package/LICENSE +0 -204
  19. package/bun.lock +0 -1965
  20. package/components.json +0 -21
  21. package/db/custom.db +0 -0
  22. package/download/README.md +0 -1
  23. package/download/tokcalc-dark-calculator.png +0 -0
  24. package/download/tokcalc-dark-default.png +0 -0
  25. package/download/tokcalc-demo.webm +0 -0
  26. package/download/tokcalc-github-link.png +0 -0
  27. package/download/tokcalc-hydration-fixed.png +0 -0
  28. package/download/tokcalc-issue-resolved.png +0 -0
  29. package/download/tokcalc-light-mode.png +0 -0
  30. package/download/tokcalc-light-reference.png +0 -0
  31. package/download/tokcalc-long-context-qwen.png +0 -0
  32. package/download/tokcalc-long-context.png +0 -0
  33. package/download/tokcalc-og-image-preview.png +0 -0
  34. package/download/tokcalc-phase2-3.png +0 -0
  35. package/download/tokcalc-plain-english.png +0 -0
  36. package/download/tokcalc-preview.png +0 -0
  37. package/download/tokcalc-share-bvb.png +0 -0
  38. package/download/tokcalc-share-feature.png +0 -0
  39. package/download/tokcalc-tab-build-vs-buy.png +0 -0
  40. package/download/tokcalc-tab-calculator.png +0 -0
  41. package/download/tokcalc-tab-reference.png +0 -0
  42. package/eslint.config.mjs +0 -50
  43. package/examples/websocket/frontend.tsx +0 -196
  44. package/examples/websocket/server.ts +0 -138
  45. package/mini-services/.gitkeep +0 -0
  46. package/mini-services/mcp-server/README.md +0 -86
  47. package/mini-services/mcp-server/bun.lock +0 -202
  48. package/mini-services/mcp-server/index.ts +0 -504
  49. package/mini-services/mcp-server/package.json +0 -40
  50. package/next.config.ts +0 -12
  51. package/postcss.config.mjs +0 -5
  52. package/prisma/schema.prisma +0 -32
  53. package/public/google6f58ca6be85fa903.html +0 -1
  54. package/public/logo.svg +0 -29
  55. package/public/manifest.json +0 -51
  56. package/public/og-icon-256.png +0 -0
  57. package/public/og.png +0 -0
  58. package/public/robots.txt +0 -25
  59. package/public/sitemap.xml +0 -23
  60. package/public/tokcalc-demo.gif +0 -0
  61. package/scripts/og-template.html +0 -120
  62. package/scripts/render-og.mjs +0 -43
  63. package/server.json +0 -21
  64. package/src/app/api/pricing/aws/route.ts +0 -186
  65. package/src/app/api/pricing/azure/route.ts +0 -168
  66. package/src/app/api/pricing/gcp/route.ts +0 -230
  67. package/src/app/api/pricing/vast-ai/route.ts +0 -164
  68. package/src/app/api/route.ts +0 -5
  69. package/src/app/compare/h100-vs-h200/layout.tsx +0 -30
  70. package/src/app/compare/h100-vs-h200/page.tsx +0 -328
  71. package/src/app/globals.css +0 -122
  72. package/src/app/layout.tsx +0 -276
  73. package/src/app/page.tsx +0 -2670
  74. package/src/components/azure-live-pricing.tsx +0 -185
  75. package/src/components/benchmark-import.tsx +0 -340
  76. package/src/components/confidence-badge.tsx +0 -116
  77. package/src/components/live-pricing-comparison.tsx +0 -241
  78. package/src/components/theme-provider.tsx +0 -11
  79. package/src/components/theme-toggle.tsx +0 -55
  80. package/src/components/ui/accordion.tsx +0 -66
  81. package/src/components/ui/alert-dialog.tsx +0 -157
  82. package/src/components/ui/alert.tsx +0 -66
  83. package/src/components/ui/aspect-ratio.tsx +0 -11
  84. package/src/components/ui/avatar.tsx +0 -53
  85. package/src/components/ui/badge.tsx +0 -46
  86. package/src/components/ui/breadcrumb.tsx +0 -109
  87. package/src/components/ui/button.tsx +0 -59
  88. package/src/components/ui/calendar.tsx +0 -213
  89. package/src/components/ui/card.tsx +0 -92
  90. package/src/components/ui/carousel.tsx +0 -241
  91. package/src/components/ui/chart.tsx +0 -353
  92. package/src/components/ui/checkbox.tsx +0 -32
  93. package/src/components/ui/collapsible.tsx +0 -33
  94. package/src/components/ui/command.tsx +0 -184
  95. package/src/components/ui/context-menu.tsx +0 -252
  96. package/src/components/ui/dialog.tsx +0 -143
  97. package/src/components/ui/drawer.tsx +0 -135
  98. package/src/components/ui/dropdown-menu.tsx +0 -257
  99. package/src/components/ui/form.tsx +0 -167
  100. package/src/components/ui/hover-card.tsx +0 -44
  101. package/src/components/ui/input-otp.tsx +0 -77
  102. package/src/components/ui/input.tsx +0 -21
  103. package/src/components/ui/label.tsx +0 -24
  104. package/src/components/ui/menubar.tsx +0 -276
  105. package/src/components/ui/navigation-menu.tsx +0 -168
  106. package/src/components/ui/pagination.tsx +0 -127
  107. package/src/components/ui/popover.tsx +0 -48
  108. package/src/components/ui/progress.tsx +0 -31
  109. package/src/components/ui/radio-group.tsx +0 -45
  110. package/src/components/ui/resizable.tsx +0 -56
  111. package/src/components/ui/scroll-area.tsx +0 -58
  112. package/src/components/ui/select.tsx +0 -185
  113. package/src/components/ui/separator.tsx +0 -28
  114. package/src/components/ui/sheet.tsx +0 -139
  115. package/src/components/ui/sidebar.tsx +0 -726
  116. package/src/components/ui/skeleton.tsx +0 -13
  117. package/src/components/ui/slider.tsx +0 -63
  118. package/src/components/ui/sonner.tsx +0 -25
  119. package/src/components/ui/switch.tsx +0 -31
  120. package/src/components/ui/table.tsx +0 -116
  121. package/src/components/ui/tabs.tsx +0 -66
  122. package/src/components/ui/textarea.tsx +0 -18
  123. package/src/components/ui/toast.tsx +0 -129
  124. package/src/components/ui/toaster.tsx +0 -35
  125. package/src/components/ui/toggle-group.tsx +0 -73
  126. package/src/components/ui/toggle.tsx +0 -47
  127. package/src/components/ui/tooltip.tsx +0 -61
  128. package/src/components/vast-ai-live-pricing.tsx +0 -176
  129. package/src/hooks/use-mobile.ts +0 -19
  130. package/src/hooks/use-toast.ts +0 -194
  131. package/src/lib/benchmark-parser-sglang.ts +0 -150
  132. package/src/lib/benchmark-parser-tokcalc.ts +0 -247
  133. package/src/lib/benchmark-parser-trtllm.ts +0 -152
  134. package/src/lib/benchmark-parser-vllm.ts +0 -198
  135. package/src/lib/benchmark-schema.ts +0 -263
  136. package/src/lib/db.ts +0 -13
  137. package/src/lib/engine-presets.ts +0 -183
  138. package/src/lib/price-schema.ts +0 -141
  139. package/src/lib/token-calc.ts +0 -808
  140. package/src/lib/track.ts +0 -31
  141. package/src/lib/url-state.ts +0 -256
  142. package/src/lib/utils.ts +0 -6
  143. package/tailwind.config.ts +0 -64
  144. package/tests/database-runtime-build.sh +0 -75
  145. package/tests/python-runtime-build.sh +0 -64
  146. package/tests/python-runtime-container.sh +0 -31
  147. package/tool-results/bash_1789888171144_2c5381860539.txt +0 -161
  148. package/tool-results/bash_1789888175925_49c53ba3c61b.txt +0 -191
  149. package/tool-results/bash_1789888181202_49c53ba3c61b.txt +0 -191
  150. package/tool-results/bash_1789888195219_4a86a5c91411.txt +0 -200
  151. package/tool-results/bash_1789888203128_6cca13c71b47.txt +0 -199
  152. package/tool-results/bash_1789929256963_2a52aff0d0a8.txt +0 -160
  153. package/tool-results/read_1789888151021_69f58eec6a5b.txt +0 -653
  154. package/tool-results/read_1789888153837_1d3a8bfc2a94.txt +0 -653
  155. package/tool-results/read_1789888163087_ccc406d47505.txt +0 -122
  156. package/tool-results/read_1789888167347_67d1d7c9830a.txt +0 -122
  157. package/tool-results/read_1789929252529_d90e8f383a25.txt +0 -285
  158. package/tsconfig.json +0 -42
  159. package/upload/Pasted Content_1789887800864.txt +0 -652
  160. package/upload/Pasted Content_1789887909561.txt +0 -652
  161. package/upload/Pasted Content_1789887918428.txt +0 -652
  162. package/upload/Pasted Content_1789887959420.txt +0 -652
  163. package/upload/Pasted Content_1789888020485.txt +0 -652
  164. package/upload/Pasted Content_1789888058079.txt +0 -652
  165. package/upload/Pasted Content_1789888885033.txt +0 -686
  166. package/upload/Pasted Content_1789928912741.txt +0 -285
  167. package/upload/Pasted Content_1789928938402.txt +0 -285
  168. package/upload/Pasted Content_1789929160389.txt +0 -285
  169. package/upload/Pasted Content_1789929176660.txt +0 -285
  170. package/upload/issue_vision.json +0 -28
  171. package/upload/pasted_image_1789883175209.png +0 -0
  172. package/upload/pasted_image_1789899056690.png +0 -0
  173. package/upload/pasted_image_1789900371483.png +0 -0
  174. package/upload/pasted_image_1789900472823.png +0 -0
  175. package/upload/pasted_image_1789900490374.png +0 -0
  176. package/upload/pasted_image_1789900585552.png +0 -0
  177. package/upload/pasted_image_1789900606519.png +0 -0
  178. package/upload/pasted_image_1789901598705.png +0 -0
  179. package/upload/pasted_image_1789901613545.png +0 -0
  180. package/upload/pasted_image_1789978382674.png +0 -0
  181. package/upload/pasted_image_1789978392749.png +0 -0
  182. package/upload/pasted_image_1789978474879.png +0 -0
  183. package/upload/pasted_image_1789978523652.png +0 -0
  184. package/upload/pasted_image_1789984219089.png +0 -0
  185. package/upload/pasted_image_1789984491896.png +0 -0
  186. package/upload/pasted_image_1789985017950.png +0 -0
  187. package/upload/pasted_image_1789985036765.png +0 -0
  188. package/upload/pasted_image_1789985049848.png +0 -0
  189. package/upload/pasted_image_1790002427833.png +0 -0
  190. package/upload/pasted_image_1790002659944.png +0 -0
  191. package/upload/pasted_image_1790037038476.png +0 -0
  192. package/upload/screenshot_analysis.json +0 -28
  193. package/upload/vision_output.json +0 -28
@@ -1,328 +0,0 @@
1
- "use client";
2
-
3
- import { useMemo, useState } from "react";
4
- import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
5
- import { Badge } from "@/components/ui/badge";
6
- import { Button } from "@/components/ui/button";
7
- import { ArrowLeft, Cpu, Zap, DollarSign, MemoryStick, Gauge } from "lucide-react";
8
- import {
9
- calculate,
10
- fmtTokens,
11
- fmtBytes,
12
- fmtMs,
13
- fmtMoney,
14
- GPU_MAP,
15
- MODELS,
16
- QUANT_MAP,
17
- type Quantization,
18
- } from "@/lib/token-calc";
19
- import { ConfidenceDot } from "@/components/confidence-badge";
20
- import {
21
- Bar,
22
- BarChart,
23
- CartesianGrid,
24
- ResponsiveContainer,
25
- XAxis,
26
- YAxis,
27
- Tooltip,
28
- Bar as BarChartBar,
29
- } from "recharts";
30
- import Link from "next/link";
31
-
32
- const MODEL_ID = "llama3-3-70b";
33
- const QUANT: Quantization = "fp8";
34
-
35
- const H100 = GPU_MAP["h100-sxm"];
36
- const H200 = GPU_MAP["h200-sxm"];
37
- const model = MODELS.find((m) => m.id === MODEL_ID)!;
38
- const quant = QUANT_MAP[QUANT];
39
-
40
- function calcForGpu(gpuId: string, gpuCount: number, contextTokens: number) {
41
- return calculate({
42
- modelId: MODEL_ID,
43
- gpuId,
44
- quantization: QUANT,
45
- numGpus: gpuCount,
46
- batchSize: 8,
47
- promptTokens: contextTokens,
48
- outputTokens: 500,
49
- });
50
- }
51
-
52
- const SPEC_ROWS = [
53
- { label: "VRAM", h100: "80 GB HBM3", h200: "141 GB HBM3e", winner: "h200" },
54
- { label: "Memory bandwidth", h100: "3,350 GB/s", h200: "4,800 GB/s", winner: "h200" },
55
- { label: "FP16/BF16 dense TFLOPS", h100: "990 TF", h200: "990 TF", winner: "tie" },
56
- { label: "FP8 support", h100: "Native", h200: "Native", winner: "tie" },
57
- { label: "NVLink bandwidth", h100: "900 GB/s", h200: "900 GB/s", winner: "tie" },
58
- { label: "Typical cloud price", h100: "~$2.50/hr", h200: "~$4.00/hr", winner: "h100" },
59
- { label: "Release year", h100: "2022", h200: "2024", winner: "h200" },
60
- { label: "TDP (power)", h100: "700W", h200: "700W", winner: "tie" },
61
- ];
62
-
63
- export default function H100vsH200Page() {
64
- const [context, setContext] = useState(50000);
65
- const [gpuCount, setGpuCount] = useState(2);
66
-
67
- const h100Result = useMemo(() => calcForGpu("h100-sxm", gpuCount, context), [gpuCount, context]);
68
- const h200Result = useMemo(() => calcForGpu("h200-sxm", gpuCount, context), [gpuCount, context]);
69
-
70
- const chartData = useMemo(() => {
71
- const ctxs = [4096, 8192, 16384, 32768, 65536, 131072];
72
- return ctxs.map((ctx) => ({
73
- context: `${ctx / 1000}K`,
74
- h100: Math.max(0, Math.round(calcForGpu("h100-sxm", gpuCount, ctx).aggregateTokensPerSec)),
75
- h200: Math.max(0, Math.round(calcForGpu("h200-sxm", gpuCount, ctx).aggregateTokensPerSec)),
76
- }));
77
- }, [gpuCount]);
78
-
79
- const chartConcurrency = useMemo(() => {
80
- const ctxs = [4096, 8192, 16384, 32768, 65536, 131072];
81
- return ctxs.map((ctx) => {
82
- const r1 = calcForGpu("h100-sxm", gpuCount, ctx);
83
- const r2 = calcForGpu("h200-sxm", gpuCount, ctx);
84
- return {
85
- context: `${ctx / 1000}K`,
86
- h100: r1.vramFits ? Math.floor(((H100!.vramGb * gpuCount) - model.paramsB * quant.bytesPerParam) / (r1.kvCachePerTokenKb * 1024 / 1e6 / ctx)) : 0,
87
- h200: r2.vramFits ? Math.floor(((H200!.vramGb * gpuCount) - model.paramsB * quant.bytesPerParam) / (r2.kvCachePerTokenKb * 1024 / 1e6 / ctx)) : 0,
88
- };
89
- });
90
- }, [gpuCount]);
91
-
92
- const shareH100 = `https://tokcalc.vercel.app/#t=calculator&m=${MODEL_ID}&g=h100-sxm&q=${QUANT}&n=${gpuCount}&b=8&p=${context}&o=500&cb=1&cbm=2`;
93
- const shareH200 = `https://tokcalc.vercel.app/#t=calculator&m=${MODEL_ID}&g=h200-sxm&q=${QUANT}&n=${gpuCount}&b=8&p=${context}&o=500&cb=1&cbm=2`;
94
-
95
- return (
96
- <div className="min-h-screen bg-background text-foreground">
97
- <div className="max-w-4xl mx-auto px-4 sm:px-6 py-8 sm:py-12">
98
- <Link href="/" className="inline-flex items-center gap-1.5 text-sm text-muted-foreground hover:text-foreground mb-6">
99
- <ArrowLeft className="size-4" />
100
- Back to tokcalc
101
- </Link>
102
-
103
- <h1 className="text-3xl sm:text-4xl font-bold tracking-tight mb-3">
104
- H100 vs H200 for LLM Inference: <span className="text-emerald-500">Throughput, Latency, VRAM & Cost</span>
105
- </h1>
106
- <p className="text-muted-foreground text-sm sm:text-base leading-relaxed mb-8">
107
- Side-by-side comparison of NVIDIA H100 SXM5 80GB vs H200 SXM5 141GB for serving
108
- Llama 3.3 70B (FP8). See exactly how context length, VRAM, and bandwidth affect
109
- your deployment capacity — with transparent formulas, not marketing claims.
110
- </p>
111
-
112
- {/* Spec comparison */}
113
- <Card className="border-border/60 shadow-sm mb-8">
114
- <CardHeader>
115
- <CardTitle className="text-base flex items-center gap-2">
116
- <Cpu className="size-4 text-emerald-500" />
117
- Specification comparison
118
- </CardTitle>
119
- </CardHeader>
120
- <CardContent className="p-0">
121
- <table className="w-full text-sm">
122
- <thead className="bg-muted/40 text-[10px] uppercase">
123
- <tr>
124
- <th className="text-left px-4 py-2">Spec</th>
125
- <th className="text-left px-4 py-2">H100 SXM5</th>
126
- <th className="text-left px-4 py-2">H200 SXM5</th>
127
- <th className="text-center px-4 py-2">Winner</th>
128
- </tr>
129
- </thead>
130
- <tbody>
131
- {SPEC_ROWS.map((row, i) => (
132
- <tr key={i} className="border-t border-border/40">
133
- <td className="px-4 py-2 font-medium">{row.label}</td>
134
- <td className="px-4 py-2 font-mono text-xs">{row.h100}</td>
135
- <td className="px-4 py-2 font-mono text-xs">{row.h200}</td>
136
- <td className="px-4 py-2 text-center">
137
- {row.winner === "h200" && <Badge className="text-[9px] bg-emerald-500">H200</Badge>}
138
- {row.winner === "h100" && <Badge className="text-[9px] bg-blue-500">H100</Badge>}
139
- {row.winner === "tie" && <span className="text-[10px] text-muted-foreground">Tie</span>}
140
- </td>
141
- </tr>
142
- ))}
143
- </tbody>
144
- </table>
145
- </CardContent>
146
- </Card>
147
-
148
- {/* Interactive comparison */}
149
- <Card className="border-emerald-500/30 shadow-sm mb-8">
150
- <CardHeader>
151
- <CardTitle className="text-base flex items-center gap-2">
152
- <Gauge className="size-4 text-emerald-500" />
153
- Live comparison — adjust context length & GPU count
154
- </CardTitle>
155
- <CardDescription className="text-xs">
156
- All numbers computed by tokcalc&apos;s open-source formulas. Click a config to open the full calculator.
157
- </CardDescription>
158
- </CardHeader>
159
- <CardContent className="space-y-4">
160
- <div className="flex flex-wrap items-end gap-4">
161
- <div>
162
- <label className="text-xs text-muted-foreground block mb-1">Context length (tokens)</label>
163
- <select
164
- value={context}
165
- onChange={(e) => setContext(Number(e.target.value))}
166
- className="bg-muted border border-border rounded-md px-3 py-1.5 text-sm"
167
- >
168
- <option value={500}>500 (chat)</option>
169
- <option value={8192}>8K</option>
170
- <option value={32768}>32K (RAG)</option>
171
- <option value={50000}>50K</option>
172
- <option value={131072}>128K (long context)</option>
173
- </select>
174
- </div>
175
- <div>
176
- <label className="text-xs text-muted-foreground block mb-1">GPUs (tensor parallel)</label>
177
- <select
178
- value={gpuCount}
179
- onChange={(e) => setGpuCount(Number(e.target.value))}
180
- className="bg-muted border border-border rounded-md px-3 py-1.5 text-sm"
181
- >
182
- <option value={1}>1×</option>
183
- <option value={2}>2×</option>
184
- <option value={4}>4×</option>
185
- <option value={8}>8×</option>
186
- </select>
187
- </div>
188
- </div>
189
-
190
- <div className="grid grid-cols-2 gap-4">
191
- {/* H100 results */}
192
- <div className={`rounded-lg border p-4 ${h100Result.vramFits ? "border-border/60" : "border-red-500/40 bg-red-500/5"}`}>
193
- <div className="flex items-center gap-2 mb-3">
194
- <span className="text-sm font-bold">H100 SXM5</span>
195
- <Badge variant="outline" className="text-[9px]">80GB</Badge>
196
- </div>
197
- <div className="space-y-2 text-sm">
198
- <div className="flex justify-between"><span className="text-muted-foreground">Decode tok/s</span><span className="font-mono font-semibold">{fmtTokens(h100Result.decodeTokensPerSec)}</span></div>
199
- <div className="flex justify-between"><span className="text-muted-foreground">Aggregate tok/s</span><span className="font-mono">{fmtTokens(h100Result.aggregateTokensPerSec)}</span></div>
200
- <div className="flex justify-between"><span className="text-muted-foreground">TTFT</span><span className="font-mono">{fmtMs(h100Result.ttftMs)}</span></div>
201
- <div className="flex justify-between"><span className="text-muted-foreground">VRAM needed</span><span className={`font-mono ${h100Result.vramFits ? "" : "text-red-500"}`}>{fmtBytes(h100Result.totalVramNeededGb)} / {H100!.vramGb * gpuCount}GB</span></div>
202
- <div className="flex justify-between"><span className="text-muted-foreground">Cost/M tokens</span><span className="font-mono text-emerald-500">{fmtMoney(h100Result.costPerMillionOutputTokens)}</span></div>
203
- <div className="flex justify-between"><span className="text-muted-foreground">Fits?</span><span className={h100Result.vramFits ? "text-emerald-500" : "text-red-500"}>{h100Result.vramFits ? "✓ Yes" : "✗ No — over budget"}</span></div>
204
- </div>
205
- <Button asChild variant="outline" size="sm" className="w-full mt-3 text-xs">
206
- <a href={shareH100} target="_blank" rel="noopener noreferrer">Open in calculator →</a>
207
- </Button>
208
- </div>
209
-
210
- {/* H200 results */}
211
- <div className={`rounded-lg border p-4 ${h200Result.vramFits ? "border-emerald-500/40 bg-emerald-500/5" : "border-red-500/40"}`}>
212
- <div className="flex items-center gap-2 mb-3">
213
- <span className="text-sm font-bold">H200 SXM5</span>
214
- <Badge variant="outline" className="text-[9px] bg-emerald-500/10">141GB</Badge>
215
- </div>
216
- <div className="space-y-2 text-sm">
217
- <div className="flex justify-between"><span className="text-muted-foreground">Decode tok/s</span><span className="font-mono font-semibold">{fmtTokens(h200Result.decodeTokensPerSec)}</span></div>
218
- <div className="flex justify-between"><span className="text-muted-foreground">Aggregate tok/s</span><span className="font-mono">{fmtTokens(h200Result.aggregateTokensPerSec)}</span></div>
219
- <div className="flex justify-between"><span className="text-muted-foreground">TTFT</span><span className="font-mono">{fmtMs(h200Result.ttftMs)}</span></div>
220
- <div className="flex justify-between"><span className="text-muted-foreground">VRAM needed</span><span className="font-mono">{fmtBytes(h200Result.totalVramNeededGb)} / {H200!.vramGb * gpuCount}GB</span></div>
221
- <div className="flex justify-between"><span className="text-muted-foreground">Cost/M tokens</span><span className="font-mono text-emerald-500">{fmtMoney(h200Result.costPerMillionOutputTokens)}</span></div>
222
- <div className="flex justify-between"><span className="text-muted-foreground">Fits?</span><span className={h200Result.vramFits ? "text-emerald-500" : "text-red-500"}>{h200Result.vramFits ? "✓ Yes" : "✗ No"}</span></div>
223
- </div>
224
- <Button asChild variant="outline" size="sm" className="w-full mt-3 text-xs">
225
- <a href={shareH200} target="_blank" rel="noopener noreferrer">Open in calculator →</a>
226
- </Button>
227
- </div>
228
- </div>
229
- </CardContent>
230
- </Card>
231
-
232
- {/* Throughput chart */}
233
- <Card className="border-border/60 shadow-sm mb-8">
234
- <CardHeader>
235
- <CardTitle className="text-base flex items-center gap-2"><Zap className="size-4 text-emerald-500" /> Throughput by context length</CardTitle>
236
- <CardDescription className="text-xs">Llama 3.3 70B FP8, {gpuCount}× GPU, batch 8, continuous batching 2.0×</CardDescription>
237
- </CardHeader>
238
- <CardContent>
239
- <div className="h-[280px] w-full">
240
- <ResponsiveContainer width="100%" height="100%">
241
- <BarChart data={chartData} margin={{ top: 8, right: 16, bottom: 0, left: 0 }}>
242
- <CartesianGrid strokeDasharray="3 3" stroke="var(--border)" opacity={0.3} />
243
- <XAxis dataKey="context" stroke="var(--muted-foreground)" fontSize={11} />
244
- <YAxis stroke="var(--muted-foreground)" fontSize={11} tickFormatter={(v) => v >= 1000 ? `${(v/1000).toFixed(0)}k` : v} />
245
- <Tooltip contentStyle={{ backgroundColor: "var(--background)", border: "1px solid var(--border)", borderRadius: "6px", fontSize: "12px" }} />
246
- <BarChartBar dataKey="h100" name="H100" fill="#3b82f6" radius={[3,3,0,0]} />
247
- <BarChartBar dataKey="h200" name="H200" fill="#10b981" radius={[3,3,0,0]} />
248
- </BarChart>
249
- </ResponsiveContainer>
250
- </div>
251
- </CardContent>
252
- </Card>
253
-
254
- {/* Key findings */}
255
- <div className="prose dark:prose-invert max-w-none mb-8">
256
- <h2 className="text-xl font-semibold mb-4">Key findings</h2>
257
- <div className="space-y-4 text-sm leading-relaxed">
258
- <div className="flex gap-3">
259
- <span className="text-emerald-500 font-bold">1.</span>
260
- <p><strong>H200 doubles H100 concurrency at every context length</strong> due to 76% more VRAM (141 vs 80 GB). The free VRAM after loading model weights is the bottleneck — H200 has 70 GB free vs H100&apos;s 9 GB for Llama 70B FP8.</p>
261
- </div>
262
- <div className="flex gap-3">
263
- <span className="text-emerald-500 font-bold">2.</span>
264
- <p><strong>H100 can&apos;t serve 32K+ context for Llama 70B FP8 on a single GPU</strong> — the KV cache alone needs 10+ GB, exceeding the 9 GB free after loading 70.6 GB of weights. H200 handles 32K with room for 6 concurrent users.</p>
265
- </div>
266
- <div className="flex gap-3">
267
- <span className="text-emerald-500 font-bold">3.</span>
268
- <p><strong>H200 is 43% faster per-token</strong> (4,800 vs 3,350 GB/s HBM bandwidth) — decode throughput scales linearly with memory bandwidth for memory-bound LLM inference.</p>
269
- </div>
270
- <div className="flex gap-3">
271
- <span className="text-emerald-500 font-bold">4.</span>
272
- <p><strong>H100 is 60% cheaper per GPU-hour</strong> (~$2.50 vs ~$4.00) but the cost-per-token is often LOWER on H200 because the higher throughput more than compensates for the higher hourly price.</p>
273
- </div>
274
- </div>
275
- </div>
276
-
277
- {/* FAQ */}
278
- <div className="prose dark:prose-invert max-w-none mb-8">
279
- <h2 className="text-xl font-semibold mb-4">FAQ</h2>
280
- <div className="space-y-4 text-sm">
281
- <details className="group">
282
- <summary className="font-medium cursor-pointer">Should I use H100 or H200 for Llama 3.3 70B?</summary>
283
- <p className="mt-2 text-muted-foreground">For context lengths under 8K, H100 is sufficient and cheaper. For 8K-32K, H200 is strongly preferred (H100 can&apos;t fit 32K on a single GPU). For 128K+, H200 is the minimum — H100 can&apos;t fit it even with TP×2.</p>
284
- </details>
285
- <details className="group">
286
- <summary className="font-medium cursor-pointer">How much faster is H200 than H100 for LLM inference?</summary>
287
- <p className="mt-2 text-muted-foreground">H200 is ~43% faster per-token decode throughput (4,800 vs 3,350 GB/s HBM bandwidth). For aggregate batched throughput, H200 is 2-8× better than H100 at long context because it has 7× more free VRAM for KV cache.</p>
288
- </details>
289
- <details className="group">
290
- <summary className="font-medium cursor-pointer">Is H200 worth the extra cost over H100?</summary>
291
- <p className="mt-2 text-muted-foreground">At 32K+ context, yes — H100 can&apos;t even fit the workload, so H200 is the only option. At short context (4K), H100 may be more cost-effective. Use the calculator above to find your break-even point.</p>
292
- </details>
293
- <details className="group">
294
- <summary className="font-medium cursor-pointer">Can H100 serve 128K context for Llama 70B?</summary>
295
- <p className="mt-2 text-muted-foreground">No — a single H100 (80 GB) can&apos;t fit Llama 70B FP8 (70.6 GB weights) + 128K KV cache (~42 GB) = 112 GB total. You&apos;d need at least 2× H100 (160 GB) or 1× H200 (141 GB).</p>
296
- </details>
297
- </div>
298
- </div>
299
-
300
- {/* Internal links */}
301
- <div className="border-t border-border/60 pt-6 mt-8">
302
- <p className="text-xs text-muted-foreground mb-3">Related comparisons:</p>
303
- <div className="flex flex-wrap gap-2">
304
- <Link href="/compare/gguf-q4-k-m-vs-q5-k-m" className="text-xs text-emerald-500 hover:underline">GGUF Q4_K_M vs Q5_K_M →</Link>
305
- <Link href="/self-host-vs-openai-api" className="text-xs text-emerald-500 hover:underline">Self-host vs OpenAI API →</Link>
306
- <Link href="/" className="text-xs text-emerald-500 hover:underline">Full capacity calculator →</Link>
307
- </div>
308
- </div>
309
-
310
- {/* JSON-LD structured data */}
311
- <script
312
- type="application/ld+json"
313
- dangerouslySetInnerHTML={{
314
- __html: JSON.stringify({
315
- "@context": "https://schema.org",
316
- "@type": "FAQPage",
317
- mainEntity: [
318
- { "@type": "Question", name: "Should I use H100 or H200 for Llama 3.3 70B?", acceptedAnswer: { "@type": "Answer", text: "For context under 8K, H100 is sufficient. For 8K-32K+, H200 is strongly preferred or required." } },
319
- { "@type": "Question", name: "How much faster is H200 than H100?", acceptedAnswer: { "@type": "Answer", text: "H200 is ~43% faster per-token and 2-8× better aggregate throughput at long context due to 76% more VRAM." } },
320
- { "@type": "Question", name: "Is H200 worth the extra cost?", acceptedAnswer: { "@type": "Answer", text: "At 32K+ context, yes. At short context, H100 may be cheaper. Use the calculator to find your break-even." } },
321
- ],
322
- }),
323
- }}
324
- />
325
- </div>
326
- </div>
327
- );
328
- }
@@ -1,122 +0,0 @@
1
- @import "tailwindcss";
2
- @import "tw-animate-css";
3
-
4
- @custom-variant dark (&:is(.dark *));
5
-
6
- @theme inline {
7
- --color-background: var(--background);
8
- --color-foreground: var(--foreground);
9
- --font-sans: var(--font-geist-sans);
10
- --font-mono: var(--font-geist-mono);
11
- --color-sidebar-ring: var(--sidebar-ring);
12
- --color-sidebar-border: var(--sidebar-border);
13
- --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
14
- --color-sidebar-accent: var(--sidebar-accent);
15
- --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
16
- --color-sidebar-primary: var(--sidebar-primary);
17
- --color-sidebar-foreground: var(--sidebar-foreground);
18
- --color-sidebar: var(--sidebar);
19
- --color-chart-5: var(--chart-5);
20
- --color-chart-4: var(--chart-4);
21
- --color-chart-3: var(--chart-3);
22
- --color-chart-2: var(--chart-2);
23
- --color-chart-1: var(--chart-1);
24
- --color-ring: var(--ring);
25
- --color-input: var(--input);
26
- --color-border: var(--border);
27
- --color-destructive: var(--destructive);
28
- --color-accent-foreground: var(--accent-foreground);
29
- --color-accent: var(--accent);
30
- --color-muted-foreground: var(--muted-foreground);
31
- --color-muted: var(--muted);
32
- --color-secondary-foreground: var(--secondary-foreground);
33
- --color-secondary: var(--secondary);
34
- --color-primary-foreground: var(--primary-foreground);
35
- --color-primary: var(--primary);
36
- --color-popover-foreground: var(--popover-foreground);
37
- --color-popover: var(--popover);
38
- --color-card-foreground: var(--card-foreground);
39
- --color-card: var(--card);
40
- --radius-sm: calc(var(--radius) - 4px);
41
- --radius-md: calc(var(--radius) - 2px);
42
- --radius-lg: var(--radius);
43
- --radius-xl: calc(var(--radius) + 4px);
44
- }
45
-
46
- :root {
47
- --radius: 0.625rem;
48
- --background: oklch(1 0 0);
49
- --foreground: oklch(0.145 0 0);
50
- --card: oklch(1 0 0);
51
- --card-foreground: oklch(0.145 0 0);
52
- --popover: oklch(1 0 0);
53
- --popover-foreground: oklch(0.145 0 0);
54
- --primary: oklch(0.205 0 0);
55
- --primary-foreground: oklch(0.985 0 0);
56
- --secondary: oklch(0.97 0 0);
57
- --secondary-foreground: oklch(0.205 0 0);
58
- --muted: oklch(0.97 0 0);
59
- --muted-foreground: oklch(0.556 0 0);
60
- --accent: oklch(0.97 0 0);
61
- --accent-foreground: oklch(0.205 0 0);
62
- --destructive: oklch(0.577 0.245 27.325);
63
- --border: oklch(0.922 0 0);
64
- --input: oklch(0.922 0 0);
65
- --ring: oklch(0.708 0 0);
66
- --chart-1: oklch(0.646 0.222 41.116);
67
- --chart-2: oklch(0.6 0.118 184.704);
68
- --chart-3: oklch(0.398 0.07 227.392);
69
- --chart-4: oklch(0.828 0.189 84.429);
70
- --chart-5: oklch(0.769 0.188 70.08);
71
- --sidebar: oklch(0.985 0 0);
72
- --sidebar-foreground: oklch(0.145 0 0);
73
- --sidebar-primary: oklch(0.205 0 0);
74
- --sidebar-primary-foreground: oklch(0.985 0 0);
75
- --sidebar-accent: oklch(0.97 0 0);
76
- --sidebar-accent-foreground: oklch(0.205 0 0);
77
- --sidebar-border: oklch(0.922 0 0);
78
- --sidebar-ring: oklch(0.708 0 0);
79
- }
80
-
81
- .dark {
82
- --background: oklch(0.145 0 0);
83
- --foreground: oklch(0.985 0 0);
84
- --card: oklch(0.205 0 0);
85
- --card-foreground: oklch(0.985 0 0);
86
- --popover: oklch(0.205 0 0);
87
- --popover-foreground: oklch(0.985 0 0);
88
- --primary: oklch(0.922 0 0);
89
- --primary-foreground: oklch(0.205 0 0);
90
- --secondary: oklch(0.269 0 0);
91
- --secondary-foreground: oklch(0.985 0 0);
92
- --muted: oklch(0.269 0 0);
93
- --muted-foreground: oklch(0.708 0 0);
94
- --accent: oklch(0.269 0 0);
95
- --accent-foreground: oklch(0.985 0 0);
96
- --destructive: oklch(0.704 0.191 22.216);
97
- --border: oklch(1 0 0 / 10%);
98
- --input: oklch(1 0 0 / 15%);
99
- --ring: oklch(0.556 0 0);
100
- --chart-1: oklch(0.488 0.243 264.376);
101
- --chart-2: oklch(0.696 0.17 162.48);
102
- --chart-3: oklch(0.769 0.188 70.08);
103
- --chart-4: oklch(0.627 0.265 303.9);
104
- --chart-5: oklch(0.645 0.246 16.439);
105
- --sidebar: oklch(0.205 0 0);
106
- --sidebar-foreground: oklch(0.985 0 0);
107
- --sidebar-primary: oklch(0.488 0.243 264.376);
108
- --sidebar-primary-foreground: oklch(0.985 0 0);
109
- --sidebar-accent: oklch(0.269 0 0);
110
- --sidebar-accent-foreground: oklch(0.985 0 0);
111
- --sidebar-border: oklch(1 0 0 / 10%);
112
- --sidebar-ring: oklch(0.556 0 0);
113
- }
114
-
115
- @layer base {
116
- * {
117
- @apply border-border outline-ring/50;
118
- }
119
- body {
120
- @apply bg-background text-foreground;
121
- }
122
- }