[docs] Rotate popular models on the landing pages, lead the Cookbook nav with Kimi (#32835)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
3c9efaf3e1
commit
5efbb18a6f
@@ -7,6 +7,24 @@ metatags:
|
||||
---
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card
|
||||
title="Kimi (Moonshot AI)"
|
||||
mode="card"
|
||||
href="/cookbook/autoregressive/Moonshotai/Kimi-K3"
|
||||
img="/cards/logos/moonshotai.png"
|
||||
/>
|
||||
<Card
|
||||
title="Thinking Machines"
|
||||
mode="card"
|
||||
href="/cookbook/autoregressive/ThinkingMachines/Inkling"
|
||||
img="/cards/logos/thinkingmachines.png"
|
||||
/>
|
||||
<Card
|
||||
title="GLM"
|
||||
mode="card"
|
||||
href="/cookbook/autoregressive/GLM/GLM-5.2"
|
||||
img="/cards/logos/glm.png"
|
||||
/>
|
||||
<Card
|
||||
title="Qwen"
|
||||
mode="card"
|
||||
@@ -31,18 +49,6 @@ metatags:
|
||||
href="/cookbook/autoregressive/Llama/Llama3.3-70B"
|
||||
img="/cards/logos/llama.png"
|
||||
/>
|
||||
<Card
|
||||
title="GLM"
|
||||
mode="card"
|
||||
href="/cookbook/autoregressive/GLM/GLM-5.2"
|
||||
img="/cards/logos/glm.png"
|
||||
/>
|
||||
<Card
|
||||
title="Thinking Machines"
|
||||
mode="card"
|
||||
href="/cookbook/autoregressive/ThinkingMachines/Inkling"
|
||||
img="/cards/logos/thinkingmachines.png"
|
||||
/>
|
||||
<Card
|
||||
title="Meituan"
|
||||
mode="card"
|
||||
@@ -67,12 +73,6 @@ metatags:
|
||||
href="/cookbook/autoregressive/OpenAI/GPT-OSS"
|
||||
img="/cards/logos/openai.png"
|
||||
/>
|
||||
<Card
|
||||
title="Moonshotai"
|
||||
mode="card"
|
||||
href="/cookbook/autoregressive/Moonshotai/Kimi-K3"
|
||||
img="/cards/logos/moonshotai.png"
|
||||
/>
|
||||
<Card
|
||||
title="MiniMax"
|
||||
mode="card"
|
||||
|
||||
@@ -6,6 +6,12 @@ metatags:
|
||||
|
||||
A community-maintained repository of practical guides and recipes for deploying and using SGLang in production environments. Our mission is simple: answer the question **"How do I use SGLang (and related models) on hardware Y for task Z?"** with clear, actionable solutions.
|
||||
|
||||
import { popularModels } from "/src/snippets/configs/popular-models.jsx";
|
||||
import { PopularModels } from "/src/snippets/_popular_models.jsx";
|
||||
|
||||
{/* Edit the list in /src/snippets/configs/popular-models.jsx — the docs landing
|
||||
page's featured hero reads the same file. */}
|
||||
<PopularModels models={popularModels} />
|
||||
|
||||
## Guides
|
||||
|
||||
|
||||
+33
-33
@@ -969,6 +969,39 @@
|
||||
"group": "Autoregressive Models",
|
||||
"pages": [
|
||||
"cookbook/autoregressive/intro",
|
||||
{
|
||||
"group": "Kimi (Moonshot AI)",
|
||||
"pages": [
|
||||
"cookbook/autoregressive/Moonshotai/Kimi-K3",
|
||||
"cookbook/autoregressive/Moonshotai/Kimi-K2.7-Code",
|
||||
"cookbook/autoregressive/Moonshotai/Kimi-K2.6",
|
||||
"cookbook/autoregressive/Moonshotai/Kimi-K2.5",
|
||||
"cookbook/autoregressive/Moonshotai/Kimi-K2",
|
||||
"cookbook/autoregressive/Moonshotai/Kimi-Linear"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Thinking Machines",
|
||||
"pages": [
|
||||
"cookbook/autoregressive/ThinkingMachines/Inkling"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "GLM",
|
||||
"pages": [
|
||||
"cookbook/autoregressive/GLM/GLM-5.2",
|
||||
"cookbook/autoregressive/GLM/GLM-5.1",
|
||||
"cookbook/autoregressive/GLM/GLM-5",
|
||||
"cookbook/autoregressive/GLM/GLM-OCR",
|
||||
"cookbook/autoregressive/GLM/GLM-Glyph",
|
||||
"cookbook/autoregressive/GLM/GLM-4.7",
|
||||
"cookbook/autoregressive/GLM/GLM-4.7-Flash",
|
||||
"cookbook/autoregressive/GLM/GLM-4.6",
|
||||
"cookbook/autoregressive/GLM/GLM-4.6V",
|
||||
"cookbook/autoregressive/GLM/GLM-4.5",
|
||||
"cookbook/autoregressive/GLM/GLM-4.5V"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Qwen",
|
||||
"pages": [
|
||||
@@ -1009,28 +1042,6 @@
|
||||
"cookbook/autoregressive/Llama/Llama3.1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "GLM",
|
||||
"pages": [
|
||||
"cookbook/autoregressive/GLM/GLM-5.2",
|
||||
"cookbook/autoregressive/GLM/GLM-5.1",
|
||||
"cookbook/autoregressive/GLM/GLM-5",
|
||||
"cookbook/autoregressive/GLM/GLM-OCR",
|
||||
"cookbook/autoregressive/GLM/GLM-Glyph",
|
||||
"cookbook/autoregressive/GLM/GLM-4.7",
|
||||
"cookbook/autoregressive/GLM/GLM-4.7-Flash",
|
||||
"cookbook/autoregressive/GLM/GLM-4.6",
|
||||
"cookbook/autoregressive/GLM/GLM-4.6V",
|
||||
"cookbook/autoregressive/GLM/GLM-4.5",
|
||||
"cookbook/autoregressive/GLM/GLM-4.5V"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Thinking Machines",
|
||||
"pages": [
|
||||
"cookbook/autoregressive/ThinkingMachines/Inkling"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Meituan",
|
||||
"pages": [
|
||||
@@ -1057,17 +1068,6 @@
|
||||
"cookbook/autoregressive/OpenAI/GPT-OSS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Moonshotai",
|
||||
"pages": [
|
||||
"cookbook/autoregressive/Moonshotai/Kimi-K3",
|
||||
"cookbook/autoregressive/Moonshotai/Kimi-K2.7-Code",
|
||||
"cookbook/autoregressive/Moonshotai/Kimi-K2.6",
|
||||
"cookbook/autoregressive/Moonshotai/Kimi-K2.5",
|
||||
"cookbook/autoregressive/Moonshotai/Kimi-K2",
|
||||
"cookbook/autoregressive/Moonshotai/Kimi-Linear"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "MiniMax",
|
||||
"pages": [
|
||||
|
||||
+6
-178
@@ -9,184 +9,12 @@ keywords:
|
||||
mode: wide
|
||||
---
|
||||
|
||||
<div className="not-prose">
|
||||
<div
|
||||
style={{
|
||||
position: "relative",
|
||||
overflow: "hidden",
|
||||
marginBottom: "1.5rem",
|
||||
padding: "clamp(1.5rem, 4vw, 2.5rem)",
|
||||
border: "1px solid rgba(251, 146, 60, 0.35)",
|
||||
borderRadius: "1rem",
|
||||
background:
|
||||
"linear-gradient(135deg, #111827 0%, #31202f 58%, #9a3412 100%)",
|
||||
boxShadow: "0 20px 45px rgba(17, 24, 39, 0.18)",
|
||||
color: "#ffffff",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "-7rem",
|
||||
right: "-5rem",
|
||||
width: "18rem",
|
||||
height: "18rem",
|
||||
borderRadius: "999px",
|
||||
background: "rgba(251, 146, 60, 0.18)",
|
||||
filter: "blur(2px)",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
position: "relative",
|
||||
zIndex: 1,
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
alignItems: "center",
|
||||
gap: "clamp(1.25rem, 3vw, 2rem)",
|
||||
}}
|
||||
>
|
||||
<div style={{ flex: "1 1 24rem", minWidth: 0 }}>
|
||||
<div
|
||||
style={{
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
gap: "0.45rem",
|
||||
marginBottom: "0.9rem",
|
||||
padding: "0.35rem 0.7rem",
|
||||
border: "1px solid rgba(255, 255, 255, 0.28)",
|
||||
borderRadius: "999px",
|
||||
background: "rgba(255, 255, 255, 0.1)",
|
||||
fontSize: "0.72rem",
|
||||
fontWeight: 750,
|
||||
letterSpacing: "0.08em",
|
||||
textTransform: "uppercase",
|
||||
}}
|
||||
>
|
||||
<span aria-hidden="true">✦</span>
|
||||
Featured model · New
|
||||
</div>
|
||||
<a
|
||||
href="/cookbook/autoregressive/Moonshotai/Kimi-K3"
|
||||
style={{
|
||||
display: "block",
|
||||
margin: 0,
|
||||
color: "#ffffff",
|
||||
fontSize: "clamp(1.75rem, 4vw, 2.65rem)",
|
||||
fontWeight: 750,
|
||||
lineHeight: 1.08,
|
||||
letterSpacing: "-0.035em",
|
||||
textDecoration: "none",
|
||||
}}
|
||||
>
|
||||
Meet Kimi-K3 on SGLang
|
||||
</a>
|
||||
<p
|
||||
style={{
|
||||
maxWidth: "48rem",
|
||||
margin: "1rem 0 0",
|
||||
color: "rgba(255, 255, 255, 0.82)",
|
||||
fontSize: "1rem",
|
||||
lineHeight: 1.65,
|
||||
}}
|
||||
>
|
||||
SGLang natively implements and deeply optimizes K3's new architecture
|
||||
with fused KDA decode kernels, DP attention, MTP, PD disaggregation,
|
||||
and KDA-aware prefix caching. Kimi-K3 is supported on both NVIDIA and
|
||||
AMD GPUs.
|
||||
</p>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
gap: "0.5rem",
|
||||
marginTop: "1.15rem",
|
||||
}}
|
||||
>
|
||||
{[
|
||||
"2.8T parameters",
|
||||
"Fused KDA decode",
|
||||
"NVIDIA + AMD",
|
||||
].map((item) => (
|
||||
<span
|
||||
key={item}
|
||||
style={{
|
||||
padding: "0.35rem 0.65rem",
|
||||
borderRadius: "999px",
|
||||
background: "rgba(255, 255, 255, 0.1)",
|
||||
color: "rgba(255, 255, 255, 0.9)",
|
||||
fontSize: "0.78rem",
|
||||
fontWeight: 650,
|
||||
}}
|
||||
>
|
||||
{item}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
<a
|
||||
href="/cookbook/autoregressive/Moonshotai/Kimi-K3"
|
||||
style={{
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
marginTop: "1.35rem",
|
||||
padding: "0.7rem 1rem",
|
||||
borderRadius: "0.55rem",
|
||||
background: "#ffffff",
|
||||
color: "#7c2d12",
|
||||
fontSize: "0.88rem",
|
||||
fontWeight: 750,
|
||||
textDecoration: "none",
|
||||
}}
|
||||
>
|
||||
Open the Kimi-K3 cookbook →
|
||||
</a>
|
||||
</div>
|
||||
<a
|
||||
href="/cookbook/autoregressive/Moonshotai/Kimi-K3"
|
||||
aria-label="Open the Kimi-K3 cookbook"
|
||||
style={{
|
||||
flex: "0 1 12rem",
|
||||
minWidth: "10rem",
|
||||
padding: "0.8rem",
|
||||
border: "1px solid rgba(255, 255, 255, 0.22)",
|
||||
borderRadius: "0.9rem",
|
||||
background: "rgba(255, 255, 255, 0.96)",
|
||||
boxShadow: "0 16px 35px rgba(0, 0, 0, 0.22)",
|
||||
textDecoration: "none",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
role="img"
|
||||
aria-label="Moonshot AI"
|
||||
style={{
|
||||
width: "100%",
|
||||
aspectRatio: "16 / 9",
|
||||
borderRadius: "0.45rem",
|
||||
backgroundColor: "#ffffff",
|
||||
backgroundImage: "url('/cards/logos/moonshotai.png')",
|
||||
backgroundPosition: "center",
|
||||
backgroundRepeat: "no-repeat",
|
||||
backgroundSize: "cover",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
padding: "0.65rem 0.35rem 0.2rem",
|
||||
color: "#111827",
|
||||
textAlign: "center",
|
||||
fontSize: "0.78rem",
|
||||
fontWeight: 750,
|
||||
letterSpacing: "0.06em",
|
||||
textTransform: "uppercase",
|
||||
}}
|
||||
>
|
||||
Kimi-K3 deployment guide
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
import { popularModels } from "/src/snippets/configs/popular-models.jsx";
|
||||
import { PopularModels } from "/src/snippets/_popular_models.jsx";
|
||||
|
||||
{/* One hero per model, rotating. The Cookbook landing page renders the same
|
||||
list as a compact strip. Edit the list, not this page. */}
|
||||
<PopularModels models={popularModels} variant="hero" />
|
||||
|
||||
<a
|
||||
class="github-button"
|
||||
|
||||
@@ -0,0 +1,458 @@
|
||||
// Auto-rotating carousel over the shared list in
|
||||
// /src/snippets/configs/popular-models.jsx:
|
||||
//
|
||||
// <PopularModels models={popularModels} variant="hero" /> // docs home
|
||||
// <PopularModels models={popularModels} /> // cookbook home
|
||||
//
|
||||
// variant="hero" full-width banner per model — headline, blurb, tags, CTA,
|
||||
// brand tile, from the entry's `hero` block.
|
||||
// variant="strip" (default) one compact line per model — brand mark, name,
|
||||
// tags, "Open" button. No prose; the tags carry the pitch.
|
||||
//
|
||||
// Rotation pauses on hover/focus and is skipped under prefers-reduced-motion.
|
||||
//
|
||||
// One export for both shapes: Mintlify evaluates each exported component on its
|
||||
// own at hydration, so anything two components would share (rotation state, the
|
||||
// timer, the control cluster) has to sit inside one — module-level helpers are
|
||||
// out of scope by the time this runs.
|
||||
|
||||
export const PopularModels = ({
|
||||
models = [],
|
||||
variant = "strip",
|
||||
// A hero blurb takes longer to read than one line of tags.
|
||||
interval = variant === "hero" ? 9000 : 6000,
|
||||
label = "Popular models",
|
||||
}) => {
|
||||
const [index, setIndex] = useState(0);
|
||||
const [paused, setPaused] = useState(false);
|
||||
const [reduceMotion, setReduceMotion] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window === "undefined" || !window.matchMedia) return;
|
||||
const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
|
||||
const sync = () => setReduceMotion(mq.matches);
|
||||
sync();
|
||||
mq.addEventListener("change", sync);
|
||||
return () => mq.removeEventListener("change", sync);
|
||||
}, []);
|
||||
|
||||
const count = models.length;
|
||||
const isHero = variant === "hero";
|
||||
|
||||
// Functional update so the timer never closes over a stale index.
|
||||
useEffect(() => {
|
||||
if (count < 2 || paused || reduceMotion) return;
|
||||
const id = window.setInterval(
|
||||
() => setIndex((i) => (i + 1) % count),
|
||||
Math.max(2000, interval)
|
||||
);
|
||||
return () => window.clearInterval(id);
|
||||
}, [count, paused, reduceMotion, interval]);
|
||||
|
||||
// A shortened list must not leave the track parked past its last slide.
|
||||
const active = count ? Math.min(index, count - 1) : 0;
|
||||
|
||||
if (!count) return null;
|
||||
|
||||
const navButtonStyle = {
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
width: "1.15rem",
|
||||
height: "1.15rem",
|
||||
padding: 0,
|
||||
border: "1px solid rgba(255, 255, 255, 0.28)",
|
||||
borderRadius: "999px",
|
||||
background: "rgba(255, 255, 255, 0.1)",
|
||||
color: "rgba(255, 255, 255, 0.92)",
|
||||
fontSize: "0.8rem",
|
||||
lineHeight: 1,
|
||||
cursor: "pointer",
|
||||
};
|
||||
|
||||
const controls =
|
||||
count > 1 ? (
|
||||
<span style={{ display: "inline-flex", alignItems: "center", gap: "0.45rem" }}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setIndex((i) => (i - 1 + count) % count)}
|
||||
aria-label="Previous model"
|
||||
style={navButtonStyle}
|
||||
>
|
||||
‹
|
||||
</button>
|
||||
<span style={{ display: "inline-flex", alignItems: "center", gap: "0.3rem" }}>
|
||||
{models.map((m, i) => (
|
||||
<button
|
||||
key={m.href || m.name}
|
||||
type="button"
|
||||
onClick={() => setIndex(i)}
|
||||
aria-label={`Show ${m.name}`}
|
||||
aria-current={i === active ? "true" : undefined}
|
||||
style={{
|
||||
width: i === active ? "1.1rem" : "0.4rem",
|
||||
height: "0.4rem",
|
||||
padding: 0,
|
||||
border: 0,
|
||||
borderRadius: "999px",
|
||||
background:
|
||||
i === active ? "rgba(255, 255, 255, 0.92)" : "rgba(255, 255, 255, 0.34)",
|
||||
cursor: "pointer",
|
||||
transition: reduceMotion
|
||||
? "none"
|
||||
: "width 0.25s ease, background 0.25s ease",
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setIndex((i) => (i + 1) % count)}
|
||||
aria-label="Next model"
|
||||
style={navButtonStyle}
|
||||
>
|
||||
›
|
||||
</button>
|
||||
</span>
|
||||
) : null;
|
||||
|
||||
// Only the active slide is opaque: mid-slide, a visible neighbour reads as two
|
||||
// half-drawn cards rather than as motion.
|
||||
const slideStyle = (i) => ({
|
||||
flex: "0 0 100%",
|
||||
minWidth: 0,
|
||||
opacity: i === active ? 1 : 0,
|
||||
pointerEvents: i === active ? "auto" : "none",
|
||||
transition: reduceMotion ? "none" : "opacity 0.3s ease",
|
||||
});
|
||||
|
||||
const tagChip = (t, big) => (
|
||||
<span
|
||||
key={t}
|
||||
style={{
|
||||
padding: big ? "0.35rem 0.65rem" : "0.15rem 0.45rem",
|
||||
borderRadius: "999px",
|
||||
background: big ? "rgba(255, 255, 255, 0.1)" : "rgba(255, 255, 255, 0.12)",
|
||||
color: "rgba(255, 255, 255, 0.9)",
|
||||
fontSize: big ? "0.78rem" : "0.68rem",
|
||||
fontWeight: 650,
|
||||
whiteSpace: big ? "normal" : "nowrap",
|
||||
}}
|
||||
>
|
||||
{t}
|
||||
</span>
|
||||
);
|
||||
|
||||
const heroSlide = (m, i) => {
|
||||
const hero = m.hero || {};
|
||||
const cta = hero.cta || `Open the ${m.name} cookbook`;
|
||||
return (
|
||||
<div key={m.href || m.name} aria-hidden={i === active ? undefined : "true"} style={slideStyle(i)}>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
alignItems: "center",
|
||||
gap: "clamp(1.25rem, 3vw, 2rem)",
|
||||
}}
|
||||
>
|
||||
<div style={{ flex: "1 1 24rem", minWidth: 0 }}>
|
||||
<a
|
||||
href={m.href}
|
||||
tabIndex={i === active ? undefined : -1}
|
||||
style={{
|
||||
display: "block",
|
||||
margin: 0,
|
||||
color: "#ffffff",
|
||||
fontSize: "clamp(1.75rem, 4vw, 2.65rem)",
|
||||
fontWeight: 750,
|
||||
lineHeight: 1.08,
|
||||
letterSpacing: "-0.035em",
|
||||
textDecoration: "none",
|
||||
}}
|
||||
>
|
||||
{hero.headline || m.name}
|
||||
</a>
|
||||
{hero.blurb ? (
|
||||
// A div, not a p: MDX rewrites `p` to its own inline element, so a
|
||||
// paragraph here would depend on how that element is styled.
|
||||
<div
|
||||
style={{
|
||||
maxWidth: "48rem",
|
||||
margin: "1rem 0 0",
|
||||
color: "rgba(255, 255, 255, 0.82)",
|
||||
fontSize: "1rem",
|
||||
lineHeight: 1.65,
|
||||
}}
|
||||
>
|
||||
{hero.blurb}
|
||||
</div>
|
||||
) : null}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
gap: "0.5rem",
|
||||
marginTop: "1.15rem",
|
||||
}}
|
||||
>
|
||||
{(hero.tags || m.tags || []).map((t) => tagChip(t, true))}
|
||||
</div>
|
||||
<a
|
||||
href={m.href}
|
||||
tabIndex={i === active ? undefined : -1}
|
||||
style={{
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
marginTop: "1.35rem",
|
||||
padding: "0.7rem 1rem",
|
||||
borderRadius: "0.55rem",
|
||||
background: "#ffffff",
|
||||
color: "#7c2d12",
|
||||
fontSize: "0.88rem",
|
||||
fontWeight: 750,
|
||||
textDecoration: "none",
|
||||
}}
|
||||
>
|
||||
{cta} →
|
||||
</a>
|
||||
</div>
|
||||
<a
|
||||
href={m.href}
|
||||
aria-label={cta}
|
||||
tabIndex={i === active ? undefined : -1}
|
||||
style={{
|
||||
flex: "0 1 12rem",
|
||||
minWidth: "10rem",
|
||||
padding: "0.8rem",
|
||||
border: "1px solid rgba(255, 255, 255, 0.22)",
|
||||
borderRadius: "0.9rem",
|
||||
background: "rgba(255, 255, 255, 0.96)",
|
||||
boxShadow: "0 16px 35px rgba(0, 0, 0, 0.22)",
|
||||
textDecoration: "none",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
role="img"
|
||||
aria-label={m.vendor || m.name}
|
||||
style={{
|
||||
width: "100%",
|
||||
aspectRatio: "16 / 9",
|
||||
borderRadius: "0.45rem",
|
||||
backgroundColor: "#ffffff",
|
||||
backgroundImage: `url('${m.logo}')`,
|
||||
backgroundPosition: "center",
|
||||
backgroundRepeat: "no-repeat",
|
||||
backgroundSize: "cover",
|
||||
}}
|
||||
/>
|
||||
{hero.caption ? (
|
||||
<div
|
||||
style={{
|
||||
padding: "0.65rem 0.35rem 0.2rem",
|
||||
color: "#111827",
|
||||
textAlign: "center",
|
||||
fontSize: "0.78rem",
|
||||
fontWeight: 750,
|
||||
letterSpacing: "0.06em",
|
||||
textTransform: "uppercase",
|
||||
}}
|
||||
>
|
||||
{hero.caption}
|
||||
</div>
|
||||
) : null}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const stripSlide = (m, i) => (
|
||||
<a
|
||||
key={m.href || m.name}
|
||||
href={m.href}
|
||||
aria-hidden={i === active ? undefined : "true"}
|
||||
tabIndex={i === active ? undefined : -1}
|
||||
style={{
|
||||
...slideStyle(i),
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "0.75rem",
|
||||
color: "#ffffff",
|
||||
textDecoration: "none",
|
||||
}}
|
||||
>
|
||||
<span
|
||||
role="img"
|
||||
aria-label={m.vendor || m.name}
|
||||
style={{
|
||||
flex: "0 0 auto",
|
||||
width: "3.4rem",
|
||||
aspectRatio: "16 / 9",
|
||||
borderRadius: "0.35rem",
|
||||
border: "1px solid rgba(255, 255, 255, 0.22)",
|
||||
backgroundColor: "#ffffff",
|
||||
backgroundImage: `url('${m.logo}')`,
|
||||
backgroundPosition: "center",
|
||||
backgroundRepeat: "no-repeat",
|
||||
backgroundSize: "cover",
|
||||
}}
|
||||
/>
|
||||
|
||||
<span style={{ flex: "1 1 auto", minWidth: 0 }}>
|
||||
<span style={{ display: "flex", alignItems: "center", flexWrap: "wrap", gap: "0.4rem" }}>
|
||||
<span
|
||||
style={{
|
||||
fontSize: "1.02rem",
|
||||
fontWeight: 750,
|
||||
letterSpacing: "-0.02em",
|
||||
lineHeight: 1.2,
|
||||
}}
|
||||
>
|
||||
{m.name}
|
||||
</span>
|
||||
{m.badge ? (
|
||||
<span
|
||||
style={{
|
||||
padding: "0.1rem 0.4rem",
|
||||
borderRadius: "999px",
|
||||
background: "rgba(255, 255, 255, 0.92)",
|
||||
color: "#7c2d12",
|
||||
fontSize: "0.6rem",
|
||||
fontWeight: 800,
|
||||
letterSpacing: "0.06em",
|
||||
textTransform: "uppercase",
|
||||
}}
|
||||
>
|
||||
{m.badge}
|
||||
</span>
|
||||
) : null}
|
||||
</span>
|
||||
|
||||
<span style={{ display: "flex", flexWrap: "wrap", gap: "0.3rem", marginTop: "0.35rem" }}>
|
||||
{(m.tags || []).map((t) => tagChip(t, false))}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span
|
||||
style={{
|
||||
flex: "0 0 auto",
|
||||
padding: "0.25rem 0.55rem",
|
||||
borderRadius: "0.4rem",
|
||||
background: "rgba(255, 255, 255, 0.92)",
|
||||
color: "#7c2d12",
|
||||
fontSize: "0.7rem",
|
||||
fontWeight: 750,
|
||||
whiteSpace: "nowrap",
|
||||
}}
|
||||
>
|
||||
Open →
|
||||
</span>
|
||||
</a>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="not-prose">
|
||||
<div
|
||||
onMouseEnter={() => setPaused(true)}
|
||||
onMouseLeave={() => setPaused(false)}
|
||||
onFocus={() => setPaused(true)}
|
||||
onBlur={() => setPaused(false)}
|
||||
aria-roledescription="carousel"
|
||||
aria-label={label}
|
||||
style={{
|
||||
position: "relative",
|
||||
overflow: "hidden",
|
||||
margin: isHero ? "0 0 1.5rem" : "1.5rem 0",
|
||||
padding: isHero ? "clamp(1.5rem, 4vw, 2.5rem)" : "0.8rem 1rem 0.9rem",
|
||||
border: "1px solid rgba(251, 146, 60, 0.35)",
|
||||
borderRadius: isHero ? "1rem" : "0.9rem",
|
||||
background: "linear-gradient(135deg, #111827 0%, #31202f 58%, #9a3412 100%)",
|
||||
boxShadow: isHero
|
||||
? "0 20px 45px rgba(17, 24, 39, 0.18)"
|
||||
: "0 14px 32px rgba(17, 24, 39, 0.16)",
|
||||
color: "#ffffff",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: isHero ? "-7rem" : "-6rem",
|
||||
right: isHero ? "-5rem" : "-4rem",
|
||||
width: isHero ? "18rem" : "14rem",
|
||||
height: isHero ? "18rem" : "14rem",
|
||||
borderRadius: "999px",
|
||||
background: "rgba(251, 146, 60, 0.18)",
|
||||
filter: "blur(2px)",
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Header line: label on the left, controls on the right. The hero's
|
||||
label is the active entry's eyebrow, so it lives here rather than in
|
||||
the slide — a floating control cluster would collide with a wide
|
||||
eyebrow badge once the card narrows. */}
|
||||
<div
|
||||
style={{
|
||||
position: "relative",
|
||||
zIndex: 1,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
gap: "0.75rem",
|
||||
flexWrap: "wrap",
|
||||
marginBottom: isHero ? "0.9rem" : "0.6rem",
|
||||
}}
|
||||
>
|
||||
<span
|
||||
style={
|
||||
isHero
|
||||
? {
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
gap: "0.45rem",
|
||||
padding: "0.35rem 0.7rem",
|
||||
border: "1px solid rgba(255, 255, 255, 0.28)",
|
||||
borderRadius: "999px",
|
||||
background: "rgba(255, 255, 255, 0.1)",
|
||||
fontSize: "0.72rem",
|
||||
fontWeight: 750,
|
||||
letterSpacing: "0.08em",
|
||||
textTransform: "uppercase",
|
||||
}
|
||||
: {
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
gap: "0.35rem",
|
||||
color: "rgba(255, 255, 255, 0.78)",
|
||||
fontSize: "0.66rem",
|
||||
fontWeight: 750,
|
||||
letterSpacing: "0.1em",
|
||||
textTransform: "uppercase",
|
||||
}
|
||||
}
|
||||
>
|
||||
<span aria-hidden="true">✦</span>
|
||||
{isHero
|
||||
? ((models[active] || {}).hero || {}).eyebrow || label
|
||||
: label}
|
||||
</span>
|
||||
{controls}
|
||||
</div>
|
||||
|
||||
<div style={{ position: "relative", zIndex: 1, overflow: "hidden" }}>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: isHero ? "stretch" : "center",
|
||||
transform: `translateX(-${active * 100}%)`,
|
||||
transition: reduceMotion ? "none" : "transform 0.45s ease",
|
||||
}}
|
||||
>
|
||||
{models.map((m, i) => (isHero ? heroSlide(m, i) : stripSlide(m, i)))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,66 @@
|
||||
// Single `export const popularModels` literal — no spreads/calls/IIFE (Mintlify
|
||||
// re-evals at hydration).
|
||||
//
|
||||
// Rotated by <PopularModels> (/src/snippets/_popular_models.jsx) on the docs home
|
||||
// (`variant="hero"`, uses each entry's `hero` block) and the Cookbook home
|
||||
// (compact strip, uses `name` / `badge` / `tags`). Both walk this list in order,
|
||||
// so an entry added here becomes a slide on both; an entry with no `hero` block
|
||||
// still rotates on the home page, just without a blurb.
|
||||
//
|
||||
// Keep the copy to claims that hold on the linked page: platform counts from that
|
||||
// model's config `supportedHardware`, precisions from its `quantizations`, blurbs
|
||||
// paraphrasing that page's own opening.
|
||||
|
||||
export const popularModels = [
|
||||
{
|
||||
name: "Kimi-K3",
|
||||
vendor: "Moonshot AI",
|
||||
href: "/cookbook/autoregressive/Moonshotai/Kimi-K3",
|
||||
logo: "/cards/logos/moonshotai.png",
|
||||
badge: "New",
|
||||
tags: ["8 platforms", "PD disagg", "DSPARK"],
|
||||
hero: {
|
||||
eyebrow: "Featured model · New",
|
||||
headline: "Meet Kimi-K3 on SGLang",
|
||||
blurb:
|
||||
"SGLang natively implements and deeply optimizes K3's new architecture with fused KDA decode kernels, DP attention, MTP, PD disaggregation, and KDA-aware prefix caching. Kimi-K3 is supported on both NVIDIA and AMD GPUs.",
|
||||
tags: ["2.8T parameters", "Fused KDA decode", "NVIDIA + AMD"],
|
||||
cta: "Open the Kimi-K3 cookbook",
|
||||
caption: "Kimi-K3 deployment guide",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Inkling",
|
||||
vendor: "Thinking Machines",
|
||||
href: "/cookbook/autoregressive/ThinkingMachines/Inkling",
|
||||
logo: "/cards/logos/thinkingmachines.png",
|
||||
badge: "New",
|
||||
tags: ["7 platforms", "NVFP4 / BF16", "MTP + DSpark"],
|
||||
hero: {
|
||||
eyebrow: "Featured model · New",
|
||||
headline: "Meet Inkling on SGLang",
|
||||
blurb:
|
||||
"Thinking Machines' open-weights Mixture-of-Experts model — 975B parameters, 41B active per token, a 1M-token context window, and native text, image, and audio input. The cookbook covers its MTP speculative-decoding path and long-context prefix caching on NVIDIA and AMD.",
|
||||
tags: ["975B · 41B active", "1M context", "Text + image + audio"],
|
||||
cta: "Open the Inkling cookbook",
|
||||
caption: "Inkling deployment guide",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "GLM-5.2",
|
||||
vendor: "Z.ai",
|
||||
href: "/cookbook/autoregressive/GLM/GLM-5.2",
|
||||
logo: "/cards/logos/glm.png",
|
||||
badge: "New",
|
||||
tags: ["7 platforms", "DSA attention", "FP8 / NVFP4"],
|
||||
hero: {
|
||||
eyebrow: "Featured model · New",
|
||||
headline: "Meet GLM-5.2 on SGLang",
|
||||
blurb:
|
||||
"Z.ai's DeepSeek-Sparse-Attention Mixture-of-Experts model, with MTP speculative decoding and a 1M-token context window. Recipes cover FP8, BF16, and NVFP4 across H200, B200, B300, GB300, and AMD MI300X / MI325X / MI355X.",
|
||||
tags: ["DSA attention", "1M context", "FP8 / BF16 / NVFP4"],
|
||||
cta: "Open the GLM-5.2 cookbook",
|
||||
caption: "GLM-5.2 deployment guide",
|
||||
},
|
||||
},
|
||||
];
|
||||
Reference in New Issue
Block a user