forked from emre/www_projectmycelium_com
112 lines
2.9 KiB
TypeScript
112 lines
2.9 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
|
|
const files = [
|
|
{
|
|
id: "train",
|
|
label: "train.py",
|
|
code: `from mycelium import GPUCluster, Dataset
|
|
|
|
# connect to private GPU cluster
|
|
cluster = GPUCluster("secure://my-node")
|
|
|
|
# load training data
|
|
data = Dataset.load("s3://models/private-dataset")
|
|
|
|
# run a reproducible training job
|
|
job = cluster.train(
|
|
model="resnet50",
|
|
dataset=data,
|
|
epochs=40,
|
|
deterministic=True
|
|
)
|
|
|
|
job.save("s3://models/checkpoints/resnet-private")`,
|
|
},
|
|
{
|
|
id: "deploy",
|
|
label: "deploy.yaml",
|
|
code: `apiVersion: mycelium/v1
|
|
kind: Service
|
|
metadata:
|
|
name: vector-api
|
|
spec:
|
|
image: registry.mycelium/vector:latest
|
|
replicas: 3
|
|
selfHeal: true
|
|
mesh: private
|
|
resources:
|
|
gpu: 1
|
|
cpu: 2
|
|
memory: 4Gi`,
|
|
},
|
|
{
|
|
id: "edge",
|
|
label: "edge.ts",
|
|
code: `import { EdgeClient } from "@mycelium/sdk"
|
|
|
|
// deploy inference to nearest node
|
|
const client = new EdgeClient()
|
|
|
|
await client.deploy({
|
|
model: "resnet-private",
|
|
region: "eu-home-nodes",
|
|
autoscale: true,
|
|
cache: "on-device"
|
|
})`,
|
|
},
|
|
];
|
|
|
|
export function ComputeCodeTabs() {
|
|
const [active, setActive] = useState("train");
|
|
const file = files.find((f) => f.id === active)!;
|
|
|
|
return (
|
|
<div className="sm:px-6 lg:px-0">
|
|
<div className="relative isolate overflow-hidden bg-cyan-600 px-6 pt-8 sm:mx-auto sm:max-w-2xl sm:rounded-3xl sm:pt-16 sm:pr-0 sm:pl-16 lg:mx-0 lg:max-w-none">
|
|
|
|
<div
|
|
aria-hidden="true"
|
|
className="absolute -inset-y-px -left-3 -z-10 w-full origin-bottom-left skew-x-[-30deg] bg-cyan-500 opacity-20 ring-1 ring-white ring-inset"
|
|
/>
|
|
|
|
<div className="mx-auto max-w-2xl sm:mx-0 sm:max-w-none">
|
|
<div className="w-screen overflow-hidden rounded-tl-xl bg-gray-900 ring-1 ring-white/10">
|
|
|
|
{/* FILE TABS */}
|
|
<div className="flex bg-gray-800/40 ring-1 ring-white/5">
|
|
<div className="-mb-px flex text-sm font-medium text-gray-400">
|
|
|
|
{files.map((f) => (
|
|
<button
|
|
key={f.id}
|
|
onClick={() => setActive(f.id)}
|
|
className={`px-4 py-2 border-r border-white/10 ${
|
|
active === f.id
|
|
? "border-b border-b-white/20 bg-white/5 text-white"
|
|
: ""
|
|
}`}
|
|
>
|
|
{f.label}
|
|
</button>
|
|
))}
|
|
|
|
</div>
|
|
</div>
|
|
|
|
{/* CODE BLOCK */}
|
|
<div className="px-6 pt-6 pb-14 font-mono text-xs leading-relaxed text-gray-200 whitespace-pre overflow-x-auto">
|
|
{file.code}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
aria-hidden="true"
|
|
className="pointer-events-none absolute inset-0 ring-1 ring-white/10 ring-inset sm:rounded-3xl"
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
} |