Project-Chronos 0.1.1__tar.gz → 0.2.0__tar.gz

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 (111) hide show
  1. {project_chronos-0.1.1 → project_chronos-0.2.0}/PKG-INFO +102 -7
  2. {project_chronos-0.1.1 → project_chronos-0.2.0}/Project_Chronos.egg-info/PKG-INFO +102 -7
  3. {project_chronos-0.1.1 → project_chronos-0.2.0}/Project_Chronos.egg-info/SOURCES.txt +10 -0
  4. {project_chronos-0.1.1 → project_chronos-0.2.0}/README.md +101 -6
  5. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/app.py +27 -0
  6. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/backend/__init__.py +7 -0
  7. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/backend/dispatcher.py +29 -11
  8. project_chronos-0.2.0/chronos/backend/mac_diagnostics.py +125 -0
  9. project_chronos-0.2.0/chronos/cli.py +99 -0
  10. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/data/flexible_dataset.py +17 -0
  11. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/eval/benchmark.py +34 -13
  12. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/eval/io_profiler.py +31 -10
  13. project_chronos-0.2.0/chronos/export.py +959 -0
  14. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/io/async_prefetcher.py +4 -1
  15. project_chronos-0.2.0/chronos/io/cluster_layout.py +581 -0
  16. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/io/expert_store.py +66 -1
  17. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/mlx/__init__.py +28 -6
  18. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/mlx/attention.py +102 -57
  19. project_chronos-0.2.0/chronos/mlx/expert_store.py +523 -0
  20. project_chronos-0.2.0/chronos/mlx/inference.py +398 -0
  21. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/mlx/model.py +76 -24
  22. project_chronos-0.2.0/chronos/mlx/moe.py +168 -0
  23. project_chronos-0.2.0/chronos/mlx/training/__init__.py +5 -0
  24. project_chronos-0.2.0/chronos/mlx/training/io.py +61 -0
  25. project_chronos-0.2.0/chronos/mlx/training/trainer.py +905 -0
  26. project_chronos-0.2.0/chronos/model/checkpoint.py +473 -0
  27. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/model/config.py +15 -0
  28. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/model/hybrid_attention.py +34 -2
  29. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/model/model_chronos.py +20 -0
  30. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/model/moe_chronos.py +103 -11
  31. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/model/temporal_loss.py +56 -0
  32. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/runtime/cache_manager.py +7 -0
  33. project_chronos-0.2.0/chronos/runtime/inference_engine.py +826 -0
  34. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/trainer/chronos_trainer.py +31 -15
  35. project_chronos-0.2.0/chronos/trainer/device_utils.py +357 -0
  36. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/trainer/distill_trainer.py +34 -15
  37. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/trainer/dpo_trainer.py +34 -15
  38. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/trainer/grpo_trainer.py +28 -13
  39. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/trainer/loss_mixin.py +10 -0
  40. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/trainer/orpo_trainer.py +34 -15
  41. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/trainer/sft_trainer.py +33 -16
  42. project_chronos-0.2.0/chronos/trainer/stage_utils.py +123 -0
  43. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/tuning/chronos_auto_tuner.py +49 -15
  44. project_chronos-0.2.0/chronos/verify.py +148 -0
  45. {project_chronos-0.1.1 → project_chronos-0.2.0}/pyproject.toml +1 -1
  46. project_chronos-0.2.0/tests/test_smoke.py +2253 -0
  47. {project_chronos-0.1.1 → project_chronos-0.2.0}/train_chronos.py +44 -29
  48. {project_chronos-0.1.1 → project_chronos-0.2.0}/train_chronos_distill.py +62 -30
  49. {project_chronos-0.1.1 → project_chronos-0.2.0}/train_chronos_dpo.py +41 -22
  50. {project_chronos-0.1.1 → project_chronos-0.2.0}/train_chronos_grpo.py +34 -23
  51. {project_chronos-0.1.1 → project_chronos-0.2.0}/train_chronos_orpo.py +41 -22
  52. {project_chronos-0.1.1 → project_chronos-0.2.0}/train_chronos_sft.py +42 -27
  53. {project_chronos-0.1.1 → project_chronos-0.2.0}/ui/gradio_compat.py +2 -1
  54. {project_chronos-0.1.1 → project_chronos-0.2.0}/ui/i18n.py +124 -0
  55. {project_chronos-0.1.1 → project_chronos-0.2.0}/ui/presets.py +49 -7
  56. {project_chronos-0.1.1 → project_chronos-0.2.0}/ui/tabs/autotune_tab.py +3 -18
  57. {project_chronos-0.1.1 → project_chronos-0.2.0}/ui/tabs/benchmark_tab.py +8 -2
  58. {project_chronos-0.1.1 → project_chronos-0.2.0}/ui/tabs/config_tab.py +109 -9
  59. project_chronos-0.2.0/ui/tabs/export_tab.py +194 -0
  60. project_chronos-0.2.0/ui/tabs/inference_tab.py +1826 -0
  61. {project_chronos-0.1.1 → project_chronos-0.2.0}/ui/tabs/pipeline_tab.py +3 -3
  62. {project_chronos-0.1.1 → project_chronos-0.2.0}/ui/tabs/train_tab.py +482 -195
  63. project_chronos-0.1.1/chronos/cli.py +0 -62
  64. project_chronos-0.1.1/chronos/io/cluster_layout.py +0 -317
  65. project_chronos-0.1.1/chronos/mlx/expert_store.py +0 -155
  66. project_chronos-0.1.1/chronos/mlx/inference.py +0 -159
  67. project_chronos-0.1.1/chronos/mlx/moe.py +0 -102
  68. project_chronos-0.1.1/chronos/runtime/inference_engine.py +0 -295
  69. project_chronos-0.1.1/tests/test_smoke.py +0 -834
  70. project_chronos-0.1.1/ui/tabs/inference_tab.py +0 -496
  71. {project_chronos-0.1.1 → project_chronos-0.2.0}/LICENSE +0 -0
  72. {project_chronos-0.1.1 → project_chronos-0.2.0}/MANIFEST.in +0 -0
  73. {project_chronos-0.1.1 → project_chronos-0.2.0}/Project_Chronos.egg-info/dependency_links.txt +0 -0
  74. {project_chronos-0.1.1 → project_chronos-0.2.0}/Project_Chronos.egg-info/entry_points.txt +0 -0
  75. {project_chronos-0.1.1 → project_chronos-0.2.0}/Project_Chronos.egg-info/requires.txt +0 -0
  76. {project_chronos-0.1.1 → project_chronos-0.2.0}/Project_Chronos.egg-info/top_level.txt +0 -0
  77. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/__init__.py +0 -0
  78. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/_backend_legacy.py +0 -0
  79. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/backend/ext/__init__.py +0 -0
  80. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/backend/ext/opencl.py +0 -0
  81. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/data/__init__.py +0 -0
  82. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/deps.py +0 -0
  83. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/eval/__init__.py +0 -0
  84. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/io/__init__.py +0 -0
  85. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/io/io_simulator.py +0 -0
  86. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/io/storage.py +0 -0
  87. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/model/__init__.py +0 -0
  88. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/model/hf_io.py +0 -0
  89. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/model/lookahead_router.py +0 -0
  90. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/router/__init__.py +0 -0
  91. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/router/expert_predictor.py +0 -0
  92. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/router/intent_classifier.py +0 -0
  93. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/router/prefill_scheduler.py +0 -0
  94. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/runtime/__init__.py +0 -0
  95. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/runtime/metrics.py +0 -0
  96. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/serving/__init__.py +0 -0
  97. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/serving/vllm_adapter.py +0 -0
  98. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/trainer/__init__.py +0 -0
  99. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/trainer/optim_utils.py +0 -0
  100. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/trainer/reward.py +0 -0
  101. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/tuning/__init__.py +0 -0
  102. {project_chronos-0.1.1 → project_chronos-0.2.0}/chronos/tuning/_base_tuner.py +0 -0
  103. {project_chronos-0.1.1 → project_chronos-0.2.0}/requirements.txt +0 -0
  104. {project_chronos-0.1.1 → project_chronos-0.2.0}/setup.cfg +0 -0
  105. {project_chronos-0.1.1 → project_chronos-0.2.0}/setup.py +0 -0
  106. {project_chronos-0.1.1 → project_chronos-0.2.0}/tests/test_smoke_cuda.py +0 -0
  107. {project_chronos-0.1.1 → project_chronos-0.2.0}/ui/__init__.py +0 -0
  108. {project_chronos-0.1.1 → project_chronos-0.2.0}/ui/estimator.py +0 -0
  109. {project_chronos-0.1.1 → project_chronos-0.2.0}/ui/tabs/__init__.py +0 -0
  110. {project_chronos-0.1.1 → project_chronos-0.2.0}/ui/tabs/data_tab.py +0 -0
  111. {project_chronos-0.1.1 → project_chronos-0.2.0}/ui/tabs/iomon_tab.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Project_Chronos
