pie-bench 0.1.2__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 (193) hide show
  1. pie_bench-0.1.2/.gitignore +7 -0
  2. pie_bench-0.1.2/PKG-INFO +76 -0
  3. pie_bench-0.1.2/PYPI.md +34 -0
  4. pie_bench-0.1.2/pyproject.toml +59 -0
  5. pie_bench-0.1.2/src/pie_bench/__init__.py +1 -0
  6. pie_bench-0.1.2/src/pie_bench/cli.py +204 -0
  7. pie_bench-0.1.2/src/pie_bench/clients/bench_pie.py +1687 -0
  8. pie_bench-0.1.2/src/pie_bench/clients/browser/bench.mjs +103 -0
  9. pie_bench-0.1.2/src/pie_bench/clients/browser/native.mjs +24 -0
  10. pie_bench-0.1.2/src/pie_bench/clients/common.py +1046 -0
  11. pie_bench-0.1.2/src/pie_bench/clients/engram_token_map.py +93 -0
  12. pie_bench-0.1.2/src/pie_bench/clients/llamacpp_bench.py +192 -0
  13. pie_bench-0.1.2/src/pie_bench/clients/mlx_bench.py +269 -0
  14. pie_bench-0.1.2/src/pie_bench/clients/sglang_bench.py +358 -0
  15. pie_bench-0.1.2/src/pie_bench/clients/shrink_checkpoint.py +1957 -0
  16. pie_bench-0.1.2/src/pie_bench/clients/vllm_bench.py +812 -0
  17. pie_bench-0.1.2/src/pie_bench/config.json +73 -0
  18. pie_bench-0.1.2/src/pie_bench/inferlets/first-token-topk/Cargo.toml +13 -0
  19. pie_bench-0.1.2/src/pie_bench/inferlets/first-token-topk/src/lib.rs +55 -0
  20. pie_bench-0.1.2/src/pie_bench/inferlets/prefill-while-typing/Cargo.toml +12 -0
  21. pie_bench-0.1.2/src/pie_bench/inferlets/prefill-while-typing/src/lib.rs +434 -0
  22. pie_bench-0.1.2/src/pie_bench/local.py +199 -0
  23. pie_bench-0.1.2/src/pie_bench/matrix/engines.yaml +94 -0
  24. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/deepseek-v4-flash-mini.json +1 -0
  25. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/deepseek-v4.1-flash-mini8.json +1 -0
  26. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/gemma-4-12b-mini12.json +1 -0
  27. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/gemma-4-26b-a4b-mini-e24.json +1 -0
  28. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/gemma-4-26b-a4b-mini-e32.json +1 -0
  29. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/gemma-4-26b-a4b-mini.json +1 -0
  30. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/gemma-4-26b-a4b-mini12-e32.json +1 -0
  31. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/gemma-4-26b-a4b-mlx4-slice.json +1 -0
  32. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/gemma-4-31b-mini.json +1 -0
  33. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/gemma-4-31b-mini12.json +1 -0
  34. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/gemma-4-31b-mini18.json +1 -0
  35. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/gemma-4-31b-mini6.json +1 -0
  36. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/gemma-4-31b-mlx4-slice-l30.json +1 -0
  37. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/gemma-4-31b-mlx4-slice.json +1 -0
  38. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/glm-5.3-flash-mini4-tpu.json +1 -0
  39. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/glm-5.3-flash-mini8-fp8.json +1 -0
  40. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/glm-5.3-mini.json +1 -0
  41. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/glm-5.3-mini78-e12.json +1 -0
  42. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/glm-5.3-mini78.json +1 -0
  43. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/gpt-oss-120b-mlx-mxfp4-slice-e10.json +1 -0
  44. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/gpt-oss-120b-mxfp4-mini12-e32.json +1 -0
  45. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/gpt-oss-120b-mxfp4-mini24-e32.json +1 -0
  46. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/gpt-oss-20b-mlx4-slice.json +1 -0
  47. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/gpt-oss-20b-mxfp4-mini12.json +1 -0
  48. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/hy4-mini6.json +1 -0
  49. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/kimi-k3-mini4-e16.json +1 -0
  50. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/kimi-k3-mini4.json +1 -0
  51. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/kimi-k3-mini8.json +1 -0
  52. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/mimo-v2.6-flash-mini.json +1 -0
  53. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/minimax-m3.1-flash-mini.json +1 -0
  54. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/minimax-m3.1-flash-mini60-e16.json +1 -0
  55. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/muse-glimmer-30b-mini.json +1 -0
  56. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/muse-glimmer-30b-mini12.json +1 -0
  57. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/muse-glimmer-30b-mini4.json +1 -0
  58. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/muse-glimmer-30b-mini8.json +1 -0
  59. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/muse-glimmer-30b-mlx4-slice.json +1 -0
  60. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/muse-spark-mini2-e8.json +1 -0
  61. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/muse-spark-mini4-e10.json +1 -0
  62. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/muse-spark-mini4.json +1 -0
  63. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/muse-spark-mlx4-slice-l2-e8.json +1 -0
  64. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/nemotron-3-super-mini.json +1 -0
  65. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/nemotron-3-super-mini22.json +1 -0
  66. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/nemotron-3-super-mini88-e64.json +1 -0
  67. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/nemotron-3-super-mini88.json +1 -0
  68. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/nemotron-3-ultra-mini-e16.json +1 -0
  69. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/nemotron-3-ultra-mini-e32.json +1 -0
  70. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/nemotron-3-ultra-mini.json +1 -0
  71. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/qwen3.6-27b-mini.json +1 -0
  72. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/qwen3.6-27b-mini12.json +1 -0
  73. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/qwen3.6-27b-mini8.json +1 -0
  74. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/qwen3.6-27b-mlx4-slice.json +1 -0
  75. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/qwen3.6-35b-a3b-mini-e16.json +1 -0
  76. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/qwen3.6-35b-a3b-mini-e32.json +1 -0
  77. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/qwen3.6-35b-a3b-mini.json +1 -0
  78. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/qwen3.8-27b-mini.json +1 -0
  79. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/qwen3.8-27b-mini12.json +1 -0
  80. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/qwen3.8-27b-mini20.json +1 -0
  81. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/qwen3.8-27b-mini8.json +1 -0
  82. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/qwen3.8-27b-mlx4-slice.json +1 -0
  83. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/qwen3.8-flash-next-mini.json +1 -0
  84. pie_bench-0.1.2/src/pie_bench/matrix/first-token-ref/qwen3.8-flash-next-mini10.json +1 -0
  85. pie_bench-0.1.2/src/pie_bench/matrix/hardware.yaml +1609 -0
  86. pie_bench-0.1.2/src/pie_bench/matrix/install.yaml +224 -0
  87. pie_bench-0.1.2/src/pie_bench/matrix/models.yaml +2579 -0
  88. pie_bench-0.1.2/src/pie_bench/matrix/modes.yaml +13 -0
  89. pie_bench-0.1.2/src/pie_bench/matrix/parity-texts/deepseek-v4.1-flash-mini8.json +49 -0
  90. pie_bench-0.1.2/src/pie_bench/matrix/parity-texts/minimax-m3.1-flash-mini60-e16.json +49 -0
  91. pie_bench-0.1.2/src/pie_bench/matrix/parity-texts/nemotron-3-super-mini88-e64.json +49 -0
  92. pie_bench-0.1.2/src/pie_bench/matrix/phones.yaml +28 -0
  93. pie_bench-0.1.2/src/pie_bench/matrix/platforms.yaml +973 -0
  94. pie_bench-0.1.2/src/pie_bench/matrix/programs.yaml +140 -0
  95. pie_bench-0.1.2/src/pie_bench/matrix/suites.yaml +172 -0
  96. pie_bench-0.1.2/src/pie_bench/matrix/support.yaml +347 -0
  97. pie_bench-0.1.2/src/pie_bench/matrix/workloads.yaml +310 -0
  98. pie_bench-0.1.2/src/pie_bench/node/__init__.py +4 -0
  99. pie_bench-0.1.2/src/pie_bench/node/accuracy/__init__.py +13 -0
  100. pie_bench-0.1.2/src/pie_bench/node/accuracy/gate.py +233 -0
  101. pie_bench-0.1.2/src/pie_bench/node/accuracy/parity.py +156 -0
  102. pie_bench-0.1.2/src/pie_bench/node/accuracy/prompts.py +51 -0
  103. pie_bench-0.1.2/src/pie_bench/node/accuracy/reference.py +247 -0
  104. pie_bench-0.1.2/src/pie_bench/node/baselines.py +410 -0
  105. pie_bench-0.1.2/src/pie_bench/node/build.py +237 -0
  106. pie_bench-0.1.2/src/pie_bench/node/engines/__init__.py +1 -0
  107. pie_bench-0.1.2/src/pie_bench/node/engines/base.py +535 -0
  108. pie_bench-0.1.2/src/pie_bench/node/engines/browser/.gitignore +1 -0
  109. pie_bench-0.1.2/src/pie_bench/node/engines/browser/bridge.mjs +178 -0
  110. pie_bench-0.1.2/src/pie_bench/node/engines/browser/llamacpp/build.sh +39 -0
  111. pie_bench-0.1.2/src/pie_bench/node/engines/browser/llamacpp/lw.cpp +143 -0
  112. pie_bench-0.1.2/src/pie_bench/node/engines/browser/package-lock.json +63 -0
  113. pie_bench-0.1.2/src/pie_bench/node/engines/browser/package.json +10 -0
  114. pie_bench-0.1.2/src/pie_bench/node/engines/browser/page/driver.mjs +79 -0
  115. pie_bench-0.1.2/src/pie_bench/node/engines/browser/page/engines/llamacpp-worker.mjs +60 -0
  116. pie_bench-0.1.2/src/pie_bench/node/engines/browser/page/engines/llamacpp.mjs +51 -0
  117. pie_bench-0.1.2/src/pie_bench/node/engines/browser/page/engines/pie.mjs +63 -0
  118. pie_bench-0.1.2/src/pie_bench/node/engines/browser/page/engines/webllm.mjs +40 -0
  119. pie_bench-0.1.2/src/pie_bench/node/engines/browser/page/index.html +4 -0
  120. pie_bench-0.1.2/src/pie_bench/node/engines/browser.py +282 -0
  121. pie_bench-0.1.2/src/pie_bench/node/engines/lifeline.py +31 -0
  122. pie_bench-0.1.2/src/pie_bench/node/engines/llamacpp.py +103 -0
  123. pie_bench-0.1.2/src/pie_bench/node/engines/mlxlm.py +91 -0
  124. pie_bench-0.1.2/src/pie_bench/node/engines/pie.py +455 -0
  125. pie_bench-0.1.2/src/pie_bench/node/engines/recipes/__init__.py +119 -0
  126. pie_bench-0.1.2/src/pie_bench/node/engines/recipes/llamacpp-webgpu.yaml +20 -0
  127. pie_bench-0.1.2/src/pie_bench/node/engines/recipes/llamacpp.yaml +107 -0
  128. pie_bench-0.1.2/src/pie_bench/node/engines/recipes/mlxlm.yaml +62 -0
  129. pie_bench-0.1.2/src/pie_bench/node/engines/recipes/pie.yaml +884 -0
  130. pie_bench-0.1.2/src/pie_bench/node/engines/recipes/sglang.yaml +219 -0
  131. pie_bench-0.1.2/src/pie_bench/node/engines/recipes/splash.yaml +35 -0
  132. pie_bench-0.1.2/src/pie_bench/node/engines/recipes/trtllm.yaml +128 -0
  133. pie_bench-0.1.2/src/pie_bench/node/engines/recipes/vllm-metal.yaml +51 -0
  134. pie_bench-0.1.2/src/pie_bench/node/engines/recipes/vllm.yaml +434 -0
  135. pie_bench-0.1.2/src/pie_bench/node/engines/recipes/webllm.yaml +28 -0
  136. pie_bench-0.1.2/src/pie_bench/node/engines/scripts/browser_bench.py +117 -0
  137. pie_bench-0.1.2/src/pie_bench/node/engines/scripts/mlx_quantize_in_place.py +87 -0
  138. pie_bench-0.1.2/src/pie_bench/node/engines/scripts/mlx_unfused.py +39 -0
  139. pie_bench-0.1.2/src/pie_bench/node/engines/scripts/no_peer_site/sitecustomize.py +35 -0
  140. pie_bench-0.1.2/src/pie_bench/node/engines/scripts/openai_bench.py +233 -0
  141. pie_bench-0.1.2/src/pie_bench/node/engines/scripts/parity_mlx.py +41 -0
  142. pie_bench-0.1.2/src/pie_bench/node/engines/scripts/parity_mlxvlm.py +34 -0
  143. pie_bench-0.1.2/src/pie_bench/node/engines/scripts/parity_pie_serve.py +39 -0
  144. pie_bench-0.1.2/src/pie_bench/node/engines/scripts/pie_xla.py +52 -0
  145. pie_bench-0.1.2/src/pie_bench/node/engines/scripts/quality_mlxvlm.py +14 -0
  146. pie_bench-0.1.2/src/pie_bench/node/engines/scripts/quality_pie.py +60 -0
  147. pie_bench-0.1.2/src/pie_bench/node/engines/scripts/trtllm_bench.py +134 -0
  148. pie_bench-0.1.2/src/pie_bench/node/engines/scripts/vllm_tpu_site/sitecustomize.py +116 -0
  149. pie_bench-0.1.2/src/pie_bench/node/engines/served.py +170 -0
  150. pie_bench-0.1.2/src/pie_bench/node/engines/sglang.py +247 -0
  151. pie_bench-0.1.2/src/pie_bench/node/engines/shape.py +114 -0
  152. pie_bench-0.1.2/src/pie_bench/node/engines/splash.py +66 -0
  153. pie_bench-0.1.2/src/pie_bench/node/engines/trtllm.py +130 -0
  154. pie_bench-0.1.2/src/pie_bench/node/engines/vllm.py +216 -0
  155. pie_bench-0.1.2/src/pie_bench/node/engines/vllm_metal.py +60 -0
  156. pie_bench-0.1.2/src/pie_bench/node/fair.py +104 -0
  157. pie_bench-0.1.2/src/pie_bench/node/gguf_slice.py +231 -0
  158. pie_bench-0.1.2/src/pie_bench/node/importer.py +96 -0
  159. pie_bench-0.1.2/src/pie_bench/node/machine.py +48 -0
  160. pie_bench-0.1.2/src/pie_bench/node/metrics/__init__.py +7 -0
  161. pie_bench-0.1.2/src/pie_bench/node/metrics/stats.py +74 -0
  162. pie_bench-0.1.2/src/pie_bench/node/miniature.py +184 -0
  163. pie_bench-0.1.2/src/pie_bench/node/mlx_quantize.py +62 -0
  164. pie_bench-0.1.2/src/pie_bench/node/preflight.py +447 -0
  165. pie_bench-0.1.2/src/pie_bench/node/profile.py +43 -0
  166. pie_bench-0.1.2/src/pie_bench/node/provenance.py +248 -0
  167. pie_bench-0.1.2/src/pie_bench/node/reclaim.py +92 -0
  168. pie_bench-0.1.2/src/pie_bench/node/runner.py +699 -0
  169. pie_bench-0.1.2/src/pie_bench/node/snapshots.py +136 -0
  170. pie_bench-0.1.2/src/pie_bench/node/validate.py +28 -0
  171. pie_bench-0.1.2/src/pie_bench/node/widen.py +128 -0
  172. pie_bench-0.1.2/src/pie_bench/node/workloads/__init__.py +1 -0
  173. pie_bench-0.1.2/src/pie_bench/node/workloads/synthetic.py +70 -0
  174. pie_bench-0.1.2/src/pie_bench/paths.py +7 -0
  175. pie_bench-0.1.2/src/pie_bench/plan/__init__.py +1 -0
  176. pie_bench-0.1.2/src/pie_bench/plan/jobs.py +154 -0
  177. pie_bench-0.1.2/src/pie_bench/plan/matrix.py +341 -0
  178. pie_bench-0.1.2/src/pie_bench/plan/suites.py +31 -0
  179. pie_bench-0.1.2/src/pie_bench/quality/__init__.py +0 -0
  180. pie_bench-0.1.2/src/pie_bench/quality/browser.py +129 -0
  181. pie_bench-0.1.2/src/pie_bench/quality/dist_run.py +536 -0
  182. pie_bench-0.1.2/src/pie_bench/quality/engines.py +188 -0
  183. pie_bench-0.1.2/src/pie_bench/quality/kl.py +161 -0
  184. pie_bench-0.1.2/src/pie_bench/quality/parity.py +83 -0
  185. pie_bench-0.1.2/src/pie_bench/quality/run.py +153 -0
  186. pie_bench-0.1.2/src/pie_bench/quality/tasks.py +177 -0
  187. pie_bench-0.1.2/src/pie_bench/results/__init__.py +1 -0
  188. pie_bench-0.1.2/src/pie_bench/results/store.py +287 -0
  189. pie_bench-0.1.2/src/pie_bench/schema/__init__.py +21 -0
  190. pie_bench-0.1.2/src/pie_bench/schema/cell.py +307 -0
  191. pie_bench-0.1.2/src/pie_bench/schema/job.py +48 -0
  192. pie_bench-0.1.2/src/pie_bench/schema/record.py +275 -0
  193. pie_bench-0.1.2/src/pie_bench/submit.py +90 -0
