@simulatte/doppler 0.1.4 → 0.1.5

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 (103) hide show
  1. package/README.md +4 -3
  2. package/package.json +25 -4
  3. package/src/client/doppler-api.browser.d.ts +1 -0
  4. package/src/client/doppler-api.browser.js +288 -0
  5. package/src/client/doppler-api.js +1 -1
  6. package/src/client/doppler-provider/types.js +1 -1
  7. package/src/config/execution-contract-check.d.ts +33 -0
  8. package/src/config/execution-contract-check.js +72 -0
  9. package/src/config/execution-v0-contract-check.d.ts +94 -0
  10. package/src/config/execution-v0-contract-check.js +251 -0
  11. package/src/config/execution-v0-graph-contract-check.d.ts +20 -0
  12. package/src/config/execution-v0-graph-contract-check.js +64 -0
  13. package/src/config/kernel-path-contract-check.d.ts +76 -0
  14. package/src/config/kernel-path-contract-check.js +479 -0
  15. package/src/config/kernel-path-loader.d.ts +16 -0
  16. package/src/config/kernel-path-loader.js +54 -0
  17. package/src/config/kernels/kernel-ref-digests.js +12 -0
  18. package/src/config/kernels/registry.json +556 -0
  19. package/src/config/loader.js +50 -46
  20. package/src/config/merge-contract-check.d.ts +16 -0
  21. package/src/config/merge-contract-check.js +321 -0
  22. package/src/config/merge-helpers.d.ts +58 -0
  23. package/src/config/merge-helpers.js +54 -0
  24. package/src/config/merge.js +3 -6
  25. package/src/config/presets/models/janus-text.json +2 -0
  26. package/src/config/quantization-contract-check.d.ts +12 -0
  27. package/src/config/quantization-contract-check.js +91 -0
  28. package/src/config/required-inference-fields-contract-check.d.ts +24 -0
  29. package/src/config/required-inference-fields-contract-check.js +231 -0
  30. package/src/config/schema/browser-suite-metrics.schema.d.ts +17 -0
  31. package/src/config/schema/browser-suite-metrics.schema.js +46 -0
  32. package/src/config/schema/conversion-report.schema.d.ts +40 -0
  33. package/src/config/schema/conversion-report.schema.js +108 -0
  34. package/src/config/schema/doppler.schema.js +12 -18
  35. package/src/config/schema/index.d.ts +22 -0
  36. package/src/config/schema/index.js +18 -0
  37. package/src/converter/core.d.ts +10 -0
  38. package/src/converter/core.js +27 -2
  39. package/src/converter/parsers/diffusion.js +63 -3
  40. package/src/gpu/kernels/depthwise_conv2d.d.ts +29 -0
  41. package/src/gpu/kernels/depthwise_conv2d.js +98 -0
  42. package/src/gpu/kernels/depthwise_conv2d.wgsl +58 -0
  43. package/src/gpu/kernels/depthwise_conv2d_f16.wgsl +62 -0
  44. package/src/gpu/kernels/grouped_pointwise_conv2d.d.ts +27 -0
  45. package/src/gpu/kernels/grouped_pointwise_conv2d.js +92 -0
  46. package/src/gpu/kernels/grouped_pointwise_conv2d.wgsl +47 -0
  47. package/src/gpu/kernels/grouped_pointwise_conv2d_f16.wgsl +51 -0
  48. package/src/gpu/kernels/index.d.ts +30 -0
  49. package/src/gpu/kernels/index.js +25 -0
  50. package/src/gpu/kernels/relu.d.ts +18 -0
  51. package/src/gpu/kernels/relu.js +45 -0
  52. package/src/gpu/kernels/relu.wgsl +21 -0
  53. package/src/gpu/kernels/relu_f16.wgsl +23 -0
  54. package/src/gpu/kernels/repeat_channels.d.ts +21 -0
  55. package/src/gpu/kernels/repeat_channels.js +60 -0
  56. package/src/gpu/kernels/repeat_channels.wgsl +29 -0
  57. package/src/gpu/kernels/repeat_channels_f16.wgsl +31 -0
  58. package/src/gpu/kernels/sana_linear_attention.d.ts +27 -0
  59. package/src/gpu/kernels/sana_linear_attention.js +122 -0
  60. package/src/gpu/kernels/sana_linear_attention_apply.wgsl +44 -0
  61. package/src/gpu/kernels/sana_linear_attention_apply_f16.wgsl +47 -0
  62. package/src/gpu/kernels/sana_linear_attention_summary.wgsl +47 -0
  63. package/src/gpu/kernels/sana_linear_attention_summary_f16.wgsl +49 -0
  64. package/src/index-browser.d.ts +1 -1
  65. package/src/index-browser.js +2 -2
  66. package/src/index.js +1 -1
  67. package/src/inference/browser-harness.js +62 -22
  68. package/src/inference/pipelines/diffusion/init.js +14 -0
  69. package/src/inference/pipelines/diffusion/pipeline.js +206 -77
  70. package/src/inference/pipelines/diffusion/sana-transformer.d.ts +53 -0
  71. package/src/inference/pipelines/diffusion/sana-transformer.js +738 -0
  72. package/src/inference/pipelines/diffusion/scheduler.d.ts +17 -1
  73. package/src/inference/pipelines/diffusion/scheduler.js +91 -3
  74. package/src/inference/pipelines/diffusion/text-encoder-gpu.d.ts +6 -4
  75. package/src/inference/pipelines/diffusion/text-encoder-gpu.js +270 -0
  76. package/src/inference/pipelines/diffusion/text-encoder.js +18 -1
  77. package/src/inference/pipelines/diffusion/types.d.ts +4 -0
  78. package/src/inference/pipelines/diffusion/vae.js +782 -78
  79. package/src/inference/pipelines/text/config.d.ts +5 -0
  80. package/src/inference/pipelines/text/config.js +1 -1
  81. package/src/inference/pipelines/text/execution-v0.js +14 -93
  82. package/src/rules/execution-rules-contract-check.d.ts +17 -0
  83. package/src/rules/execution-rules-contract-check.js +245 -0
  84. package/src/rules/kernels/depthwise-conv2d.rules.json +6 -0
  85. package/src/rules/kernels/grouped-pointwise-conv2d.rules.json +6 -0
  86. package/src/rules/kernels/relu.rules.json +6 -0
  87. package/src/rules/kernels/repeat-channels.rules.json +6 -0
  88. package/src/rules/kernels/sana-linear-attention.rules.json +6 -0
  89. package/src/rules/layer-pattern-contract-check.d.ts +17 -0
  90. package/src/rules/layer-pattern-contract-check.js +231 -0
  91. package/src/rules/rule-registry.d.ts +28 -0
  92. package/src/rules/rule-registry.js +38 -0
  93. package/src/tooling/conversion-config-materializer.d.ts +24 -0
  94. package/src/tooling/conversion-config-materializer.js +99 -0
  95. package/src/tooling/lean-execution-contract-runner.d.ts +43 -0
  96. package/src/tooling/lean-execution-contract-runner.js +158 -0
  97. package/src/tooling/node-convert.d.ts +10 -0
  98. package/src/tooling/node-converter.js +59 -0
  99. package/src/tooling/node-webgpu.js +9 -9
  100. package/src/version.d.ts +2 -0
  101. package/src/version.js +2 -0
  102. package/tools/convert-safetensors-node.js +47 -0
  103. package/tools/doppler-cli.js +115 -1
