|
1 |
+ |
# EveryCycle — Roadmap
|
|
2 |
+ |
|
|
3 |
+ |
This is the live thread roadmap. Work advances on parallel threads, not numbered phases. The project's "current state" is the snapshot of where every thread stands together.
|
|
4 |
+ |
|
|
5 |
+ |
When a thread is ready to advance, the next milestone on it is the next bit of work — independent of where other threads are. A resident or intern can take a thread or even a single milestone without having to follow a linear sequence.
|
|
6 |
+ |
|
|
7 |
+ |
## Identity
|
|
8 |
+ |
|
|
9 |
+ |
**EveryCycle is a Linux system service for heterogeneous GPU compute.** The daemon (`everycycled`) owns the GPU fleet on a host and intermediates between the system and the silicon — across vendors, generations, and the long tail of hardware whose vendors have moved on.
|
|
10 |
+ |
|
|
11 |
+ |
The category EveryCycle is creating is the **GPU-compute analog of PipeWire (audio), NetworkManager (networking), CUPS (printing)**: a system service that owns a device class and provides a stable API to userspace, replacing the chaos in which every program directly drives the GPU via vendor SDKs.
|
|
12 |
+ |
|
|
13 |
+ |
## The product and the business
|
|
14 |
+ |
|
|
15 |
+ |
EveryCycle is software. The daemon (`everycycled` + clients + libraries + operator tools) is the product, MIT-licensed, distributed via standard distro packaging.
|
|
16 |
+ |
|
|
17 |
+ |
Make Creative, LLC is a for-profit company with good intentions. It funds the software by designing and selling **MakeMachines** — reference appliances pre-configured with EveryCycle. MakeMachine revenue pays for the open-source work. We sell machines, not compute-as-a-service.
|
|
18 |
+ |
|
|
19 |
+ |
MNW is a MakeMachine customer like any other: it buys MakeMachines from the MakeMachine line at fair internal-transfer pricing and runs its own workloads on them. External sales and internal sales are the same business — both fund EveryCycle.
|
|
20 |
+ |
|
|
21 |
+ |
This is a clean separation of concerns: software identity lives in EveryCycle, hardware design and revenue live in the MakeMachine line, and MNW is a customer.
|
|
22 |
+ |
|
|
23 |
+ |
## Wedge
|
|
24 |
+ |
|
|
25 |
+ |
1. **Heterogeneity is the default.** Cheap, mixed-generation, mixed-vendor silicon serves real workloads when the runtime above the kernels is honest about the hardware. We do not assume a homogeneous fleet.
|
|
26 |
+ |
2. **Defensive curation.** When vendors abandon old hardware, EveryCycle catches it. We watch for support discontinuation, fork upstreams when they drop too aggressively, and partner with OSS driver and kernel projects (nouveau, NVK, Mesa, RADV) to extend useful life past vendor end-of-life. Old hardware that can still serve at all is a first-class supported tier.
|
|
27 |
+ |
|
|
28 |
+ |
The work is *curatorial and operational*, not greenfield kernel engineering. We bind to existing kernel collections (ggml-cuda for NVIDIA, ggml-rocm for AMD) vendored in-tree so we can fork when needed. The novel work is the layer above: the supervisor, the planner, the audit, the operator UX, the client API.
|
|
29 |
+ |
|
|
30 |
+ |
## Platform and distribution
|
|
31 |
+ |
|
|
32 |
+ |
- **Linux only by design.** macOS-native is not on the roadmap. Apple Silicon support, if it comes, comes via Asahi Linux.
|
|
33 |
+ |
- **Pinned to Ubuntu LTS (24.04).** One supported distro across the whole project — matches the MNW production server target, so one test matrix covers infra and inference. Other distros are best-effort, no support commitment.
|
|
34 |
+ |
- **Glibc build, .deb packaging.** The daemon is a standard glibc binary packaged as a .deb for Ubuntu LTS. Executor isolation (in-process dlopen vs out-of-process sidecar) is decided per executor by vendor SDK stability and crash blast-radius, not by libc compatibility.
|
|
35 |
+ |
|
|
36 |
+ |
## Threads
|
|
37 |
+ |
|
|
38 |
+ |
### Thread A — GPU complexity
|
|
39 |
+ |
|
|
40 |
+ |
| Milestone | Cards | Approx cost | What it teaches |
|
|
41 |
+ |
|---|---|---|---|
|
|
42 |
+ |
| **A1** | 1× Tesla P40 (24 GB GDDR5, Pascal) + GT 710 boot card | ~$230 | Audit, plan, serve, ggml-cuda wrap, first defensive-curation regression suite. Pascal is the next NVIDIA shoe to drop, so the wedge is in immediate practice. |
|
|
43 |
+ |
| **A2** | 2× Tesla P40 | ~$400 | Same-executor tensor-split, per-card capability reporting, planner spreads across same-vendor devices. |
|
|
44 |
+ |
| **A3** | 1× P40 + 1× P100 (16 GB HBM2) | ~$500 | Mixed-arch within one executor (cc 6.1 + cc 6.0, different memory bandwidth and fp16 support). Capability-aware placement. |
|
|
45 |
+ |
| **A4** | 1× P40 + 1× MI50 (16 GB HBM2, Vega 20) | ~$550 | Inter-executor activation protocol; AMD executor; cross-vendor supervisor coordination; the wedge demo. **Cross-vendor enters here, not earlier.** |
|
|
46 |
+ |
| **A5** | + 3090 + Arc card | varies | Real heterogeneous fleet; planner makes real tradeoffs. |
|
|
47 |
+ |
|
|
48 |
+ |
Single-vendor Pascal-era Tesla through A3. Cross-vendor enters at A4. The executor trait must be forward-compatible with cross-vendor handoff from A1 even though no impl uses it until A4.
|
|
49 |
+ |
|
|
50 |
+ |
### Thread B — Model complexity
|
|
51 |
+ |
|
|
52 |
+ |
Smaller models first. Qwen family is the default — open weights, well-quantized in the wild, multiple sizes that step up cleanly. The progression demonstrates the runtime, not the model.
|
|
53 |
+ |
|
|
54 |
+ |
| Milestone | Model | Why |
|
|
55 |
+ |
|---|---|---|
|
|
56 |
+ |
| **B1** | Qwen 3 0.6B Q8 (or Qwen 2.5 0.5B Q8) | Smoke test. Validates audit → plan → serve end-to-end with a model that loads in seconds. |
|
|
57 |
+ |
| **B2** | Qwen 3 1.7B Q4 (or Qwen 2.5 1.5B Q4) | First "useful" responses. Streaming tokens, OpenAI-compatible chat. |
|
|
58 |
+ |
| **B3** | Qwen 3 8B Q4 (or Qwen 2.5 7B Q4) | The workhorse demo model. Fits a Tesla P40 with comfortable kv-cache headroom. |
|
|
59 |
+ |
| **B4** | Qwen 2.5 32B Q4 | Pushes the P40 harder; still fits 24 GB. |
|
|
60 |
+ |
| **B5** | Qwen 2.5 72B Q4 | Saturates the P40's VRAM; first encounter with kv-cache pressure that wants NVMe overflow. |
|
|
61 |
+ |
| **B6** | Frontier-size with offload | Layer placement across multiple devices + CPU + NVMe. Couples tightly with A4/A5 on the GPU thread. |
|
|
62 |
+ |
|
|
63 |
+ |
### Thread C — Supervisor and multi-client arbitration
|
|
64 |
+ |
|
|
65 |
+ |
The supervisor owns the device fleet on behalf of *concurrent* clients. Single-tenant operation is not a stable resting point — it's a degenerate case of the multi-client design. PipeWire is fundamentally multi-tenant from day one; so is EveryCycle.
|
|
66 |
+ |
|
|
67 |
+ |
Shape: enumerate-and-dispatch (A1, single client) → **two-client arbitration with priority + fair-share** (A2, the load-bearing milestone for the analogy) → crash isolation (per-executor watchdog + structured panic handling) → hot-plug → preemption and QoS classes → multi-box fleet routing.
|
|
68 |
+ |
|
|
69 |
+ |
Two clients sharing a GPU under daemon-enforced policy is a required A2 demo, not a late-roadmap luxury. L5 (preemptive multi-tenant scheduling) moves into the early path on this thread.
|
|
70 |
+ |
|
|
71 |
+ |
### Thread D — Audit depth
|
|
72 |
+ |
|
|
73 |
+ |
Open. Shape: enumeration (boot, ms) → calibration cache (first-boot per fingerprint, seconds) → live profiling (background, minutes) → drift detection (continuous; recalibrate when observed perf deviates from cache by N%).
|
|
74 |
+ |
|
|
75 |
+ |
### Thread E — Defensive curation
|
|
76 |
+ |
|
|
77 |
+ |
Open. Shape: regression suite stub (just records what hardware passes today) → watch list of vendors' end-of-life announcements (Pascal, Vega, Polaris are the near-term candidates) → first OSS partnership (likely nouveau/NVK for Pascal post-CUDA, or RADV for Vega post-ROCm) → first real fork-and-maintain event when an upstream drops a generation we promised to keep alive.
|
|
78 |
+ |
|
|
79 |
+ |
### Thread F — BMC and hardware product
|
|
80 |
+ |
|
|
81 |
+ |
Open. Shape: wrap stock Redfish on whatever BMC is on the MakeMachine board (ASRock Rack AST2600) → flash OpenBMC → bmc-agent emits structured telemetry → scheduler consumes thermal data for placement decisions. This thread runs in parallel with the runtime work; it does not block A1.
|
|
82 |
+ |
|
|
83 |
+ |
### Thread G — Operator UX
|
|
84 |
+ |
|
|
85 |
+ |
Open. Shape: audit screen (the brand moment — beautiful, structured, says "this runtime understands your hardware") → live ops dashboard → multi-box view → incident response views. The TUI exists as `everycycle-tui` already; what's missing is the actual screen content.
|
|
86 |
+ |
|
|
87 |
+ |
### Thread H — MakeMachine appliance line (the business that funds the software)
|
|
88 |
+ |
|
|
89 |
+ |
MakeMachines are how Make Creative pays for EveryCycle's development. The first MakeMachine (BOM at `docs/hardware/mm-v1-bom.md`) is in service as Sando host and EveryCycle dev box; MNW will buy MakeMachines from this line for its own workloads. Subsequent designs span a price ladder for external customers. Each design is a coherent BOM + chassis + thermal model + BMC config + sample software config.
|
|
90 |
+ |
|
|
91 |
+ |
| Milestone | Design | Target | Notes |
|
|
92 |
+ |
|---|---|---|---|
|
|
93 |
+ |
| **H1** | MakeMachine v1 | First unit: Sando host + EveryCycle dev. Subsequent units: MNW (internal-transfer) and small-batch external sales. | Threadripper Pro WRX90 + flexible GPU bays. The dogfood design and the first revenue unit. |
|
|
94 |
+ |
| **H2** | Mid-tier workstation | Solo operators, small labs (~$5K) | Single-CPU EPYC or TR non-Pro, 1-2 GPU bays, tower form factor. |
|
|
95 |
+ |
| **H3** | Entry-level edge | Hobbyists, classrooms, residencies (~$2K) | Mini-ITX or SFF, single GPU, quiet, low-power. |
|
|
96 |
+ |
| **H4** | Rack appliance | Datacenter and colo deployments (~$15K+) | 2U or 4U, 4-8 GPU bays, redundant PSU, dual NIC, OpenBMC. |
|
|
97 |
+ |
|
|
98 |
+ |
Each milestone produces: published BOM, chassis CAD, thermal model, BMC firmware bundle, EveryCycle config tuned for the platform, assembly guide. See `_meta/docs/hardware_operation.md` for the broader operation framing (chassis, residency, supplier relationships).
|
|
99 |
+ |
|
|
100 |
+ |
### Thread I — Client API and adoption
|
|
101 |
+ |
|
|
102 |
+ |
This is the long-pole project. PipeWire's decade of distro defaults and upstream integrations *was* the work; same applies here. The thread starts at A1, not after A3 — the API surface clients write against has to be designed before the runtime locks shape around its first internal users.
|
|
103 |
+ |
|
|
104 |
+ |
Shape: native client API sketch (A1, alongside the executor trait) → API v0 published with explicit "unstable" marker (A2) → reference shims and SDKs (A3) → **API v1 freeze** with semver and compat charter (A4 or when the second external client ships against it, whichever first) → distro packaging and default-daemon advocacy (multi-year) → upstream integrations as alternative backends in llama.cpp / vLLM / TGI / ComfyUI / etc.
|
|
105 |
+ |
|
|
106 |
+ |
The v1 freeze is a gate, not a date. Until it lands, every client is opting into churn; after it lands, breaking the API requires a major version and a migration story. This commitment is what makes EveryCycle a *platform* rather than a tool.
|
|
107 |
+ |
|
|
108 |
+ |
### Thread J — Compatibility shims
|
|
109 |
+ |
|
|
110 |
+ |
The adoption mechanism. PipeWire displaced PulseAudio and JACK not by asking apps to port, but by shipping `pipewire-pulse` and `pipewire-jack` — drop-in replacements that spoke the existing protocols. Existing apps pointed at the new daemon without modification.
|
|
111 |
+ |
|
|
112 |
+ |
EveryCycle's analogs, in rough priority order:
|
|
113 |
+ |
|
|
114 |
+ |
| Shim | What it impersonates | Why it matters |
|
|
115 |
+ |
|---|---|---|
|
|
116 |
+ |
| **J1** | OpenAI Chat Completions / Responses API | Largest existing client ecosystem; every LLM tool already speaks it. |
|
|
117 |
+ |
| **J2** | llama.cpp server (`/completion`, `/v1/chat/completions` extensions) | Captures the local-inference tool ecosystem (Open WebUI, LM Studio clients, etc.). |
|
|
118 |
+ |
| **J3** | Ollama API | Captures the hobbyist surface. |
|
|
119 |
+ |
| **J4** | vLLM / TGI HTTP surfaces | Captures production-inference clients without code change. |
|
|
120 |
+ |
| **J5** | ComfyUI / diffusion backend protocols | Extends past text into image/video workloads on the same daemon. |
|
|
121 |
+ |
|
|
122 |
+ |
J1 ships alongside B2 (first useful responses). The shims are *separate processes* that translate to the native EveryCycle client API — they are clients of Thread I's API, not special-cased daemon code. This keeps the native API honest: if a shim can't express something cleanly, that's a Thread I design problem, not a shim problem.
|
|
123 |
+ |
|
|
124 |
+ |
## Settled architectural decisions
|
|
125 |
+ |
|
|
126 |
+ |
- **Backend approach: wrap vendored kernel collections per vendor.** Don't write kernels from scratch. Vendor the source in-tree so we can fork when needed. NVIDIA executor wraps ggml-cuda; AMD executor wraps ggml-rocm; Apple executor wraps MLX; CPU executor is the always-present fallback.
|
|
127 |
+ |
- **Cross-vendor layer placement: belongs to A4.** The executor trait is forward-compatible from day one (activation-handoff signatures present even if no impl uses them); the inter-executor protocol gets built when A4 is reached.
|
|
128 |
+ |
- **Project structure: parallel threads, not numbered phases.** Each thread has its own pace; project state is the snapshot across all threads.
|
|
129 |
+ |
- **First GPU: Tesla P40.** Walks the defensive-curation talk on day one. Pascal facing imminent CUDA-legacy transition makes this card the canonical example of what EveryCycle exists to support.
|
|
130 |
+ |
- **Host platform: dual-use with the MakeMachine.** See `docs/hardware/mm-v1-bom.md`. Threadripper Pro 7975WX + WRX90D8 + 512 GB ECC + Gen5 NVMe is the substrate; GPUs are fungible.
|
|
131 |
+ |
- **First model family: Qwen, starting small.** B1 is the smallest Qwen variant that loads; subsequent milestones step up. Choice driven by open weights, broad quant availability, and clean size laddering.
|
|
132 |
+ |
- **Client API stability is a sacred commitment.** Once Thread I reaches v1 freeze, the client-facing API follows strict semver: minor versions are additive, patch versions are bug-fix-only, major versions require a migration document and a deprecation window of at least one full release cycle on every supported distro. Before v1 freeze, the API is explicitly marked unstable and may break on any release. The freeze is the line that turns EveryCycle from a tool into a platform; everything downstream (compatibility shims, third-party clients, distro defaults) depends on this commitment being honored.
|
|
133 |
+ |
- **Multi-client is the default, not a feature.** The daemon assumes concurrent clients from A1, even when only one is connected. The internal data model, scheduler, and audit surface are designed around N clients sharing M devices under policy; the N=1 case is just the limit. This is the structural difference between a system service and a runtime library.
|
|
134 |
+ |
- **Compatibility shims are clients, not daemon code.** Each protocol shim (OpenAI, llama.cpp, Ollama, vLLM, ComfyUI) is a separate process that speaks the native EveryCycle client API. The shims do not get privileged access to internals. This forces the native API to be expressive enough that the shims are thin — and keeps the daemon free of protocol-specific code paths.
|
|
135 |
+ |
- **Implementation languages.** Main binary is Rust, built natively for Ubuntu LTS 24.04 (glibc, .deb-packaged). Module boundary is a **stable C ABI** from a reasonable point — early enough that the second executor doesn't lock the trait shape into Rust-internals. Module *implementations* may be in any language that emits a C-ABI shared library (Rust, Zig, C). The BMC agent is a separate binary and is the leading candidate for being written in Zig rather than Rust; that decision deferred until the agent is real.
|
|
136 |
+ |
|
|
137 |
+ |
## Model stance
|
|
138 |
+ |
|
|
139 |
+ |
**Open weights only, on principle.** EveryCycle serves models whose weights are publicly available. We do not wire to closed-weight model APIs and we do not ship closed weights as part of the runtime distribution. Operators are free to load whatever weights they want — we just don't make non-open-weight serving the default path.
|
|
140 |
+ |
|
|
141 |
+ |
**Models are commodities.** We expect the model market to be fully commoditized: many capable open families, rapid generation turnover, no durable moat at any particular model. EveryCycle's architecture follows this stance:
|
|
142 |
+ |
|
|
143 |
+ |
- No model-specific kernels. Backend kernels handle architectures generically (attention, RMSNorm, rotary, MoE routing) via the wrapped kernel collections.
|
|
144 |
+ |
- No model-specific loaders. Standard formats (GGUF, safetensors) only; loaders for new architectures land in the wrapped backends, not in EveryCycle.
|
|
145 |
+ |
- No model registry of our own. Operators bring their own models; we serve them.
|
|
146 |
+ |
- The serving API stays OpenAI-compatible — that interface is stable across model churn.
|
|
147 |
+ |
- Marketing and demos focus on **what the runtime does to the hardware**, not on what model is loaded. The model is a workload, not a feature.
|
|
148 |
+ |
|
|
149 |
+ |
When a new model family emerges (Llama 4, Mistral Next, DeepSeek N+1, etc.), supporting it should be a backend-version bump, not an EveryCycle code change.
|
|
150 |
+ |
|
|
151 |
+ |
## Open questions (will be resolved iteratively)
|
|
152 |
+ |
|
|
153 |
+ |
- Executor isolation: in-process dlopen + watchdog threads + structured panic handling, or out-of-process with local-socket IPC. Per executor, driven by vendor SDK stability and crash blast-radius. In-process is the default for executors that behave; out-of-process when an executor empirically destabilizes the host process. The Ubuntu LTS / glibc pin removes libc compatibility as a forcing factor — CUDA and ROCm SDKs target glibc natively, so sidecar separation is now a stability choice, not a packaging workaround.
|
|
154 |
+ |
- CPU executor placement: statically linked into the base binary (always-present fallback) vs another module
|
|
155 |
+ |
- A1 dispatch planner: greedy heuristic only, or invest in a real optimizer up front
|
|
156 |
+ |
- BMC agent's actual A1-equivalent role: just enumerate Redfish, or already running on flashed OpenBMC
|
|
157 |
+ |
- First-boot online vs offline default
|
|
158 |
+ |
|
|
159 |
+ |
## Long-arc vision: the OS-for-compute level decomposition
|
|
160 |
+ |
|
|
161 |
+ |
EveryCycle's identity grows over time toward "operating system for heterogeneous GPU compute." The progression, in increasing order of difficulty:
|
|
162 |
+ |
|
|
163 |
+ |
| Level | What | Status |
|
|
164 |
+ |
|---|---|---|
|
|
165 |
+ |
| **L0** | Unified inventory (audit) | Thread D, A1 |
|
|
166 |
+ |
| **L1** | Unified routing (per-request placement) | Thread C, A1 |
|
|
167 |
+ |
| **L2** | Per-model layer placement (across same-vendor devices) | Thread A, A2-A3 |
|
|
168 |
+ |
| **L3** | Virtual VRAM with paging (kv-cache first; weights later) | Thread D, mid-roadmap |
|
|
169 |
+ |
| **L4** | Cross-device kernel sharding (same-vendor first, cross-vendor later) | A4+ |
|
|
170 |
+ |
| **L5** | Preemptive multi-tenant scheduling | Thread C, A2 (fair-share) → mid-roadmap (preemption + QoS classes) |
|
|
171 |
+ |
| **L6** | Transparent failure recovery (request-level early; mid-token much later) | Mid roadmap and beyond |
|
|
172 |
+ |
| **L7** | Unified telemetry surface (operators reason about "the cluster," not individual devices) | Thread G + Thread F |
|
|
173 |
+ |
| **L8** | Full programmability against the abstract device (clients write to EveryCycle's API, never to vendor SDKs) | Thread I; the adoption goal |
|
|
174 |
+ |
|
|
175 |
+ |
Levels through L4 (same-vendor) are achievable solo + residency. L4 (cross-vendor), full-fidelity L3 (weight paging), L5's preemption+QoS layer (fair-share at L5 is in scope solo), and L6 (mid-token recovery) are team-required and are honest team-scale R&D. Worth naming because the levels frame what each thread is *for* and where each milestone fits in the larger picture.
|
|
176 |
+ |
|
|
177 |
+ |
What this forbids:
|
|
178 |
+ |
- **Performance parity across topologies.** "One big GPU" means unified abstraction, not magical speed. Cross-vendor will be slower than single-vendor; that's physics.
|
|
179 |
+ |
- **Hiding hardware completely.** Operators still need to see what's there. The abstraction is programmer-facing; the operator surface stays physically honest.
|
|
180 |
+ |
- **Forcing the abstraction.** Workloads that need locality guarantees can pin. "One big GPU" is the opt-in default, not the only mode.
|
|
181 |
+ |
|
|
182 |
+ |
## Non-goals
|
|
183 |
+ |
|
|
184 |
+ |
Restated for emphasis:
|
|
185 |
+ |
|
|
186 |
+ |
- Not training. Not in v1, not in v3.
|
|
187 |
+ |
- Not writing kernels from scratch. We bind, we wrap, we fork.
|
|
188 |
+ |
- Not Kubernetes-first. Client API; orchestrators can wrap it.
|
|
189 |
+ |
- Not a web UI. TUI + Prometheus/OTel exporters.
|
|
190 |
+ |
- Not a model zoo of our own. We serve the open models that exist.
|
|
191 |
+ |
- Not macOS-native. Linux only; Apple Silicon via Asahi if at all.
|
|
192 |
+ |
- Not a license-paid product. Software is MIT; revenue comes from selling MakeMachine appliances (external and internal-transfer to MNW). Not compute-as-a-service.
|