mlx-bun 0.0.11 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +63 -27
  2. package/THIRD_PARTY_LICENSES.md +9 -0
  3. package/docs/design/colibri-glm52-port.md +1486 -0
  4. package/docs/design/pre-colibri-stabilization.md +329 -0
  5. package/docs/investigations/colibri-oracle-pin.md +1284 -0
  6. package/docs/investigations/indexshare-performance-spike.md +357 -0
  7. package/docs/planning/release-notes-v0.0.12.md +80 -0
  8. package/docs/planning/release-notes-v0.0.13.md +77 -0
  9. package/docs/reference/cli.md +28 -2
  10. package/docs/reference/distribution.md +25 -1
  11. package/docs/reference/embedding.md +5 -2
  12. package/docs/reference/features-matrix.md +5 -2
  13. package/docs/reference/library-api.md +41 -13
  14. package/docs/reference/models.md +49 -2
  15. package/docs/reference/server-api.md +113 -20
  16. package/docs/reference/server-config.md +21 -14
  17. package/docs/reference/training.md +10 -1
  18. package/package.json +1 -1
  19. package/src/anthropic.ts +54 -44
  20. package/src/chat-template.ts +189 -11
  21. package/src/cli.ts +127 -8
  22. package/src/config.ts +81 -26
  23. package/src/diffusion/diffusion-generate.ts +14 -8
  24. package/src/download.ts +103 -12
  25. package/src/eval/ifeval.ts +63 -120
  26. package/src/eval/runner.ts +14 -5
  27. package/src/eval/tasks/ifeval.ts +167 -31
  28. package/src/expert-io.ts +391 -0
  29. package/src/expert-residency.ts +1134 -0
  30. package/src/expert-usage.ts +415 -0
  31. package/src/generate.ts +114 -17
  32. package/src/hf-push.ts +1 -1
  33. package/src/index.ts +14 -2
  34. package/src/jobs/runner.ts +37 -18
  35. package/src/kv-store.ts +147 -8
  36. package/src/lora.ts +77 -14
  37. package/src/media-fetch.ts +198 -56
  38. package/src/mlx/array.ts +43 -0
  39. package/src/mlx/autograd.ts +51 -14
  40. package/src/mlx/checkpoint.ts +46 -13
  41. package/src/mlx/custom-vjp.ts +83 -35
  42. package/src/model/factory.ts +96 -5
  43. package/src/model/gemma4-base.ts +32 -0
  44. package/src/model/glm52-atlas.ts +511 -0
  45. package/src/model/glm52-cache.ts +706 -0
  46. package/src/model/glm52-config.ts +262 -0
  47. package/src/model/glm52-container.ts +305 -0
  48. package/src/model/glm52-coupling.ts +388 -0
  49. package/src/model/glm52-dsa.ts +602 -0
  50. package/src/model/glm52-expert-layout.ts +253 -0
  51. package/src/model/glm52-layout.ts +152 -0
  52. package/src/model/glm52-memory.ts +473 -0
  53. package/src/model/glm52-mla.ts +786 -0
  54. package/src/model/glm52-moe.ts +223 -0
  55. package/src/model/glm52-pilot.ts +537 -0
  56. package/src/model/glm52-reference.ts +445 -0
  57. package/src/model/glm52-residency.ts +557 -0
  58. package/src/model/glm52-resident-weights.ts +135 -0
  59. package/src/model/glm52-streamed-experts.ts +453 -0
  60. package/src/model/glm52-streamed-metal.ts +610 -0
  61. package/src/model/glm52-weights.ts +503 -0
  62. package/src/model/glm52.ts +1153 -0
  63. package/src/model/support.ts +8 -1
  64. package/src/native/expert_io.c +523 -0
  65. package/src/native-pack.ts +6 -4
  66. package/src/responses.ts +62 -49
  67. package/src/serve/batch-scheduler.ts +95 -16
  68. package/src/serve/generation-gateway.ts +41 -16
  69. package/src/server.ts +471 -93
  70. package/src/spec/glm52-mtp-source.ts +392 -0
  71. package/src/spec/serve-loop.ts +99 -18
  72. package/src/spec/source.ts +31 -6
  73. package/src/ssd-cache.ts +6 -2
  74. package/src/tool-call.ts +30 -2
  75. package/src/train/job.ts +0 -10
  76. package/src/train/lora-params.ts +17 -6
  77. package/src/train/trainer.ts +59 -26
  78. package/src/web/app.html +13 -2
  79. package/src/web/app.js +30 -3
  80. package/src/web/src/status.ts +51 -3
  81. package/src/web-tools.ts +54 -2
  82. package/src/weights.ts +82 -19
package/src/weights.ts CHANGED
@@ -22,34 +22,97 @@ import { C } from "./mlx/ffi";
22
22
 
23
23
  const cstr = (s: string) => Buffer.from(s + "\0", "utf8");
24
24
 
