Compare commits
6 Commits
dcbde330e4
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 0813f55762 | |||
| 4c24610aae | |||
| e061d3c170 | |||
| ff1fecc0ed | |||
| c08c444a39 | |||
| 03337bc545 |
@@ -14,6 +14,7 @@ A custom Nix overlay and flake providing additional packages not found in upstre
|
|||||||
|---------|-------------|----------|
|
|---------|-------------|----------|
|
||||||
| `awg-tool` | CLI for AmneziaWG self-hosting — generates 1.0/1.5/2.0/3.0 obfuscation parameters, exports .conf and vpn:// configs, installs servers over SSH | Networking |
|
| `awg-tool` | CLI for AmneziaWG self-hosting — generates 1.0/1.5/2.0/3.0 obfuscation parameters, exports .conf and vpn:// configs, installs servers over SSH | Networking |
|
||||||
| `aionui` | Free, open-source, Cowork app with AI Agents | AI Coding Agents |
|
| `aionui` | Free, open-source, Cowork app with AI Agents | AI Coding Agents |
|
||||||
|
| `codeaf` | Coding harness and software factory for open models: hand work off, then watch every project from one terminal | AI Coding Agents |
|
||||||
| `container-use` | Containerized environments for coding agents | AI Coding Agents |
|
| `container-use` | Containerized environments for coding agents | AI Coding Agents |
|
||||||
| `desloppify` | Multi-language codebase health scanner and technical debt tracker for AI agents | AI Coding Agents |
|
| `desloppify` | Multi-language codebase health scanner and technical debt tracker for AI agents | AI Coding Agents |
|
||||||
| `ds4` | DeepSeek 4 Flash and PRO local inference engine for ROCm (Strix Halo) | AI Inference |
|
| `ds4` | DeepSeek 4 Flash and PRO local inference engine for ROCm (Strix Halo) | AI Inference |
|
||||||
@@ -30,6 +31,7 @@ A custom Nix overlay and flake providing additional packages not found in upstre
|
|||||||
| `shardr` | Decentralized LLM repository: content-addressed model store, BitTorrent-based sync, OpenAI-compatible serving via llama-server | AI Inference |
|
| `shardr` | Decentralized LLM repository: content-addressed model store, BitTorrent-based sync, OpenAI-compatible serving via llama-server | AI Inference |
|
||||||
| `skillsmcp` | MCP server that exposes Agent Skills to AI agents via the Model Context Protocol | MCP Servers |
|
| `skillsmcp` | MCP server that exposes Agent Skills to AI agents via the Model Context Protocol | MCP Servers |
|
||||||
| `kubernetes-mcp-server` | Model Context Protocol (MCP) server for Kubernetes and OpenShift | MCP Servers |
|
| `kubernetes-mcp-server` | Model Context Protocol (MCP) server for Kubernetes and OpenShift | MCP Servers |
|
||||||
|
| `kyojin` | ExLlamaV3-based inference engine with speculative decoding for 100 GB-class MoE packs on one 128 GB AMD Strix Halo (gfx1151, ROCm 7) | AI Inference |
|
||||||
| `llama-cpp` | llama.cpp pinned to build b11439, built for Strix Halo (gfx1151) with ROCm + Vulkan backends | AI Inference |
|
| `llama-cpp` | llama.cpp pinned to build b11439, built for Strix Halo (gfx1151) with ROCm + Vulkan backends | AI Inference |
|
||||||
| `loop` | Corporate messenger for your team | Communication |
|
| `loop` | Corporate messenger for your team | Communication |
|
||||||
| `radar` | Modern Kubernetes visibility — topology, event timeline, service traffic, resource browsing, Helm management, and GitOps support | Kubernetes |
|
| `radar` | Modern Kubernetes visibility — topology, event timeline, service traffic, resource browsing, Helm management, and GitOps support | Kubernetes |
|
||||||
@@ -93,6 +95,30 @@ nix run git+https://git.millerson.name/alex/millerson-overlay.nix.git#mcp-gatewa
|
|||||||
nix profile install git+https://git.millerson.name/alex/millerson-overlay.nix.git#mcp-gateway
|
nix profile install git+https://git.millerson.name/alex/millerson-overlay.nix.git#mcp-gateway
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Kyojin JIT Toolchain
|
||||||
|
|
||||||
|
Kyojin's serving wrappers use the packaged ROCm compiler by default. Supply a
|
||||||
|
pinned SDK to compile HIP JIT kernels with another compiler without rebuilding
|
||||||
|
PyTorch or the HIP extension:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
kyojin.override { jitRocmSdk = myJitSdk; }
|
||||||
|
```
|
||||||
|
|
||||||
|
The SDK must provide `bin/hipcc` and matching `amdgcn/bitcode`. Its compiler
|
||||||
|
wrapper must set `HIP_DEVICE_LIB_PATH` to that bitcode **in the compiler
|
||||||
|
subprocess only**, along with any required `ROCM_PATH` and Nix C++ toolchain
|
||||||
|
flags. Keep the compiler wrapper's real path inside the SDK prefix so upstream's
|
||||||
|
compiler provenance check recognizes it.
|
||||||
|
|
||||||
|
The serving process keeps PyTorch's ROCm device libraries. Setting TheRock's
|
||||||
|
Clang 23 bitcode globally makes the ROCm 7.2 runtime crash on a basic PyTorch
|
||||||
|
matrix multiplication. The serving wrappers also disable unsupported expandable
|
||||||
|
allocator segments. `nix build .#kyojin.tests.jit` checks compilation of five HIP
|
||||||
|
kernel modules without requiring a GPU; `packages/kyojin/check-jit.py --gpu`, run
|
||||||
|
with the package's Python environment and serving variables, additionally checks
|
||||||
|
PyTorch matrix multiplication and module loading through its existing HIP runtime.
|
||||||
|
|
||||||
### nftablesbuilder Runtime Notes
|
### nftablesbuilder Runtime Notes
|
||||||
|
|
||||||
`nftablesbuilder` is a web interface for managing nftables. It consists of a
|
`nftablesbuilder` is a web interface for managing nftables. It consists of a
|
||||||
@@ -185,6 +211,7 @@ nix-overlay/
|
|||||||
├── packages/ # Package definitions
|
├── packages/ # Package definitions
|
||||||
│ ├── awg-tool/ # AmneziaWG parameter generation and SSH deployment CLI
|
│ ├── awg-tool/ # AmneziaWG parameter generation and SSH deployment CLI
|
||||||
│ ├── aionui/ # AionUi - AI Cowork desktop app
|
│ ├── aionui/ # AionUi - AI Cowork desktop app
|
||||||
|
│ ├── codeaf/ # Coding harness and software factory for open models
|
||||||
│ ├── container-use/ # Containerized environments for coding agents
|
│ ├── container-use/ # Containerized environments for coding agents
|
||||||
│ ├── default/ # Meta-package listing all packages
|
│ ├── default/ # Meta-package listing all packages
|
||||||
│ ├── desloppify/ # Codebase health scanner for AI agents
|
│ ├── desloppify/ # Codebase health scanner for AI agents
|
||||||
@@ -197,6 +224,7 @@ nix-overlay/
|
|||||||
│ ├── haivemind/ # Multi-model AI consensus runner
|
│ ├── haivemind/ # Multi-model AI consensus runner
|
||||||
│ ├── hipengine/ # ROCm-native LLM inference engine for AMD GPUs
|
│ ├── hipengine/ # ROCm-native LLM inference engine for AMD GPUs
|
||||||
│ ├── kubernetes-mcp-server/ # MCP server for Kubernetes and OpenShift
|
│ ├── kubernetes-mcp-server/ # MCP server for Kubernetes and OpenShift
|
||||||
|
│ ├── kyojin/ # ExLlamaV3-based inference engine for Strix Halo (gfx1151)
|
||||||
│ ├── loop/ # Corporate messenger for your team
|
│ ├── loop/ # Corporate messenger for your team
|
||||||
│ ├── mcp-gateway/ # MCP protocol gateway
|
│ ├── mcp-gateway/ # MCP protocol gateway
|
||||||
│ ├── omniroute/ # Unified AI router with 160+ providers
|
│ ├── omniroute/ # Unified AI router with 160+ providers
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
pkgs.callPackage ./package.nix {
|
||||||
|
# Not a package of its own: codeaf is the only consumer, and codeaf is the one
|
||||||
|
# that knows which furrow version it pinned. See ./furrow.nix.
|
||||||
|
furrow = pkgs.callPackage ./furrow.nix { };
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
rustPlatform,
|
||||||
|
fetchFromGitHub,
|
||||||
|
}:
|
||||||
|
|
||||||
|
# furrow is the copy-on-write workspace snapper codeaf drives. codeaf ships a
|
||||||
|
# copy of it inside the go binary: the release asset from GitHub, glibc-dynamic
|
||||||
|
# and untouched by anything in this build, so the file codeaf writes out to
|
||||||
|
# ~/.codeaf/bin/furrow-<version> cannot start here — NixOS answers "Could not
|
||||||
|
# start dynamically linked executable" and names stub-ld. Building furrow here
|
||||||
|
# instead gives the same version as an ordinary Nix binary, and codeaf is told
|
||||||
|
# to use it through CODEAF_FURROW, which internal/furrow reads before it ever
|
||||||
|
# looks at the embedded copy. See ./package.nix.
|
||||||
|
#
|
||||||
|
# The version here has to be the one codeaf pinned in
|
||||||
|
# internal/furrowbin/pin.json: the decoders in codeaf were written for that
|
||||||
|
# furrow. Bump the two together.
|
||||||
|
rustPlatform.buildRustPackage rec {
|
||||||
|
pname = "furrow";
|
||||||
|
version = "0.1.0";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "Agent-Field";
|
||||||
|
repo = "furrow";
|
||||||
|
rev = "v${version}";
|
||||||
|
hash = "sha256-xknfvnBDFxDYeBE1yAjXl1Fx3VDHrNSUhXEWQO3PK6s=";
|
||||||
|
};
|
||||||
|
|
||||||
|
cargoHash = "sha256-FGtrKtWFPcT3R8nF5OQFlmIiKSuZ8aiHfj76bBvga5A=";
|
||||||
|
|
||||||
|
# Only the unit tests run here. Every cli integration test builds a fixture
|
||||||
|
# whose first step is `xattr::set(…, "user.furrow-test", …)`, and the sandbox
|
||||||
|
# /tmp is a tmpfs that answers EOPNOTSUPP for user.* xattrs, so all 54 of them
|
||||||
|
# die in setup — same reason forks_files_links_modes_and_xattrs is skipped, in
|
||||||
|
# the one lib test that touches an xattr. Upstream's CI runs the whole suite on
|
||||||
|
# a filesystem that supports them.
|
||||||
|
cargoTestFlags = [ "--lib" ];
|
||||||
|
checkFlags = [
|
||||||
|
"--skip"
|
||||||
|
"forks_files_links_modes_and_xattrs"
|
||||||
|
];
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Local-first working-state snapshots for agentic development";
|
||||||
|
homepage = "https://github.com/Agent-Field/furrow";
|
||||||
|
changelog = "https://github.com/Agent-Field/furrow/releases/tag/v${version}";
|
||||||
|
license = licenses.asl20;
|
||||||
|
# Thirteen source files use std::os::unix with no windows guards, so the
|
||||||
|
# upstream release has no windows asset either.
|
||||||
|
platforms = platforms.unix;
|
||||||
|
mainProgram = "furrow";
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
buildGoModule,
|
||||||
|
fetchFromGitHub,
|
||||||
|
makeWrapper,
|
||||||
|
furrow,
|
||||||
|
}:
|
||||||
|
|
||||||
|
# codeaf carries a furrow inside itself: internal/furrowbin embeds whatever is
|
||||||
|
# staged in internal/furrowbin/cache and, on first use, writes it out to
|
||||||
|
# ~/.codeaf/bin/furrow-<version>. Upstream stages the GitHub release asset there,
|
||||||
|
# whose bytes are someone else's glibc-dynamic build that no Nix phase ever
|
||||||
|
# touched, so the file that lands in the state root cannot start here. Staging a
|
||||||
|
# rebuilt furrow is not an option either: upstream's fetcher re-checks the sha256
|
||||||
|
# named in internal/furrowbin/pin.json and would refuse one. So this build stages
|
||||||
|
# nothing, and hands over ./furrow.nix through CODEAF_FURROW instead, which
|
||||||
|
# internal/furrow reads before it looks at the embedded copy at all. Nothing of
|
||||||
|
# furrow's ends up in the codeaf binary; without that variable codeaf looks for
|
||||||
|
# furrow on PATH, the way a plain `go build` does.
|
||||||
|
#
|
||||||
|
# A codeaf run without this wrapper is not the same program: it has no furrow
|
||||||
|
# unless one is on PATH.
|
||||||
|
buildGoModule rec {
|
||||||
|
pname = "codeaf";
|
||||||
|
version = "0.7.1";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "Agent-Field";
|
||||||
|
repo = "CodeAF";
|
||||||
|
rev = "v${version}";
|
||||||
|
hash = "sha256-F4rRDNrTCF8/cj6g0KM41+gNdzvTWw5Vj2N0OJp+vCc=";
|
||||||
|
};
|
||||||
|
|
||||||
|
vendorHash = "sha256-eIocnhp3uGk+wG0kprRie0Csms+Deqxy3K3HuI1vJyM=";
|
||||||
|
|
||||||
|
env.CGO_ENABLED = 0;
|
||||||
|
|
||||||
|
nativeBuildInputs = [ makeWrapper ];
|
||||||
|
|
||||||
|
# The shipped binary carries the packed manual rather than the raw Markdown.
|
||||||
|
tags = [ "codeaf_packed_manual" ];
|
||||||
|
|
||||||
|
subPackages = [ "cmd/codeaf" ];
|
||||||
|
|
||||||
|
# Upstream's own suite is a CI matrix (make test / make check) with network
|
||||||
|
# and timing assumptions; it is not buildGoModule-shaped.
|
||||||
|
doCheck = false;
|
||||||
|
|
||||||
|
# `make build` runs a host-side step before compiling: packing the manual into
|
||||||
|
# what the codeaf_packed_manual tag embeds. It is built for the build machine
|
||||||
|
# even when codeaf targets another platform, hence the unset GOOS/GOARCH. The
|
||||||
|
# vendoring derivation runs preBuild too, before vendor/ exists, and this step
|
||||||
|
# needs the vendored dependencies, so it waits for it. Upstream's other step,
|
||||||
|
# staging the furrow release, is deliberately not run: see ./furrow.nix.
|
||||||
|
preBuild = ''
|
||||||
|
if [ -d vendor ]; then
|
||||||
|
env -u GOOS -u GOARCH go generate ./internal/manual
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
postInstall = ''
|
||||||
|
wrapProgram $out/bin/codeaf --set CODEAF_FURROW ${furrow}/bin/furrow
|
||||||
|
'';
|
||||||
|
|
||||||
|
ldflags = [
|
||||||
|
"-s"
|
||||||
|
"-w"
|
||||||
|
"-X github.com/Agent-Field/codeaf/internal/buildinfo.rev=${version}"
|
||||||
|
"-X github.com/Agent-Field/codeaf/internal/buildinfo.dirty=false"
|
||||||
|
];
|
||||||
|
|
||||||
|
passthru = {
|
||||||
|
inherit furrow;
|
||||||
|
category = "AI Coding Agents";
|
||||||
|
updateScript = [
|
||||||
|
"nix-update"
|
||||||
|
"--flake"
|
||||||
|
".#codeaf"
|
||||||
|
# furrow.nix is not a flake output, so nix-update never touches it: bump it
|
||||||
|
# by hand alongside the version codeaf pins in internal/furrowbin/pin.json.
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Coding harness and software factory for open models: hand off work and watch every project from one terminal";
|
||||||
|
homepage = "https://github.com/Agent-Field/CodeAF";
|
||||||
|
changelog = "https://github.com/Agent-Field/CodeAF/blob/v${version}/CHANGELOG.md";
|
||||||
|
license = licenses.asl20;
|
||||||
|
# Runs the furrow built from source by ./furrow.nix, not the release asset
|
||||||
|
# upstream would have embedded.
|
||||||
|
mainProgram = "codeaf";
|
||||||
|
platforms = platforms.linux ++ platforms.darwin;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
"""Compile Kyojin's JIT kernels; --gpu also loads them through torch's HIP runtime."""
|
||||||
|
import ctypes
|
||||||
|
import importlib
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from exllamav3.util import hip_compiler
|
||||||
|
from exllamav3.util.hip_lib import load_hip_runtime
|
||||||
|
|
||||||
|
sdk = Path(os.environ["EXL3_ROCM_SDK"])
|
||||||
|
assert Path(hip_compiler.hipcc()) == sdk / "bin/hipcc"
|
||||||
|
assert Path(os.environ["HIP_DEVICE_LIB_PATH"]).is_dir()
|
||||||
|
assert (sdk / "amdgcn/bitcode").is_dir()
|
||||||
|
if os.environ.get("KYOJIN_REQUIRE_SDK") == "1":
|
||||||
|
assert hip_compiler.warning() is None, hip_compiler.warning()
|
||||||
|
print(hip_compiler.describe(), flush=True)
|
||||||
|
|
||||||
|
lib = None
|
||||||
|
if "--gpu" in sys.argv:
|
||||||
|
import torch
|
||||||
|
|
||||||
|
# Also exercise the runtime bitcode path: merely loading a HIP module
|
||||||
|
# does not catch incompatible device libraries in CLR/COMGR.
|
||||||
|
x = torch.ones((32, 32), device="cuda", dtype=torch.float32)
|
||||||
|
assert torch.equal(x @ x, torch.full_like(x, 32))
|
||||||
|
torch.cuda.synchronize()
|
||||||
|
lib = load_hip_runtime()
|
||||||
|
lib.hipModuleLoad.argtypes = [ctypes.POINTER(ctypes.c_void_p), ctypes.c_char_p]
|
||||||
|
lib.hipModuleUnload.argtypes = [ctypes.c_void_p]
|
||||||
|
|
||||||
|
for module, function, args in [
|
||||||
|
("gr_mix_hip", "compile_hsaco", ()),
|
||||||
|
("exllamav3.modules.attention_fn.qsa_prefill_hip", "compile_hsaco", ()),
|
||||||
|
("exllamav3.modules.ple_fn.ple_hip", "compile_hsaco", ()),
|
||||||
|
("exllamav3.vendor.fla.hip.gdn_fused_h_hip", "_compile", ("", "gfx1151")),
|
||||||
|
("exllamav3.vendor.fla.hip.kda_fused_h_hip", "_compile", ("", "gfx1151")),
|
||||||
|
]:
|
||||||
|
path = Path(getattr(importlib.import_module(module), function)(*args))
|
||||||
|
# HIP accepts ELF, offload bundles, and compressed offload bundles (CCOB).
|
||||||
|
assert path.read_bytes().startswith((b"\x7fELF", b"__CLANG_OFFLOAD_BUNDLE__", b"CCOB")), path
|
||||||
|
if lib is not None:
|
||||||
|
handle = ctypes.c_void_p()
|
||||||
|
assert lib.hipModuleLoad(ctypes.byref(handle), os.fsencode(path)) == 0, path
|
||||||
|
assert lib.hipModuleUnload(handle) == 0, path
|
||||||
|
print(f"OK: {module}", flush=True)
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
inputs,
|
||||||
|
jitRocmSdk ? null,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
# The HIP extension has to be compiled against a ROCm build of PyTorch, and the
|
||||||
|
# only ROCm torch in this flake with a cached binary is the one from the pinned
|
||||||
|
# nixpkgs-torch211 input (2.11 + ROCm 7.2, python 3.13). Current nixos-unstable
|
||||||
|
# ships torch 2.13, whose ROCm build fails to configure in nixpkgs and is not
|
||||||
|
# on cache.nixos.org.
|
||||||
|
inputs.nixpkgs-torch211.legacyPackages.${pkgs.stdenv.hostPlatform.system}.callPackage ./package.nix
|
||||||
|
{ inherit jitRocmSdk; }
|
||||||
@@ -0,0 +1,251 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
stdenv,
|
||||||
|
pkgs,
|
||||||
|
python3,
|
||||||
|
fetchFromGitHub,
|
||||||
|
makeWrapper,
|
||||||
|
rocmPackages,
|
||||||
|
# Override only the serving toolchain; torch and the extension keep their ROCm.
|
||||||
|
jitRocmSdk ? null,
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
py = python3.pkgs;
|
||||||
|
|
||||||
|
# Kyojin is the Yamz fork of ExLlamaV3: a Python package plus a C++ extension
|
||||||
|
# that torch's cpp_extension cross-compiles to HIP code objects. Upstream
|
||||||
|
# only supports AMD Strix Halo, so the kernels are built for gfx1151 alone.
|
||||||
|
rocmArch = "gfx1151";
|
||||||
|
|
||||||
|
version = "1.3";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "Yamz-Labs";
|
||||||
|
repo = "kyojin";
|
||||||
|
rev = "v${version}";
|
||||||
|
hash = "sha256-/DPoqW/iaLXRAH8XF5RdE+K5YS4jZT6Sic6QeCDQMlU=";
|
||||||
|
};
|
||||||
|
|
||||||
|
# setup.py passes EXL3_ROCM_DEV_INCLUDE as -I to every translation unit. The
|
||||||
|
# AMD wheels ship one devel tree holding hipsparse/ and thrust/; nixpkgs
|
||||||
|
# splits them per package, so join the include dirs. torch's public HIP
|
||||||
|
# headers also pull hipsolver/, and it no longer vendors pybind11.
|
||||||
|
rocmDevInclude = pkgs.symlinkJoin {
|
||||||
|
name = "kyojin-rocm-dev-include";
|
||||||
|
paths = map lib.getDev (
|
||||||
|
[ py.pybind11 ]
|
||||||
|
++ [
|
||||||
|
rocmPackages.clr
|
||||||
|
rocmPackages.hipblas
|
||||||
|
rocmPackages.hipblaslt
|
||||||
|
rocmPackages.hipcub
|
||||||
|
rocmPackages.hipfft
|
||||||
|
rocmPackages.hiprand
|
||||||
|
rocmPackages.hipsparse
|
||||||
|
rocmPackages.hipsolver
|
||||||
|
rocmPackages.rocblas
|
||||||
|
rocmPackages.rocprim
|
||||||
|
rocmPackages.rocrand
|
||||||
|
rocmPackages.rocsolver
|
||||||
|
rocmPackages.rocsparse
|
||||||
|
rocmPackages.rocthrust
|
||||||
|
]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
# torch's HIP path in cpp_extension expects one ROCM_HOME holding bin/hipcc,
|
||||||
|
# the headers and the amdgcn bitcode; nixpkgs ships them separately.
|
||||||
|
rocmToolkit = pkgs.symlinkJoin {
|
||||||
|
name = "kyojin-rocm-toolkit";
|
||||||
|
paths = [
|
||||||
|
rocmPackages."rocm-core"
|
||||||
|
rocmPackages."rocm-runtime"
|
||||||
|
rocmPackages."rocm-device-libs"
|
||||||
|
rocmPackages."rocm-comgr"
|
||||||
|
rocmPackages.clr
|
||||||
|
(lib.getBin rocmPackages.hipcc)
|
||||||
|
rocmPackages.rocblas
|
||||||
|
rocmPackages.hipblas
|
||||||
|
rocmPackages.hipblas-common
|
||||||
|
rocmPackages.hipblaslt
|
||||||
|
rocmPackages.hipsparse
|
||||||
|
rocmPackages.hipsolver
|
||||||
|
rocmPackages.hiprand
|
||||||
|
rocmPackages.rocrand
|
||||||
|
rocmPackages.hipfft
|
||||||
|
rocmPackages.rocsparse
|
||||||
|
rocmPackages.rocsolver
|
||||||
|
rocmPackages.rocthrust
|
||||||
|
rocmPackages.rocprim
|
||||||
|
rocmPackages.hipcub
|
||||||
|
];
|
||||||
|
# The setup hooks of the joined packages would rewrite build flags; the
|
||||||
|
# compiler only needs the files.
|
||||||
|
postBuild = ''
|
||||||
|
rm -rf $out/nix-support
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# The library: exllamav3 plus the compiled exllamav3_ext module.
|
||||||
|
library = py.buildPythonPackage {
|
||||||
|
inherit src version;
|
||||||
|
pname = "kyojin";
|
||||||
|
|
||||||
|
format = "pyproject";
|
||||||
|
build-system = with py; [
|
||||||
|
setuptools
|
||||||
|
wheel
|
||||||
|
];
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
py.ninja
|
||||||
|
rocmPackages."rocm-runtime"
|
||||||
|
];
|
||||||
|
|
||||||
|
buildInputs = [ (lib.getBin rocmPackages.hipcc) ];
|
||||||
|
|
||||||
|
propagatedBuildInputs = with py; [
|
||||||
|
aiohttp
|
||||||
|
huggingface-hub
|
||||||
|
jinja2
|
||||||
|
llguidance
|
||||||
|
marisa-trie
|
||||||
|
numpy
|
||||||
|
pillow
|
||||||
|
pydantic
|
||||||
|
pyyaml
|
||||||
|
rich
|
||||||
|
safetensors
|
||||||
|
tokenizers
|
||||||
|
torchWithRocm
|
||||||
|
typing-extensions
|
||||||
|
];
|
||||||
|
|
||||||
|
env = {
|
||||||
|
PYTORCH_ROCM_ARCH = rocmArch;
|
||||||
|
ROCM_PATH = "${rocmToolkit}";
|
||||||
|
ROCM_HOME = "${rocmToolkit}";
|
||||||
|
HIP_PATH = "${rocmToolkit}";
|
||||||
|
HIPCC = "${rocmToolkit}/bin/hipcc";
|
||||||
|
HIP_DEVICE_LIB_PATH = "${rocmPackages."rocm-device-libs"}/amdgcn/bitcode";
|
||||||
|
# Upstream build scripts look these up to find the ROCm devel tree.
|
||||||
|
EXL3_ROCM_SDK = "${rocmToolkit}";
|
||||||
|
EXL3_ROCM_DEV_INCLUDE = "${rocmDevInclude}/include";
|
||||||
|
# Default defines of upstream build.sh (tools/strix_halo/rebuild.sh).
|
||||||
|
EXL3_HIP_DEFINES = "EXL3_HIP_STG_PAD";
|
||||||
|
};
|
||||||
|
|
||||||
|
# setup.py pulls the extension source list and the arch helper with
|
||||||
|
# `from exllamav3...import ...`, which runs the package __init__ and
|
||||||
|
# therefore exllamav3/ext.py. That module JIT-compiles the extension when no
|
||||||
|
# precompiled exllamav3_ext is importable, i.e. during every wheel build
|
||||||
|
# (and it wants a writable $HOME for it). Register an empty `exllamav3`
|
||||||
|
# package first so only the two leaf modules are imported, and load
|
||||||
|
# build_config without the package wrapper.
|
||||||
|
postPatch = ''
|
||||||
|
sed -i '1i import sys as _sys, types as _types; _exl3_pkg = _types.ModuleType("exllamav3"); _exl3_pkg.__path__ = ["exllamav3"]; _sys.modules.setdefault("exllamav3", _exl3_pkg)' setup.py
|
||||||
|
sed -i 's|^from exllamav3\.exllamav3_ext\.build_config import get_sources as _get_sources$|import sys as _exl3_sys; _exl3_sys.path.insert(0, "exllamav3/exllamav3_ext"); from build_config import get_sources as _get_sources; _exl3_sys.path.pop(0)|' setup.py
|
||||||
|
grep -q 'from build_config import' setup.py
|
||||||
|
|
||||||
|
# Upstream serves these from the checkout (pip install -e .); the wheel only
|
||||||
|
# packages what pyproject lists, and three things are read out of the
|
||||||
|
# installed package at run time: the .hip sources the JIT kernels compile,
|
||||||
|
# the qsa_proof marker gating the QSA prefill kernel, and the dense-GEMM
|
||||||
|
# tuning seed (without it every start re-tunes for ~7 minutes).
|
||||||
|
sed -i 's|^ "exllamav3_ext/\*\*/\*",$|&\n "**/*.hip",\n "**/*.ok",\n "model/dense_gemm_tune_seed.txt",|' pyproject.toml
|
||||||
|
grep -q '"\*\*/\*.hip"' pyproject.toml
|
||||||
|
'';
|
||||||
|
|
||||||
|
# tests/ needs a real gfx1151 GPU and the published model packs.
|
||||||
|
doCheck = false;
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Inference engine for 100 GB-class EXL3 MoE models on AMD Strix Halo (gfx1151, ROCm 7)";
|
||||||
|
homepage = "https://github.com/Yamz-Labs/kyojin";
|
||||||
|
changelog = "https://github.com/Yamz-Labs/kyojin/releases";
|
||||||
|
license = licenses.mit;
|
||||||
|
sourceProvenance = with sourceTypes; [ fromSource ];
|
||||||
|
# HIP code objects are gfx1151-only and ROCm is Linux-only.
|
||||||
|
platforms = platforms.linux;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
python = py.python.withPackages (_: [ library ]);
|
||||||
|
jitSdk = if jitRocmSdk == null then rocmToolkit else jitRocmSdk;
|
||||||
|
in
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
inherit src version;
|
||||||
|
pname = "kyojin";
|
||||||
|
|
||||||
|
# Only the wrappers are installed here: the serve scripts are plain scripts,
|
||||||
|
# they import their siblings by path, and the module itself is in `library`.
|
||||||
|
#
|
||||||
|
# Upstream `tools/strix_halo/env.sh` is sourced before serving, and on a
|
||||||
|
# distro box that brings a system `cc` (the AMD Triton backend compiles a
|
||||||
|
# CPython glue module at runtime, and again per kernel launcher) plus a hipcc
|
||||||
|
# for the JIT HIP kernels (qsa prefill, gdn, kda, ple). Nix gives the wrapper
|
||||||
|
# neither, so export them here instead: Triton takes the compiler from $CC,
|
||||||
|
# exllamav3 finds hipcc under $EXL3_ROCM_SDK, and hipclang only finds the
|
||||||
|
# amdgcn bitcode through $HIP_DEVICE_LIB_PATH (hipcc's own DEVICE_LIB_PATH is
|
||||||
|
# not enough for a --genco call). The ROCm paths stay out of LD_LIBRARY_PATH
|
||||||
|
# (upstream Trap 1/5: a second libhsa segfaults torch), and PYTHONPATH gets
|
||||||
|
# `gr/`: upstream env.sh puts the repo root there so `import gr_mix_hip` (the
|
||||||
|
# hand-written gated-residual WMMA kernel the server asks for with
|
||||||
|
# EXL3_GR_HIP=1) resolves, and it is not part of the wheel either.
|
||||||
|
dontConfigure = true;
|
||||||
|
dontBuild = true;
|
||||||
|
|
||||||
|
nativeBuildInputs = [ makeWrapper ];
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
|
||||||
|
mkdir -p $out/bin
|
||||||
|
for model in glm mimo qwen; do
|
||||||
|
makeWrapper ${python}/bin/python $out/bin/kyojin-serve-$model \
|
||||||
|
--set PYTORCH_ROCM_ARCH ${rocmArch} \
|
||||||
|
--set CC ${stdenv.cc}/bin/cc \
|
||||||
|
--set EXL3_ROCM_SDK ${jitSdk} \
|
||||||
|
--set HIP_DEVICE_LIB_PATH ${rocmPackages."rocm-device-libs"}/amdgcn/bitcode \
|
||||||
|
--set EXL3_EXPANDABLE_SEGMENTS 0 \
|
||||||
|
--prefix PATH : ${lib.makeBinPath [ stdenv.cc ]} \
|
||||||
|
--prefix PYTHONPATH : ${src}/gr \
|
||||||
|
--add-flags "${src}/tools/$model/serve.py"
|
||||||
|
done
|
||||||
|
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
|
||||||
|
passthru = {
|
||||||
|
inherit python rocmArch;
|
||||||
|
pythonPackage = library;
|
||||||
|
jitRocmSdk = jitSdk;
|
||||||
|
tests.jit =
|
||||||
|
pkgs.runCommand "kyojin-jit-check"
|
||||||
|
{
|
||||||
|
EXL3_ROCM_SDK = jitSdk;
|
||||||
|
# CLR/COMGR also reads this variable. Newer bitcode crashes torch
|
||||||
|
# matmul; a custom hipcc must select its own bitcode in its subprocess.
|
||||||
|
HIP_DEVICE_LIB_PATH = "${rocmPackages."rocm-device-libs"}/amdgcn/bitcode";
|
||||||
|
EXL3_EXPANDABLE_SEGMENTS = "0";
|
||||||
|
PYTHONPATH = "${src}/gr";
|
||||||
|
KYOJIN_REQUIRE_SDK = lib.boolToString (jitRocmSdk != null);
|
||||||
|
}
|
||||||
|
''
|
||||||
|
export HOME="$TMPDIR"
|
||||||
|
${python}/bin/python ${./check-jit.py}
|
||||||
|
touch "$out"
|
||||||
|
'';
|
||||||
|
category = "AI Inference";
|
||||||
|
updateScript = [
|
||||||
|
"nix-update"
|
||||||
|
"--flake"
|
||||||
|
".#kyojin"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = library.meta // {
|
||||||
|
mainProgram = "kyojin-serve-qwen";
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -36,12 +36,30 @@ rustPlatform.buildRustPackage rec {
|
|||||||
# src/orchestrator/bus.rs, src/orchestrator/preemption.rs), so the
|
# src/orchestrator/bus.rs, src/orchestrator/preemption.rs), so the
|
||||||
# manager-loop tests fail nondeterministically when the harness runs them on
|
# manager-loop tests fail nondeterministically when the harness runs them on
|
||||||
# parallel threads: rebuilding one unchanged derivation yielded 3 failures,
|
# parallel threads: rebuilding one unchanged derivation yielded 3 failures,
|
||||||
# then 1 failure, then 0 with serial threads. All 325 tests still run — none
|
# then 1 failure, then 0 with serial threads. Drop this flag once upstream
|
||||||
# are skipped or filtered. Drop this flag once upstream makes that state
|
# makes that state per-instance.
|
||||||
# per-instance.
|
#
|
||||||
|
# The two sandbox-exec tests are skipped. They re-exec `sh` through
|
||||||
|
# `marmel --internal-sandbox-exec`, and apply_landlock_linux() allow-lists
|
||||||
|
# FHS paths only (/usr, /bin, /lib, /opt, /etc, /var) plus /tmp. Landlock
|
||||||
|
# matches inodes rather than symlinked views, and every binary on NixOS
|
||||||
|
# resolves into the store (`/bin/sh` is
|
||||||
|
# /nix/store/<hash>-bash-interactive-5.3p9/bin/bash), so the exec is denied:
|
||||||
|
# "Failed to exec shell in sandbox: Permission denied (os error 13)". Checked
|
||||||
|
# against this build on a NixOS host, where the same command succeeds once
|
||||||
|
# the workspace root is `/` and therefore covers /nix/store. Inside the build
|
||||||
|
# sandbox the tests are doubly impossible: /usr, /lib, /run and /var do not
|
||||||
|
# exist, so the `if let Ok(fd)` guards silently drop those rules, and
|
||||||
|
# /etc/resolv.conf is absent because the sandbox has no network. 342 of 344
|
||||||
|
# tests still run. Upstream main still carries the FHS-only list; drop these
|
||||||
|
# skips if that ever gains /nix/store.
|
||||||
cargoTestFlags = [
|
cargoTestFlags = [
|
||||||
"--"
|
"--"
|
||||||
"--test-threads=1"
|
"--test-threads=1"
|
||||||
|
"--skip"
|
||||||
|
"harness::sandbox::tests::test_internal_sandbox_exec_dev_null_and_dns"
|
||||||
|
"--skip"
|
||||||
|
"harness::sandbox::tests::test_internal_sandbox_cross_directory_rename"
|
||||||
];
|
];
|
||||||
|
|
||||||
# Role prompts are embedded with `include_str!`, so the binary needs no
|
# Role prompts are embedded with `include_str!`, so the binary needs no
|
||||||
|
|||||||
Reference in New Issue
Block a user