3
- Version: 0.1.1
3
+ Version: 0.2.0
4
4
  Summary: On-device low-latency lookahead dual-layer MoE inference — Lookahead Routing + Async Prefetch + Hybrid Attention
5
5
  License-Expression: Apache-2.0
6
6
  Keywords: llm,moe,inference,lookahead-routing,hybrid-attention,edge-ai
@@ -37,7 +37,7 @@ Dynamic: requires-python
37
37
 
38
38
  **A storage-aware MoE stack built for SSD+DRAM hybrid inference, with a full six-stage training pipeline.**
39
39
 
40
- [![PyPI](https://img.shields.io/pypi/v/project-chronos)](https://pypi.org/project/project-chronos/)
40
+ [![PyPI](https://img.shields.io/pypi/v/Project_Chronos)](https://pypi.org/project/Project_Chronos/)
41
41
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue)](LICENSE)
42
42
  [![Python](https://img.shields.io/badge/python-3.10%2B-blue)](https://python.org)
43
43
 
@@ -139,7 +139,7 @@ Even the worst case does not hard-stop generation:
139
139
  output = avail[i] * expert_output + (1.0 - avail[i]) * shared_expert_output
140
140
  ```
141
141
 
142
- The shared expert is always resident, so generation continues while the missing expert finishes loading in the background. Quality degrades smoothly and recovers automatically once the expert becomes available.
142
+ The shared expert is always resident, so generation continues while the missing expert finishes loading in the background. For exact lazy/offload comparison modes, Chronos synchronously materializes only the selected missing expert and evicts low-LRU experts to stay inside the resident budget; it does not silently full-load all experts. Quality degrades smoothly only when fallback mode is explicitly enabled.
143
143
 
144
144
  ---
145
145
 
@@ -222,6 +222,29 @@ flowchart LR
222
222
  | 5 GRPO | `train_chronos_grpo.py` | `PG * A - beta * KL` with `ToyReward` or pluggable `LMRewardModel` | 0.10 |
223
223
  | 6 Distill | `train_chronos_distill.py` | `alpha * T^2 * KL(student || teacher) + (1 - alpha) * CE` | 0.05 |
224
224
 
225
+ Training dtype and resource policy:
226
+
227
+ - `--dtype auto` is the default. MPS/MLX resolve to BF16-first for training stability, CUDA/XPU resolve to FP16, and CPU resolves to FP32 unless `--dtype float16` or `--dtype bfloat16` is set explicitly.
228
+ - CPU training configures PyTorch to use physical cores by default. Override with `--cpu_threads` or `--cpu_budget_percent`.
229
+ - On macOS, MPS/MLX training forces DataLoader workers to `0` by default to avoid Metal command-buffer crashes from multiprocessing. CPU/CUDA still use worker processes; advanced users can override the guard with `CHRONOS_ALLOW_METAL_DATALOADER_WORKERS=1`.
230
+ - Native MLX training pushes UI logs, scalar readouts, and chart points every `log_interval` steps, and Web UI Stop is checked at each batch boundary.
231
+ - The Web UI writes a warning-only `<checkpoint>.verify.json` after each stage. It checks no-mask vs all-available MoE parity and, on Apple Silicon, MLX prefill logits against the PyTorch CPU baseline.
232
+
233
+ Native MLX training is a separate Apple Silicon backend, not `torch.to("mlx")`.
234
+ The six-stage MLX trainer mirrors the PyTorch loss stack in `chronos.mlx.*`:
235
+ masked CE, DPO/ORPO/GRPO/distillation losses, load balance, temporal locality,
236
+ lookahead soft-target supervision, lookahead top-k hit loss, and router KL
237
+ anchor. Numerically sensitive pieces run in FP32 even when model weights use
238
+ BF16/FP16, which is why `auto` prefers BF16 on MLX/MPS: FP16 has too little
239
+ exponent range for router softmax, CE, and Adam moments on small unstable
240
+ training runs.
241
+
242
+ The MLX Web UI trainer reports the same fields as CPU/MPS training:
243
+ step/loss/steps-per-second/ETA, checkpoint-save events, stop events, and
244
+ verify results. Stop is cooperative at batch boundaries and save intervals
245
+ write a valid `.pth` plus sibling `.config.json`, so MLX stages can resume or
246
+ feed the PyTorch/export pipeline.
247
+
225
248
  The full six-stage comparison harness lives in `tools/compare_minimind_chronos_v3.py`.
226
249
 
227
250
  ---
@@ -254,9 +277,36 @@ d.describe() # human-readable capability summary
254
277
  - **First-class backends for training and inference**: `cpu`, `mps`, `cuda`, `mlx`
255
278
  - **Inference-only / experimental**: `vulkan` when PyTorch was custom-built with `USE_VULKAN=ON`
256
279
  - **Third-party extension hook**: `opencl`, via `chronos/backend/ext/opencl.py:PROBE()`
280
+ - **Apple Silicon policy**: inference auto still prefers MLX; training keeps MLX on the native `chronos.mlx.*` path instead of calling `torch.model.to("mlx")`.
257
281
 
258
282
  Honest note: upstream PyTorch does not ship a real OpenCL backend, and Vulkan support is still niche. Chronos provides a dispatcher seam so external integrations can plug in cleanly without touching core code.
259
283
 
284
+ ### MLX lazy/offload runtime
285
+
286
+ MLX uses Apple unified memory, so Chronos treats "VRAM" and "RAM" as logical
287
+ tiers rather than physical buses. The native lazy runtime still enforces the
288
+ same offload contract as CUDA/MPS/CPU:
289
+
290
+ - **Hot slots** hold only the execution-budget experts materialized as live
291
+ MLX modules.
292
+ - **Warm cache** holds a bounded prediction buffer loaded from `.ctsr`
293
+ safetensors, never a hidden copy of every expert.
294
+ - **Cold storage** is the checkpoint/export reader or per-expert cluster cache.
295
+ In lazy mode, live experts are replaced by placeholders after cache creation;
296
+ Chronos does not keep a `_saved_live` full-expert repair cache.
297
+ - Lookahead predictions are queued into the warm cache and only promoted when
298
+ ready. A true miss synchronously materializes the selected expert only; it
299
+ does not full-load the model.
300
+ - MLX attention dynamically grows RoPE lookup tables past
301
+ `max_position_embeddings`, so long prompts plus decode do not fail at token
302
+ 257/513/etc.
303
+
304
+ Inference compare/sweep reports real hot/warm counts, resident hit rate,
305
+ prediction hit rate, sync SSD loads, MLX active/cache/peak memory, process RSS,
306
+ prefill/decode time, and tokens/sec. A lazy run is not considered
307
+ offload-ready unless deterministic exact-lazy output matches full-DRAM output
308
+ and fallback weight stays zero.
309
+
260
310
  ---
261
311
 
262
312
  ## Hugging Face and vLLM compatibility (M5)
@@ -339,7 +389,7 @@ All lambda terms are searchable with Optuna TPE, together with structural hyperp
339
389
  ## Installation
340
390
 
341
391
  ```bash
342
- pip install project-chronos
392
+ pip install Project_Chronos
343
393
  ```
344
394
 
345
395
  Or from source:
@@ -353,7 +403,7 @@ pip install -e ".[dev]"
353
403
  **MLX (Apple Silicon):**
354
404
 
355
405
  ```bash
356
- pip install "project-chronos[mlx]"
406
+ pip install "Project_Chronos[mlx]"
357
407
  ```
358
408
 
359
409
  **vLLM serving (optional, Linux + CUDA only):**
@@ -372,7 +422,7 @@ pip install vllm
372
422
 
373
423
  ## Quick start
374
424
 
375
- ### Web UI (M6: 7 tabs, 4 languages)
425
+ ### Web UI (M6: 8 tabs, 4 languages)
376
426
 
377
427
  ```bash
378
428
  chronos-ui
@@ -386,12 +436,31 @@ Tabs included:
386
436
  - `Train` with its own `data_path`
387
437
  - `6-Stage Pipeline` with per-stage dataset paths
388
438
  - `Inference`
389
- - `Benchmark` with Markdown table + bar plot
439
+ - `Export` for FP16/Q8_0 safetensors and GGUF deployment artifacts
440
+ - `Benchmark` with Markdown table + comparison plots
390
441
  - `Auto-Tune` with persistent logs and one-click `Apply Best -> Config`
391
442
  - `IO Monitor`
392
443
 
393
444
  Built-in i18n: `zh-Hans`, `zh-Hant`, `en`, `ja`
394
445
 
446
+ ### Deployment export
447
+
448
+ ```bash
449
+ chronos export \
450
+ --model_path ./out/sft_384_moe.pth \
451
+ --output_dir ./exports/sft_384 \
452
+ --formats fp16-safetensors q8_0-safetensors fp16-gguf q8_0-gguf
453
+ ```
454
+
455
+ Exports include `config.json`, `chronos_export_manifest.json`, and Chronos
456
+ metadata for MoE top-k, shared fallback experts, lookahead router, hybrid
457
+ attention, and optional expert-cache layout. Chronos can load exported
458
+ `safetensors`/`GGUF` artifacts through its native lazy expert loader.
459
+
460
+ Compatibility note: the GGUF files use `general.architecture=chronos`. Stock
461
+ Ollama/llama.cpp builds need a Chronos architecture adapter to execute them
462
+ correctly; Chronos is not a LLaMA tensor-layout clone.
463
+
395
464
  ### Stage 1: pretrain
396
465
 
397
466
  ```bash
@@ -421,6 +490,32 @@ python train_chronos_distill.py \
421
490
  --alpha 0.7 --temperature 4.0
422
491
  ```
423
492
 
493
+ ### Checkpoint and offload diagnostics
494
+
495
+ Every new `.pth` checkpoint writes a sibling `*.config.json` with the MoE
496
+ topology that cannot be recovered from tensor shapes, including
497
+ `num_experts_per_tok`. Use the diagnostic command to verify chat-template
498
+ generation, no-mask vs all-available masked drift, cold shared fallback,
499
+ LookaheadRouter prediction quality, and SSD/RAM/VRAM offload stats.
500
+
501
+ ```bash
502
+ python diagnose_checkpoint.py \
503
+ --model_path ./out/sft_384_moe.pth \
504
+ --config_path ./chronos_config.json \
505
+ --sft_data ./Dataset/sft_t2t.jsonl \
506
+ --mlx_parity \
507
+ --device cpu
508
+
509
+ # or through the unified CLI:
510
+ chronos diagnose --model_path ./out/sft_384_moe.pth --config_path ./chronos_config.json
511
+ ```
512
+
513
+ For backend speed and dtype sanity checks:
514
+
515
+ ```bash
516
+ python benchmark_training_backends.py --backends cpu mps mlx --dtypes auto bfloat16 float16 --steps 2
517
+ ```
518
+
424
519
  ### End-to-end comparison (minimind vs Chronos)
425
520
 
426
521
  ```bash
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Project_Chronos
3
- Version: 0.1.1
3
+ Version: 0.2.0
4
4
  Summary: On-device low-latency lookahead dual-layer MoE inference — Lookahead Routing + Async Prefetch + Hybrid Attention
5
5
  License-Expression: Apache-2.0
6
6
  Keywords: llm,moe,inference,lookahead-routing,hybrid-attention,edge-ai
@@ -37,7 +37,7 @@ Dynamic: requires-python
37
37
 
38
38
  **A storage-aware MoE stack built for SSD+DRAM hybrid inference, with a full six-stage training pipeline.**
39
39
 
40
- [![PyPI](https://img.shields.io/pypi/v/project-chronos)](https://pypi.org/project/project-chronos/)
40
+ [![PyPI](https://img.shields.io/pypi/v/Project_Chronos)](https://pypi.org/project/Project_Chronos/)
41
41
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue)](LICENSE)
42
42
  [![Python](https://img.shields.io/badge/python-3.10%2B-blue)](https://python.org)
43
43
 
@@ -139,7 +139,7 @@ Even the worst case does not hard-stop generation:
139
139
  output = avail[i] * expert_output + (1.0 - avail[i]) * shared_expert_output
140
140
  ```
141
141
 
142
- The shared expert is always resident, so generation continues while the missing expert finishes loading in the background. Quality degrades smoothly and recovers automatically once the expert becomes available.
142
+ The shared expert is always resident, so generation continues while the missing expert finishes loading in the background. For exact lazy/offload comparison modes, Chronos synchronously materializes only the selected missing expert and evicts low-LRU experts to stay inside the resident budget; it does not silently full-load all experts. Quality degrades smoothly only when fallback mode is explicitly enabled.
143
143
 
144
144
  ---
145
145
 
@@ -222,6 +222,29 @@ flowchart LR
222
222
  | 5 GRPO | `train_chronos_grpo.py` | `PG * A - beta * KL` with `ToyReward` or pluggable `LMRewardModel` | 0.10 |
223
223
  | 6 Distill | `train_chronos_distill.py` | `alpha * T^2 * KL(student || teacher) + (1 - alpha) * CE` | 0.05 |
224
224
 
225
+ Training dtype and resource policy:
226
+
227
+ - `--dtype auto` is the default. MPS/MLX resolve to BF16-first for training stability, CUDA/XPU resolve to FP16, and CPU resolves to FP32 unless `--dtype float16` or `--dtype bfloat16` is set explicitly.
228
+ - CPU training configures PyTorch to use physical cores by default. Override with `--cpu_threads` or `--cpu_budget_percent`.
229
+ - On macOS, MPS/MLX training forces DataLoader workers to `0` by default to avoid Metal command-buffer crashes from multiprocessing. CPU/CUDA still use worker processes; advanced users can override the guard with `CHRONOS_ALLOW_METAL_DATALOADER_WORKERS=1`.
230
+ - Native MLX training pushes UI logs, scalar readouts, and chart points every `log_interval` steps, and Web UI Stop is checked at each batch boundary.
231
+ - The Web UI writes a warning-only `<checkpoint>.verify.json` after each stage. It checks no-mask vs all-available MoE parity and, on Apple Silicon, MLX prefill logits against the PyTorch CPU baseline.
232
+
233
+ Native MLX training is a separate Apple Silicon backend, not `torch.to("mlx")`.
234
+ The six-stage MLX trainer mirrors the PyTorch loss stack in `chronos.mlx.*`:
235
+ masked CE, DPO/ORPO/GRPO/distillation losses, load balance, temporal locality,
236
+ lookahead soft-target supervision, lookahead top-k hit loss, and router KL
237
+ anchor. Numerically sensitive pieces run in FP32 even when model weights use
238
+ BF16/FP16, which is why `auto` prefers BF16 on MLX/MPS: FP16 has too little
239
+ exponent range for router softmax, CE, and Adam moments on small unstable
240
+ training runs.
241
+
242
+ The MLX Web UI trainer reports the same fields as CPU/MPS training:
243
+ step/loss/steps-per-second/ETA, checkpoint-save events, stop events, and
244
+ verify results. Stop is cooperative at batch boundaries and save intervals
245
+ write a valid `.pth` plus sibling `.config.json`, so MLX stages can resume or
246
+ feed the PyTorch/export pipeline.
247
+
225
248
  The full six-stage comparison harness lives in `tools/compare_minimind_chronos_v3.py`.
226
249
 
227
250
  ---
@@ -254,9 +277,36 @@ d.describe() # human-readable capability summary
254
277
  - **First-class backends for training and inference**: `cpu`, `mps`, `cuda`, `mlx`
255
278
  - **Inference-only / experimental**: `vulkan` when PyTorch was custom-built with `USE_VULKAN=ON`
256
279
  - **Third-party extension hook**: `opencl`, via `chronos/backend/ext/opencl.py:PROBE()`
280
+ - **Apple Silicon policy**: inference auto still prefers MLX; training keeps MLX on the native `chronos.mlx.*` path instead of calling `torch.model.to("mlx")`.
257
281
 
258
282
  Honest note: upstream PyTorch does not ship a real OpenCL backend, and Vulkan support is still niche. Chronos provides a dispatcher seam so external integrations can plug in cleanly without touching core code.
259
283
 
284
+ ### MLX lazy/offload runtime
285
+
286
+ MLX uses Apple unified memory, so Chronos treats "VRAM" and "RAM" as logical
287
+ tiers rather than physical buses. The native lazy runtime still enforces the
288
+ same offload contract as CUDA/MPS/CPU:
289
+
290
+ - **Hot slots** hold only the execution-budget experts materialized as live
291
+ MLX modules.
292
+ - **Warm cache** holds a bounded prediction buffer loaded from `.ctsr`
293
+ safetensors, never a hidden copy of every expert.
294
+ - **Cold storage** is the checkpoint/export reader or per-expert cluster cache.
295
+ In lazy mode, live experts are replaced by placeholders after cache creation;
296
+ Chronos does not keep a `_saved_live` full-expert repair cache.
297
+ - Lookahead predictions are queued into the warm cache and only promoted when
298
+ ready. A true miss synchronously materializes the selected expert only; it
299
+ does not full-load the model.
300
+ - MLX attention dynamically grows RoPE lookup tables past
301
+ `max_position_embeddings`, so long prompts plus decode do not fail at token
302
+ 257/513/etc.
303
+
304
+ Inference compare/sweep reports real hot/warm counts, resident hit rate,
305
+ prediction hit rate, sync SSD loads, MLX active/cache/peak memory, process RSS,
306
+ prefill/decode time, and tokens/sec. A lazy run is not considered
307
+ offload-ready unless deterministic exact-lazy output matches full-DRAM output
308
+ and fallback weight stays zero.
309
+
260
310
  ---
261
311
 
262
312
  ## Hugging Face and vLLM compatibility (M5)
@@ -339,7 +389,7 @@ All lambda terms are searchable with Optuna TPE, together with structural hyperp
339
389
  ## Installation
340
390
 
341
391
  ```bash
342
- pip install project-chronos
392
+ pip install Project_Chronos
343
393
  ```
344
394
 
345
395
  Or from source:
@@ -353,7 +403,7 @@ pip install -e ".[dev]"
353
403
  **MLX (Apple Silicon):**
354
404
 
355
405
  ```bash
356
- pip install "project-chronos[mlx]"
406
+ pip install "Project_Chronos[mlx]"
357
407
  ```
358
408
 
359
409
  **vLLM serving (optional, Linux + CUDA only):**
@@ -372,7 +422,7 @@ pip install vllm
372
422
 
373
423
  ## Quick start
374
424
 
375
- ### Web UI (M6: 7 tabs, 4 languages)
425
+ ### Web UI (M6: 8 tabs, 4 languages)
376
426
 
377
427
  ```bash
378
428
  chronos-ui
@@ -386,12 +436,31 @@ Tabs included:
386
436
  - `Train` with its own `data_path`
387
437
  - `6-Stage Pipeline` with per-stage dataset paths
388
438
  - `Inference`
389
- - `Benchmark` with Markdown table + bar plot
439
+ - `Export` for FP16/Q8_0 safetensors and GGUF deployment artifacts
440
+ - `Benchmark` with Markdown table + comparison plots
390
441
  - `Auto-Tune` with persistent logs and one-click `Apply Best -> Config`
391
442
  - `IO Monitor`
392
443
 
393
444
  Built-in i18n: `zh-Hans`, `zh-Hant`, `en`, `ja`
394
445
 
446
+ ### Deployment export
447
+
448
+ ```bash
449
+ chronos export \
450
+ --model_path ./out/sft_384_moe.pth \
451
+ --output_dir ./exports/sft_384 \
452
+ --formats fp16-safetensors q8_0-safetensors fp16-gguf q8_0-gguf
453
+ ```
454
+
455
+ Exports include `config.json`, `chronos_export_manifest.json`, and Chronos
456
+ metadata for MoE top-k, shared fallback experts, lookahead router, hybrid
457
+ attention, and optional expert-cache layout. Chronos can load exported
458
+ `safetensors`/`GGUF` artifacts through its native lazy expert loader.
459
+
460
+ Compatibility note: the GGUF files use `general.architecture=chronos`. Stock
461
+ Ollama/llama.cpp builds need a Chronos architecture adapter to execute them
462
+ correctly; Chronos is not a LLaMA tensor-layout clone.
463
+
395
464
  ### Stage 1: pretrain
396
465
 
397
466
  ```bash
@@ -421,6 +490,32 @@ python train_chronos_distill.py \
421
490
  --alpha 0.7 --temperature 4.0
422
491
  ```
423
492
 
493
+ ### Checkpoint and offload diagnostics
494
+
495
+ Every new `.pth` checkpoint writes a sibling `*.config.json` with the MoE
496
+ topology that cannot be recovered from tensor shapes, including
497
+ `num_experts_per_tok`. Use the diagnostic command to verify chat-template
498
+ generation, no-mask vs all-available masked drift, cold shared fallback,
499
+ LookaheadRouter prediction quality, and SSD/RAM/VRAM offload stats.
500
+
501
+ ```bash
502
+ python diagnose_checkpoint.py \
503
+ --model_path ./out/sft_384_moe.pth \
504
+ --config_path ./chronos_config.json \
505
+ --sft_data ./Dataset/sft_t2t.jsonl \
506
+ --mlx_parity \
507
+ --device cpu
508
+
509
+ # or through the unified CLI:
510
+ chronos diagnose --model_path ./out/sft_384_moe.pth --config_path ./chronos_config.json
511
+ ```
512
+
513
+ For backend speed and dtype sanity checks:
514
+
515
+ ```bash
516
+ python benchmark_training_backends.py --backends cpu mps mlx --dtypes auto bfloat16 float16 --steps 2
517
+ ```
518
+
424
519
  ### End-to-end comparison (minimind vs Chronos)
425
520
 
426
521
  ```bash
@@ -21,8 +21,11 @@ chronos/_backend_legacy.py
21
21
  chronos/app.py
22
22
  chronos/cli.py
23
23
  chronos/deps.py
24
+ chronos/export.py
25
+ chronos/verify.py
24
26
  chronos/backend/__init__.py
25
27
  chronos/backend/dispatcher.py
28
+ chronos/backend/mac_diagnostics.py
26
29
  chronos/backend/ext/__init__.py
27
30
  chronos/backend/ext/opencl.py
28
31
  chronos/data/__init__.py
@@ -42,7 +45,11 @@ chronos/mlx/expert_store.py
42
45
  chronos/mlx/inference.py
43
46
  chronos/mlx/model.py
44
47
  chronos/mlx/moe.py
48
+ chronos/mlx/training/__init__.py
49
+ chronos/mlx/training/io.py
50
+ chronos/mlx/training/trainer.py
45
51
  chronos/model/__init__.py
52
+ chronos/model/checkpoint.py
46
53
  chronos/model/config.py
47
54
  chronos/model/hf_io.py
48
55
  chronos/model/hybrid_attention.py
@@ -62,6 +69,7 @@ chronos/serving/__init__.py
62
69
  chronos/serving/vllm_adapter.py
63
70
  chronos/trainer/__init__.py
64
71
  chronos/trainer/chronos_trainer.py
72
+ chronos/trainer/device_utils.py
65
73
  chronos/trainer/distill_trainer.py
66
74
  chronos/trainer/dpo_trainer.py
67
75
  chronos/trainer/grpo_trainer.py
@@ -70,6 +78,7 @@ chronos/trainer/optim_utils.py
70
78
  chronos/trainer/orpo_trainer.py
71
79
  chronos/trainer/reward.py
72
80
  chronos/trainer/sft_trainer.py
81
+ chronos/trainer/stage_utils.py
73
82
  chronos/tuning/__init__.py
74
83
  chronos/tuning/_base_tuner.py
75
84
  chronos/tuning/chronos_auto_tuner.py
@@ -85,6 +94,7 @@ ui/tabs/autotune_tab.py
85
94
  ui/tabs/benchmark_tab.py
86
95
  ui/tabs/config_tab.py
87
96
  ui/tabs/data_tab.py
97
+ ui/tabs/export_tab.py
88
98
  ui/tabs/inference_tab.py
89
99
  ui/tabs/iomon_tab.py
90
100
  ui/tabs/pipeline_tab.py
@@ -2,7 +2,7 @@
2
2
 
3
3
  **A storage-aware MoE stack built for SSD+DRAM hybrid inference, with a full six-stage training pipeline.**
4
4
 
5
- [![PyPI](https://img.shields.io/pypi/v/project-chronos)](https://pypi.org/project/project-chronos/)
5
+ [![PyPI](https://img.shields.io/pypi/v/Project_Chronos)](https://pypi.org/project/Project_Chronos/)
6
6
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue)](LICENSE)
7
7
  [![Python](https://img.shields.io/badge/python-3.10%2B-blue)](https://python.org)
8
8
 
@@ -104,7 +104,7 @@ Even the worst case does not hard-stop generation:
104
104
  output = avail[i] * expert_output + (1.0 - avail[i]) * shared_expert_output
105
105
  ```
106
106
 
107
- The shared expert is always resident, so generation continues while the missing expert finishes loading in the background. Quality degrades smoothly and recovers automatically once the expert becomes available.
107
+ The shared expert is always resident, so generation continues while the missing expert finishes loading in the background. For exact lazy/offload comparison modes, Chronos synchronously materializes only the selected missing expert and evicts low-LRU experts to stay inside the resident budget; it does not silently full-load all experts. Quality degrades smoothly only when fallback mode is explicitly enabled.
108
108
 
109
109
  ---
110
110
 
@@ -187,6 +187,29 @@ flowchart LR
187
187
  | 5 GRPO | `train_chronos_grpo.py` | `PG * A - beta * KL` with `ToyReward` or pluggable `LMRewardModel` | 0.10 |
188
188
  | 6 Distill | `train_chronos_distill.py` | `alpha * T^2 * KL(student || teacher) + (1 - alpha) * CE` | 0.05 |
189
189
 
190
+ Training dtype and resource policy:
191
+
192
+ - `--dtype auto` is the default. MPS/MLX resolve to BF16-first for training stability, CUDA/XPU resolve to FP16, and CPU resolves to FP32 unless `--dtype float16` or `--dtype bfloat16` is set explicitly.
193
+ - CPU training configures PyTorch to use physical cores by default. Override with `--cpu_threads` or `--cpu_budget_percent`.
194
+ - On macOS, MPS/MLX training forces DataLoader workers to `0` by default to avoid Metal command-buffer crashes from multiprocessing. CPU/CUDA still use worker processes; advanced users can override the guard with `CHRONOS_ALLOW_METAL_DATALOADER_WORKERS=1`.
195
+ - Native MLX training pushes UI logs, scalar readouts, and chart points every `log_interval` steps, and Web UI Stop is checked at each batch boundary.
196
+ - The Web UI writes a warning-only `<checkpoint>.verify.json` after each stage. It checks no-mask vs all-available MoE parity and, on Apple Silicon, MLX prefill logits against the PyTorch CPU baseline.
197
+
198
+ Native MLX training is a separate Apple Silicon backend, not `torch.to("mlx")`.
199
+ The six-stage MLX trainer mirrors the PyTorch loss stack in `chronos.mlx.*`:
200
+ masked CE, DPO/ORPO/GRPO/distillation losses, load balance, temporal locality,
201
+ lookahead soft-target supervision, lookahead top-k hit loss, and router KL
202
+ anchor. Numerically sensitive pieces run in FP32 even when model weights use
203
+ BF16/FP16, which is why `auto` prefers BF16 on MLX/MPS: FP16 has too little
204
+ exponent range for router softmax, CE, and Adam moments on small unstable
205
+ training runs.
206
+
207
+ The MLX Web UI trainer reports the same fields as CPU/MPS training:
208
+ step/loss/steps-per-second/ETA, checkpoint-save events, stop events, and
209
+ verify results. Stop is cooperative at batch boundaries and save intervals
210
+ write a valid `.pth` plus sibling `.config.json`, so MLX stages can resume or
211
+ feed the PyTorch/export pipeline.
212
+
190
213
  The full six-stage comparison harness lives in `tools/compare_minimind_chronos_v3.py`.
191
214
 
192
215
  ---
@@ -219,9 +242,36 @@ d.describe() # human-readable capability summary
219
242
  - **First-class backends for training and inference**: `cpu`, `mps`, `cuda`, `mlx`
220
243
  - **Inference-only / experimental**: `vulkan` when PyTorch was custom-built with `USE_VULKAN=ON`
221
244
  - **Third-party extension hook**: `opencl`, via `chronos/backend/ext/opencl.py:PROBE()`
245
+ - **Apple Silicon policy**: inference auto still prefers MLX; training keeps MLX on the native `chronos.mlx.*` path instead of calling `torch.model.to("mlx")`.
222
246
 
223
247
  Honest note: upstream PyTorch does not ship a real OpenCL backend, and Vulkan support is still niche. Chronos provides a dispatcher seam so external integrations can plug in cleanly without touching core code.
224
248
 
249
+ ### MLX lazy/offload runtime
250
+
251
+ MLX uses Apple unified memory, so Chronos treats "VRAM" and "RAM" as logical
252
+ tiers rather than physical buses. The native lazy runtime still enforces the
253
+ same offload contract as CUDA/MPS/CPU:
254
+
255
+ - **Hot slots** hold only the execution-budget experts materialized as live
256
+ MLX modules.
257
+ - **Warm cache** holds a bounded prediction buffer loaded from `.ctsr`
258
+ safetensors, never a hidden copy of every expert.
259
+ - **Cold storage** is the checkpoint/export reader or per-expert cluster cache.
260
+ In lazy mode, live experts are replaced by placeholders after cache creation;
261
+ Chronos does not keep a `_saved_live` full-expert repair cache.
262
+ - Lookahead predictions are queued into the warm cache and only promoted when
263
+ ready. A true miss synchronously materializes the selected expert only; it
264
+ does not full-load the model.
265
+ - MLX attention dynamically grows RoPE lookup tables past
266
+ `max_position_embeddings`, so long prompts plus decode do not fail at token
267
+ 257/513/etc.
268
+
269
+ Inference compare/sweep reports real hot/warm counts, resident hit rate,
270
+ prediction hit rate, sync SSD loads, MLX active/cache/peak memory, process RSS,
271
+ prefill/decode time, and tokens/sec. A lazy run is not considered
272
+ offload-ready unless deterministic exact-lazy output matches full-DRAM output
273
+ and fallback weight stays zero.
274
+
225
275
  ---
226
276
 
227
277
  ## Hugging Face and vLLM compatibility (M5)
@@ -304,7 +354,7 @@ All lambda terms are searchable with Optuna TPE, together with structural hyperp
304
354
  ## Installation
305
355
 
306
356
  ```bash
307
- pip install project-chronos
357
+ pip install Project_Chronos
308
358
  ```
309
359
 
310
360
  Or from source:
@@ -318,7 +368,7 @@ pip install -e ".[dev]"
318
368
  **MLX (Apple Silicon):**
319
369
 
320
370
  ```bash
321
- pip install "project-chronos[mlx]"
371
+ pip install "Project_Chronos[mlx]"
322
372
  ```
323
373
 
324
374
  **vLLM serving (optional, Linux + CUDA only):**
@@ -337,7 +387,7 @@ pip install vllm
337
387
 
338
388
  ## Quick start
339
389
 
340
- ### Web UI (M6: 7 tabs, 4 languages)
390
+ ### Web UI (M6: 8 tabs, 4 languages)
341
391
 
342
392
  ```bash
343
393
  chronos-ui
@@ -351,12 +401,31 @@ Tabs included:
351
401
  - `Train` with its own `data_path`
352
402
  - `6-Stage Pipeline` with per-stage dataset paths
353
403
  - `Inference`
354
- - `Benchmark` with Markdown table + bar plot
404
+ - `Export` for FP16/Q8_0 safetensors and GGUF deployment artifacts
405
+ - `Benchmark` with Markdown table + comparison plots
355
406
  - `Auto-Tune` with persistent logs and one-click `Apply Best -> Config`
356
407
  - `IO Monitor`
357
408
 
358
409
  Built-in i18n: `zh-Hans`, `zh-Hant`, `en`, `ja`
359
410
 
411
+ ### Deployment export
412
+
413
+ ```bash
414
+ chronos export \
415
+ --model_path ./out/sft_384_moe.pth \
416
+ --output_dir ./exports/sft_384 \
417
+ --formats fp16-safetensors q8_0-safetensors fp16-gguf q8_0-gguf
418
+ ```
419
+
420
+ Exports include `config.json`, `chronos_export_manifest.json`, and Chronos
421
+ metadata for MoE top-k, shared fallback experts, lookahead router, hybrid
422
+ attention, and optional expert-cache layout. Chronos can load exported
423
+ `safetensors`/`GGUF` artifacts through its native lazy expert loader.
424
+
425
+ Compatibility note: the GGUF files use `general.architecture=chronos`. Stock
426
+ Ollama/llama.cpp builds need a Chronos architecture adapter to execute them
427
+ correctly; Chronos is not a LLaMA tensor-layout clone.
428
+
360
429
  ### Stage 1: pretrain
361
430
 
362
431
  ```bash
@@ -386,6 +455,32 @@ python train_chronos_distill.py \
386
455
  --alpha 0.7 --temperature 4.0
387
456
  ```
388
457
 
458
+ ### Checkpoint and offload diagnostics
459
+
460
+ Every new `.pth` checkpoint writes a sibling `*.config.json` with the MoE
461
+ topology that cannot be recovered from tensor shapes, including
462
+ `num_experts_per_tok`. Use the diagnostic command to verify chat-template
463
+ generation, no-mask vs all-available masked drift, cold shared fallback,
464
+ LookaheadRouter prediction quality, and SSD/RAM/VRAM offload stats.
465
+
466
+ ```bash
467
+ python diagnose_checkpoint.py \
468
+ --model_path ./out/sft_384_moe.pth \
469
+ --config_path ./chronos_config.json \
470
+ --sft_data ./Dataset/sft_t2t.jsonl \
471
+ --mlx_parity \
472
+ --device cpu
473
+
474
+ # or through the unified CLI:
475
+ chronos diagnose --model_path ./out/sft_384_moe.pth --config_path ./chronos_config.json
476
+ ```
477
+
478
+ For backend speed and dtype sanity checks:
479
+
480
+ ```bash
481
+ python benchmark_training_backends.py --backends cpu mps mlx --dtypes auto bfloat16 float16 --steps 2
482
+ ```
483
+
389
484
  ### End-to-end comparison (minimind vs Chronos)
390
485
 
391
486
  ```bash
@@ -18,6 +18,21 @@ _pkg_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
18
18
  if _pkg_root not in sys.path:
19
19
  sys.path.insert(0, _pkg_root)
20
20
 
21
+ from chronos.trainer.device_utils import (
22
+ configure_cpu_thread_env,
23
+ configure_cpu_threads,
24
+ cpu_thread_snapshot,
25
+ )
26
+
27
+ # Configure CPU thread pools before importing Gradio/UI modules that may pull
28
+ # in numpy/torch-heavy dependencies. Training can still override this from the
29
+ # Config tab, but the process starts from a multi-thread policy instead of a
30
+ # shell-provided OMP_NUM_THREADS=1.
31
+ _BOOT_CPU_THREADS = configure_cpu_thread_env(
32
+ os.environ.get("CHRONOS_UI_CPU_THREADS", "auto"),
33
+ budget_percent=os.environ.get("CHRONOS_CPU_BUDGET_PERCENT", 100),
34
+ )
35
+
21
36
  from ui.gradio_compat import gr
22
37
 
23
38
  import chronos.deps # auto-bootstrap minimind
@@ -28,6 +43,7 @@ from ui.i18n import (
28
43
  from ui.tabs.config_tab import build_config_tab
29
44
  from ui.tabs.train_tab import build_train_tab
30
45
  from ui.tabs.inference_tab import build_inference_tab
46
+ from ui.tabs.export_tab import build_export_tab
31
47
  from ui.tabs.benchmark_tab import build_benchmark_tab
32
48
  from ui.tabs.autotune_tab import build_autotune_tab
33
49
  from ui.tabs.iomon_tab import build_iomon_tab
@@ -85,6 +101,7 @@ def build_app() -> gr.Blocks:
85
101
  build_train_tab(config_state, cfg_save_dir)
86
102
  build_pipeline_tab()
87
103
  build_inference_tab(config_state)
104
+ build_export_tab()
88
105
  build_benchmark_tab()
89
106
  build_autotune_tab(config_state, config_inputs)
90
107
  build_iomon_tab()
@@ -107,8 +124,18 @@ def main():
107
124
  parser.add_argument("--port", type=int, default=7860)
108
125
  parser.add_argument("--host", type=str, default="127.0.0.1")
109
126
  parser.add_argument("--share", action="store_true")
127
+ parser.add_argument("--cpu-threads", default="auto",
128
+ help="PyTorch/BLAS CPU threads for the WebUI process.")
129
+ parser.add_argument("--cpu-budget-percent", type=float, default=100,
130
+ help="CPU physical-core budget used when --cpu-threads=auto.")
110
131
  args = parser.parse_args()
111
132
 
133
+ threads = configure_cpu_threads(args.cpu_threads, budget_percent=args.cpu_budget_percent)
134
+ print(
135
+ f"[Chronos UI] CPU threads configured: {threads} "
136
+ f"(boot={_BOOT_CPU_THREADS}); {cpu_thread_snapshot()}"
137
+ )
138
+
112
139
  app = build_app()
113
140
  app.launch(
114
141
  server_name=args.host,
@@ -20,6 +20,12 @@ from chronos.backend.dispatcher import (
20
20
  AUTO_PRIORITY,
21
21
  TRAINING_AUTO_PRIORITY,
22
22
  )
23
+ from chronos.backend.mac_diagnostics import (
24
+ mac_backend_diagnostics,
25
+ mlx_memory_snapshot,
26
+ mps_memory_snapshot,
27
+ rss_snapshot,
28
+ )
23
29
 
24
30
  # Back-compat shim for the pre-M5 API that code elsewhere still calls.
25
31
  from chronos._backend_legacy import build_model, BackendType # type: ignore
@@ -35,6 +41,7 @@ __all__ = [
35
41
  "available", "select", "training_available", "select_training",
36
42
  "device_str", "training_device_str", "resolve_training_device",
37
43
  "describe", "describe_training",
44
+ "mac_backend_diagnostics", "mlx_memory_snapshot", "mps_memory_snapshot", "rss_snapshot",
38
45
  "AUTO_PRIORITY", "TRAINING_AUTO_PRIORITY",
39
46
  "get_backend", "build_model", "BackendType",
40
47
  ]