@@ -0,0 +1,7 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ dist/
5
+ *.egg-info/
6
+ .pytest_cache/
7
+ .ruff_cache/
@@ -0,0 +1,76 @@
1
+ Metadata-Version: 2.5
2
+ Name: pie-bench
3
+ Version: 0.1.2
4
+ Summary: Measure pie against other inference engines on your own machine and publish the results.
5
+ Project-URL: Homepage, https://pie-project.org/benchmarks
6
+ Project-URL: Source, https://github.com/pie-project/benchmarks
7
+ License-Expression: Apache-2.0
8
+ Requires-Python: >=3.11
9
+ Requires-Dist: click>=8.1
10
+ Requires-Dist: hf-xet>=1.1
11
+ Requires-Dist: huggingface-hub>=0.24
12
+ Requires-Dist: mlx-lm; sys_platform == 'darwin'
13
+ Requires-Dist: numpy>=1.26
14
+ Requires-Dist: pyarrow>=16.0
15
+ Requires-Dist: pydantic>=2.7
16
+ Requires-Dist: pyyaml>=6.0
17
+ Requires-Dist: requests>=2.31
18
+ Requires-Dist: transformers>=4.44
19
+ Provides-Extra: dev
20
+ Requires-Dist: fastapi>=0.115; extra == 'dev'
21
+ Requires-Dist: httpx>=0.27; extra == 'dev'
22
+ Requires-Dist: psycopg-pool>=3.2; extra == 'dev'
23
+ Requires-Dist: psycopg[binary]>=3.2; extra == 'dev'
24
+ Requires-Dist: pyjwt>=2.8; extra == 'dev'
25
+ Requires-Dist: pytest-timeout>=2.3; extra == 'dev'
26
+ Requires-Dist: pytest>=8.0; extra == 'dev'
27
+ Requires-Dist: ruff>=0.5; extra == 'dev'
28
+ Provides-Extra: quality
29
+ Requires-Dist: blobfile; extra == 'quality'
30
+ Requires-Dist: jinja2; extra == 'quality'
31
+ Requires-Dist: lm-eval[ifeval]>=0.4; extra == 'quality'
32
+ Requires-Dist: tiktoken; extra == 'quality'
33
+ Provides-Extra: server
34
+ Requires-Dist: fastapi>=0.115; extra == 'server'
35
+ Requires-Dist: psycopg-pool>=3.2; extra == 'server'
36
+ Requires-Dist: psycopg[binary]>=3.2; extra == 'server'
37
+ Requires-Dist: pyjwt>=2.8; extra == 'server'
38
+ Requires-Dist: uvicorn[standard]>=0.30; extra == 'server'
39
+ Provides-Extra: torch
40
+ Requires-Dist: torch; extra == 'torch'
41
+ Description-Content-Type: text/markdown
42
+
43
+ # pie-bench
44
+
45
+ Measure [Pie](https://github.com/pie-project/pie) against other inference engines on your own machine, and share the results on [pie-project.org/benchmarks](https://pie-project.org/benchmarks).
46
+
47
+ ## Run it
48
+
49
+ ```sh
50
+ pip install pie-bench
51
+ pie-bench doctor
52
+ pie-bench run
53
+ ```
54
+
55
+ `pie-bench run` detects the machine, picks the models that fit, installs each engine at its pinned version, builds pie, measures every engine on the same prompts, and uploads one signed submission when it is done. Nothing is sent while it runs.
56
+
57
+ ```sh
58
+ pie-bench plan # what would run here
59
+ pie-bench run --models qwen3.6-35b # only some models
60
+ pie-bench run --engines pie,llamacpp # only some engines
61
+ pie-bench run --pie 0.6.0 # a pie release, branch or commit
62
+ pie-bench run --no-upload # keep the results local
63
+ pie-bench upload ~/.pie-bench/runs/<time> # upload later
64
+ ```
65
+
66
+ Each run writes a folder under `~/.pie-bench/runs/`:
67
+
68
+ | File | What |
69
+ |---|---|
70
+ | `records.jsonl` | one line per measured cell |
71
+ | `run.log` | the full log, for audit and debugging |
72
+ | `submission.json.gz` | both, plus machine specs and versions: what gets uploaded |
73
+
74
+ Uploading needs a token, made automatically the first time and kept in `~/.config/pie-bench/token`.
75
+
76
+ Requirements: Python 3.11+, git, [Rust](https://rustup.rs) and [uv](https://docs.astral.sh/uv/). On a Mac, Apple Silicon. On Linux, NVIDIA GPUs.
@@ -0,0 +1,34 @@
1
+ # pie-bench
2
+
3
+ Measure [Pie](https://github.com/pie-project/pie) against other inference engines on your own machine, and share the results on [pie-project.org/benchmarks](https://pie-project.org/benchmarks).
4
+
5
+ ## Run it
6
+
7
+ ```sh
8
+ pip install pie-bench
9
+ pie-bench doctor
10
+ pie-bench run
11
+ ```
12
+
13
+ `pie-bench run` detects the machine, picks the models that fit, installs each engine at its pinned version, builds pie, measures every engine on the same prompts, and uploads one signed submission when it is done. Nothing is sent while it runs.
14
+
15
+ ```sh
16
+ pie-bench plan # what would run here
17
+ pie-bench run --models qwen3.6-35b # only some models
18
+ pie-bench run --engines pie,llamacpp # only some engines
19
+ pie-bench run --pie 0.6.0 # a pie release, branch or commit
20
+ pie-bench run --no-upload # keep the results local
21
+ pie-bench upload ~/.pie-bench/runs/<time> # upload later
22
+ ```
23
+
24
+ Each run writes a folder under `~/.pie-bench/runs/`:
25
+
26
+ | File | What |
27
+ |---|---|
28
+ | `records.jsonl` | one line per measured cell |
29
+ | `run.log` | the full log, for audit and debugging |
30
+ | `submission.json.gz` | both, plus machine specs and versions: what gets uploaded |
31
+
32
+ Uploading needs a token, made automatically the first time and kept in `~/.config/pie-bench/token`.
33
+
34
+ Requirements: Python 3.11+, git, [Rust](https://rustup.rs) and [uv](https://docs.astral.sh/uv/). On a Mac, Apple Silicon. On Linux, NVIDIA GPUs.
@@ -0,0 +1,59 @@
1
+ [project]
2
+ name = "pie-bench"
3
+ version = "0.1.2"
4
+ description = "Measure pie against other inference engines on your own machine and publish the results."
5
+ readme = "PYPI.md"
6
+ license = "Apache-2.0"
7
+ requires-python = ">=3.11"
8
+ dependencies = [
9
+ "pydantic>=2.7",
10
+ "pyyaml>=6.0",
11
+ "pyarrow>=16.0",
12
+ "numpy>=1.26",
13
+ "click>=8.1",
14
+ "requests>=2.31",
15
+ "huggingface_hub>=0.24",
16
+ "hf_xet>=1.1",
17
+ "transformers>=4.44",
18
+ "mlx-lm; sys_platform == 'darwin'",
19
+ ]
20
+
21
+ [project.optional-dependencies]
22
+ quality = ["lm-eval[ifeval]>=0.4", "jinja2", "tiktoken", "blobfile"]
23
+ torch = ["torch"]
24
+ server = ["fastapi>=0.115", "uvicorn[standard]>=0.30", "psycopg[binary]>=3.2", "psycopg-pool>=3.2", "pyjwt>=2.8"]
25
+ dev = ["pytest>=8.0", "pytest-timeout>=2.3", "ruff>=0.5", "httpx>=0.27", "fastapi>=0.115", "psycopg[binary]>=3.2", "psycopg-pool>=3.2", "pyjwt>=2.8"]
26
+
27
+ [project.urls]
28
+ Homepage = "https://pie-project.org/benchmarks"
29
+ Source = "https://github.com/pie-project/benchmarks"
30
+
31
+ [project.scripts]
32
+ pie-bench = "pie_bench.cli:main"
33
+
34
+ [build-system]
35
+ requires = ["hatchling"]
36
+ build-backend = "hatchling.build"
37
+
38
+ [tool.hatch.build.targets.wheel]
39
+ packages = ["src/pie_bench"]
40
+
41
+ [tool.hatch.build.targets.sdist]
42
+ include = ["/src/pie_bench", "/PYPI.md"]
43
+
44
+ [tool.ruff]
45
+ line-length = 100
46
+ target-version = "py311"
47
+
48
+ [tool.pytest.ini_options]
49
+ testpaths = ["tests"]
50
+ pythonpath = ["."]
51
+ timeout = 120
52
+ markers = ["slow: expands the whole matrix"]
53
+
54
+ [tool.ruff.lint]
55
+ select = ["E", "F", "I", "UP", "B"]
56
+ ignore = ["E501", "E731", "UP017", "B008", "B905", "E402", "B023", "B904"]
57
+
58
+ [tool.ruff.lint.per-file-ignores]
59
+ "__init__.py" = ["F401"]
@@ -0,0 +1 @@
1
+ __version__ = "0.1.2"
@@ -0,0 +1,204 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import os
5
+ import shutil
6
+ import subprocess
7
+ import sys
8
+ from datetime import datetime, timezone
9
+ from pathlib import Path
10
+
11
+ import click
12
+
13
+ from pie_bench import __version__, local, submit
14
+ from pie_bench.paths import MATRIX
15
+ from pie_bench.plan.matrix import Matrix
16
+ from pie_bench.plan.suites import SUITES
17
+
18
+ PATHS = [Path.home() / ".local/bin", Path.home() / ".cargo/bin", Path("/opt/homebrew/bin")]
19
+
20
+
21
+ def _split(values: tuple[str, ...]) -> list[str] | None:
22
+ out = [v.strip() for s in values for v in s.split(",") if v.strip()]
23
+ return out or None
24
+
25
+
26
+ def _say(msg: str) -> None:
27
+ click.echo(msg, err=True)
28
+
29
+
30
+ def _env() -> None:
31
+ os.environ["PATH"] = os.pathsep.join([*(str(p) for p in PATHS if p.is_dir()), os.environ.get("PATH", "")])
32
+
33
+
34
+ def _mask_gpus(count: int) -> None:
35
+ if os.environ.get("CUDA_VISIBLE_DEVICES") or not shutil.which("nvidia-smi"):
36
+ return
37
+ visible = sum(1 for ln in subprocess.run(["nvidia-smi", "-L"], capture_output=True, text=True).stdout.splitlines() if ln.startswith("GPU "))
38
+ if visible > count:
39
+ os.environ["CUDA_VISIBLE_DEVICES"] = ",".join(str(i) for i in range(count))
40
+
41
+
42
+ def _upload(out: Path) -> None:
43
+ path = out / submit.SUBMISSION
44
+ _say(f"uploading {path} to {submit.API}")
45
+ try:
46
+ res = submit.upload(path)
47
+ except submit.ApiError as e:
48
+ _say(f"upload failed: {e}\nyour results are safe in {out}; retry with: pie-bench upload {out}")
49
+ sys.exit(1)
50
+ _say(f"uploaded: run {res.get('run_id')}, {res.get('results', 0)} results")
51
+
52
+
53
+ @click.group()
54
+ @click.version_option(__version__, prog_name="pie-bench")
55
+ def main():
56
+ _env()
57
+
58
+
59
+ @main.command(help="Measure pie against the other engines on this machine, then upload the results.")
60
+ @click.option("--models", multiple=True, help="model names to measure, comma-separated (default: the release suite)")
61
+ @click.option("--engines", multiple=True, help="engines to measure, comma-separated (default: every engine on this machine)")
62
+ @click.option("--workloads", multiple=True, help="workload ids, comma-separated (default: the release workloads)")
63
+ @click.option("--suite", type=click.Choice(SUITES), default="targeted", show_default=True)
64
+ @click.option("--machine", "machine_id", default=None, help="this machine's id when it is not detected")
65
+ @click.option("--pie", "pie_ref", default="latest", show_default=True, help="pie release tag, branch or commit")
66
+ @click.option("--pie-root", type=click.Path(path_type=Path), default=None, help="an existing pie checkout to build and use")
67
+ @click.option("--out", type=click.Path(path_type=Path), default=None, help="folder for the results (default: ~/.pie-bench/runs/<time>)")
68
+ @click.option("--upload/--no-upload", default=True, show_default=True)
69
+ @click.option("-y", "--yes", is_flag=True, help="start without asking")
70
+ def run(models, engines, workloads, suite, machine_id, pie_ref, pie_root, out, upload, yes):
71
+ m = Matrix.load(MATRIX)
72
+ machine = local.detect(m, machine_id)
73
+ missing = local.prerequisites(machine)
74
+ if missing:
75
+ _say("install these first:\n " + "\n ".join(missing))
76
+ sys.exit(1)
77
+ commit, tag = local.resolve_pie(pie_ref)
78
+ job = local.plan(m, machine, pie_commit=commit, models=_split(models), engines=_split(engines), workloads=_split(workloads), suite=suite)
79
+ if job is None:
80
+ _say(f"nothing to measure on {machine.platform.id}; try `pie-bench plan` with other --models")
81
+ sys.exit(1)
82
+ groups = job.cells_by_process()
83
+ _say(f"machine {machine.platform.id} ({machine.platform.accelerator}, {machine.platform.memory_gib:g} GiB){'' if machine.known else ', new to the catalog'}")
84
+ _say(f"pie {tag} ({commit[:9]})")
85
+ _say(f"measure {len(job.cells)} cells, {len({c.artifact.id for c in job.cells})} models, engines {', '.join(sorted({str(c.engine) for c in job.cells}))}")
86
+ _say(f"estimate about {max(1, round(job.est_minutes + 3 * len(groups)))} minutes, plus model downloads on a first run")
87
+ if not yes and not click.confirm("start?", default=True, err=True):
88
+ return
89
+ out = (out or local.HOME / "runs" / datetime.now(timezone.utc).strftime("%Y%m%d-%H%M%S")).resolve()
90
+ out.mkdir(parents=True, exist_ok=True)
91
+ (out / "job.json").write_text(job.model_dump_json(indent=1))
92
+ os.environ.update(local.setup_engines(m, job, log=_say))
93
+ _mask_gpus(machine.platform.count)
94
+ from pie_bench.node.machine import MachineBusy, machine_lock
95
+ from pie_bench.node.runner import NodeRunner
96
+
97
+ try:
98
+ with machine_lock(job.job_id, max_wait_s=3600, log=_say):
99
+ runner = NodeRunner(job, pie_root=(pie_root or local.HOME / "pie").resolve(), out_dir=out, download=True)
100
+ recs = runner.run()
101
+ except MachineBusy as e:
102
+ _say(str(e))
103
+ sys.exit(3)
104
+ by: dict[str, int] = {}
105
+ for r in recs:
106
+ by[str(r.status)] = by.get(str(r.status), 0) + 1
107
+ submit.pack(out, {"run_id": runner.run_id, "tier": str(job.tier), "tag": tag, "tag_kind": "release" if not tag.startswith("manual-") else "manual",
108
+ "platform": machine.platform.model_dump(mode="json"), "pie_commit": commit})
109
+ _say(f"done: {len(recs)} results ({', '.join(f'{v} {k}' for k, v in sorted(by.items()))}) in {out}")
110
+ if upload:
111
+ _upload(out)
112
+
113
+
114
+ @main.command(help="Show what `pie-bench run` would measure here, without running anything.")
115
+ @click.option("--models", multiple=True)
116
+ @click.option("--engines", multiple=True)
117
+ @click.option("--workloads", multiple=True)
118
+ @click.option("--suite", type=click.Choice(SUITES), default="targeted", show_default=True)
119
+ @click.option("--machine", "machine_id", default=None)
120
+ @click.option("--json", "as_json", is_flag=True)
121
+ def plan(models, engines, workloads, suite, machine_id, as_json):
122
+ m = Matrix.load(MATRIX)
123
+ machine = local.detect(m, machine_id)
124
+ job = local.plan(m, machine, pie_commit="0" * 40, models=_split(models), engines=_split(engines), workloads=_split(workloads), suite=suite)
125
+ cells = job.cells if job else []
126
+ if as_json:
127
+ click.echo(json.dumps([c.cell_key for c in cells], indent=1))
128
+ return
129
+ click.echo(f"{machine.platform.id}: {len(cells)} cells")
130
+ for (engine, artifact, _), group in (job.cells_by_process().items() if job else []):
131
+ click.echo(f" {engine:<10} {artifact:<60} {', '.join(sorted({c.workload.id for c in group}))}")
132
+
133
+
134
+ @main.command(help="Every machine id the catalog knows.")
135
+ def machines():
136
+ m = Matrix.load(MATRIX)
137
+ for p in sorted(m.platforms.values(), key=lambda p: (p.os, p.id)):
138
+ click.echo(f"{p.id:<22} {p.os:<6} {p.accelerator} x{p.count}, {p.memory_gib:g} GiB")
139
+
140
+
141
+ @main.command(help="Get an upload token for this machine (once).")
142
+ @click.option("--name", default=None, help="a name for this machine's token (default: its host name)")
143
+ def login(name):
144
+ try:
145
+ res = submit.login(name)
146
+ except submit.ApiError as e:
147
+ _say(f"login failed: {e}")
148
+ sys.exit(1)
149
+ _say(f"token saved to {submit.TOKEN_FILE} (quota {res.get('quota')} uploads)")
150
+
151
+
152
+ @main.command(help="Upload a finished run's folder.")
153
+ @click.argument("out", type=click.Path(exists=True, file_okay=False, path_type=Path))
154
+ def upload(out):
155
+ if not (out / submit.SUBMISSION).exists():
156
+ job = json.loads((out / "job.json").read_text())
157
+ run_id = (out / "run_id.txt").read_text().strip() if (out / "run_id.txt").exists() else job["job_id"]
158
+ submit.pack(out, {"run_id": run_id, "tier": job["tier"], "tag": None, "tag_kind": "manual",
159
+ "platform": job["cells"][0]["platform"] if job["cells"] else None, "pie_commit": job.get("pie_commit")})
160
+ _upload(out.resolve())
161
+
162
+
163
+ @main.command(help="Score model accuracy on question sets, then upload the scores.")
164
+ @click.option("--models", multiple=True, required=True, help="model artifact ids, comma-separated")
165
+ @click.option("--task", "tasks", multiple=True, default=("gsm8k", "ifeval", "mmlu", "arc", "math500"), show_default=True)
166
+ @click.option("--n", type=int, default=100, show_default=True)
167
+ @click.option("--pie-root", type=click.Path(path_type=Path), default=None)
168
+ @click.option("--out", type=click.Path(path_type=Path), default=None)
169
+ @click.option("--upload/--no-upload", default=True, show_default=True)
170
+ def quality(models, tasks, n, pie_root, out, upload):
171
+ from pie_bench.quality.run import run_quality
172
+
173
+ m = Matrix.load(MATRIX)
174
+ machine = local.detect(m)
175
+ out = (out or local.HOME / "runs" / f"quality-{datetime.now(timezone.utc):%Y%m%d-%H%M%S}").resolve()
176
+ out.mkdir(parents=True, exist_ok=True)
177
+ failed = []
178
+ for a in _split(models) or []:
179
+ try:
180
+ run_quality(a, _split(tasks), n, store_dir=str(out), pie_root=(pie_root or local.HOME / "pie").resolve(),
181
+ platform=machine.platform.id, log=_say)
182
+ except Exception as e:
183
+ failed.append(a)
184
+ _say(f"{a}: {type(e).__name__}: {e}")
185
+ submit.pack(out, {"run_id": out.name, "tier": "quality", "tag": None, "tag_kind": "manual", "platform": machine.platform.model_dump(mode="json"), "pie_commit": None})
186
+ if upload:
187
+ _upload(out)
188
+ sys.exit(1 if failed else 0)
189
+
190
+
191
+ @main.command(help="Check this machine is ready to run pie-bench.")
192
+ def doctor():
193
+ m = Matrix.load(MATRIX)
194
+ machine = local.detect(m)
195
+ click.echo(f"machine {machine.platform.id} ({machine.platform.accelerator}){'' if machine.known else ', new to the catalog'}")
196
+ missing = local.prerequisites(machine)
197
+ click.echo("tools " + ("ready" if not missing else "missing: " + "; ".join(missing)))
198
+ click.echo(f"token {'saved' if submit.saved_token() else 'not yet (made on the first upload)'}")
199
+ click.echo(f"api {submit.API}")
200
+ sys.exit(1 if missing else 0)
201
+
202
+
203
+ if __name__ == "__main__":
204
+ main()