Compare commits
3 Commits
f9694ae033
...
f342521d46
| Author | SHA1 | Date | |
|---|---|---|---|
|
f342521d46
|
|||
|
7e779ca0f7
|
|||
|
06b2016bd6
|
@@ -20,6 +20,7 @@
|
|||||||
./modules/no-rgb.nix
|
./modules/no-rgb.nix
|
||||||
./modules/security.nix
|
./modules/security.nix
|
||||||
./modules/ntfy-alerts.nix
|
./modules/ntfy-alerts.nix
|
||||||
|
./modules/power.nix
|
||||||
|
|
||||||
./services/postgresql.nix
|
./services/postgresql.nix
|
||||||
./services/jellyfin.nix
|
./services/jellyfin.nix
|
||||||
@@ -46,6 +47,8 @@
|
|||||||
|
|
||||||
./services/soulseek.nix
|
./services/soulseek.nix
|
||||||
|
|
||||||
|
./services/llama-cpp.nix
|
||||||
|
|
||||||
./services/ups.nix
|
./services/ups.nix
|
||||||
./services/monitoring.nix
|
./services/monitoring.nix
|
||||||
./services/jellyfin-annotations.nix
|
./services/jellyfin-annotations.nix
|
||||||
@@ -91,13 +94,6 @@
|
|||||||
|
|
||||||
services.kmscon.enable = true;
|
services.kmscon.enable = true;
|
||||||
|
|
||||||
systemd.targets = {
|
|
||||||
sleep.enable = false;
|
|
||||||
suspend.enable = false;
|
|
||||||
hibernate.enable = false;
|
|
||||||
hybrid-sleep.enable = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Disable serial getty on ttyS0 to prevent dmesg warnings
|
# Disable serial getty on ttyS0 to prevent dmesg warnings
|
||||||
systemd.services."serial-getty@ttyS0".enable = false;
|
systemd.services."serial-getty@ttyS0".enable = false;
|
||||||
|
|
||||||
@@ -109,12 +105,6 @@
|
|||||||
enable = false;
|
enable = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
powerManagement = {
|
|
||||||
powertop.enable = true;
|
|
||||||
enable = true;
|
|
||||||
cpuFreqGovernor = "powersave";
|
|
||||||
};
|
|
||||||
|
|
||||||
# https://github.com/NixOS/nixpkgs/issues/101459#issuecomment-758306434
|
# https://github.com/NixOS/nixpkgs/issues/101459#issuecomment-758306434
|
||||||
security.pam.loginLimits = [
|
security.pam.loginLimits = [
|
||||||
{
|
{
|
||||||
|
|||||||
53
flake.lock
generated
53
flake.lock
generated
@@ -150,6 +150,24 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"flake-parts": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-lib": "nixpkgs-lib"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1730504689,
|
||||||
|
"narHash": "sha256-hgmguH29K2fvs9szpq2r3pz2/8cJd2LPS+b4tfNFCwE=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"rev": "506278e768c2a08bec68eb62932193e341f55c90",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"flake-utils": {
|
"flake-utils": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"systems": "systems_4"
|
"systems": "systems_4"
|
||||||
@@ -276,6 +294,28 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"llamacpp": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-parts": "flake-parts",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1775101360,
|
||||||
|
"narHash": "sha256-X1cyWED8lmsGKFc7Pb6nGJ8EVzpPqi5iKcyL8NVVIe8=",
|
||||||
|
"owner": "TheTom",
|
||||||
|
"repo": "llama-cpp-turboquant",
|
||||||
|
"rev": "04eeabb0d344b54ca12d4140b8af8c236ffe7beb",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "TheTom",
|
||||||
|
"ref": "feature/turboquant-kv-cache",
|
||||||
|
"repo": "llama-cpp-turboquant",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nix-minecraft": {
|
"nix-minecraft": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-compat": "flake-compat_3",
|
"flake-compat": "flake-compat_3",
|
||||||
@@ -330,6 +370,18 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nixpkgs-lib": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1730504152,
|
||||||
|
"narHash": "sha256-lXvH/vOfb4aGYyvFmZK/HlsNsr/0CVWlwYvo2rxJk3s=",
|
||||||
|
"type": "tarball",
|
||||||
|
"url": "https://github.com/NixOS/nixpkgs/archive/cc2f28000298e1269cea6612cd06ec9979dd5d7f.tar.gz"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"type": "tarball",
|
||||||
|
"url": "https://github.com/NixOS/nixpkgs/archive/cc2f28000298e1269cea6612cd06ec9979dd5d7f.tar.gz"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nixpkgs-p2pool-module": {
|
"nixpkgs-p2pool-module": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
@@ -395,6 +447,7 @@
|
|||||||
"home-manager": "home-manager",
|
"home-manager": "home-manager",
|
||||||
"impermanence": "impermanence",
|
"impermanence": "impermanence",
|
||||||
"lanzaboote": "lanzaboote",
|
"lanzaboote": "lanzaboote",
|
||||||
|
"llamacpp": "llamacpp",
|
||||||
"nix-minecraft": "nix-minecraft",
|
"nix-minecraft": "nix-minecraft",
|
||||||
"nixos-hardware": "nixos-hardware",
|
"nixos-hardware": "nixos-hardware",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
|
|||||||
@@ -28,6 +28,11 @@
|
|||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
llamacpp = {
|
||||||
|
url = "github:TheTom/llama-cpp-turboquant/feature/turboquant-kv-cache";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
srvos = {
|
srvos = {
|
||||||
url = "github:nix-community/srvos";
|
url = "github:nix-community/srvos";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
|||||||
93
modules/power.nix
Normal file
93
modules/power.nix
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
powerManagement = {
|
||||||
|
enable = true;
|
||||||
|
powertop.enable = true;
|
||||||
|
cpuFreqGovernor = "powersave";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Always-on server: disable all sleep targets.
|
||||||
|
systemd.targets = {
|
||||||
|
sleep.enable = false;
|
||||||
|
suspend.enable = false;
|
||||||
|
hibernate.enable = false;
|
||||||
|
hybrid-sleep.enable = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
boot.kernelParams = [
|
||||||
|
# Disable NMI watchdog at boot. Eliminates periodic perf-counter interrupts
|
||||||
|
# across all cores (~1 W). Safe: apcupsd provides hardware hang detection
|
||||||
|
# via UPS, and softlockup watchdog remains active.
|
||||||
|
"nmi_watchdog=0"
|
||||||
|
|
||||||
|
# Route kernel work items to already-busy CPUs rather than waking idle ones.
|
||||||
|
# Reduces C-state exit frequency at the cost of slightly higher latency on
|
||||||
|
# work items -- irrelevant for a server whose latency-sensitive paths are
|
||||||
|
# all in userspace (caddy, jellyfin).
|
||||||
|
"workqueue.power_efficient=1"
|
||||||
|
|
||||||
|
# Force PCIe ASPM on even if the BIOS doesn't advertise support. ASRock
|
||||||
|
# B550M Pro4 BIOS defaults are conservative; the Zen 3 root complex and
|
||||||
|
# all downstream devices (NVMe, AHCI, Intel NIC) support L1 substates.
|
||||||
|
# powertop auto-tune sets the policy to powersupersave at runtime, but
|
||||||
|
# without `force` the kernel may refuse to enable ASPM at all if the BIOS
|
||||||
|
# opted out, making the policy write a no-op.
|
||||||
|
"pcie_aspm=force"
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.kernel.sysctl = {
|
||||||
|
# Belt-and-suspenders: also set via boot param, but sysctl ensures it
|
||||||
|
# stays off if anything re-enables it at runtime.
|
||||||
|
"kernel.nmi_watchdog" = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Server has no audio consumers. Power-gate the HDA codec at module load
|
||||||
|
# rather than waiting for powertop auto-tune to do it after boot.
|
||||||
|
boot.extraModprobeConfig = ''
|
||||||
|
options snd_hda_intel power_save=1 power_save_controller=Y
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Apply sysfs power knobs that powertop --auto-tune cannot reach (hardened
|
||||||
|
# kernel blocks debugfs mount, so powertop silently skips ASPM policy and
|
||||||
|
# may only lower EPP to balance_power instead of power).
|
||||||
|
#
|
||||||
|
# AMD pstate EPP "power": deepest P-states, fastest core parking. Safe because:
|
||||||
|
# - xmrig runs at Nice=19 / CPUSchedulingPolicy=idle and tolerates latency
|
||||||
|
# - web services (caddy, jellyfin) are I/O-bound; the ~50 us extra C-state
|
||||||
|
# exit latency is invisible behind network RTT
|
||||||
|
# - Minecraft server benefits from single-thread boost, which pstate still
|
||||||
|
# provides on demand even in "power" mode (just with slightly slower ramp)
|
||||||
|
#
|
||||||
|
# ASPM powersupersave: deepest PCIe link power states (L1.1/L1.2). The
|
||||||
|
# pcie_aspm=force boot param enables ASPM, but the runtime policy defaults
|
||||||
|
# to "default" which only uses L0s. powersupersave adds L1 substates for
|
||||||
|
# all downstream devices (NVMe, AHCI, NIC).
|
||||||
|
systemd.services.power-tune = {
|
||||||
|
description = "Apply power-saving sysfs knobs (EPP, ASPM policy)";
|
||||||
|
after = [ "multi-user.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
ExecStart = lib.getExe (
|
||||||
|
pkgs.writeShellApplication {
|
||||||
|
name = "power-tune";
|
||||||
|
text = ''
|
||||||
|
# AMD pstate energy performance preference
|
||||||
|
for epp in /sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference; do
|
||||||
|
[ -f "$epp" ] && echo power > "$epp"
|
||||||
|
done
|
||||||
|
|
||||||
|
# PCIe ASPM policy
|
||||||
|
aspm=/sys/module/pcie_aspm/parameters/policy
|
||||||
|
[ -f "$aspm" ] && echo powersupersave > "$aspm"
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -169,6 +169,10 @@ rec {
|
|||||||
port = 9162;
|
port = 9162;
|
||||||
proto = "tcp";
|
proto = "tcp";
|
||||||
};
|
};
|
||||||
|
llama_cpp = {
|
||||||
|
port = 6688;
|
||||||
|
proto = "tcp";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ in
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
# x265 (HD) - override template -10000 penalty
|
# x265 (HD) - override template -10000 penalty for non-2160p HEVC
|
||||||
{
|
{
|
||||||
trash_ids = [ "dc98083864ea246d05a42df0d05f81cc" ];
|
trash_ids = [ "dc98083864ea246d05a42df0d05f81cc" ];
|
||||||
assign_scores_to = [
|
assign_scores_to = [
|
||||||
@@ -109,7 +109,7 @@ in
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
# x265 (no HDR/DV) - override template -10000 penalty
|
# x265 (no HDR/DV) - override template -10000 penalty for non-2160p HEVC
|
||||||
{
|
{
|
||||||
trash_ids = [ "839bea857ed2c0a8e084f3cbdbd65ecb" ];
|
trash_ids = [ "839bea857ed2c0a8e084f3cbdbd65ecb" ];
|
||||||
assign_scores_to = [
|
assign_scores_to = [
|
||||||
@@ -119,6 +119,28 @@ in
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
# Codec ranking: AV1 (20) > HEVC (10) > AVC (0)
|
||||||
|
#
|
||||||
|
# Positive scores only -- nothing drops below min_format_score.
|
||||||
|
# AVC stays at 0 implicitly (no custom format adds or removes score).
|
||||||
|
{
|
||||||
|
trash_ids = [ "cae4ca30163749b891686f95532519bd" ]; # AV1
|
||||||
|
assign_scores_to = [
|
||||||
|
{
|
||||||
|
name = "Remux + WEB 2160p";
|
||||||
|
score = 20;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
trash_ids = [ "9170d55c319f4fe40da8711ba9d8050d" ]; # x265
|
||||||
|
assign_scores_to = [
|
||||||
|
{
|
||||||
|
name = "Remux + WEB 2160p";
|
||||||
|
score = 10;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -177,7 +199,7 @@ in
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
# x265 (HD) - override template -10000 penalty
|
# x265 (HD) - override template -10000 penalty for non-2160p HEVC
|
||||||
{
|
{
|
||||||
trash_ids = [ "47435ece6b99a0b477caf360e79ba0bb" ];
|
trash_ids = [ "47435ece6b99a0b477caf360e79ba0bb" ];
|
||||||
assign_scores_to = [
|
assign_scores_to = [
|
||||||
@@ -187,7 +209,7 @@ in
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
# x265 (no HDR/DV) - override template -10000 penalty
|
# x265 (no HDR/DV) - override template -10000 penalty for non-2160p HEVC
|
||||||
{
|
{
|
||||||
trash_ids = [ "9b64dff695c2115facf1b6ea59c9bd07" ];
|
trash_ids = [ "9b64dff695c2115facf1b6ea59c9bd07" ];
|
||||||
assign_scores_to = [
|
assign_scores_to = [
|
||||||
@@ -197,6 +219,28 @@ in
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
# Codec ranking: AV1 (20) > HEVC (10) > AVC (0)
|
||||||
|
#
|
||||||
|
# Positive scores only -- nothing drops below min_format_score.
|
||||||
|
# AVC stays at 0 implicitly (no custom format adds or removes score).
|
||||||
|
{
|
||||||
|
trash_ids = [ "15a05bc7c1a36e2b57fd628f8977e2fc" ]; # AV1
|
||||||
|
assign_scores_to = [
|
||||||
|
{
|
||||||
|
name = "WEB-2160p";
|
||||||
|
score = 20;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
trash_ids = [ "c9eafd50846d299b862ca9bb6ea91950" ]; # x265
|
||||||
|
assign_scores_to = [
|
||||||
|
{
|
||||||
|
name = "WEB-2160p";
|
||||||
|
score = 10;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
40
services/llama-cpp.nix
Normal file
40
services/llama-cpp.nix
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
service_configs,
|
||||||
|
config,
|
||||||
|
inputs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
services.llama-cpp = {
|
||||||
|
enable = true;
|
||||||
|
model = toString (
|
||||||
|
pkgs.fetchurl {
|
||||||
|
url = "https://huggingface.co/Jackrong/Qwen3.5-9B-Claude-4.6-Opus-Reasoning-Distilled-v2-GGUF/resolve/main/Qwen3.5-9B.Q4_K_M.gguf";
|
||||||
|
sha256 = "8fbbc7b04a7d4b052d14b7aa97c8bf2014d39ceca8c2baaa043711712ba71ccc";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
port = service_configs.ports.private.llama_cpp.port;
|
||||||
|
host = "0.0.0.0";
|
||||||
|
package = (lib.optimizePackage inputs.llamacpp.packages.${pkgs.system}.vulkan);
|
||||||
|
extraFlags = [
|
||||||
|
"-ngl"
|
||||||
|
"12"
|
||||||
|
"-c"
|
||||||
|
"16384"
|
||||||
|
"-ctk"
|
||||||
|
"q8_0"
|
||||||
|
"-ctv"
|
||||||
|
"turbo3"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# have to do this in order to get vulkan to work
|
||||||
|
systemd.services.llama-cpp.serviceConfig.DynamicUser = lib.mkForce false;
|
||||||
|
|
||||||
|
services.caddy.virtualHosts."llm.${service_configs.https.domain}".extraConfig = ''
|
||||||
|
import ${config.age.secrets.caddy_auth.path}
|
||||||
|
reverse_proxy :${toString config.services.llama-cpp.port}
|
||||||
|
'';
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user