@@ -5537,6 +5537,228 @@
5537
5537
  }
5538
5538
  }
5539
5539
  },
5540
+ "depthwise_conv2d": {
5541
+ "description": "Depthwise Conv2D (NCHW)",
5542
+ "baseBindings": [
5543
+ {
5544
+ "index": 0,
5545
+ "name": "uniforms",
5546
+ "type": "uniform"
5547
+ },
5548
+ {
5549
+ "index": 1,
5550
+ "name": "input",
5551
+ "type": "read-only-storage"
5552
+ },
5553
+ {
5554
+ "index": 2,
5555
+ "name": "weight",
5556
+ "type": "read-only-storage"
5557
+ },
5558
+ {
5559
+ "index": 3,
5560
+ "name": "bias",
5561
+ "type": "read-only-storage"
5562
+ },
5563
+ {
5564
+ "index": 4,
5565
+ "name": "output",
5566
+ "type": "storage"
5567
+ }
5568
+ ],
5569
+ "baseUniforms": {
5570
+ "size": 48,
5571
+ "fields": [
5572
+ {
5573
+ "name": "channels",
5574
+ "type": "u32",
5575
+ "offset": 0
5576
+ },
5577
+ {
5578
+ "name": "height",
5579
+ "type": "u32",
5580
+ "offset": 4
5581
+ },
5582
+ {
5583
+ "name": "width",
5584
+ "type": "u32",
5585
+ "offset": 8
5586
+ },
5587
+ {
5588
+ "name": "out_height",
5589
+ "type": "u32",
5590
+ "offset": 12
5591
+ },
5592
+ {
5593
+ "name": "out_width",
5594
+ "type": "u32",
5595
+ "offset": 16
5596
+ },
5597
+ {
5598
+ "name": "kernel_h",
5599
+ "type": "u32",
5600
+ "offset": 20
5601
+ },
5602
+ {
5603
+ "name": "kernel_w",
5604
+ "type": "u32",
5605
+ "offset": 24
5606
+ },
5607
+ {
5608
+ "name": "stride",
5609
+ "type": "u32",
5610
+ "offset": 28
5611
+ },
5612
+ {
5613
+ "name": "pad",
5614
+ "type": "u32",
5615
+ "offset": 32
5616
+ },
5617
+ {
5618
+ "name": "_pad0",
5619
+ "type": "u32",
5620
+ "offset": 36
5621
+ },
5622
+ {
5623
+ "name": "_pad1",
5624
+ "type": "u32",
5625
+ "offset": 40
5626
+ },
5627
+ {
5628
+ "name": "_pad2",
5629
+ "type": "u32",
5630
+ "offset": 44
5631
+ }
5632
+ ]
5633
+ },
5634
+ "variants": {
5635
+ "default": {
5636
+ "wgsl": "depthwise_conv2d.wgsl",
5637
+ "entryPoint": "main",
5638
+ "workgroup": [
5639
+ 256,
5640
+ 1,
5641
+ 1
5642
+ ],
5643
+ "requires": [],
5644
+ "outputDtype": "f32"
5645
+ },
5646
+ "default_f16": {
5647
+ "wgsl": "depthwise_conv2d_f16.wgsl",
5648
+ "entryPoint": "main",
5649
+ "workgroup": [
5650
+ 256,
5651
+ 1,
5652
+ 1
5653
+ ],
5654
+ "requires": [
5655
+ "shader-f16"
5656
+ ],
5657
+ "outputDtype": "f16"
5658
+ }
5659
+ }
5660
+ },
5661
+ "grouped_pointwise_conv2d": {
5662
+ "description": "Grouped Pointwise Conv2D (NCHW)",
5663
+ "baseBindings": [
5664
+ {
5665
+ "index": 0,
5666
+ "name": "uniforms",
5667
+ "type": "uniform"
5668
+ },
5669
+ {
5670
+ "index": 1,
5671
+ "name": "input",
5672
+ "type": "read-only-storage"
5673
+ },
5674
+ {
5675
+ "index": 2,
5676
+ "name": "weight",
5677
+ "type": "read-only-storage"
5678
+ },
5679
+ {
5680
+ "index": 3,
5681
+ "name": "bias",
5682
+ "type": "read-only-storage"
5683
+ },
5684
+ {
5685
+ "index": 4,
5686
+ "name": "output",
5687
+ "type": "storage"
5688
+ }
5689
+ ],
5690
+ "baseUniforms": {
5691
+ "size": 32,
5692
+ "fields": [
5693
+ {
5694
+ "name": "in_channels",
5695
+ "type": "u32",
5696
+ "offset": 0
5697
+ },
5698
+ {
5699
+ "name": "out_channels",
5700
+ "type": "u32",
5701
+ "offset": 4
5702
+ },
5703
+ {
5704
+ "name": "height",
5705
+ "type": "u32",
5706
+ "offset": 8
5707
+ },
5708
+ {
5709
+ "name": "width",
5710
+ "type": "u32",
5711
+ "offset": 12
5712
+ },
5713
+ {
5714
+ "name": "groups",
5715
+ "type": "u32",
5716
+ "offset": 16
5717
+ },
5718
+ {
5719
+ "name": "_pad0",
5720
+ "type": "u32",
5721
+ "offset": 20
5722
+ },
5723
+ {
5724
+ "name": "_pad1",
5725
+ "type": "u32",
5726
+ "offset": 24
5727
+ },
5728
+ {
5729
+ "name": "_pad2",
5730
+ "type": "u32",
5731
+ "offset": 28
5732
+ }
5733
+ ]
5734
+ },
5735
+ "variants": {
5736
+ "default": {
5737
+ "wgsl": "grouped_pointwise_conv2d.wgsl",
5738
+ "entryPoint": "main",
5739
+ "workgroup": [
5740
+ 256,
5741
+ 1,
5742
+ 1
5743
+ ],
5744
+ "requires": [],
5745
+ "outputDtype": "f32"
5746
+ },
5747
+ "default_f16": {
5748
+ "wgsl": "grouped_pointwise_conv2d_f16.wgsl",
5749
+ "entryPoint": "main",
5750
+ "workgroup": [
5751
+ 256,
5752
+ 1,
5753
+ 1
5754
+ ],
5755
+ "requires": [
5756
+ "shader-f16"
5757
+ ],
5758
+ "outputDtype": "f16"
5759
+ }
5760
+ }
5761
+ },
5540
5762
  "groupnorm_stats": {
5541
5763
  "description": "GroupNorm stats (mean/var) for each group",
5542
5764
  "baseBindings": [
@@ -6424,6 +6646,340 @@
6424
6646
  }
6425
6647
  }
