magicmindnet 0.2.0__tar.gz → 0.2.1__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 (141) hide show
  1. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/Cargo.lock +11 -11
  2. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/Cargo.toml +1 -1
  3. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/PKG-INFO +4 -2
  4. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/README.md +3 -1
  5. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/block_tensors.rs +71 -1
  6. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/chatbot_io.rs +142 -3
  7. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/hf_safetensors.rs +2 -1
  8. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-models/src/chatbot.rs +358 -43
  9. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-models/src/lib.rs +1 -0
  10. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-nn/src/kv_cache.rs +44 -1
  11. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-nn/src/lib.rs +40 -22
  12. magicmindnet-0.2.1/crates/mmn-py/src/encoder_util.rs +30 -0
  13. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-py/src/models/chatbot.rs +60 -15
  14. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-py/src/tokenizer.rs +82 -0
  15. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-py/src/train/mod.rs +10 -7
  16. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/pyproject.toml +1 -1
  17. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/__init__.py +1 -1
  18. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/_native.pyi +27 -0
  19. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/eval/tasks_lm.py +57 -0
  20. magicmindnet-0.2.0/crates/mmn-py/src/encoder_util.rs +0 -19
  21. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/LICENSE +0 -0
  22. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-core/Cargo.toml +0 -0
  23. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-core/src/autograd.rs +0 -0
  24. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-core/src/device.rs +0 -0
  25. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-core/src/dtype.rs +0 -0
  26. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-core/src/elementwise.rs +0 -0
  27. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-core/src/error.rs +0 -0
  28. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-core/src/lib.rs +0 -0
  29. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-core/src/ops.rs +0 -0
  30. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-core/src/tensor.rs +0 -0
  31. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-cuda/Cargo.toml +0 -0
  32. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-cuda/src/lib.rs +0 -0
  33. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-data/Cargo.toml +0 -0
  34. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-data/src/bpe.rs +0 -0
  35. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-data/src/chatxml.rs +0 -0
  36. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-data/src/dataset.rs +0 -0
  37. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-data/src/encoder.rs +0 -0
  38. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-data/src/error.rs +0 -0
  39. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-data/src/gpt2_bpe.rs +0 -0
  40. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-data/src/lib.rs +0 -0
  41. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-data/src/unigram.rs +0 -0
  42. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-data/src/vision.rs +0 -0
  43. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/Cargo.toml +0 -0
  44. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/checkpoint_util.rs +0 -0
  45. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/classifier_io.rs +0 -0
  46. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/detect.rs +0 -0
  47. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/diffusion_io.rs +0 -0
  48. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/hf_adapt.rs +0 -0
  49. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/hf_classifier_safetensors.rs +0 -0
  50. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/hf_tensor_codec.rs +0 -0
  51. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/arrays_auto.rs +0 -0
  52. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/blosc.rs +0 -0
  53. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/blosclz.rs +0 -0
  54. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/deflate.rs +0 -0
  55. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/flax.rs +0 -0
  56. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/ggml_legacy.rs +0 -0
  57. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/gguf.rs +0 -0
  58. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/gguf_chatbot.rs +0 -0
  59. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/gguf_info.rs +0 -0
  60. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/gguf_iq_grids.rs +0 -0
  61. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/gguf_quant.rs +0 -0
  62. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/gguf_quant_iq.rs +0 -0
  63. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/gguf_quant_k_encode.rs +0 -0
  64. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/hdf5.rs +0 -0
  65. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/hdf5_write.rs +0 -0
  66. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/inflate.rs +0 -0
  67. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/lz4.rs +0 -0
  68. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/mod.rs +0 -0
  69. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/msgpack.rs +0 -0
  70. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/npy.rs +0 -0
  71. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/npz_chatbot.rs +0 -0
  72. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/onnx.rs +0 -0
  73. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/pickle.rs +0 -0
  74. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/pickle_arrays.rs +0 -0
  75. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/proto.rs +0 -0
  76. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/sharded.rs +0 -0
  77. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/snappy.rs +0 -0
  78. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/st_arrays.rs +0 -0
  79. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/tf_checkpoint.rs +0 -0
  80. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/tflite.rs +0 -0
  81. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/torch_pt.rs +0 -0
  82. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/zarr.rs +0 -0
  83. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/zip.rs +0 -0
  84. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/interop/zstd.rs +0 -0
  85. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/io_tests/chatbot_io_tests.rs +0 -0
  86. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/io_tests/classifier_io_tests.rs +0 -0
  87. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/io_tests/diffusion_io_tests.rs +0 -0
  88. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/io_tests/helpers.rs +0 -0
  89. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/io_tests/mod.rs +0 -0
  90. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/lib.rs +0 -0
  91. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/mmn_json.rs +0 -0
  92. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/st_codec.rs +0 -0
  93. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-io/src/tensor_merge.rs +0 -0
  94. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-models/Cargo.toml +0 -0
  95. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-models/src/autoset.rs +0 -0
  96. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-nn/Cargo.toml +0 -0
  97. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-ops/Cargo.toml +0 -0
  98. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-ops/src/lib.rs +0 -0
  99. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-optim/Cargo.toml +0 -0
  100. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-optim/src/lib.rs +0 -0
  101. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-py/Cargo.toml +0 -0
  102. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-py/src/datasets/classification.rs +0 -0
  103. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-py/src/datasets/corpus.rs +0 -0
  104. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-py/src/datasets/image.rs +0 -0
  105. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-py/src/datasets/mod.rs +0 -0
  106. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-py/src/datasets/qa.rs +0 -0
  107. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-py/src/errors.rs +0 -0
  108. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-py/src/io/mod.rs +0 -0
  109. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-py/src/lib.rs +0 -0
  110. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-py/src/models/classifier.rs +0 -0
  111. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-py/src/models/diffusion.rs +0 -0
  112. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-py/src/models/mod.rs +0 -0
  113. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-py/src/resource.rs +0 -0
  114. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-py/src/train_config.rs +0 -0
  115. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-py/src/vision.rs +0 -0
  116. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-resource/Cargo.toml +0 -0
  117. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-resource/src/lib.rs +0 -0
  118. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-train/Cargo.toml +0 -0
  119. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-train/src/generate.rs +0 -0
  120. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-train/src/json_constrain.rs +0 -0
  121. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/crates/mmn-train/src/lib.rs +0 -0
  122. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/bpe_io.py +0 -0
  123. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/chat.py +0 -0
  124. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/eval/__init__.py +0 -0
  125. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/eval/__main__.py +0 -0
  126. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/eval/_util.py +0 -0
  127. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/eval/registry.py +0 -0
  128. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/eval/runner.py +0 -0
  129. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/eval/tasks_cls.py +0 -0
  130. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/eval/tasks_diffusion.py +0 -0
  131. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/eval/tasks_extra.py +0 -0
  132. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/eval/tasks_hub.py +0 -0
  133. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/eval/tasks_io.py +0 -0
  134. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/eval/tasks_rl.py +0 -0
  135. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/eval/types.py +0 -0
  136. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/hub.py +0 -0
  137. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/interop.py +0 -0
  138. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/py.typed +0 -0
  139. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/serve.py +0 -0
  140. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/unigram_io.py +0 -0
  141. {magicmindnet-0.2.0 → magicmindnet-0.2.1}/python/magicmindnet/vision.py +0 -0