25
+ export interface WeightsNativeBindings {
26
+ newArrayMap(): bigint;
27
+ freeArrayMap(handle: bigint): void;
28
+ newStringMap(): bigint;
29
+ freeStringMap(handle: bigint): void;
30
+ loadSafetensors(
31
+ arrayMapSlot: BigUint64Array,
32
+ metadataMapSlot: BigUint64Array,
33
+ path: string,
34
+ ): number;
35
+ }
36
+
37
+ export interface WeightsOpenOptions {
38
+ /** Failure-injection seam; production callers use the native MLX bindings. */
39
+ native?: WeightsNativeBindings;
40
+ /** Parser seam used by ownership tests to provide deterministic shard order. */
41
+ openShards?: (modelDir: string) => Promise<ShardedSafetensors>;
42
+ }
43
+
44
+ const NATIVE_WEIGHTS: WeightsNativeBindings = {
45
+ newArrayMap: () => C.mlx_map_string_to_array_new(),
46
+ freeArrayMap: (handle) => {
47
+ C.mlx_map_string_to_array_free(handle);
48
+ },
49
+ newStringMap: () => C.mlx_map_string_to_string_new(),
50
+ freeStringMap: (handle) => {
51
+ C.mlx_map_string_to_string_free(handle);
52
+ },
53
+ loadSafetensors: (arrayMapSlot, metadataMapSlot, path) =>
54
+ C.mlx_load_safetensors(
55
+ ptr(arrayMapSlot),
56
+ ptr(metadataMapSlot),
57
+ ptr(cstr(path)),
58
+ cpuStream,
59
+ ),
60
+ };
61
+
25
62
  export class Weights {
26
63
  readonly shards: ShardedSafetensors;
27
64
  /** shard filename → native mlx map handle (string → lazy array). */
28
65
  readonly #maps = new Map<string, bigint>();
29
66
  readonly #arrays = new Map<string, MlxArray>();
67
+ readonly #native: WeightsNativeBindings;
30
68
 
31
- private constructor(shards: ShardedSafetensors) {
69
+ private constructor(
70
+ shards: ShardedSafetensors,
71
+ native: WeightsNativeBindings,
72
+ ) {
32
73
  this.shards = shards;
74
+ this.#native = native;
33
75
  }
34
76
 
35
- static async open(modelDir: string): Promise<Weights> {
36
- const self = new Weights(await ShardedSafetensors.open(modelDir));
37
- for (const [file, sf] of self.shards.files) {
38
- // out-param slots read back via read.u64, not [0] (DFG stale-read
39
- // bug — see outArray in mlx/ffi.ts). Cold path, but the rule is
40
- // uniform: native wrote it, read.* reads it.
41
- const arrMap = new BigUint64Array([C.mlx_map_string_to_array_new()]);
42
- const metaMap = new BigUint64Array([C.mlx_map_string_to_string_new()]);
43
- const arrMapPtr = ptr(arrMap);
44
- const metaMapPtr = ptr(metaMap);
45
- const status = C.mlx_load_safetensors(
46
- arrMapPtr, metaMapPtr, ptr(cstr(sf.path)), cpuStream,
47
- );
48
- C.mlx_map_string_to_string_free(read.u64(metaMapPtr, 0));
49
- if (status !== 0) throw new Error(`mlx_load_safetensors(${sf.path}) failed`);
50
- self.#maps.set(file, read.u64(arrMapPtr, 0));
77
+ static async open(
78
+ modelDir: string,
79
+ options: WeightsOpenOptions = {},
80
+ ): Promise<Weights> {
81
+ const native = options.native ?? NATIVE_WEIGHTS;
82
+ const shards = await (options.openShards ?? ShardedSafetensors.open)(modelDir);
83
+ const self = new Weights(shards, native);
84
+ try {
85
+ for (const [file, sf] of self.shards.files) {
86
+ // out-param slots read back via read.u64, not [0] (DFG stale-read
87
+ // bug — see outArray in mlx/ffi.ts). Cold path, but the rule is
88
+ // uniform: native wrote it, read.* reads it.
89
+ const arrMap = new BigUint64Array([native.newArrayMap()]);
90
+ const arrMapPtr = ptr(arrMap);
91
+ let arrayMapTransferred = false;
92
+ try {
93
+ const metaMap = new BigUint64Array([native.newStringMap()]);
94
+ const metaMapPtr = ptr(metaMap);
95
+ try {
96
+ const status = native.loadSafetensors(arrMap, metaMap, sf.path);
97
+ if (status !== 0)
98
+ throw new Error(`mlx_load_safetensors(${sf.path}) failed`);
99
+ self.#maps.set(file, read.u64(arrMapPtr, 0));
100
+ arrayMapTransferred = true;
101
+ } finally {
102
+ native.freeStringMap(read.u64(metaMapPtr, 0));
103
+ }
104
+ } finally {
105
+ if (!arrayMapTransferred)
106
+ native.freeArrayMap(read.u64(arrMapPtr, 0));
107
+ }
108
+ }
109
+ return self;
110
+ } catch (error) {
111
+ // A failure on shard N must release every array map transferred by
112
+ // shards 1..N-1. The current shard remains owned by the inner guard.
113
+ self.dispose();
114
+ throw error;
51
115
  }
52
- return self;
53
116
  }
54
117
 
55
118
  get tensorNames(): string[] {
@@ -85,7 +148,7 @@ export class Weights {
85
148
  dispose(): void {
86
149
  for (const arr of this.#arrays.values()) arr.dispose();
87
150
  this.#arrays.clear();
88
- for (const map of this.#maps.values()) C.mlx_map_string_to_array_free(map);
151
+ for (const map of this.#maps.values()) this.#native.freeArrayMap(map);
89
152
  this.#maps.clear();
90
153
  }
91
154
  }