nx_gen_modelid.nx source
↩ module page · 99 lines · 3954 B
1// nx_gen_modelid.nx -- identify ANY model file: container, family, role. The front door of a
2// hot-swappable pipeline.
3//
4// Operator 2026-08-07: *"when i use krea or something else it needs to have comfyui capabilities
5// without its messy interface"*. ComfyUI's real capability is not its node graph -- it is that you
6// can drop in an arbitrary set of parts and it knows what they are and how they wire. The UI is
7// the part worth leaving behind.
8//
9// So: point this at a file and it answers "what IS this", by probing TENSOR NAMES. Names are the
10// only honest signature -- the installed zoo already proves why:
11// * a `.safetensors` DiT can be Z-Image or FLUX (Realism_Engine_Klein_V2 is Flux)
12// * a `.gguf` can be a DiT or a text-encoder LLM
13// * one file can be 453 tensors or 789 and still be the same family
14// ★ FILENAME AND EXTENSION ARE CLAIMS; THE TENSOR NAMES ARE EVIDENCE.
15//
16// It REFUSES to guess. An unknown file is reported UNKNOWN, never defaulted to the family we
17// happen to support -- a wrong family runs to completion and produces a wrong picture.
18//
19// Usage: nx_gen_modelid <model_file>
20// license_tier: ORIGINAL
21
22import "nx_syscalls.nx"
23import "nx_le.nx"
24import "nx_f32.nx"
25import "nx_f32_div.nx"
26import "nx_f32_cvt.nx"
27import "nx_f16.nx"
28import "nx_strconv.nx"
29import "nx_genver.nx"
30import "nx_genweights.nx"
31import "nx_genarch.nx"
32import "nx_genrole.nx"
33
34func mi_puts(s: *u8) -> i64 {
35 var n: i64 = 0
36 while s[n] != (0 as u8) { n = n + 1 }
37 return sys_write(1, s, n)
38}
39func mi_len(s: *u8) -> i64 {
40 var n: i64 = 0
41 while s[n] != (0 as u8) { n = n + 1 }
42 return n
43}
44func mi_has(gw: *i64, name: *u8) -> i64 {
45 if nx_gw_find(gw, name, mi_len(name)) < 0 { return 0 }
46 return 1
47}
48
49func main(argc: i64, argv: *i64) -> i64 {
50 if argc < 2 {
51 mi_puts("usage: nx_gen_modelid <model_file>\n" as *u8)
52 return 2
53 }
54 let gw: *i64 = nx_gw_open(argv[1] as *u8)
55 if (gw as i64) == 0 {
56 mi_puts("container=UNREADABLE (neither GGUF nor safetensors)\n" as *u8)
57 return 20
58 }
59 if gw[3] == NX_GW_FMT_ST { mi_puts("container=safetensors\n" as *u8) }
60 else { mi_puts("container=gguf\n" as *u8); nx_genver_emit("tensors" as *u8, nx_gw_ntensors(gw)) }
61
62 // Every probe below used to live here in full, and a second copy lived in nx_gen_zoo. They
63 // drifted. There is now exactly one: nx_genrole.
64 let rl: *i64 = sys_mmap(RL_SLOTS * 8 + 64) as *i64
65 let role: i64 = nx_role_probe(gw, rl)
66
67 mi_puts("family=" as *u8); mi_puts(nx_family_name(rl[RL_FAMILY]))
68 mi_puts(" role=" as *u8); mi_puts(nx_role_name(role))
69 if role == ROLE_ADAPTER { mi_puts("-" as *u8); mi_puts(nx_adkind_name(rl[RL_ADKIND])) }
70 if rl[RL_RUNNABLE] == 1 { mi_puts(" runnable=yes\n" as *u8) }
71 else {
72 mi_puts(" runnable=no (" as *u8)
73 mi_puts(nx_role_blocker(rl))
74 mi_puts(")\n" as *u8)
75 }
76
77 if role == ROLE_UNKNOWN {
78 mi_puts(" refusing to guess -- a wrong family runs to completion and yields a wrong picture\n" as *u8)
79 return 3
80 }
81 if role == ROLE_ADAPTER {
82 mi_puts(" an adapter is not a model: it needs a base checkpoint of the same family\n" as *u8)
83 return 0
84 }
85 if role == ROLE_DIT {
86 let arch: *i64 = sys_mmap(NX_ARCH_SLOTS * 8 + 64) as *i64
87 if nx_arch_probe(gw, arch) == 0 {
88 nx_genver_emit("hidden_dim" as *u8, arch[NX_ARCH_D])
89 nx_genver_emit("head_dim" as *u8, arch[NX_ARCH_HEAD_DIM])
90 nx_genver_emit("n_heads" as *u8, arch[NX_ARCH_N_HEADS])
91 nx_genver_emit("ffn_dim" as *u8, arch[NX_ARCH_FFN_DIM])
92 nx_genver_emit("n_layers" as *u8, arch[NX_ARCH_N_LAYERS])
93 nx_genver_emit("n_refiner_layers" as *u8, arch[NX_ARCH_N_REFINE])
94 nx_genver_emit("adaln_chunks" as *u8, arch[NX_ARCH_N_CHUNKS])
95 nx_genver_emit("out_dim" as *u8, arch[NX_ARCH_OUT_DIM])
96 }
97 }
98 return 0
99}