@@ -723,7 +723,7 @@ dependencies = [
723
723
 
724
724
  [[package]]
725
725
  name = "mmn-core"
726
- version = "0.2.0"
726
+ version = "0.2.1"
727
727
  dependencies = [
728
728
  "half",
729
729
  "ndarray",
@@ -733,7 +733,7 @@ dependencies = [
733
733
 
734
734
  [[package]]
735
735
  name = "mmn-cuda"
736
- version = "0.2.0"
736
+ version = "0.2.1"
737
737
  dependencies = [
738
738
  "cudarc",
739
739
  "mmn-core",
@@ -743,7 +743,7 @@ dependencies = [
743
743
 
744
744
  [[package]]
745
745
  name = "mmn-data"
746
- version = "0.2.0"
746
+ version = "0.2.1"
747
747
  dependencies = [
748
748
  "arrow",
749
749
  "image",
@@ -757,7 +757,7 @@ dependencies = [
757
757
 
758
758
  [[package]]
759
759
  name = "mmn-io"
760
- version = "0.2.0"
760
+ version = "0.2.1"
761
761
  dependencies = [
762
762
  "half",
763
763
  "mmn-core",
@@ -771,7 +771,7 @@ dependencies = [
771
771
 
772
772
  [[package]]
773
773
  name = "mmn-models"
774
- version = "0.2.0"
774
+ version = "0.2.1"
775
775
  dependencies = [
776
776
  "mmn-core",
777
777
  "mmn-data",
@@ -785,7 +785,7 @@ dependencies = [
785
785
 
786
786
  [[package]]
787
787
  name = "mmn-nn"
788
- version = "0.2.0"
788
+ version = "0.2.1"
789
789
  dependencies = [
790
790
  "mmn-core",
791
791
  "mmn-ops",
@@ -795,7 +795,7 @@ dependencies = [
795
795
 
796
796
  [[package]]
797
797
  name = "mmn-ops"
798
- version = "0.2.0"
798
+ version = "0.2.1"
799
799
  dependencies = [
800
800
  "mmn-core",
801
801
  "mmn-cuda",
@@ -804,7 +804,7 @@ dependencies = [
804
804
 
805
805
  [[package]]
806
806
  name = "mmn-optim"
807
- version = "0.2.0"
807
+ version = "0.2.1"
808
808
  dependencies = [
809
809
  "half",
810
810
  "mmn-core",
@@ -814,7 +814,7 @@ dependencies = [
814
814
 
815
815
  [[package]]
816
816
  name = "mmn-py"
817
- version = "0.2.0"
817
+ version = "0.2.1"
818
818
  dependencies = [
819
819
  "mmn-core",
820
820
  "mmn-cuda",
@@ -833,7 +833,7 @@ dependencies = [
833
833
 
834
834
  [[package]]
835
835
  name = "mmn-resource"
836
- version = "0.2.0"
836
+ version = "0.2.1"
837
837
  dependencies = [
838
838
  "libc",
839
839
  "mmn-core",
@@ -843,7 +843,7 @@ dependencies = [
843
843
 
844
844
  [[package]]
845
845
  name = "mmn-train"
846
- version = "0.2.0"
846
+ version = "0.2.1"
847
847
  dependencies = [
848
848
  "image",
849
849
  "mmn-core",
@@ -3,7 +3,7 @@ resolver = "2"
3
3
  members = ["crates/mmn-core", "crates/mmn-ops", "crates/mmn-cuda", "crates/mmn-optim", "crates/mmn-data", "crates/mmn-nn", "crates/mmn-models", "crates/mmn-train", "crates/mmn-io", "crates/mmn-resource", "crates/mmn-py"]
4
4
 
5
5
  [workspace.package]
6
- version = "0.2.0"
6
+ version = "0.2.1"
7
7
  edition = "2021"
8
8
  license = "GPL-3.0-or-later"
9
9
  license-file = "LICENSE"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: magicmindnet
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: Intended Audience :: Education
@@ -229,7 +229,7 @@ pip install magicmindnet
229
229
  pip install "magicmindnet[hub]" # transformers / diffusers / modelscope
230
230
  ```
231
231
 
232
- Package metadata: version **0.2.0**, console scripts `mmn-serve` and `mmn-eval`, typed stubs (`py.typed`).
232
+ Package metadata: version **0.2.1**, console scripts `mmn-serve` and `mmn-eval`, typed stubs (`py.typed`).
233
233
 
234
234
  ### Editable / from source
235
235
 
@@ -368,6 +368,8 @@ Format details: [docs/checkpoints.md](docs/checkpoints.md).
368
368
  | `examples/learned_pos_embed_roundtrip.py` | Learned `pos_embed` export → import + loss parity |
369
369
  | `examples/rope_roundtrip.py` | RoPE chatbot export → import + loss parity |
370
370
  | `examples/classifier_roundtrip.py` | Classifier export → import |
371
+ | `examples/train_glint2.py` | Glint-2 exact training (looped, RMS, SwiGLU, coda, window, BPE) |
372
+ | `examples/generate_glint2.py` | Generate with a trained Glint-2 MagicMindNet checkpoint |
371
373
 
372
374
  Full catalog: [examples/README.md](examples/README.md).
373
375
 
@@ -183,7 +183,7 @@ pip install magicmindnet
183
183
  pip install "magicmindnet[hub]" # transformers / diffusers / modelscope
184
184
  ```
185
185
 
186
- Package metadata: version **0.2.0**, console scripts `mmn-serve` and `mmn-eval`, typed stubs (`py.typed`).
186
+ Package metadata: version **0.2.1**, console scripts `mmn-serve` and `mmn-eval`, typed stubs (`py.typed`).
187
187
 
188
188
  ### Editable / from source
189
189
 
@@ -322,6 +322,8 @@ Format details: [docs/checkpoints.md](docs/checkpoints.md).
322
322
  | `examples/learned_pos_embed_roundtrip.py` | Learned `pos_embed` export → import + loss parity |
323
323
  | `examples/rope_roundtrip.py` | RoPE chatbot export → import + loss parity |
324
324
  | `examples/classifier_roundtrip.py` | Classifier export → import |
325
+ | `examples/train_glint2.py` | Glint-2 exact training (looped, RMS, SwiGLU, coda, window, BPE) |
326
+ | `examples/generate_glint2.py` | Generate with a trained Glint-2 MagicMindNet checkpoint |
325
327
 
326
328
  Full catalog: [examples/README.md](examples/README.md).
327
329
 
@@ -4,7 +4,77 @@ use crate::checkpoint_util::{
4
4
  expect_tensor_shape, require_tensor_entry, tensor_from_entry, tensor_to_entry, TensorMap,
5
5
  };
6
6
  use mmn_core::{MmnError, Tensor};
7
- use mmn_models::Chatbot;
7
+ use mmn_models::{Chatbot, TransformerBlock};
8
+
9
+ /// Export a list of blocks with a custom prefix (e.g. "prelude" or "coda").
10
+ pub(crate) fn export_named_block_list(blocks: &[TransformerBlock], prefix: &str, map: &mut TensorMap) {
11
+ for (i, block) in blocks.iter().enumerate() {
12
+ let p = format!("{prefix}.{i}");
13
+ map.insert(format!("{p}.attn.q"), tensor_to_entry(&block.attn.q_proj.weight));
14
+ map.insert(format!("{p}.attn.k"), tensor_to_entry(&block.attn.k_proj.weight));
15
+ map.insert(format!("{p}.attn.v"), tensor_to_entry(&block.attn.v_proj.weight));
16
+ map.insert(format!("{p}.attn.out"), tensor_to_entry(&block.attn.out_proj.weight));
17
+ map.insert(format!("{p}.ffn"), tensor_to_entry(&block.ffn.weight));
18
+ map.insert(format!("{p}.ffn2"), tensor_to_entry(&block.ffn2.weight));
19
+ if let Some(gate) = &block.ffn_gate {
20
+ map.insert(format!("{p}.ffn_gate"), tensor_to_entry(&gate.weight));
21
+ }
22
+ map.insert(format!("{p}.ln1.gamma"), tensor_to_entry(&block.ln1.gamma));
23
+ map.insert(format!("{p}.ln1.beta"), tensor_to_entry(&block.ln1.beta));
24
+ map.insert(format!("{p}.ln2.gamma"), tensor_to_entry(&block.ln2.gamma));
25
+ map.insert(format!("{p}.ln2.beta"), tensor_to_entry(&block.ln2.beta));
26
+ }
27
+ }
28
+
29
+ /// Import a list of blocks with a custom prefix (e.g. "prelude" or "coda").
30
+ pub(crate) fn import_named_block_list(
31
+ blocks: &mut [TransformerBlock],
32
+ prefix: &str,
33
+ tensors: &TensorMap,
34
+ d_model: usize,
35
+ ffn_dim: usize,
36
+ q_dim: usize,
37
+ kv_dim: usize,
38
+ use_rms: bool,
39
+ ) -> Result<(), MmnError> {
40
+ for (i, block) in blocks.iter_mut().enumerate() {
41
+ let p = format!("{prefix}.{i}");
42
+ let keys: [(&str, &mut Tensor); 10] = [
43
+ ("attn.q", &mut block.attn.q_proj.weight),
44
+ ("attn.k", &mut block.attn.k_proj.weight),
45
+ ("attn.v", &mut block.attn.v_proj.weight),
46
+ ("attn.out", &mut block.attn.out_proj.weight),
47
+ ("ffn", &mut block.ffn.weight),
48
+ ("ffn2", &mut block.ffn2.weight),
49
+ ("ln1.gamma", &mut block.ln1.gamma),
50
+ ("ln1.beta", &mut block.ln1.beta),
51
+ ("ln2.gamma", &mut block.ln2.gamma),
52
+ ("ln2.beta", &mut block.ln2.beta),
53
+ ];
54
+ for (suffix, dest) in keys {
55
+ let key = format!("{p}.{suffix}");
56
+ *dest = tensor_from_entry(require_tensor_entry(tensors, &key)?)?;
57
+ }
58
+ if let Some(gate) = block.ffn_gate.as_mut() {
59
+ let key = format!("{p}.ffn_gate");
60
+ gate.weight = tensor_from_entry(require_tensor_entry(tensors, &key)?)?;
61
+ expect_tensor_shape(&gate.weight, &[ffn_dim, d_model], &key)?;
62
+ }
63
+ expect_tensor_shape(&block.attn.q_proj.weight, &[q_dim, d_model], &format!("{p}.attn.q"))?;
64
+ expect_tensor_shape(&block.attn.k_proj.weight, &[kv_dim, d_model], &format!("{p}.attn.k"))?;
65
+ expect_tensor_shape(&block.attn.v_proj.weight, &[kv_dim, d_model], &format!("{p}.attn.v"))?;
66
+ expect_tensor_shape(&block.attn.out_proj.weight, &[d_model, q_dim], &format!("{p}.attn.out"))?;
67
+ expect_tensor_shape(&block.ffn.weight, &[ffn_dim, d_model], &format!("{p}.ffn"))?;
68
+ expect_tensor_shape(&block.ffn2.weight, &[d_model, ffn_dim], &format!("{p}.ffn2"))?;
69
+ expect_tensor_shape(&block.ln1.gamma, &[d_model], &format!("{p}.ln1.gamma"))?;
70
+ expect_tensor_shape(&block.ln1.beta, &[d_model], &format!("{p}.ln1.beta"))?;
71
+ expect_tensor_shape(&block.ln2.gamma, &[d_model], &format!("{p}.ln2.gamma"))?;
72
+ expect_tensor_shape(&block.ln2.beta, &[d_model], &format!("{p}.ln2.beta"))?;
73
+ block.ln1.use_rms = use_rms;
74
+ block.ln2.use_rms = use_rms;
75
+ }
76
+ Ok(())
77
+ }
8
78
 
9
79
  pub(crate) fn export_block_tensors(model: &Chatbot, map: &mut TensorMap) {
10
80
  for (i, block) in model.blocks.iter().enumerate() {
@@ -1,4 +1,4 @@
1
- use crate::block_tensors::{export_block_tensors, import_block_tensors};
1
+ use crate::block_tensors::{export_block_tensors, export_named_block_list, import_block_tensors, import_named_block_list};
2
2
  use crate::checkpoint_util::{
3
3
  expect_tensor_shape, optional_tensor_entry, quantize_tensor, require_tensor_entry,
4
4
  tensor_from_entry, tensor_to_entry, write_file_create_parents, TensorMap,
@@ -53,6 +53,20 @@ pub fn export_safetensors<'a>(
53
53
  if model.n_loops != 1 {
54
54
  meta["n_loops"] = serde_json::json!(model.n_loops);
55
55
  }
56
+ if model.max_loops != model.n_loops {
57
+ meta["max_loops"] = serde_json::json!(model.max_loops);
58
+ }
59
+ if !model.prelude_blocks.is_empty() {
60
+ meta["prelude_layers"] = serde_json::json!(model.prelude_blocks.len());
61
+ export_named_block_list(&model.prelude_blocks, "prelude", &mut map);
62
+ }
63
+ if !model.coda_blocks.is_empty() {
64
+ meta["coda_layers"] = serde_json::json!(model.coda_blocks.len());
65
+ export_named_block_list(&model.coda_blocks, "coda", &mut map);
66
+ }
67
+ if let Some(w) = model.attention_window {
68
+ meta["attention_window"] = serde_json::json!(w);
69
+ }
56
70
  if model.tie_embeddings {
57
71
  meta["tie_embeddings"] = serde_json::json!(true);
58
72
  }
@@ -242,7 +256,7 @@ fn import_mmn_json_safetensors(text: &str) -> Result<Chatbot, MmnError> {
242
256
  }
243
257
  if let Some(le) = model.loop_embed.as_mut() {
244
258
  le.weight = tensor_from_entry(require_tensor_entry(tensors, "loop_embed.weight")?)?;
245
- expect_tensor_shape(&le.weight, &[model.n_loops, d_model], "loop_embed.weight")?;
259
+ expect_tensor_shape(&le.weight, &[model.max_loops, d_model], "loop_embed.weight")?;
246
260
  }
247
261
  if let Some(fnorm) = model.final_norm.as_mut() {
248
262
  fnorm.gamma = tensor_from_entry(require_tensor_entry(tensors, "final_norm.gamma")?)?;
@@ -347,11 +361,43 @@ fn import_mmn_json_safetensors(text: &str) -> Result<Chatbot, MmnError> {
347
361
  }
348
362
  }
349
363
  import_block_tensors(&mut model, tensors)?;
364
+ // Import prelude and coda blocks if present
365
+ if !model.prelude_blocks.is_empty() {
366
+ import_named_block_list(
367
+ &mut model.prelude_blocks,
368
+ "prelude",
369
+ tensors,
370
+ d_model,
371
+ model.shape.ffn_dim,
372
+ model.shape.q_dim(),
373
+ model.shape.kv_dim(),
374
+ model.norm_kind == "rms",
375
+ )?;
376
+ for block in &mut model.prelude_blocks {
377
+ block.attn.attention_window = model.attention_window;
378
+ }
379
+ }
380
+ if !model.coda_blocks.is_empty() {
381
+ import_named_block_list(
382
+ &mut model.coda_blocks,
383
+ "coda",
384
+ tensors,
385
+ d_model,
386
+ model.shape.ffn_dim,
387
+ model.shape.q_dim(),
388
+ model.shape.kv_dim(),
389
+ model.norm_kind == "rms",
390
+ )?;
391
+ for block in &mut model.coda_blocks {
392
+ block.attn.attention_window = model.attention_window;
393
+ }
394
+ }
350
395
  Ok(model)
351
396
  }
352
397
 
353
398
  fn arch_extras_from_meta(meta: &serde_json::Value) -> ChatbotArchExtras {
354
399
  let n_loops = meta["n_loops"].as_u64().unwrap_or(1) as usize;
400
+ let max_loops = meta.get("max_loops").and_then(|v| v.as_u64()).map(|v| v as usize);
355
401
  let tie_embeddings = meta["tie_embeddings"].as_bool().unwrap_or(false);
356
402
  let norm = meta["norm"].as_str().unwrap_or("layer");
357
403
  let ffn = meta
@@ -362,6 +408,9 @@ fn arch_extras_from_meta(meta: &serde_json::Value) -> ChatbotArchExtras {
362
408
  let loop_embed = meta["loop_embed"].as_bool().unwrap_or(false);
363
409
  let final_norm = meta["final_norm"].as_bool().unwrap_or(false);
364
410
  let lora_rank = meta["lora_rank"].as_u64().unwrap_or(0) as usize;
411
+ let prelude_layers = meta.get("prelude_layers").and_then(|v| v.as_u64()).unwrap_or(0) as usize;
412
+ let coda_layers = meta.get("coda_layers").and_then(|v| v.as_u64()).unwrap_or(0) as usize;
413
+ let attention_window = meta.get("attention_window").and_then(|v| v.as_u64()).map(|v| v as usize);
365
414
  ChatbotArchExtras {
366
415
  n_loops: n_loops.max(1),
367
416
  tie_embeddings,
@@ -370,6 +419,10 @@ fn arch_extras_from_meta(meta: &serde_json::Value) -> ChatbotArchExtras {
370
419
  loop_embed: loop_embed && n_loops > 1,
371
420
  final_norm,
372
421
  lora_rank,
422
+ prelude_layers,
423
+ coda_layers,
424
+ max_loops,
425
+ attention_window,
373
426
  }
374
427
  }
375
428
 
@@ -414,6 +467,43 @@ pub fn merge_models(a: &Chatbot, b: &Chatbot) -> Result<Chatbot, MmnError> {
414
467
  explanation: "merge() requires matching loop/norm/FFN/tie/LoRA configuration.".into(),
415
468
  });
416
469
  }
470
+ if a.prelude_blocks.len() != b.prelude_blocks.len()
471
+ || a.coda_blocks.len() != b.coda_blocks.len()
472
+ {
473
+ return Err(MmnError::ModelMismatch {
474
+ message: format!(
475
+ "Cannot merge models with different prelude/coda layers \
476
+ (a: prelude={}, coda={}; b: prelude={}, coda={})",
477
+ a.prelude_blocks.len(),
478
+ a.coda_blocks.len(),
479
+ b.prelude_blocks.len(),
480
+ b.coda_blocks.len(),
481
+ ),
482
+ fix: "Use two models with the same prelude_layers and coda_layers.".into(),
483
+ explanation: "merge() requires matching Glint-2 prelude/coda block counts.".into(),
484
+ });
485
+ }
486
+ if a.max_loops != b.max_loops {
487
+ return Err(MmnError::ModelMismatch {
488
+ message: format!(
489
+ "Cannot merge models with different max_loops (a={}, b={})",
490
+ a.max_loops, b.max_loops
491
+ ),
492
+ fix: "Use two models with the same max_loops.".into(),
493
+ explanation: "merge() requires matching max_loops capacity for loop_embed/LoRA tables."
494
+ .into(),
495
+ });
496
+ }
497
+ if a.attention_window != b.attention_window {
498
+ return Err(MmnError::ModelMismatch {
499
+ message: format!(
500
+ "Cannot merge models with different attention_window (a={:?}, b={:?})",
501
+ a.attention_window, b.attention_window
502
+ ),
503
+ fix: "Use two models with the same attention_window.".into(),
504
+ explanation: "merge() requires matching sliding window configuration.".into(),
505
+ });
506
+ }
417
507
  let extras = ChatbotArchExtras {
418
508
  n_loops: a.n_loops,
419
509
  tie_embeddings: a.tie_embeddings,
@@ -422,6 +512,10 @@ pub fn merge_models(a: &Chatbot, b: &Chatbot) -> Result<Chatbot, MmnError> {
422
512
  loop_embed: a.loop_embed.is_some(),
423
513
  final_norm: a.final_norm.is_some(),
424
514
  lora_rank: a.loop_lora.as_ref().map(|l| l.rank).unwrap_or(0),
515
+ prelude_layers: a.prelude_blocks.len(),
516
+ coda_layers: a.coda_blocks.len(),
517
+ max_loops: Some(a.max_loops),
518
+ attention_window: a.attention_window,
425
519
  };
426
520
  let mut out = Chatbot::new_with_arch(
427
521
  a.vision || b.vision,
@@ -516,6 +610,46 @@ pub fn merge_models(a: &Chatbot, b: &Chatbot) -> Result<Chatbot, MmnError> {
516
610
  block.ln2.gamma = average_tensors(&ab.ln2.gamma, &bb.ln2.gamma);
517
611
  block.ln2.beta = average_tensors(&ab.ln2.beta, &bb.ln2.beta);
518
612
  }
613
+ for (i, block) in out.prelude_blocks.iter_mut().enumerate() {
614
+ let ab = &a.prelude_blocks[i];
615
+ let bb = &b.prelude_blocks[i];
616
+ block.attn.q_proj.weight = average_tensors(&ab.attn.q_proj.weight, &bb.attn.q_proj.weight);
617
+ block.attn.k_proj.weight = average_tensors(&ab.attn.k_proj.weight, &bb.attn.k_proj.weight);
618
+ block.attn.v_proj.weight = average_tensors(&ab.attn.v_proj.weight, &bb.attn.v_proj.weight);
619
+ block.attn.out_proj.weight =
620
+ average_tensors(&ab.attn.out_proj.weight, &bb.attn.out_proj.weight);
621
+ block.ffn.weight = average_tensors(&ab.ffn.weight, &bb.ffn.weight);
622
+ block.ffn2.weight = average_tensors(&ab.ffn2.weight, &bb.ffn2.weight);
623
+ if let (Some(ag), Some(bg), Some(og)) =
624
+ (&ab.ffn_gate, &bb.ffn_gate, block.ffn_gate.as_mut())
625
+ {
626
+ og.weight = average_tensors(&ag.weight, &bg.weight);
627
+ }
628
+ block.ln1.gamma = average_tensors(&ab.ln1.gamma, &bb.ln1.gamma);
629
+ block.ln1.beta = average_tensors(&ab.ln1.beta, &bb.ln1.beta);
630
+ block.ln2.gamma = average_tensors(&ab.ln2.gamma, &bb.ln2.gamma);
631
+ block.ln2.beta = average_tensors(&ab.ln2.beta, &bb.ln2.beta);
632
+ }
633
+ for (i, block) in out.coda_blocks.iter_mut().enumerate() {
634
+ let ab = &a.coda_blocks[i];
635
+ let bb = &b.coda_blocks[i];
636
+ block.attn.q_proj.weight = average_tensors(&ab.attn.q_proj.weight, &bb.attn.q_proj.weight);
637
+ block.attn.k_proj.weight = average_tensors(&ab.attn.k_proj.weight, &bb.attn.k_proj.weight);
638
+ block.attn.v_proj.weight = average_tensors(&ab.attn.v_proj.weight, &bb.attn.v_proj.weight);
639
+ block.attn.out_proj.weight =
640
+ average_tensors(&ab.attn.out_proj.weight, &bb.attn.out_proj.weight);
641
+ block.ffn.weight = average_tensors(&ab.ffn.weight, &bb.ffn.weight);
642
+ block.ffn2.weight = average_tensors(&ab.ffn2.weight, &bb.ffn2.weight);
643
+ if let (Some(ag), Some(bg), Some(og)) =
644
+ (&ab.ffn_gate, &bb.ffn_gate, block.ffn_gate.as_mut())
645
+ {
646
+ og.weight = average_tensors(&ag.weight, &bg.weight);
647
+ }
648
+ block.ln1.gamma = average_tensors(&ab.ln1.gamma, &bb.ln1.gamma);
649
+ block.ln1.beta = average_tensors(&ab.ln1.beta, &bb.ln1.beta);
650
+ block.ln2.gamma = average_tensors(&ab.ln2.gamma, &bb.ln2.gamma);
651
+ block.ln2.beta = average_tensors(&ab.ln2.beta, &bb.ln2.beta);
652
+ }
519
653
  if let (Some(aa), Some(bb), Some(oo)) = (&a.loop_embed, &b.loop_embed, out.loop_embed.as_mut())
520
654
  {
521
655
  oo.weight = average_tensors(&aa.weight, &bb.weight);
@@ -572,7 +706,12 @@ pub fn quantize_model(model: &mut Chatbot, mode: &str) -> Result<(), MmnError> {
572
706
  quantize_tensor(&mut cross.k_proj.weight, scale);
573
707
  quantize_tensor(&mut cross.v_proj.weight, scale);
574
708
  }
575
- for block in &mut model.blocks {
709
+ let all_blocks = model
710
+ .blocks
711
+ .iter_mut()
712
+ .chain(model.prelude_blocks.iter_mut())
713
+ .chain(model.coda_blocks.iter_mut());
714
+ for block in all_blocks {
576
715
  quantize_tensor(&mut block.attn.q_proj.weight, scale);
577
716
  quantize_tensor(&mut block.attn.k_proj.weight, scale);
578
717
  quantize_tensor(&mut block.attn.v_proj.weight, scale);
@@ -322,6 +322,7 @@ pub(crate) fn load_chatbot_from_mmn_tensors(
322
322
  loop_embed: loop_embed && n_loops > 1,
323
323
  final_norm,
324
324
  lora_rank,
325
+ ..Default::default()
325
326
  };
326
327
  let mut model = Chatbot::new_with_arch(
327
328
  vision,
@@ -395,7 +396,7 @@ pub(crate) fn load_chatbot_from_mmn_tensors(
395
396
  le.weight = tensor_from_entry(require_tensor_entry(&json_tensors, "loop_embed.weight")?)?;
396
397
  expect_tensor_shape(
397
398
  &le.weight,
398
- &[model.n_loops, d_model],
399
+ &[model.max_loops, d_model],
399
400
  "loop_embed.weight",
400
401
  )?;
401
402
  }