6426
6648
  },
6649
+ "sana_linear_attention_summary": {
6650
+ "description": "Sana linear attention summary stage",
6651
+ "baseBindings": [
6652
+ {
6653
+ "index": 0,
6654
+ "name": "uniforms",
6655
+ "type": "uniform"
6656
+ },
6657
+ {
6658
+ "index": 1,
6659
+ "name": "query",
6660
+ "type": "read-only-storage"
6661
+ },
6662
+ {
6663
+ "index": 2,
6664
+ "name": "key",
6665
+ "type": "read-only-storage"
6666
+ },
6667
+ {
6668
+ "index": 3,
6669
+ "name": "value",
6670
+ "type": "read-only-storage"
6671
+ },
6672
+ {
6673
+ "index": 4,
6674
+ "name": "summary",
6675
+ "type": "storage"
6676
+ }
6677
+ ],
6678
+ "baseUniforms": {
6679
+ "size": 24,
6680
+ "fields": [
6681
+ {
6682
+ "name": "num_heads",
6683
+ "type": "u32",
6684
+ "offset": 0
6685
+ },
6686
+ {
6687
+ "name": "head_dim",
6688
+ "type": "u32",
6689
+ "offset": 4
6690
+ },
6691
+ {
6692
+ "name": "num_tokens",
6693
+ "type": "u32",
6694
+ "offset": 8
6695
+ },
6696
+ {
6697
+ "name": "hidden_size",
6698
+ "type": "u32",
6699
+ "offset": 12
6700
+ },
6701
+ {
6702
+ "name": "_pad0",
6703
+ "type": "u32",
6704
+ "offset": 16
6705
+ },
6706
+ {
6707
+ "name": "_pad1",
6708
+ "type": "u32",
6709
+ "offset": 20
6710
+ }
6711
+ ]
6712
+ },
6713
+ "variants": {
6714
+ "default": {
6715
+ "wgsl": "sana_linear_attention_summary.wgsl",
6716
+ "entryPoint": "main",
6717
+ "workgroup": [
6718
+ 256,
6719
+ 1,
6720
+ 1
6721
+ ],
6722
+ "requires": [],
6723
+ "outputDtype": "f32"
6724
+ },
6725
+ "default_f16": {
6726
+ "wgsl": "sana_linear_attention_summary_f16.wgsl",
6727
+ "entryPoint": "main",
6728
+ "workgroup": [
6729
+ 256,
6730
+ 1,
6731
+ 1
6732
+ ],
6733
+ "requires": [
6734
+ "shader-f16"
6735
+ ],
6736
+ "outputDtype": "f32"
6737
+ }
6738
+ }
6739
+ },
6740
+ "sana_linear_attention_apply": {
6741
+ "description": "Sana linear attention apply stage",
6742
+ "baseBindings": [
6743
+ {
6744
+ "index": 0,
6745
+ "name": "uniforms",
6746
+ "type": "uniform"
6747
+ },
6748
+ {
6749
+ "index": 1,
6750
+ "name": "query",
6751
+ "type": "read-only-storage"
6752
+ },
6753
+ {
6754
+ "index": 2,
6755
+ "name": "summary",
6756
+ "type": "read-only-storage"
6757
+ },
6758
+ {
6759
+ "index": 3,
6760
+ "name": "output",
6761
+ "type": "storage"
6762
+ }
6763
+ ],
6764
+ "baseUniforms": {
6765
+ "size": 32,
6766
+ "fields": [
6767
+ {
6768
+ "name": "num_heads",
6769
+ "type": "u32",
6770
+ "offset": 0
6771
+ },
6772
+ {
6773
+ "name": "head_dim",
6774
+ "type": "u32",
6775
+ "offset": 4
6776
+ },
6777
+ {
6778
+ "name": "num_tokens",
6779
+ "type": "u32",
6780
+ "offset": 8
6781
+ },
6782
+ {
6783
+ "name": "hidden_size",
6784
+ "type": "u32",
6785
+ "offset": 12
6786
+ },
6787
+ {
6788
+ "name": "eps",
6789
+ "type": "f32",
6790
+ "offset": 16
6791
+ },
6792
+ {
6793
+ "name": "_pad0",
6794
+ "type": "u32",
6795
+ "offset": 20
6796
+ },
6797
+ {
6798
+ "name": "_pad1",
6799
+ "type": "u32",
6800
+ "offset": 24
6801
+ },
6802
+ {
6803
+ "name": "_pad2",
6804
+ "type": "u32",
6805
+ "offset": 28
6806
+ }
6807
+ ]
6808
+ },
6809
+ "variants": {
6810
+ "default": {
6811
+ "wgsl": "sana_linear_attention_apply.wgsl",
6812
+ "entryPoint": "main",
6813
+ "workgroup": [
6814
+ 256,
6815
+ 1,
6816
+ 1
6817
+ ],
6818
+ "requires": [],
6819
+ "outputDtype": "f32"
6820
+ },
6821
+ "default_f16": {
6822
+ "wgsl": "sana_linear_attention_apply_f16.wgsl",
6823
+ "entryPoint": "main",
6824
+ "workgroup": [
6825
+ 256,
6826
+ 1,
6827
+ 1
6828
+ ],
6829
+ "requires": [
6830
+ "shader-f16"
6831
+ ],
6832
+ "outputDtype": "f16"
6833
+ }
6834
+ }
6835
+ },
6836
+ "repeat_channels": {
6837
+ "description": "Repeat channels along the NCHW channel axis",
6838
+ "baseBindings": [
6839
+ {
6840
+ "index": 0,
6841
+ "name": "uniforms",
6842
+ "type": "uniform"
6843
+ },
6844
+ {
6845
+ "index": 1,
6846
+ "name": "input",
6847
+ "type": "read-only-storage"
6848
+ },
6849
+ {
6850
+ "index": 2,
6851
+ "name": "output",
6852
+ "type": "storage"
6853
+ }
6854
+ ],
6855
+ "baseUniforms": {
6856
+ "size": 20,
6857
+ "fields": [
6858
+ {
6859
+ "name": "in_channels",
6860
+ "type": "u32",
6861
+ "offset": 0
6862
+ },
6863
+ {
6864
+ "name": "height",
6865
+ "type": "u32",
6866
+ "offset": 4
6867
+ },
6868
+ {
6869
+ "name": "width",
6870
+ "type": "u32",
6871
+ "offset": 8
6872
+ },
6873
+ {
6874
+ "name": "repeats",
6875
+ "type": "u32",
6876
+ "offset": 12
6877
+ },
6878
+ {
6879
+ "name": "_pad0",
6880
+ "type": "u32",
6881
+ "offset": 16
6882
+ }
6883
+ ]
6884
+ },
6885
+ "variants": {
6886
+ "default": {
6887
+ "wgsl": "repeat_channels.wgsl",
6888
+ "entryPoint": "main",
6889
+ "workgroup": [
6890
+ 256,
6891
+ 1,
6892
+ 1
6893
+ ],
6894
+ "requires": [],
6895
+ "outputDtype": "f32"
6896
+ },
6897
+ "default_f16": {
6898
+ "wgsl": "repeat_channels_f16.wgsl",
6899
+ "entryPoint": "main",
6900
+ "workgroup": [
6901
+ 256,
6902
+ 1,
6903
+ 1
6904
+ ],
6905
+ "requires": [
6906
+ "shader-f16"
6907
+ ],
6908
+ "outputDtype": "f16"
6909
+ }
6910
+ }
6911
+ },
6912
+ "relu": {
6913
+ "description": "ReLU activation",
6914
+ "baseBindings": [
6915
+ {
6916
+ "index": 0,
6917
+ "name": "uniforms",
6918
+ "type": "uniform"
6919
+ },
6920
+ {
6921
+ "index": 1,
6922
+ "name": "input",
6923
+ "type": "read-only-storage"
6924
+ },
6925
+ {
6926
+ "index": 2,
6927
+ "name": "output",
6928
+ "type": "storage"
6929
+ }
6930
+ ],
6931
+ "baseUniforms": {
6932
+ "size": 16,
6933
+ "fields": [
6934
+ {
6935
+ "name": "size",
6936
+ "type": "u32",
6937
+ "offset": 0
6938
+ },
6939
+ {
6940
+ "name": "_pad0",
6941
+ "type": "u32",
6942
+ "offset": 4
6943
+ },
6944
+ {
6945
+ "name": "_pad1",
6946
+ "type": "u32",
6947
+ "offset": 8
6948
+ },
6949
+ {
6950
+ "name": "_pad2",
6951
+ "type": "u32",
6952
+ "offset": 12
6953
+ }
6954
+ ]
6955
+ },
6956
+ "variants": {
6957
+ "default": {
6958
+ "wgsl": "relu.wgsl",
6959
+ "entryPoint": "main",
6960
+ "workgroup": [
6961
+ 256,
6962
+ 1,
6963
+ 1
6964
+ ],
6965
+ "requires": [],
6966
+ "outputDtype": "f32"
6967
+ },
6968
+ "default_f16": {
6969
+ "wgsl": "relu_f16.wgsl",
6970
+ "entryPoint": "main",
6971
+ "workgroup": [
6972
+ 256,
6973
+ 1,
6974
+ 1
6975
+ ],
6976
+ "requires": [
6977
+ "shader-f16"
6978
+ ],
6979
+ "outputDtype": "f16"
6980
+ }
6981
+ }
6982
+ },
6427
6983
  "conv2d_backward_input": {
6428
6984
  "description": "Conv2D backward (input gradient)",
6429
6985
  "baseBindings": [
@@ -5,6 +5,7 @@ import {
5
5
  } from './schema/index.js';
6
6
  import { createDopplerError, ERROR_CODES } from '../errors/index.js';
7
7
  import { loadJson } from '../utils/load-json.js';
8
+ import { chooseNullish, mergeLayeredShallowObjects } from './merge-helpers.js';
8
9
 
9
10
  // Static imports keep presets bundled for browser use.
10
11
  const transformerPreset = await loadJson('./presets/models/transformer.json', import.meta.url, 'Failed to load preset');
@@ -190,18 +191,21 @@ export function resolveConfig(
190
191
  // Note: Uses nullish coalesce (??) so null values fall through to next level.
191
192
  // This means explicit null in manifest = "use preset/default".
192
193
  const presetArch = preset.architecture || {};
193
- const numLayers = manifestArch.numLayers ?? presetArch.numLayers;
194
- const hiddenSize = manifestArch.hiddenSize ?? presetArch.hiddenSize;
195
- const intermediateSize = manifestArch.intermediateSize ?? presetArch.intermediateSize;
196
- const numAttentionHeads = manifestArch.numAttentionHeads ?? presetArch.numAttentionHeads;
197
- const numKeyValueHeads = manifestArch.numKeyValueHeads ?? presetArch.numKeyValueHeads ?? numAttentionHeads;
198
- const headDim = manifestArch.headDim ?? presetArch.headDim ?? (
199
- hiddenSize && numAttentionHeads ? hiddenSize / numAttentionHeads : undefined
194
+ const numLayers = chooseNullish(manifestArch.numLayers, presetArch.numLayers);
195
+ const hiddenSize = chooseNullish(manifestArch.hiddenSize, presetArch.hiddenSize);
196
+ const intermediateSize = chooseNullish(manifestArch.intermediateSize, presetArch.intermediateSize);
197
+ const numAttentionHeads = chooseNullish(manifestArch.numAttentionHeads, presetArch.numAttentionHeads);
198
+ const numKeyValueHeads = chooseNullish(
199
+ manifestArch.numKeyValueHeads,
200
+ chooseNullish(presetArch.numKeyValueHeads, numAttentionHeads)
200
201
  );
201
- const vocabSize = manifestArch.vocabSize ?? presetArch.vocabSize;
202
- const maxSeqLen = manifestArch.maxSeqLen ?? presetArch.maxSeqLen;
203
- const ropeTheta = manifestArch.ropeTheta ?? presetArch.ropeTheta;
204
- const rmsNormEps = manifestArch.rmsNormEps ?? presetArch.rmsNormEps;
202
+ const headDim = chooseNullish(manifestArch.headDim, chooseNullish(presetArch.headDim, (
203
+ hiddenSize && numAttentionHeads ? hiddenSize / numAttentionHeads : undefined
204
+ )));
205
+ const vocabSize = chooseNullish(manifestArch.vocabSize, presetArch.vocabSize);
206
+ const maxSeqLen = chooseNullish(manifestArch.maxSeqLen, presetArch.maxSeqLen);
207
+ const ropeTheta = chooseNullish(manifestArch.ropeTheta, presetArch.ropeTheta);
208
+ const rmsNormEps = chooseNullish(manifestArch.rmsNormEps, presetArch.rmsNormEps);
205
209
 
206
210
  const architecture = {
207
211
  numLayers,
@@ -226,44 +230,44 @@ export function resolveConfig(
226
230
  const manifestInference = extractInferenceFromConfig(manifest.config || {});
227
231
 
228
232
  const inference = {
229
- attention: {
230
- ...baseInference.attention,
231
- ...presetInference.attention,
232
- ...manifestInference.attention,
233
- },
234
- normalization: {
235
- ...baseInference.normalization,
236
- ...presetInference.normalization,
237
- },
238
- ffn: {
239
- ...baseInference.ffn,
240
- ...presetInference.ffn,
241
- },
242
- moe: presetInference.moe ?? baseInference.moe ?? null,
243
- output: {
244
- ...baseInference.output,
245
- ...presetInference.output,
246
- ...manifestInference.output,
247
- },
248
- layerPattern: presetInference.layerPattern ?? baseInference.layerPattern,
249
- rope: {
250
- ...baseInference.rope,
251
- ...presetInference.rope,
252
- ...manifestInference.rope,
253
- },
254
- pipeline: manifestInference.pipeline ?? presetInference.pipeline ?? baseInference.pipeline,
255
- chatTemplate: {
256
- ...baseInference.chatTemplate,
257
- ...presetInference.chatTemplate,
258
- },
259
- kernelPath: presetInference.kernelPath ?? baseInference.kernelPath,
233
+ attention: mergeLayeredShallowObjects(
234
+ baseInference.attention,
235
+ presetInference.attention,
236
+ manifestInference.attention
237
+ ),
238
+ normalization: mergeLayeredShallowObjects(
239
+ baseInference.normalization,
240
+ presetInference.normalization
241
+ ),
242
+ ffn: mergeLayeredShallowObjects(
243
+ baseInference.ffn,
244
+ presetInference.ffn
245
+ ),
246
+ moe: chooseNullish(presetInference.moe, chooseNullish(baseInference.moe, null)),
247
+ output: mergeLayeredShallowObjects(
248
+ baseInference.output,
249
+ presetInference.output,
250
+ manifestInference.output
251
+ ),
252
+ layerPattern: chooseNullish(presetInference.layerPattern, baseInference.layerPattern),
253
+ rope: mergeLayeredShallowObjects(
254
+ baseInference.rope,
255
+ presetInference.rope,
256
+ manifestInference.rope
257
+ ),
258
+ pipeline: chooseNullish(manifestInference.pipeline, chooseNullish(presetInference.pipeline, baseInference.pipeline)),
259
+ chatTemplate: mergeLayeredShallowObjects(
260
+ baseInference.chatTemplate,
261
+ presetInference.chatTemplate
262
+ ),
263
+ kernelPath: chooseNullish(presetInference.kernelPath, baseInference.kernelPath),
260
264
  };
261
265
 
262
266
  // Merge tokenizer config
263
- const tokenizer = {
264
- ...preset.tokenizer,
265
- ...extractTokenizerFromManifest(manifest),
266
- };
267
+ const tokenizer = mergeLayeredShallowObjects(
268
+ preset.tokenizer,
269
+ extractTokenizerFromManifest(manifest)
270
+ );
267
271
 
268
272
  // Sampling defaults
269
273
  const sampling = preset.sampling ?? {
@@ -0,0 +1,16 @@
1
+ export interface MergeContractCheckResult {
2
+ id: string;
3
+ ok: boolean;
4
+ detail: string;
5
+ mode: 'actual' | 'modeled';
6
+ }
7
+
8
+ export interface MergeContractArtifact {
9
+ schemaVersion: 1;
10
+ source: 'doppler';
11
+ ok: boolean;
12
+ checks: MergeContractCheckResult[];
13
+ errors: string[];
14
+ }
15
+
16
+ export declare function buildMergeContractArtifact(): MergeContractArtifact;