nateraw commited on
Commit
c7a96cd
1 Parent(s): 8e14831

🍻 cheers

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .dockerignore +3 -0
  2. Cargo.lock +3402 -0
  3. Cargo.toml +16 -0
  4. Dockerfile +179 -99
  5. LICENSE +201 -0
  6. Makefile +45 -0
  7. aml/deployment.yaml +38 -0
  8. aml/endpoint.yaml +3 -0
  9. aml/model.yaml +3 -0
  10. assets/architecture.jpg +0 -0
  11. assets/benchmark.png +0 -0
  12. benchmark/Cargo.lock +2884 -0
  13. benchmark/Cargo.toml +35 -0
  14. benchmark/rust-toolchain.toml +3 -0
  15. benchmark/src/app.rs +688 -0
  16. benchmark/src/event.rs +65 -0
  17. benchmark/src/generation.rs +226 -0
  18. benchmark/src/lib.rs +110 -0
  19. benchmark/src/main.rs +131 -0
  20. benchmark/src/utils.rs +43 -0
  21. clients/python/Makefile +6 -0
  22. clients/python/poetry.lock +0 -0
  23. clients/python/pyproject.toml +29 -0
  24. clients/python/tests/conftest.py +51 -0
  25. clients/python/tests/test_client.py +146 -0
  26. clients/python/tests/test_errors.py +64 -0
  27. clients/python/tests/test_inference_api.py +42 -0
  28. clients/python/tests/test_types.py +84 -0
  29. clients/python/text_generation/__init__.py +18 -0
  30. clients/python/text_generation/client.py +481 -0
  31. clients/python/text_generation/errors.py +106 -0
  32. clients/python/text_generation/inference_api.py +168 -0
  33. clients/python/text_generation/types.py +231 -0
  34. docs/index.html +30 -0
  35. docs/openapi.json +730 -0
  36. k6/load_test.js +98 -0
  37. launcher/Cargo.toml +22 -0
  38. launcher/build.rs +29 -0
  39. launcher/src/env_runtime.rs +45 -0
  40. launcher/src/main.rs +925 -0
  41. launcher/tests/bloom_560m.json +142 -0
  42. launcher/tests/integration_tests.rs +172 -0
  43. launcher/tests/mt0_base.json +137 -0
  44. proto/generate.proto +181 -0
  45. router/Cargo.toml +44 -0
  46. router/build.rs +26 -0
  47. router/client/Cargo.toml +19 -0
  48. router/client/build.rs +19 -0
  49. router/client/src/client.rs +121 -0
  50. router/client/src/lib.rs +44 -0
.dockerignore ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ aml
2
+ target
3
+ server/transformers
Cargo.lock ADDED
@@ -0,0 +1,3402 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 3
4
+
5
+ [[package]]
6
+ name = "adler"
7
+ version = "1.0.2"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
10
+
11
+ [[package]]
12
+ name = "aes"
13
+ version = "0.7.5"
14
+ source = "registry+https://github.com/rust-lang/crates.io-index"
15
+ checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8"
16
+ dependencies = [
17
+ "cfg-if",
18
+ "cipher",
19
+ "cpufeatures",
20
+ "opaque-debug",
21
+ ]
22
+
23
+ [[package]]
24
+ name = "ahash"
25
+ version = "0.7.6"
26
+ source = "registry+https://github.com/rust-lang/crates.io-index"
27
+ checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
28
+ dependencies = [
29
+ "getrandom",
30
+ "once_cell",
31
+ "version_check",
32
+ ]
33
+
34
+ [[package]]
35
+ name = "aho-corasick"
36
+ version = "0.7.20"
37
+ source = "registry+https://github.com/rust-lang/crates.io-index"
38
+ checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
39
+ dependencies = [
40
+ "memchr",
41
+ ]
42
+
43
+ [[package]]
44
+ name = "anstream"
45
+ version = "0.3.0"
46
+ source = "registry+https://github.com/rust-lang/crates.io-index"
47
+ checksum = "9e579a7752471abc2a8268df8b20005e3eadd975f585398f17efcfd8d4927371"
48
+ dependencies = [
49
+ "anstyle",
50
+ "anstyle-parse",
51
+ "anstyle-query",
52
+ "anstyle-wincon",
53
+ "colorchoice",
54
+ "is-terminal",
55
+ "utf8parse",
56
+ ]
57
+
58
+ [[package]]
59
+ name = "anstyle"
60
+ version = "1.0.0"
61
+ source = "registry+https://github.com/rust-lang/crates.io-index"
62
+ checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d"
63
+
64
+ [[package]]
65
+ name = "anstyle-parse"
66
+ version = "0.2.0"
67
+ source = "registry+https://github.com/rust-lang/crates.io-index"
68
+ checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee"
69
+ dependencies = [
70
+ "utf8parse",
71
+ ]
72
+
73
+ [[package]]
74
+ name = "anstyle-query"
75
+ version = "1.0.0"
76
+ source = "registry+https://github.com/rust-lang/crates.io-index"
77
+ checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
78
+ dependencies = [
79
+ "windows-sys 0.48.0",
80
+ ]
81
+
82
+ [[package]]
83
+ name = "anstyle-wincon"
84
+ version = "1.0.0"
85
+ source = "registry+https://github.com/rust-lang/crates.io-index"
86
+ checksum = "4bcd8291a340dd8ac70e18878bc4501dd7b4ff970cfa21c207d36ece51ea88fd"
87
+ dependencies = [
88
+ "anstyle",
89
+ "windows-sys 0.48.0",
90
+ ]
91
+
92
+ [[package]]
93
+ name = "anyhow"
94
+ version = "1.0.70"
95
+ source = "registry+https://github.com/rust-lang/crates.io-index"
96
+ checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4"
97
+
98
+ [[package]]
99
+ name = "async-stream"
100
+ version = "0.3.5"
101
+ source = "registry+https://github.com/rust-lang/crates.io-index"
102
+ checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51"
103
+ dependencies = [
104
+ "async-stream-impl",
105
+ "futures-core",
106
+ "pin-project-lite",
107
+ ]
108
+
109
+ [[package]]
110
+ name = "async-stream-impl"
111
+ version = "0.3.5"
112
+ source = "registry+https://github.com/rust-lang/crates.io-index"
113
+ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
114
+ dependencies = [
115
+ "proc-macro2",
116
+ "quote",
117
+ "syn 2.0.15",
118
+ ]
119
+
120
+ [[package]]
121
+ name = "async-trait"
122
+ version = "0.1.68"
123
+ source = "registry+https://github.com/rust-lang/crates.io-index"
124
+ checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842"
125
+ dependencies = [
126
+ "proc-macro2",
127
+ "quote",
128
+ "syn 2.0.15",
129
+ ]
130
+
131
+ [[package]]
132
+ name = "autocfg"
133
+ version = "1.1.0"
134
+ source = "registry+https://github.com/rust-lang/crates.io-index"
135
+ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
136
+
137
+ [[package]]
138
+ name = "axum"
139
+ version = "0.6.15"
140
+ source = "registry+https://github.com/rust-lang/crates.io-index"
141
+ checksum = "3b32c5ea3aabaf4deb5f5ced2d688ec0844c881c9e6c696a8b769a05fc691e62"
142
+ dependencies = [
143
+ "async-trait",
144
+ "axum-core",
145
+ "bitflags",
146
+ "bytes",
147
+ "futures-util",
148
+ "http",
149
+ "http-body",
150
+ "hyper",
151
+ "itoa",
152
+ "matchit",
153
+ "memchr",
154
+ "mime",
155
+ "percent-encoding",
156
+ "pin-project-lite",
157
+ "rustversion",
158
+ "serde",
159
+ "serde_json",
160
+ "serde_path_to_error",
161
+ "serde_urlencoded",
162
+ "sync_wrapper",
163
+ "tokio",
164
+ "tower",
165
+ "tower-layer",
166
+ "tower-service",
167
+ ]
168
+
169
+ [[package]]
170
+ name = "axum-core"
171
+ version = "0.3.4"
172
+ source = "registry+https://github.com/rust-lang/crates.io-index"
173
+ checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c"
174
+ dependencies = [
175
+ "async-trait",
176
+ "bytes",
177
+ "futures-util",
178
+ "http",
179
+ "http-body",
180
+ "mime",
181
+ "rustversion",
182
+ "tower-layer",
183
+ "tower-service",
184
+ ]
185
+
186
+ [[package]]
187
+ name = "axum-tracing-opentelemetry"
188
+ version = "0.10.0"
189
+ source = "registry+https://github.com/rust-lang/crates.io-index"
190
+ checksum = "164b95427e83b79583c7699a72b4a6b485a12bbdef5b5c054ee5ff2296d82f52"
191
+ dependencies = [
192
+ "axum",
193
+ "futures",
194
+ "http",
195
+ "opentelemetry",
196
+ "tower",
197
+ "tower-http 0.3.5",
198
+ "tracing",
199
+ "tracing-opentelemetry",
200
+ ]
201
+
202
+ [[package]]
203
+ name = "base64"
204
+ version = "0.13.1"
205
+ source = "registry+https://github.com/rust-lang/crates.io-index"
206
+ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
207
+
208
+ [[package]]
209
+ name = "base64"
210
+ version = "0.21.0"
211
+ source = "registry+https://github.com/rust-lang/crates.io-index"
212
+ checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
213
+
214
+ [[package]]
215
+ name = "base64ct"
216
+ version = "1.6.0"
217
+ source = "registry+https://github.com/rust-lang/crates.io-index"
218
+ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
219
+
220
+ [[package]]
221
+ name = "bitflags"
222
+ version = "1.3.2"
223
+ source = "registry+https://github.com/rust-lang/crates.io-index"
224
+ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
225
+
226
+ [[package]]
227
+ name = "block-buffer"
228
+ version = "0.10.4"
229
+ source = "registry+https://github.com/rust-lang/crates.io-index"
230
+ checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
231
+ dependencies = [
232
+ "generic-array",
233
+ ]
234
+
235
+ [[package]]
236
+ name = "bumpalo"
237
+ version = "3.12.0"
238
+ source = "registry+https://github.com/rust-lang/crates.io-index"
239
+ checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
240
+
241
+ [[package]]
242
+ name = "byteorder"
243
+ version = "1.4.3"
244
+ source = "registry+https://github.com/rust-lang/crates.io-index"
245
+ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
246
+
247
+ [[package]]
248
+ name = "bytes"
249
+ version = "1.4.0"
250
+ source = "registry+https://github.com/rust-lang/crates.io-index"
251
+ checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
252
+
253
+ [[package]]
254
+ name = "bzip2"
255
+ version = "0.4.4"
256
+ source = "registry+https://github.com/rust-lang/crates.io-index"
257
+ checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8"
258
+ dependencies = [
259
+ "bzip2-sys",
260
+ "libc",
261
+ ]
262
+
263
+ [[package]]
264
+ name = "bzip2-sys"
265
+ version = "0.1.11+1.0.8"
266
+ source = "registry+https://github.com/rust-lang/crates.io-index"
267
+ checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc"
268
+ dependencies = [
269
+ "cc",
270
+ "libc",
271
+ "pkg-config",
272
+ ]
273
+
274
+ [[package]]
275
+ name = "cached-path"
276
+ version = "0.6.1"
277
+ source = "registry+https://github.com/rust-lang/crates.io-index"
278
+ checksum = "097968e38f1319207f057d0f4d76452e4f4f847a5de61c5215379f297fa034f3"
279
+ dependencies = [
280
+ "flate2",
281
+ "fs2",
282
+ "glob",
283
+ "indicatif 0.16.2",
284
+ "log",
285
+ "rand",
286
+ "reqwest",
287
+ "serde",
288
+ "serde_json",
289
+ "sha2",
290
+ "tar",
291
+ "tempfile",
292
+ "thiserror",
293
+ "zip",
294
+ ]
295
+
296
+ [[package]]
297
+ name = "cc"
298
+ version = "1.0.79"
299
+ source = "registry+https://github.com/rust-lang/crates.io-index"
300
+ checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
301
+ dependencies = [
302
+ "jobserver",
303
+ ]
304
+
305
+ [[package]]
306
+ name = "cfg-if"
307
+ version = "1.0.0"
308
+ source = "registry+https://github.com/rust-lang/crates.io-index"
309
+ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
310
+
311
+ [[package]]
312
+ name = "cipher"
313
+ version = "0.3.0"
314
+ source = "registry+https://github.com/rust-lang/crates.io-index"
315
+ checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7"
316
+ dependencies = [
317
+ "generic-array",
318
+ ]
319
+
320
+ [[package]]
321
+ name = "clap"
322
+ version = "4.2.2"
323
+ source = "registry+https://github.com/rust-lang/crates.io-index"
324
+ checksum = "9b802d85aaf3a1cdb02b224ba472ebdea62014fccfcb269b95a4d76443b5ee5a"
325
+ dependencies = [
326
+ "clap_builder",
327
+ "clap_derive",
328
+ "once_cell",
329
+ ]
330
+
331
+ [[package]]
332
+ name = "clap_builder"
333
+ version = "4.2.2"
334
+ source = "registry+https://github.com/rust-lang/crates.io-index"
335
+ checksum = "14a1a858f532119338887a4b8e1af9c60de8249cd7bafd68036a489e261e37b6"
336
+ dependencies = [
337
+ "anstream",
338
+ "anstyle",
339
+ "bitflags",
340
+ "clap_lex",
341
+ "strsim",
342
+ ]
343
+
344
+ [[package]]
345
+ name = "clap_derive"
346
+ version = "4.2.0"
347
+ source = "registry+https://github.com/rust-lang/crates.io-index"
348
+ checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4"
349
+ dependencies = [
350
+ "heck",
351
+ "proc-macro2",
352
+ "quote",
353
+ "syn 2.0.15",
354
+ ]
355
+
356
+ [[package]]
357
+ name = "clap_lex"
358
+ version = "0.4.1"
359
+ source = "registry+https://github.com/rust-lang/crates.io-index"
360
+ checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1"
361
+
362
+ [[package]]
363
+ name = "colorchoice"
364
+ version = "1.0.0"
365
+ source = "registry+https://github.com/rust-lang/crates.io-index"
366
+ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
367
+
368
+ [[package]]
369
+ name = "console"
370
+ version = "0.15.5"
371
+ source = "registry+https://github.com/rust-lang/crates.io-index"
372
+ checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60"
373
+ dependencies = [
374
+ "encode_unicode",
375
+ "lazy_static",
376
+ "libc",
377
+ "unicode-width",
378
+ "windows-sys 0.42.0",
379
+ ]
380
+
381
+ [[package]]
382
+ name = "constant_time_eq"
383
+ version = "0.1.5"
384
+ source = "registry+https://github.com/rust-lang/crates.io-index"
385
+ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
386
+
387
+ [[package]]
388
+ name = "core-foundation"
389
+ version = "0.9.3"
390
+ source = "registry+https://github.com/rust-lang/crates.io-index"
391
+ checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
392
+ dependencies = [
393
+ "core-foundation-sys",
394
+ "libc",
395
+ ]
396
+
397
+ [[package]]
398
+ name = "core-foundation-sys"
399
+ version = "0.8.4"
400
+ source = "registry+https://github.com/rust-lang/crates.io-index"
401
+ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
402
+
403
+ [[package]]
404
+ name = "cpufeatures"
405
+ version = "0.2.6"
406
+ source = "registry+https://github.com/rust-lang/crates.io-index"
407
+ checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181"
408
+ dependencies = [
409
+ "libc",
410
+ ]
411
+
412
+ [[package]]
413
+ name = "crc32fast"
414
+ version = "1.3.2"
415
+ source = "registry+https://github.com/rust-lang/crates.io-index"
416
+ checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
417
+ dependencies = [
418
+ "cfg-if",
419
+ ]
420
+
421
+ [[package]]
422
+ name = "crossbeam-channel"
423
+ version = "0.5.8"
424
+ source = "registry+https://github.com/rust-lang/crates.io-index"
425
+ checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
426
+ dependencies = [
427
+ "cfg-if",
428
+ "crossbeam-utils",
429
+ ]
430
+
431
+ [[package]]
432
+ name = "crossbeam-deque"
433
+ version = "0.8.3"
434
+ source = "registry+https://github.com/rust-lang/crates.io-index"
435
+ checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
436
+ dependencies = [
437
+ "cfg-if",
438
+ "crossbeam-epoch",
439
+ "crossbeam-utils",
440
+ ]
441
+
442
+ [[package]]
443
+ name = "crossbeam-epoch"
444
+ version = "0.9.14"
445
+ source = "registry+https://github.com/rust-lang/crates.io-index"
446
+ checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695"
447
+ dependencies = [
448
+ "autocfg",
449
+ "cfg-if",
450
+ "crossbeam-utils",
451
+ "memoffset",
452
+ "scopeguard",
453
+ ]
454
+
455
+ [[package]]
456
+ name = "crossbeam-utils"
457
+ version = "0.8.15"
458
+ source = "registry+https://github.com/rust-lang/crates.io-index"
459
+ checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
460
+ dependencies = [
461
+ "cfg-if",
462
+ ]
463
+
464
+ [[package]]
465
+ name = "crypto-common"
466
+ version = "0.1.6"
467
+ source = "registry+https://github.com/rust-lang/crates.io-index"
468
+ checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
469
+ dependencies = [
470
+ "generic-array",
471
+ "typenum",
472
+ ]
473
+
474
+ [[package]]
475
+ name = "ctrlc"
476
+ version = "3.2.5"
477
+ source = "registry+https://github.com/rust-lang/crates.io-index"
478
+ checksum = "bbcf33c2a618cbe41ee43ae6e9f2e48368cd9f9db2896f10167d8d762679f639"
479
+ dependencies = [
480
+ "nix",
481
+ "windows-sys 0.45.0",
482
+ ]
483
+
484
+ [[package]]
485
+ name = "darling"
486
+ version = "0.14.4"
487
+ source = "registry+https://github.com/rust-lang/crates.io-index"
488
+ checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850"
489
+ dependencies = [
490
+ "darling_core",
491
+ "darling_macro",
492
+ ]
493
+
494
+ [[package]]
495
+ name = "darling_core"
496
+ version = "0.14.4"
497
+ source = "registry+https://github.com/rust-lang/crates.io-index"
498
+ checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0"
499
+ dependencies = [
500
+ "fnv",
501
+ "ident_case",
502
+ "proc-macro2",
503
+ "quote",
504
+ "strsim",
505
+ "syn 1.0.109",
506
+ ]
507
+
508
+ [[package]]
509
+ name = "darling_macro"
510
+ version = "0.14.4"
511
+ source = "registry+https://github.com/rust-lang/crates.io-index"
512
+ checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e"
513
+ dependencies = [
514
+ "darling_core",
515
+ "quote",
516
+ "syn 1.0.109",
517
+ ]
518
+
519
+ [[package]]
520
+ name = "dashmap"
521
+ version = "5.4.0"
522
+ source = "registry+https://github.com/rust-lang/crates.io-index"
523
+ checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc"
524
+ dependencies = [
525
+ "cfg-if",
526
+ "hashbrown",
527
+ "lock_api",
528
+ "once_cell",
529
+ "parking_lot_core",
530
+ ]
531
+
532
+ [[package]]
533
+ name = "derive_builder"
534
+ version = "0.12.0"
535
+ source = "registry+https://github.com/rust-lang/crates.io-index"
536
+ checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8"
537
+ dependencies = [
538
+ "derive_builder_macro",
539
+ ]
540
+
541
+ [[package]]
542
+ name = "derive_builder_core"
543
+ version = "0.12.0"
544
+ source = "registry+https://github.com/rust-lang/crates.io-index"
545
+ checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f"
546
+ dependencies = [
547
+ "darling",
548
+ "proc-macro2",
549
+ "quote",
550
+ "syn 1.0.109",
551
+ ]
552
+
553
+ [[package]]
554
+ name = "derive_builder_macro"
555
+ version = "0.12.0"
556
+ source = "registry+https://github.com/rust-lang/crates.io-index"
557
+ checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e"
558
+ dependencies = [
559
+ "derive_builder_core",
560
+ "syn 1.0.109",
561
+ ]
562
+
563
+ [[package]]
564
+ name = "digest"
565
+ version = "0.10.6"
566
+ source = "registry+https://github.com/rust-lang/crates.io-index"
567
+ checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
568
+ dependencies = [
569
+ "block-buffer",
570
+ "crypto-common",
571
+ "subtle",
572
+ ]
573
+
574
+ [[package]]
575
+ name = "dirs"
576
+ version = "4.0.0"
577
+ source = "registry+https://github.com/rust-lang/crates.io-index"
578
+ checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
579
+ dependencies = [
580
+ "dirs-sys",
581
+ ]
582
+
583
+ [[package]]
584
+ name = "dirs-sys"
585
+ version = "0.3.7"
586
+ source = "registry+https://github.com/rust-lang/crates.io-index"
587
+ checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
588
+ dependencies = [
589
+ "libc",
590
+ "redox_users",
591
+ "winapi",
592
+ ]
593
+
594
+ [[package]]
595
+ name = "either"
596
+ version = "1.8.1"
597
+ source = "registry+https://github.com/rust-lang/crates.io-index"
598
+ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
599
+
600
+ [[package]]
601
+ name = "encode_unicode"
602
+ version = "0.3.6"
603
+ source = "registry+https://github.com/rust-lang/crates.io-index"
604
+ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
605
+
606
+ [[package]]
607
+ name = "encoding_rs"
608
+ version = "0.8.32"
609
+ source = "registry+https://github.com/rust-lang/crates.io-index"
610
+ checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394"
611
+ dependencies = [
612
+ "cfg-if",
613
+ ]
614
+
615
+ [[package]]
616
+ name = "errno"
617
+ version = "0.3.1"
618
+ source = "registry+https://github.com/rust-lang/crates.io-index"
619
+ checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
620
+ dependencies = [
621
+ "errno-dragonfly",
622
+ "libc",
623
+ "windows-sys 0.48.0",
624
+ ]
625
+
626
+ [[package]]
627
+ name = "errno-dragonfly"
628
+ version = "0.1.2"
629
+ source = "registry+https://github.com/rust-lang/crates.io-index"
630
+ checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
631
+ dependencies = [
632
+ "cc",
633
+ "libc",
634
+ ]
635
+
636
+ [[package]]
637
+ name = "esaxx-rs"
638
+ version = "0.1.8"
639
+ source = "registry+https://github.com/rust-lang/crates.io-index"
640
+ checksum = "1f748b253ceca9fed5f42f8b5ceb3851e93102199bc25b64b65369f76e5c0a35"
641
+ dependencies = [
642
+ "cc",
643
+ ]
644
+
645
+ [[package]]
646
+ name = "fastrand"
647
+ version = "1.9.0"
648
+ source = "registry+https://github.com/rust-lang/crates.io-index"
649
+ checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
650
+ dependencies = [
651
+ "instant",
652
+ ]
653
+
654
+ [[package]]
655
+ name = "filetime"
656
+ version = "0.2.21"
657
+ source = "registry+https://github.com/rust-lang/crates.io-index"
658
+ checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153"
659
+ dependencies = [
660
+ "cfg-if",
661
+ "libc",
662
+ "redox_syscall 0.2.16",
663
+ "windows-sys 0.48.0",
664
+ ]
665
+
666
+ [[package]]
667
+ name = "fixedbitset"
668
+ version = "0.4.2"
669
+ source = "registry+https://github.com/rust-lang/crates.io-index"
670
+ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
671
+
672
+ [[package]]
673
+ name = "flate2"
674
+ version = "1.0.25"
675
+ source = "registry+https://github.com/rust-lang/crates.io-index"
676
+ checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841"
677
+ dependencies = [
678
+ "crc32fast",
679
+ "miniz_oxide",
680
+ ]
681
+
682
+ [[package]]
683
+ name = "float_eq"
684
+ version = "1.0.1"
685
+ source = "registry+https://github.com/rust-lang/crates.io-index"
686
+ checksum = "28a80e3145d8ad11ba0995949bbcf48b9df2be62772b3d351ef017dff6ecb853"
687
+
688
+ [[package]]
689
+ name = "flume"
690
+ version = "0.10.14"
691
+ source = "registry+https://github.com/rust-lang/crates.io-index"
692
+ checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577"
693
+ dependencies = [
694
+ "futures-core",
695
+ "futures-sink",
696
+ "nanorand",
697
+ "pin-project",
698
+ "spin",
699
+ ]
700
+
701
+ [[package]]
702
+ name = "fnv"
703
+ version = "1.0.7"
704
+ source = "registry+https://github.com/rust-lang/crates.io-index"
705
+ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
706
+
707
+ [[package]]
708
+ name = "foreign-types"
709
+ version = "0.3.2"
710
+ source = "registry+https://github.com/rust-lang/crates.io-index"
711
+ checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
712
+ dependencies = [
713
+ "foreign-types-shared",
714
+ ]
715
+
716
+ [[package]]
717
+ name = "foreign-types-shared"
718
+ version = "0.1.1"
719
+ source = "registry+https://github.com/rust-lang/crates.io-index"
720
+ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
721
+
722
+ [[package]]
723
+ name = "form_urlencoded"
724
+ version = "1.1.0"
725
+ source = "registry+https://github.com/rust-lang/crates.io-index"
726
+ checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
727
+ dependencies = [
728
+ "percent-encoding",
729
+ ]
730
+
731
+ [[package]]
732
+ name = "fs2"
733
+ version = "0.4.3"
734
+ source = "registry+https://github.com/rust-lang/crates.io-index"
735
+ checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
736
+ dependencies = [
737
+ "libc",
738
+ "winapi",
739
+ ]
740
+
741
+ [[package]]
742
+ name = "futures"
743
+ version = "0.3.28"
744
+ source = "registry+https://github.com/rust-lang/crates.io-index"
745
+ checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40"
746
+ dependencies = [
747
+ "futures-channel",
748
+ "futures-core",
749
+ "futures-executor",
750
+ "futures-io",
751
+ "futures-sink",
752
+ "futures-task",
753
+ "futures-util",
754
+ ]
755
+
756
+ [[package]]
757
+ name = "futures-channel"
758
+ version = "0.3.28"
759
+ source = "registry+https://github.com/rust-lang/crates.io-index"
760
+ checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2"
761
+ dependencies = [
762
+ "futures-core",
763
+ "futures-sink",
764
+ ]
765
+
766
+ [[package]]
767
+ name = "futures-core"
768
+ version = "0.3.28"
769
+ source = "registry+https://github.com/rust-lang/crates.io-index"
770
+ checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
771
+
772
+ [[package]]
773
+ name = "futures-executor"
774
+ version = "0.3.28"
775
+ source = "registry+https://github.com/rust-lang/crates.io-index"
776
+ checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0"
777
+ dependencies = [
778
+ "futures-core",
779
+ "futures-task",
780
+ "futures-util",
781
+ ]
782
+
783
+ [[package]]
784
+ name = "futures-io"
785
+ version = "0.3.28"
786
+ source = "registry+https://github.com/rust-lang/crates.io-index"
787
+ checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
788
+
789
+ [[package]]
790
+ name = "futures-macro"
791
+ version = "0.3.28"
792
+ source = "registry+https://github.com/rust-lang/crates.io-index"
793
+ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
794
+ dependencies = [
795
+ "proc-macro2",
796
+ "quote",
797
+ "syn 2.0.15",
798
+ ]
799
+
800
+ [[package]]
801
+ name = "futures-sink"
802
+ version = "0.3.28"
803
+ source = "registry+https://github.com/rust-lang/crates.io-index"
804
+ checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
805
+
806
+ [[package]]
807
+ name = "futures-task"
808
+ version = "0.3.28"
809
+ source = "registry+https://github.com/rust-lang/crates.io-index"
810
+ checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
811
+
812
+ [[package]]
813
+ name = "futures-util"
814
+ version = "0.3.28"
815
+ source = "registry+https://github.com/rust-lang/crates.io-index"
816
+ checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
817
+ dependencies = [
818
+ "futures-channel",
819
+ "futures-core",
820
+ "futures-io",
821
+ "futures-macro",
822
+ "futures-sink",
823
+ "futures-task",
824
+ "memchr",
825
+ "pin-project-lite",
826
+ "pin-utils",
827
+ "slab",
828
+ ]
829
+
830
+ [[package]]
831
+ name = "generic-array"
832
+ version = "0.14.7"
833
+ source = "registry+https://github.com/rust-lang/crates.io-index"
834
+ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
835
+ dependencies = [
836
+ "typenum",
837
+ "version_check",
838
+ ]
839
+
840
+ [[package]]
841
+ name = "getrandom"
842
+ version = "0.2.9"
843
+ source = "registry+https://github.com/rust-lang/crates.io-index"
844
+ checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4"
845
+ dependencies = [
846
+ "cfg-if",
847
+ "js-sys",
848
+ "libc",
849
+ "wasi 0.11.0+wasi-snapshot-preview1",
850
+ "wasm-bindgen",
851
+ ]
852
+
853
+ [[package]]
854
+ name = "glob"
855
+ version = "0.3.1"
856
+ source = "registry+https://github.com/rust-lang/crates.io-index"
857
+ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
858
+
859
+ [[package]]
860
+ name = "grpc-metadata"
861
+ version = "0.1.0"
862
+ dependencies = [
863
+ "opentelemetry",
864
+ "tonic",
865
+ "tracing",
866
+ "tracing-opentelemetry",
867
+ ]
868
+
869
+ [[package]]
870
+ name = "h2"
871
+ version = "0.3.18"
872
+ source = "registry+https://github.com/rust-lang/crates.io-index"
873
+ checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21"
874
+ dependencies = [
875
+ "bytes",
876
+ "fnv",
877
+ "futures-core",
878
+ "futures-sink",
879
+ "futures-util",
880
+ "http",
881
+ "indexmap",
882
+ "slab",
883
+ "tokio",
884
+ "tokio-util",
885
+ "tracing",
886
+ ]
887
+
888
+ [[package]]
889
+ name = "hashbrown"
890
+ version = "0.12.3"
891
+ source = "registry+https://github.com/rust-lang/crates.io-index"
892
+ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
893
+ dependencies = [
894
+ "ahash",
895
+ ]
896
+
897
+ [[package]]
898
+ name = "heck"
899
+ version = "0.4.1"
900
+ source = "registry+https://github.com/rust-lang/crates.io-index"
901
+ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
902
+
903
+ [[package]]
904
+ name = "hermit-abi"
905
+ version = "0.2.6"
906
+ source = "registry+https://github.com/rust-lang/crates.io-index"
907
+ checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
908
+ dependencies = [
909
+ "libc",
910
+ ]
911
+
912
+ [[package]]
913
+ name = "hermit-abi"
914
+ version = "0.3.1"
915
+ source = "registry+https://github.com/rust-lang/crates.io-index"
916
+ checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
917
+
918
+ [[package]]
919
+ name = "hmac"
920
+ version = "0.12.1"
921
+ source = "registry+https://github.com/rust-lang/crates.io-index"
922
+ checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
923
+ dependencies = [
924
+ "digest",
925
+ ]
926
+
927
+ [[package]]
928
+ name = "http"
929
+ version = "0.2.9"
930
+ source = "registry+https://github.com/rust-lang/crates.io-index"
931
+ checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
932
+ dependencies = [
933
+ "bytes",
934
+ "fnv",
935
+ "itoa",
936
+ ]
937
+
938
+ [[package]]
939
+ name = "http-body"
940
+ version = "0.4.5"
941
+ source = "registry+https://github.com/rust-lang/crates.io-index"
942
+ checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
943
+ dependencies = [
944
+ "bytes",
945
+ "http",
946
+ "pin-project-lite",
947
+ ]
948
+
949
+ [[package]]
950
+ name = "http-range-header"
951
+ version = "0.3.0"
952
+ source = "registry+https://github.com/rust-lang/crates.io-index"
953
+ checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29"
954
+
955
+ [[package]]
956
+ name = "httparse"
957
+ version = "1.8.0"
958
+ source = "registry+https://github.com/rust-lang/crates.io-index"
959
+ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
960
+
961
+ [[package]]
962
+ name = "httpdate"
963
+ version = "1.0.2"
964
+ source = "registry+https://github.com/rust-lang/crates.io-index"
965
+ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
966
+
967
+ [[package]]
968
+ name = "hyper"
969
+ version = "0.14.26"
970
+ source = "registry+https://github.com/rust-lang/crates.io-index"
971
+ checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4"
972
+ dependencies = [
973
+ "bytes",
974
+ "futures-channel",
975
+ "futures-core",
976
+ "futures-util",
977
+ "h2",
978
+ "http",
979
+ "http-body",
980
+ "httparse",
981
+ "httpdate",
982
+ "itoa",
983
+ "pin-project-lite",
984
+ "socket2",
985
+ "tokio",
986
+ "tower-service",
987
+ "tracing",
988
+ "want",
989
+ ]
990
+
991
+ [[package]]
992
+ name = "hyper-timeout"
993
+ version = "0.4.1"
994
+ source = "registry+https://github.com/rust-lang/crates.io-index"
995
+ checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
996
+ dependencies = [
997
+ "hyper",
998
+ "pin-project-lite",
999
+ "tokio",
1000
+ "tokio-io-timeout",
1001
+ ]
1002
+
1003
+ [[package]]
1004
+ name = "hyper-tls"
1005
+ version = "0.5.0"
1006
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1007
+ checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
1008
+ dependencies = [
1009
+ "bytes",
1010
+ "hyper",
1011
+ "native-tls",
1012
+ "tokio",
1013
+ "tokio-native-tls",
1014
+ ]
1015
+
1016
+ [[package]]
1017
+ name = "ident_case"
1018
+ version = "1.0.1"
1019
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1020
+ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
1021
+
1022
+ [[package]]
1023
+ name = "idna"
1024
+ version = "0.3.0"
1025
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1026
+ checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
1027
+ dependencies = [
1028
+ "unicode-bidi",
1029
+ "unicode-normalization",
1030
+ ]
1031
+
1032
+ [[package]]
1033
+ name = "indexmap"
1034
+ version = "1.9.3"
1035
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1036
+ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
1037
+ dependencies = [
1038
+ "autocfg",
1039
+ "hashbrown",
1040
+ "serde",
1041
+ ]
1042
+
1043
+ [[package]]
1044
+ name = "indicatif"
1045
+ version = "0.15.0"
1046
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1047
+ checksum = "7baab56125e25686df467fe470785512329883aab42696d661247aca2a2896e4"
1048
+ dependencies = [
1049
+ "console",
1050
+ "lazy_static",
1051
+ "number_prefix 0.3.0",
1052
+ "regex",
1053
+ ]
1054
+
1055
+ [[package]]
1056
+ name = "indicatif"
1057
+ version = "0.16.2"
1058
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1059
+ checksum = "2d207dc617c7a380ab07ff572a6e52fa202a2a8f355860ac9c38e23f8196be1b"
1060
+ dependencies = [
1061
+ "console",
1062
+ "lazy_static",
1063
+ "number_prefix 0.4.0",
1064
+ "regex",
1065
+ ]
1066
+
1067
+ [[package]]
1068
+ name = "instant"
1069
+ version = "0.1.12"
1070
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1071
+ checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
1072
+ dependencies = [
1073
+ "cfg-if",
1074
+ ]
1075
+
1076
+ [[package]]
1077
+ name = "io-lifetimes"
1078
+ version = "1.0.10"
1079
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1080
+ checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220"
1081
+ dependencies = [
1082
+ "hermit-abi 0.3.1",
1083
+ "libc",
1084
+ "windows-sys 0.48.0",
1085
+ ]
1086
+
1087
+ [[package]]
1088
+ name = "ipnet"
1089
+ version = "2.7.2"
1090
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1091
+ checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f"
1092
+
1093
+ [[package]]
1094
+ name = "is-terminal"
1095
+ version = "0.4.7"
1096
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1097
+ checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f"
1098
+ dependencies = [
1099
+ "hermit-abi 0.3.1",
1100
+ "io-lifetimes",
1101
+ "rustix",
1102
+ "windows-sys 0.48.0",
1103
+ ]
1104
+
1105
+ [[package]]
1106
+ name = "itertools"
1107
+ version = "0.8.2"
1108
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1109
+ checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
1110
+ dependencies = [
1111
+ "either",
1112
+ ]
1113
+
1114
+ [[package]]
1115
+ name = "itertools"
1116
+ version = "0.9.0"
1117
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1118
+ checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
1119
+ dependencies = [
1120
+ "either",
1121
+ ]
1122
+
1123
+ [[package]]
1124
+ name = "itertools"
1125
+ version = "0.10.5"
1126
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1127
+ checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
1128
+ dependencies = [
1129
+ "either",
1130
+ ]
1131
+
1132
+ [[package]]
1133
+ name = "itoa"
1134
+ version = "1.0.6"
1135
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1136
+ checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
1137
+
1138
+ [[package]]
1139
+ name = "jobserver"
1140
+ version = "0.1.26"
1141
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1142
+ checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2"
1143
+ dependencies = [
1144
+ "libc",
1145
+ ]
1146
+
1147
+ [[package]]
1148
+ name = "js-sys"
1149
+ version = "0.3.61"
1150
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1151
+ checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730"
1152
+ dependencies = [
1153
+ "wasm-bindgen",
1154
+ ]
1155
+
1156
+ [[package]]
1157
+ name = "lazy_static"
1158
+ version = "1.4.0"
1159
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1160
+ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
1161
+
1162
+ [[package]]
1163
+ name = "libc"
1164
+ version = "0.2.141"
1165
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1166
+ checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5"
1167
+
1168
+ [[package]]
1169
+ name = "linux-raw-sys"
1170
+ version = "0.3.1"
1171
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1172
+ checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f"
1173
+
1174
+ [[package]]
1175
+ name = "lock_api"
1176
+ version = "0.4.9"
1177
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1178
+ checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
1179
+ dependencies = [
1180
+ "autocfg",
1181
+ "scopeguard",
1182
+ ]
1183
+
1184
+ [[package]]
1185
+ name = "log"
1186
+ version = "0.4.17"
1187
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1188
+ checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
1189
+ dependencies = [
1190
+ "cfg-if",
1191
+ ]
1192
+
1193
+ [[package]]
1194
+ name = "mach"
1195
+ version = "0.3.2"
1196
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1197
+ checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa"
1198
+ dependencies = [
1199
+ "libc",
1200
+ ]
1201
+
1202
+ [[package]]
1203
+ name = "macro_rules_attribute"
1204
+ version = "0.1.3"
1205
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1206
+ checksum = "cf0c9b980bf4f3a37fd7b1c066941dd1b1d0152ce6ee6e8fe8c49b9f6810d862"
1207
+ dependencies = [
1208
+ "macro_rules_attribute-proc_macro",
1209
+ "paste",
1210
+ ]
1211
+
1212
+ [[package]]
1213
+ name = "macro_rules_attribute-proc_macro"
1214
+ version = "0.1.3"
1215
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1216
+ checksum = "58093314a45e00c77d5c508f76e77c3396afbbc0d01506e7fae47b018bac2b1d"
1217
+
1218
+ [[package]]
1219
+ name = "matchers"
1220
+ version = "0.1.0"
1221
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1222
+ checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
1223
+ dependencies = [
1224
+ "regex-automata",
1225
+ ]
1226
+
1227
+ [[package]]
1228
+ name = "matchit"
1229
+ version = "0.7.0"
1230
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1231
+ checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40"
1232
+
1233
+ [[package]]
1234
+ name = "memchr"
1235
+ version = "2.5.0"
1236
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1237
+ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
1238
+
1239
+ [[package]]
1240
+ name = "memoffset"
1241
+ version = "0.8.0"
1242
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1243
+ checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
1244
+ dependencies = [
1245
+ "autocfg",
1246
+ ]
1247
+
1248
+ [[package]]
1249
+ name = "metrics"
1250
+ version = "0.20.1"
1251
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1252
+ checksum = "7b9b8653cec6897f73b519a43fba5ee3d50f62fe9af80b428accdcc093b4a849"
1253
+ dependencies = [
1254
+ "ahash",
1255
+ "metrics-macros",
1256
+ "portable-atomic",
1257
+ ]
1258
+
1259
+ [[package]]
1260
+ name = "metrics-exporter-prometheus"
1261
+ version = "0.11.0"
1262
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1263
+ checksum = "8603921e1f54ef386189335f288441af761e0fc61bcb552168d9cedfe63ebc70"
1264
+ dependencies = [
1265
+ "hyper",
1266
+ "indexmap",
1267
+ "ipnet",
1268
+ "metrics",
1269
+ "metrics-util",
1270
+ "parking_lot",
1271
+ "portable-atomic",
1272
+ "quanta",
1273
+ "thiserror",
1274
+ "tokio",
1275
+ "tracing",
1276
+ ]
1277
+
1278
+ [[package]]
1279
+ name = "metrics-macros"
1280
+ version = "0.6.0"
1281
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1282
+ checksum = "731f8ecebd9f3a4aa847dfe75455e4757a45da40a7793d2f0b1f9b6ed18b23f3"
1283
+ dependencies = [
1284
+ "proc-macro2",
1285
+ "quote",
1286
+ "syn 1.0.109",
1287
+ ]
1288
+
1289
+ [[package]]
1290
+ name = "metrics-util"
1291
+ version = "0.14.0"
1292
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1293
+ checksum = "f7d24dc2dbae22bff6f1f9326ffce828c9f07ef9cc1e8002e5279f845432a30a"
1294
+ dependencies = [
1295
+ "crossbeam-epoch",
1296
+ "crossbeam-utils",
1297
+ "hashbrown",
1298
+ "metrics",
1299
+ "num_cpus",
1300
+ "parking_lot",
1301
+ "portable-atomic",
1302
+ "quanta",
1303
+ "sketches-ddsketch",
1304
+ ]
1305
+
1306
+ [[package]]
1307
+ name = "mime"
1308
+ version = "0.3.17"
1309
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1310
+ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
1311
+
1312
+ [[package]]
1313
+ name = "mime_guess"
1314
+ version = "2.0.4"
1315
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1316
+ checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
1317
+ dependencies = [
1318
+ "mime",
1319
+ "unicase",
1320
+ ]
1321
+
1322
+ [[package]]
1323
+ name = "minimal-lexical"
1324
+ version = "0.2.1"
1325
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1326
+ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
1327
+
1328
+ [[package]]
1329
+ name = "miniz_oxide"
1330
+ version = "0.6.2"
1331
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1332
+ checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
1333
+ dependencies = [
1334
+ "adler",
1335
+ ]
1336
+
1337
+ [[package]]
1338
+ name = "mio"
1339
+ version = "0.8.6"
1340
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1341
+ checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
1342
+ dependencies = [
1343
+ "libc",
1344
+ "log",
1345
+ "wasi 0.11.0+wasi-snapshot-preview1",
1346
+ "windows-sys 0.45.0",
1347
+ ]
1348
+
1349
+ [[package]]
1350
+ name = "monostate"
1351
+ version = "0.1.6"
1352
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1353
+ checksum = "0230b703f1ac35df1e24f6d0d2255472bcccaf657ecdfa4f1fcbcad1ad5bb98a"
1354
+ dependencies = [
1355
+ "monostate-impl",
1356
+ "serde",
1357
+ ]
1358
+
1359
+ [[package]]
1360
+ name = "monostate-impl"
1361
+ version = "0.1.6"
1362
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1363
+ checksum = "8795add3e14028f11f8e848bd3294898a8294767b3776b6f733560d33bd2530b"
1364
+ dependencies = [
1365
+ "proc-macro2",
1366
+ "quote",
1367
+ "syn 2.0.15",
1368
+ ]
1369
+
1370
+ [[package]]
1371
+ name = "multimap"
1372
+ version = "0.8.3"
1373
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1374
+ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
1375
+
1376
+ [[package]]
1377
+ name = "nanorand"
1378
+ version = "0.7.0"
1379
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1380
+ checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
1381
+ dependencies = [
1382
+ "getrandom",
1383
+ ]
1384
+
1385
+ [[package]]
1386
+ name = "native-tls"
1387
+ version = "0.2.11"
1388
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1389
+ checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
1390
+ dependencies = [
1391
+ "lazy_static",
1392
+ "libc",
1393
+ "log",
1394
+ "openssl",
1395
+ "openssl-probe",
1396
+ "openssl-sys",
1397
+ "schannel",
1398
+ "security-framework",
1399
+ "security-framework-sys",
1400
+ "tempfile",
1401
+ ]
1402
+
1403
+ [[package]]
1404
+ name = "nix"
1405
+ version = "0.26.2"
1406
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1407
+ checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
1408
+ dependencies = [
1409
+ "bitflags",
1410
+ "cfg-if",
1411
+ "libc",
1412
+ "static_assertions",
1413
+ ]
1414
+
1415
+ [[package]]
1416
+ name = "nohash-hasher"
1417
+ version = "0.2.0"
1418
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1419
+ checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
1420
+
1421
+ [[package]]
1422
+ name = "nom"
1423
+ version = "7.1.3"
1424
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1425
+ checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
1426
+ dependencies = [
1427
+ "memchr",
1428
+ "minimal-lexical",
1429
+ ]
1430
+
1431
+ [[package]]
1432
+ name = "ntapi"
1433
+ version = "0.4.1"
1434
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1435
+ checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4"
1436
+ dependencies = [
1437
+ "winapi",
1438
+ ]
1439
+
1440
+ [[package]]
1441
+ name = "nu-ansi-term"
1442
+ version = "0.46.0"
1443
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1444
+ checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
1445
+ dependencies = [
1446
+ "overload",
1447
+ "winapi",
1448
+ ]
1449
+
1450
+ [[package]]
1451
+ name = "num_cpus"
1452
+ version = "1.15.0"
1453
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1454
+ checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
1455
+ dependencies = [
1456
+ "hermit-abi 0.2.6",
1457
+ "libc",
1458
+ ]
1459
+
1460
+ [[package]]
1461
+ name = "number_prefix"
1462
+ version = "0.3.0"
1463
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1464
+ checksum = "17b02fc0ff9a9e4b35b3342880f48e896ebf69f2967921fe8646bf5b7125956a"
1465
+
1466
+ [[package]]
1467
+ name = "number_prefix"
1468
+ version = "0.4.0"
1469
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1470
+ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
1471
+
1472
+ [[package]]
1473
+ name = "once_cell"
1474
+ version = "1.17.1"
1475
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1476
+ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
1477
+
1478
+ [[package]]
1479
+ name = "onig"
1480
+ version = "6.4.0"
1481
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1482
+ checksum = "8c4b31c8722ad9171c6d77d3557db078cab2bd50afcc9d09c8b315c59df8ca4f"
1483
+ dependencies = [
1484
+ "bitflags",
1485
+ "libc",
1486
+ "once_cell",
1487
+ "onig_sys",
1488
+ ]
1489
+
1490
+ [[package]]
1491
+ name = "onig_sys"
1492
+ version = "69.8.1"
1493
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1494
+ checksum = "7b829e3d7e9cc74c7e315ee8edb185bf4190da5acde74afd7fc59c35b1f086e7"
1495
+ dependencies = [
1496
+ "cc",
1497
+ "pkg-config",
1498
+ ]
1499
+
1500
+ [[package]]
1501
+ name = "opaque-debug"
1502
+ version = "0.3.0"
1503
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1504
+ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
1505
+
1506
+ [[package]]
1507
+ name = "openssl"
1508
+ version = "0.10.50"
1509
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1510
+ checksum = "7e30d8bc91859781f0a943411186324d580f2bbeb71b452fe91ae344806af3f1"
1511
+ dependencies = [
1512
+ "bitflags",
1513
+ "cfg-if",
1514
+ "foreign-types",
1515
+ "libc",
1516
+ "once_cell",
1517
+ "openssl-macros",
1518
+ "openssl-sys",
1519
+ ]
1520
+
1521
+ [[package]]
1522
+ name = "openssl-macros"
1523
+ version = "0.1.1"
1524
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1525
+ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
1526
+ dependencies = [
1527
+ "proc-macro2",
1528
+ "quote",
1529
+ "syn 2.0.15",
1530
+ ]
1531
+
1532
+ [[package]]
1533
+ name = "openssl-probe"
1534
+ version = "0.1.5"
1535
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1536
+ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
1537
+
1538
+ [[package]]
1539
+ name = "openssl-sys"
1540
+ version = "0.9.85"
1541
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1542
+ checksum = "0d3d193fb1488ad46ffe3aaabc912cc931d02ee8518fe2959aea8ef52718b0c0"
1543
+ dependencies = [
1544
+ "cc",
1545
+ "libc",
1546
+ "pkg-config",
1547
+ "vcpkg",
1548
+ ]
1549
+
1550
+ [[package]]
1551
+ name = "opentelemetry"
1552
+ version = "0.18.0"
1553
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1554
+ checksum = "69d6c3d7288a106c0a363e4b0e8d308058d56902adefb16f4936f417ffef086e"
1555
+ dependencies = [
1556
+ "opentelemetry_api",
1557
+ "opentelemetry_sdk",
1558
+ ]
1559
+
1560
+ [[package]]
1561
+ name = "opentelemetry-otlp"
1562
+ version = "0.11.0"
1563
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1564
+ checksum = "d1c928609d087790fc936a1067bdc310ae702bdf3b090c3f281b713622c8bbde"
1565
+ dependencies = [
1566
+ "async-trait",
1567
+ "futures",
1568
+ "futures-util",
1569
+ "http",
1570
+ "opentelemetry",
1571
+ "opentelemetry-proto",
1572
+ "prost",
1573
+ "thiserror",
1574
+ "tokio",
1575
+ "tonic",
1576
+ ]
1577
+
1578
+ [[package]]
1579
+ name = "opentelemetry-proto"
1580
+ version = "0.1.0"
1581
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1582
+ checksum = "d61a2f56df5574508dd86aaca016c917489e589ece4141df1b5e349af8d66c28"
1583
+ dependencies = [
1584
+ "futures",
1585
+ "futures-util",
1586
+ "opentelemetry",
1587
+ "prost",
1588
+ "tonic",
1589
+ "tonic-build",
1590
+ ]
1591
+
1592
+ [[package]]
1593
+ name = "opentelemetry_api"
1594
+ version = "0.18.0"
1595
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1596
+ checksum = "c24f96e21e7acc813c7a8394ee94978929db2bcc46cf6b5014fc612bf7760c22"
1597
+ dependencies = [
1598
+ "fnv",
1599
+ "futures-channel",
1600
+ "futures-util",
1601
+ "indexmap",
1602
+ "js-sys",
1603
+ "once_cell",
1604
+ "pin-project-lite",
1605
+ "thiserror",
1606
+ ]
1607
+
1608
+ [[package]]
1609
+ name = "opentelemetry_sdk"
1610
+ version = "0.18.0"
1611
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1612
+ checksum = "1ca41c4933371b61c2a2f214bf16931499af4ec90543604ec828f7a625c09113"
1613
+ dependencies = [
1614
+ "async-trait",
1615
+ "crossbeam-channel",
1616
+ "dashmap",
1617
+ "fnv",
1618
+ "futures-channel",
1619
+ "futures-executor",
1620
+ "futures-util",
1621
+ "once_cell",
1622
+ "opentelemetry_api",
1623
+ "percent-encoding",
1624
+ "rand",
1625
+ "thiserror",
1626
+ "tokio",
1627
+ "tokio-stream",
1628
+ ]
1629
+
1630
+ [[package]]
1631
+ name = "overload"
1632
+ version = "0.1.1"
1633
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1634
+ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
1635
+
1636
+ [[package]]
1637
+ name = "parking_lot"
1638
+ version = "0.12.1"
1639
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1640
+ checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
1641
+ dependencies = [
1642
+ "lock_api",
1643
+ "parking_lot_core",
1644
+ ]
1645
+
1646
+ [[package]]
1647
+ name = "parking_lot_core"
1648
+ version = "0.9.7"
1649
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1650
+ checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
1651
+ dependencies = [
1652
+ "cfg-if",
1653
+ "libc",
1654
+ "redox_syscall 0.2.16",
1655
+ "smallvec",
1656
+ "windows-sys 0.45.0",
1657
+ ]
1658
+
1659
+ [[package]]
1660
+ name = "password-hash"
1661
+ version = "0.4.2"
1662
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1663
+ checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700"
1664
+ dependencies = [
1665
+ "base64ct",
1666
+ "rand_core",
1667
+ "subtle",
1668
+ ]
1669
+
1670
+ [[package]]
1671
+ name = "paste"
1672
+ version = "1.0.12"
1673
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1674
+ checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79"
1675
+
1676
+ [[package]]
1677
+ name = "pbkdf2"
1678
+ version = "0.11.0"
1679
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1680
+ checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917"
1681
+ dependencies = [
1682
+ "digest",
1683
+ "hmac",
1684
+ "password-hash",
1685
+ "sha2",
1686
+ ]
1687
+
1688
+ [[package]]
1689
+ name = "percent-encoding"
1690
+ version = "2.2.0"
1691
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1692
+ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
1693
+
1694
+ [[package]]
1695
+ name = "petgraph"
1696
+ version = "0.6.3"
1697
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1698
+ checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4"
1699
+ dependencies = [
1700
+ "fixedbitset",
1701
+ "indexmap",
1702
+ ]
1703
+
1704
+ [[package]]
1705
+ name = "pin-project"
1706
+ version = "1.0.12"
1707
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1708
+ checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc"
1709
+ dependencies = [
1710
+ "pin-project-internal",
1711
+ ]
1712
+
1713
+ [[package]]
1714
+ name = "pin-project-internal"
1715
+ version = "1.0.12"
1716
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1717
+ checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"
1718
+ dependencies = [
1719
+ "proc-macro2",
1720
+ "quote",
1721
+ "syn 1.0.109",
1722
+ ]
1723
+
1724
+ [[package]]
1725
+ name = "pin-project-lite"
1726
+ version = "0.2.9"
1727
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1728
+ checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
1729
+
1730
+ [[package]]
1731
+ name = "pin-utils"
1732
+ version = "0.1.0"
1733
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1734
+ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
1735
+
1736
+ [[package]]
1737
+ name = "pkg-config"
1738
+ version = "0.3.26"
1739
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1740
+ checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
1741
+
1742
+ [[package]]
1743
+ name = "portable-atomic"
1744
+ version = "0.3.19"
1745
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1746
+ checksum = "26f6a7b87c2e435a3241addceeeff740ff8b7e76b74c13bf9acb17fa454ea00b"
1747
+
1748
+ [[package]]
1749
+ name = "ppv-lite86"
1750
+ version = "0.2.17"
1751
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1752
+ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
1753
+
1754
+ [[package]]
1755
+ name = "prettyplease"
1756
+ version = "0.1.25"
1757
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1758
+ checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86"
1759
+ dependencies = [
1760
+ "proc-macro2",
1761
+ "syn 1.0.109",
1762
+ ]
1763
+
1764
+ [[package]]
1765
+ name = "proc-macro-error"
1766
+ version = "1.0.4"
1767
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1768
+ checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
1769
+ dependencies = [
1770
+ "proc-macro-error-attr",
1771
+ "proc-macro2",
1772
+ "quote",
1773
+ "syn 1.0.109",
1774
+ "version_check",
1775
+ ]
1776
+
1777
+ [[package]]
1778
+ name = "proc-macro-error-attr"
1779
+ version = "1.0.4"
1780
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1781
+ checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
1782
+ dependencies = [
1783
+ "proc-macro2",
1784
+ "quote",
1785
+ "version_check",
1786
+ ]
1787
+
1788
+ [[package]]
1789
+ name = "proc-macro2"
1790
+ version = "1.0.56"
1791
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1792
+ checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
1793
+ dependencies = [
1794
+ "unicode-ident",
1795
+ ]
1796
+
1797
+ [[package]]
1798
+ name = "prost"
1799
+ version = "0.11.9"
1800
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1801
+ checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd"
1802
+ dependencies = [
1803
+ "bytes",
1804
+ "prost-derive",
1805
+ ]
1806
+
1807
+ [[package]]
1808
+ name = "prost-build"
1809
+ version = "0.11.9"
1810
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1811
+ checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270"
1812
+ dependencies = [
1813
+ "bytes",
1814
+ "heck",
1815
+ "itertools 0.10.5",
1816
+ "lazy_static",
1817
+ "log",
1818
+ "multimap",
1819
+ "petgraph",
1820
+ "prettyplease",
1821
+ "prost",
1822
+ "prost-types",
1823
+ "regex",
1824
+ "syn 1.0.109",
1825
+ "tempfile",
1826
+ "which",
1827
+ ]
1828
+
1829
+ [[package]]
1830
+ name = "prost-derive"
1831
+ version = "0.11.9"
1832
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1833
+ checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4"
1834
+ dependencies = [
1835
+ "anyhow",
1836
+ "itertools 0.10.5",
1837
+ "proc-macro2",
1838
+ "quote",
1839
+ "syn 1.0.109",
1840
+ ]
1841
+
1842
+ [[package]]
1843
+ name = "prost-types"
1844
+ version = "0.11.9"
1845
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1846
+ checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13"
1847
+ dependencies = [
1848
+ "prost",
1849
+ ]
1850
+
1851
+ [[package]]
1852
+ name = "quanta"
1853
+ version = "0.10.1"
1854
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1855
+ checksum = "b7e31331286705f455e56cca62e0e717158474ff02b7936c1fa596d983f4ae27"
1856
+ dependencies = [
1857
+ "crossbeam-utils",
1858
+ "libc",
1859
+ "mach",
1860
+ "once_cell",
1861
+ "raw-cpuid",
1862
+ "wasi 0.10.2+wasi-snapshot-preview1",
1863
+ "web-sys",
1864
+ "winapi",
1865
+ ]
1866
+
1867
+ [[package]]
1868
+ name = "quote"
1869
+ version = "1.0.26"
1870
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1871
+ checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
1872
+ dependencies = [
1873
+ "proc-macro2",
1874
+ ]
1875
+
1876
+ [[package]]
1877
+ name = "rand"
1878
+ version = "0.8.5"
1879
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1880
+ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
1881
+ dependencies = [
1882
+ "libc",
1883
+ "rand_chacha",
1884
+ "rand_core",
1885
+ ]
1886
+
1887
+ [[package]]
1888
+ name = "rand_chacha"
1889
+ version = "0.3.1"
1890
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1891
+ checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
1892
+ dependencies = [
1893
+ "ppv-lite86",
1894
+ "rand_core",
1895
+ ]
1896
+
1897
+ [[package]]
1898
+ name = "rand_core"
1899
+ version = "0.6.4"
1900
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1901
+ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
1902
+ dependencies = [
1903
+ "getrandom",
1904
+ ]
1905
+
1906
+ [[package]]
1907
+ name = "raw-cpuid"
1908
+ version = "10.7.0"
1909
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1910
+ checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332"
1911
+ dependencies = [
1912
+ "bitflags",
1913
+ ]
1914
+
1915
+ [[package]]
1916
+ name = "rayon"
1917
+ version = "1.7.0"
1918
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1919
+ checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b"
1920
+ dependencies = [
1921
+ "either",
1922
+ "rayon-core",
1923
+ ]
1924
+
1925
+ [[package]]
1926
+ name = "rayon-cond"
1927
+ version = "0.1.0"
1928
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1929
+ checksum = "fd1259362c9065e5ea39a789ef40b1e3fd934c94beb7b5ab3ac6629d3b5e7cb7"
1930
+ dependencies = [
1931
+ "either",
1932
+ "itertools 0.8.2",
1933
+ "rayon",
1934
+ ]
1935
+
1936
+ [[package]]
1937
+ name = "rayon-core"
1938
+ version = "1.11.0"
1939
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1940
+ checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d"
1941
+ dependencies = [
1942
+ "crossbeam-channel",
1943
+ "crossbeam-deque",
1944
+ "crossbeam-utils",
1945
+ "num_cpus",
1946
+ ]
1947
+
1948
+ [[package]]
1949
+ name = "redox_syscall"
1950
+ version = "0.2.16"
1951
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1952
+ checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
1953
+ dependencies = [
1954
+ "bitflags",
1955
+ ]
1956
+
1957
+ [[package]]
1958
+ name = "redox_syscall"
1959
+ version = "0.3.5"
1960
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1961
+ checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
1962
+ dependencies = [
1963
+ "bitflags",
1964
+ ]
1965
+
1966
+ [[package]]
1967
+ name = "redox_users"
1968
+ version = "0.4.3"
1969
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1970
+ checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
1971
+ dependencies = [
1972
+ "getrandom",
1973
+ "redox_syscall 0.2.16",
1974
+ "thiserror",
1975
+ ]
1976
+
1977
+ [[package]]
1978
+ name = "regex"
1979
+ version = "1.7.3"
1980
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1981
+ checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d"
1982
+ dependencies = [
1983
+ "aho-corasick",
1984
+ "memchr",
1985
+ "regex-syntax",
1986
+ ]
1987
+
1988
+ [[package]]
1989
+ name = "regex-automata"
1990
+ version = "0.1.10"
1991
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1992
+ checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
1993
+ dependencies = [
1994
+ "regex-syntax",
1995
+ ]
1996
+
1997
+ [[package]]
1998
+ name = "regex-syntax"
1999
+ version = "0.6.29"
2000
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2001
+ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
2002
+
2003
+ [[package]]
2004
+ name = "reqwest"
2005
+ version = "0.11.16"
2006
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2007
+ checksum = "27b71749df584b7f4cac2c426c127a7c785a5106cc98f7a8feb044115f0fa254"
2008
+ dependencies = [
2009
+ "base64 0.21.0",
2010
+ "bytes",
2011
+ "encoding_rs",
2012
+ "futures-core",
2013
+ "futures-util",
2014
+ "h2",
2015
+ "http",
2016
+ "http-body",
2017
+ "hyper",
2018
+ "hyper-tls",
2019
+ "ipnet",
2020
+ "js-sys",
2021
+ "log",
2022
+ "mime",
2023
+ "native-tls",
2024
+ "once_cell",
2025
+ "percent-encoding",
2026
+ "pin-project-lite",
2027
+ "serde",
2028
+ "serde_json",
2029
+ "serde_urlencoded",
2030
+ "tokio",
2031
+ "tokio-native-tls",
2032
+ "tower-service",
2033
+ "url",
2034
+ "wasm-bindgen",
2035
+ "wasm-bindgen-futures",
2036
+ "web-sys",
2037
+ "winreg",
2038
+ ]
2039
+
2040
+ [[package]]
2041
+ name = "rust-embed"
2042
+ version = "6.6.1"
2043
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2044
+ checksum = "1b68543d5527e158213414a92832d2aab11a84d2571a5eb021ebe22c43aab066"
2045
+ dependencies = [
2046
+ "rust-embed-impl",
2047
+ "rust-embed-utils",
2048
+ "walkdir",
2049
+ ]
2050
+
2051
+ [[package]]
2052
+ name = "rust-embed-impl"
2053
+ version = "6.5.0"
2054
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2055
+ checksum = "4d4e0f0ced47ded9a68374ac145edd65a6c1fa13a96447b873660b2a568a0fd7"
2056
+ dependencies = [
2057
+ "proc-macro2",
2058
+ "quote",
2059
+ "rust-embed-utils",
2060
+ "shellexpand",
2061
+ "syn 1.0.109",
2062
+ "walkdir",
2063
+ ]
2064
+
2065
+ [[package]]
2066
+ name = "rust-embed-utils"
2067
+ version = "7.5.0"
2068
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2069
+ checksum = "512b0ab6853f7e14e3c8754acb43d6f748bb9ced66aa5915a6553ac8213f7731"
2070
+ dependencies = [
2071
+ "sha2",
2072
+ "walkdir",
2073
+ ]
2074
+
2075
+ [[package]]
2076
+ name = "rustc_version"
2077
+ version = "0.4.0"
2078
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2079
+ checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
2080
+ dependencies = [
2081
+ "semver",
2082
+ ]
2083
+
2084
+ [[package]]
2085
+ name = "rustix"
2086
+ version = "0.37.11"
2087
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2088
+ checksum = "85597d61f83914ddeba6a47b3b8ffe7365107221c2e557ed94426489fefb5f77"
2089
+ dependencies = [
2090
+ "bitflags",
2091
+ "errno",
2092
+ "io-lifetimes",
2093
+ "libc",
2094
+ "linux-raw-sys",
2095
+ "windows-sys 0.48.0",
2096
+ ]
2097
+
2098
+ [[package]]
2099
+ name = "rustversion"
2100
+ version = "1.0.12"
2101
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2102
+ checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06"
2103
+
2104
+ [[package]]
2105
+ name = "ryu"
2106
+ version = "1.0.13"
2107
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2108
+ checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
2109
+
2110
+ [[package]]
2111
+ name = "same-file"
2112
+ version = "1.0.6"
2113
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2114
+ checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
2115
+ dependencies = [
2116
+ "winapi-util",
2117
+ ]
2118
+
2119
+ [[package]]
2120
+ name = "schannel"
2121
+ version = "0.1.21"
2122
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2123
+ checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3"
2124
+ dependencies = [
2125
+ "windows-sys 0.42.0",
2126
+ ]
2127
+
2128
+ [[package]]
2129
+ name = "scopeguard"
2130
+ version = "1.1.0"
2131
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2132
+ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
2133
+
2134
+ [[package]]
2135
+ name = "security-framework"
2136
+ version = "2.8.2"
2137
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2138
+ checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254"
2139
+ dependencies = [
2140
+ "bitflags",
2141
+ "core-foundation",
2142
+ "core-foundation-sys",
2143
+ "libc",
2144
+ "security-framework-sys",
2145
+ ]
2146
+
2147
+ [[package]]
2148
+ name = "security-framework-sys"
2149
+ version = "2.8.0"
2150
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2151
+ checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4"
2152
+ dependencies = [
2153
+ "core-foundation-sys",
2154
+ "libc",
2155
+ ]
2156
+
2157
+ [[package]]
2158
+ name = "semver"
2159
+ version = "1.0.17"
2160
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2161
+ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
2162
+
2163
+ [[package]]
2164
+ name = "serde"
2165
+ version = "1.0.160"
2166
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2167
+ checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c"
2168
+ dependencies = [
2169
+ "serde_derive",
2170
+ ]
2171
+
2172
+ [[package]]
2173
+ name = "serde_derive"
2174
+ version = "1.0.160"
2175
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2176
+ checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df"
2177
+ dependencies = [
2178
+ "proc-macro2",
2179
+ "quote",
2180
+ "syn 2.0.15",
2181
+ ]
2182
+
2183
+ [[package]]
2184
+ name = "serde_json"
2185
+ version = "1.0.96"
2186
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2187
+ checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
2188
+ dependencies = [
2189
+ "itoa",
2190
+ "ryu",
2191
+ "serde",
2192
+ ]
2193
+
2194
+ [[package]]
2195
+ name = "serde_path_to_error"
2196
+ version = "0.1.11"
2197
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2198
+ checksum = "f7f05c1d5476066defcdfacce1f52fc3cae3af1d3089727100c02ae92e5abbe0"
2199
+ dependencies = [
2200
+ "serde",
2201
+ ]
2202
+
2203
+ [[package]]
2204
+ name = "serde_urlencoded"
2205
+ version = "0.7.1"
2206
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2207
+ checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
2208
+ dependencies = [
2209
+ "form_urlencoded",
2210
+ "itoa",
2211
+ "ryu",
2212
+ "serde",
2213
+ ]
2214
+
2215
+ [[package]]
2216
+ name = "sha1"
2217
+ version = "0.10.5"
2218
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2219
+ checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
2220
+ dependencies = [
2221
+ "cfg-if",
2222
+ "cpufeatures",
2223
+ "digest",
2224
+ ]
2225
+
2226
+ [[package]]
2227
+ name = "sha2"
2228
+ version = "0.10.6"
2229
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2230
+ checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
2231
+ dependencies = [
2232
+ "cfg-if",
2233
+ "cpufeatures",
2234
+ "digest",
2235
+ ]
2236
+
2237
+ [[package]]
2238
+ name = "sharded-slab"
2239
+ version = "0.1.4"
2240
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2241
+ checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"
2242
+ dependencies = [
2243
+ "lazy_static",
2244
+ ]
2245
+
2246
+ [[package]]
2247
+ name = "shellexpand"
2248
+ version = "2.1.2"
2249
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2250
+ checksum = "7ccc8076840c4da029af4f87e4e8daeb0fca6b87bbb02e10cb60b791450e11e4"
2251
+ dependencies = [
2252
+ "dirs",
2253
+ ]
2254
+
2255
+ [[package]]
2256
+ name = "signal-hook-registry"
2257
+ version = "1.4.1"
2258
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2259
+ checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
2260
+ dependencies = [
2261
+ "libc",
2262
+ ]
2263
+
2264
+ [[package]]
2265
+ name = "sketches-ddsketch"
2266
+ version = "0.2.1"
2267
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2268
+ checksum = "68a406c1882ed7f29cd5e248c9848a80e7cb6ae0fea82346d2746f2f941c07e1"
2269
+
2270
+ [[package]]
2271
+ name = "slab"
2272
+ version = "0.4.8"
2273
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2274
+ checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d"
2275
+ dependencies = [
2276
+ "autocfg",
2277
+ ]
2278
+
2279
+ [[package]]
2280
+ name = "smallvec"
2281
+ version = "1.10.0"
2282
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2283
+ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
2284
+
2285
+ [[package]]
2286
+ name = "socket2"
2287
+ version = "0.4.9"
2288
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2289
+ checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
2290
+ dependencies = [
2291
+ "libc",
2292
+ "winapi",
2293
+ ]
2294
+
2295
+ [[package]]
2296
+ name = "spin"
2297
+ version = "0.9.8"
2298
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2299
+ checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
2300
+ dependencies = [
2301
+ "lock_api",
2302
+ ]
2303
+
2304
+ [[package]]
2305
+ name = "spm_precompiled"
2306
+ version = "0.1.4"
2307
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2308
+ checksum = "5851699c4033c63636f7ea4cf7b7c1f1bf06d0cc03cfb42e711de5a5c46cf326"
2309
+ dependencies = [
2310
+ "base64 0.13.1",
2311
+ "nom",
2312
+ "serde",
2313
+ "unicode-segmentation",
2314
+ ]
2315
+
2316
+ [[package]]
2317
+ name = "static_assertions"
2318
+ version = "1.1.0"
2319
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2320
+ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
2321
+
2322
+ [[package]]
2323
+ name = "strsim"
2324
+ version = "0.10.0"
2325
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2326
+ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
2327
+
2328
+ [[package]]
2329
+ name = "subprocess"
2330
+ version = "0.2.9"
2331
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2332
+ checksum = "0c2e86926081dda636c546d8c5e641661049d7562a68f5488be4a1f7f66f6086"
2333
+ dependencies = [
2334
+ "libc",
2335
+ "winapi",
2336
+ ]
2337
+
2338
+ [[package]]
2339
+ name = "subtle"
2340
+ version = "2.4.1"
2341
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2342
+ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
2343
+
2344
+ [[package]]
2345
+ name = "syn"
2346
+ version = "1.0.109"
2347
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2348
+ checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
2349
+ dependencies = [
2350
+ "proc-macro2",
2351
+ "quote",
2352
+ "unicode-ident",
2353
+ ]
2354
+
2355
+ [[package]]
2356
+ name = "syn"
2357
+ version = "2.0.15"
2358
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2359
+ checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822"
2360
+ dependencies = [
2361
+ "proc-macro2",
2362
+ "quote",
2363
+ "unicode-ident",
2364
+ ]
2365
+
2366
+ [[package]]
2367
+ name = "sync_wrapper"
2368
+ version = "0.1.2"
2369
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2370
+ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
2371
+
2372
+ [[package]]
2373
+ name = "sysinfo"
2374
+ version = "0.28.4"
2375
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2376
+ checksum = "b4c2f3ca6693feb29a89724516f016488e9aafc7f37264f898593ee4b942f31b"
2377
+ dependencies = [
2378
+ "cfg-if",
2379
+ "core-foundation-sys",
2380
+ "libc",
2381
+ "ntapi",
2382
+ "once_cell",
2383
+ "winapi",
2384
+ ]
2385
+
2386
+ [[package]]
2387
+ name = "tar"
2388
+ version = "0.4.38"
2389
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2390
+ checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6"
2391
+ dependencies = [
2392
+ "filetime",
2393
+ "libc",
2394
+ "xattr",
2395
+ ]
2396
+
2397
+ [[package]]
2398
+ name = "tempfile"
2399
+ version = "3.5.0"
2400
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2401
+ checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998"
2402
+ dependencies = [
2403
+ "cfg-if",
2404
+ "fastrand",
2405
+ "redox_syscall 0.3.5",
2406
+ "rustix",
2407
+ "windows-sys 0.45.0",
2408
+ ]
2409
+
2410
+ [[package]]
2411
+ name = "text-generation-client"
2412
+ version = "0.6.0"
2413
+ dependencies = [
2414
+ "futures",
2415
+ "grpc-metadata",
2416
+ "prost",
2417
+ "prost-build",
2418
+ "thiserror",
2419
+ "tokio",
2420
+ "tonic",
2421
+ "tonic-build",
2422
+ "tower",
2423
+ "tracing",
2424
+ "tracing-error",
2425
+ ]
2426
+
2427
+ [[package]]
2428
+ name = "text-generation-launcher"
2429
+ version = "0.6.0"
2430
+ dependencies = [
2431
+ "clap",
2432
+ "ctrlc",
2433
+ "float_eq",
2434
+ "reqwest",
2435
+ "serde",
2436
+ "serde_json",
2437
+ "subprocess",
2438
+ "tracing",
2439
+ "tracing-subscriber",
2440
+ "vergen",
2441
+ ]
2442
+
2443
+ [[package]]
2444
+ name = "text-generation-router"
2445
+ version = "0.6.0"
2446
+ dependencies = [
2447
+ "async-stream",
2448
+ "axum",
2449
+ "axum-tracing-opentelemetry",
2450
+ "clap",
2451
+ "flume",
2452
+ "futures",
2453
+ "metrics",
2454
+ "metrics-exporter-prometheus",
2455
+ "nohash-hasher",
2456
+ "opentelemetry",
2457
+ "opentelemetry-otlp",
2458
+ "rand",
2459
+ "reqwest",
2460
+ "serde",
2461
+ "serde_json",
2462
+ "text-generation-client",
2463
+ "thiserror",
2464
+ "tokenizers",
2465
+ "tokio",
2466
+ "tower-http 0.4.0",
2467
+ "tracing",
2468
+ "tracing-opentelemetry",
2469
+ "tracing-subscriber",
2470
+ "utoipa",
2471
+ "utoipa-swagger-ui",
2472
+ "vergen",
2473
+ ]
2474
+
2475
+ [[package]]
2476
+ name = "thiserror"
2477
+ version = "1.0.40"
2478
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2479
+ checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
2480
+ dependencies = [
2481
+ "thiserror-impl",
2482
+ ]
2483
+
2484
+ [[package]]
2485
+ name = "thiserror-impl"
2486
+ version = "1.0.40"
2487
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2488
+ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
2489
+ dependencies = [
2490
+ "proc-macro2",
2491
+ "quote",
2492
+ "syn 2.0.15",
2493
+ ]
2494
+
2495
+ [[package]]
2496
+ name = "thread_local"
2497
+ version = "1.1.7"
2498
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2499
+ checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
2500
+ dependencies = [
2501
+ "cfg-if",
2502
+ "once_cell",
2503
+ ]
2504
+
2505
+ [[package]]
2506
+ name = "time"
2507
+ version = "0.3.20"
2508
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2509
+ checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890"
2510
+ dependencies = [
2511
+ "itoa",
2512
+ "serde",
2513
+ "time-core",
2514
+ "time-macros",
2515
+ ]
2516
+
2517
+ [[package]]
2518
+ name = "time-core"
2519
+ version = "0.1.0"
2520
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2521
+ checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
2522
+
2523
+ [[package]]
2524
+ name = "time-macros"
2525
+ version = "0.2.8"
2526
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2527
+ checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36"
2528
+ dependencies = [
2529
+ "time-core",
2530
+ ]
2531
+
2532
+ [[package]]
2533
+ name = "tinyvec"
2534
+ version = "1.6.0"
2535
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2536
+ checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
2537
+ dependencies = [
2538
+ "tinyvec_macros",
2539
+ ]
2540
+
2541
+ [[package]]
2542
+ name = "tinyvec_macros"
2543
+ version = "0.1.1"
2544
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2545
+ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
2546
+
2547
+ [[package]]
2548
+ name = "tokenizers"
2549
+ version = "0.13.3"
2550
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2551
+ checksum = "5cf49017523bf0bc01c9966f172c5f120bbb7b96cccd1708772dd42e767fb9f5"
2552
+ dependencies = [
2553
+ "aho-corasick",
2554
+ "cached-path",
2555
+ "clap",
2556
+ "derive_builder",
2557
+ "dirs",
2558
+ "esaxx-rs",
2559
+ "getrandom",
2560
+ "indicatif 0.15.0",
2561
+ "itertools 0.9.0",
2562
+ "lazy_static",
2563
+ "log",
2564
+ "macro_rules_attribute",
2565
+ "monostate",
2566
+ "onig",
2567
+ "paste",
2568
+ "rand",
2569
+ "rayon",
2570
+ "rayon-cond",
2571
+ "regex",
2572
+ "regex-syntax",
2573
+ "reqwest",
2574
+ "serde",
2575
+ "serde_json",
2576
+ "spm_precompiled",
2577
+ "thiserror",
2578
+ "unicode-normalization-alignments",
2579
+ "unicode-segmentation",
2580
+ "unicode_categories",
2581
+ ]
2582
+
2583
+ [[package]]
2584
+ name = "tokio"
2585
+ version = "1.27.0"
2586
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2587
+ checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001"
2588
+ dependencies = [
2589
+ "autocfg",
2590
+ "bytes",
2591
+ "libc",
2592
+ "mio",
2593
+ "num_cpus",
2594
+ "parking_lot",
2595
+ "pin-project-lite",
2596
+ "signal-hook-registry",
2597
+ "socket2",
2598
+ "tokio-macros",
2599
+ "windows-sys 0.45.0",
2600
+ ]
2601
+
2602
+ [[package]]
2603
+ name = "tokio-io-timeout"
2604
+ version = "1.2.0"
2605
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2606
+ checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf"
2607
+ dependencies = [
2608
+ "pin-project-lite",
2609
+ "tokio",
2610
+ ]
2611
+
2612
+ [[package]]
2613
+ name = "tokio-macros"
2614
+ version = "2.0.0"
2615
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2616
+ checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce"
2617
+ dependencies = [
2618
+ "proc-macro2",
2619
+ "quote",
2620
+ "syn 2.0.15",
2621
+ ]
2622
+
2623
+ [[package]]
2624
+ name = "tokio-native-tls"
2625
+ version = "0.3.1"
2626
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2627
+ checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
2628
+ dependencies = [
2629
+ "native-tls",
2630
+ "tokio",
2631
+ ]
2632
+
2633
+ [[package]]
2634
+ name = "tokio-stream"
2635
+ version = "0.1.12"
2636
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2637
+ checksum = "8fb52b74f05dbf495a8fba459fdc331812b96aa086d9eb78101fa0d4569c3313"
2638
+ dependencies = [
2639
+ "futures-core",
2640
+ "pin-project-lite",
2641
+ "tokio",
2642
+ ]
2643
+
2644
+ [[package]]
2645
+ name = "tokio-util"
2646
+ version = "0.7.7"
2647
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2648
+ checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2"
2649
+ dependencies = [
2650
+ "bytes",
2651
+ "futures-core",
2652
+ "futures-sink",
2653
+ "pin-project-lite",
2654
+ "tokio",
2655
+ "tracing",
2656
+ ]
2657
+
2658
+ [[package]]
2659
+ name = "tonic"
2660
+ version = "0.8.3"
2661
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2662
+ checksum = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb"
2663
+ dependencies = [
2664
+ "async-stream",
2665
+ "async-trait",
2666
+ "axum",
2667
+ "base64 0.13.1",
2668
+ "bytes",
2669
+ "futures-core",
2670
+ "futures-util",
2671
+ "h2",
2672
+ "http",
2673
+ "http-body",
2674
+ "hyper",
2675
+ "hyper-timeout",
2676
+ "percent-encoding",
2677
+ "pin-project",
2678
+ "prost",
2679
+ "prost-derive",
2680
+ "tokio",
2681
+ "tokio-stream",
2682
+ "tokio-util",
2683
+ "tower",
2684
+ "tower-layer",
2685
+ "tower-service",
2686
+ "tracing",
2687
+ "tracing-futures",
2688
+ ]
2689
+
2690
+ [[package]]
2691
+ name = "tonic-build"
2692
+ version = "0.8.4"
2693
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2694
+ checksum = "5bf5e9b9c0f7e0a7c027dcfaba7b2c60816c7049171f679d99ee2ff65d0de8c4"
2695
+ dependencies = [
2696
+ "prettyplease",
2697
+ "proc-macro2",
2698
+ "prost-build",
2699
+ "quote",
2700
+ "syn 1.0.109",
2701
+ ]
2702
+
2703
+ [[package]]
2704
+ name = "tower"
2705
+ version = "0.4.13"
2706
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2707
+ checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
2708
+ dependencies = [
2709
+ "futures-core",
2710
+ "futures-util",
2711
+ "indexmap",
2712
+ "pin-project",
2713
+ "pin-project-lite",
2714
+ "rand",
2715
+ "slab",
2716
+ "tokio",
2717
+ "tokio-util",
2718
+ "tower-layer",
2719
+ "tower-service",
2720
+ "tracing",
2721
+ ]
2722
+
2723
+ [[package]]
2724
+ name = "tower-http"
2725
+ version = "0.3.5"
2726
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2727
+ checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858"
2728
+ dependencies = [
2729
+ "bitflags",
2730
+ "bytes",
2731
+ "futures-core",
2732
+ "futures-util",
2733
+ "http",
2734
+ "http-body",
2735
+ "http-range-header",
2736
+ "pin-project-lite",
2737
+ "tower-layer",
2738
+ "tower-service",
2739
+ "tracing",
2740
+ ]
2741
+
2742
+ [[package]]
2743
+ name = "tower-http"
2744
+ version = "0.4.0"
2745
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2746
+ checksum = "5d1d42a9b3f3ec46ba828e8d376aec14592ea199f70a06a548587ecd1c4ab658"
2747
+ dependencies = [
2748
+ "bitflags",
2749
+ "bytes",
2750
+ "futures-core",
2751
+ "futures-util",
2752
+ "http",
2753
+ "http-body",
2754
+ "http-range-header",
2755
+ "pin-project-lite",
2756
+ "tower-layer",
2757
+ "tower-service",
2758
+ ]
2759
+
2760
+ [[package]]
2761
+ name = "tower-layer"
2762
+ version = "0.3.2"
2763
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2764
+ checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
2765
+
2766
+ [[package]]
2767
+ name = "tower-service"
2768
+ version = "0.3.2"
2769
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2770
+ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
2771
+
2772
+ [[package]]
2773
+ name = "tracing"
2774
+ version = "0.1.37"
2775
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2776
+ checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
2777
+ dependencies = [
2778
+ "cfg-if",
2779
+ "log",
2780
+ "pin-project-lite",
2781
+ "tracing-attributes",
2782
+ "tracing-core",
2783
+ ]
2784
+
2785
+ [[package]]
2786
+ name = "tracing-attributes"
2787
+ version = "0.1.23"
2788
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2789
+ checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
2790
+ dependencies = [
2791
+ "proc-macro2",
2792
+ "quote",
2793
+ "syn 1.0.109",
2794
+ ]
2795
+
2796
+ [[package]]
2797
+ name = "tracing-core"
2798
+ version = "0.1.30"
2799
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2800
+ checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
2801
+ dependencies = [
2802
+ "once_cell",
2803
+ "valuable",
2804
+ ]
2805
+
2806
+ [[package]]
2807
+ name = "tracing-error"
2808
+ version = "0.2.0"
2809
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2810
+ checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e"
2811
+ dependencies = [
2812
+ "tracing",
2813
+ "tracing-subscriber",
2814
+ ]
2815
+
2816
+ [[package]]
2817
+ name = "tracing-futures"
2818
+ version = "0.2.5"
2819
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2820
+ checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
2821
+ dependencies = [
2822
+ "pin-project",
2823
+ "tracing",
2824
+ ]
2825
+
2826
+ [[package]]
2827
+ name = "tracing-log"
2828
+ version = "0.1.3"
2829
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2830
+ checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
2831
+ dependencies = [
2832
+ "lazy_static",
2833
+ "log",
2834
+ "tracing-core",
2835
+ ]
2836
+
2837
+ [[package]]
2838
+ name = "tracing-opentelemetry"
2839
+ version = "0.18.0"
2840
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2841
+ checksum = "21ebb87a95ea13271332df069020513ab70bdb5637ca42d6e492dc3bbbad48de"
2842
+ dependencies = [
2843
+ "once_cell",
2844
+ "opentelemetry",
2845
+ "tracing",
2846
+ "tracing-core",
2847
+ "tracing-log",
2848
+ "tracing-subscriber",
2849
+ ]
2850
+
2851
+ [[package]]
2852
+ name = "tracing-serde"
2853
+ version = "0.1.3"
2854
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2855
+ checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1"
2856
+ dependencies = [
2857
+ "serde",
2858
+ "tracing-core",
2859
+ ]
2860
+
2861
+ [[package]]
2862
+ name = "tracing-subscriber"
2863
+ version = "0.3.16"
2864
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2865
+ checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70"
2866
+ dependencies = [
2867
+ "matchers",
2868
+ "nu-ansi-term",
2869
+ "once_cell",
2870
+ "regex",
2871
+ "serde",
2872
+ "serde_json",
2873
+ "sharded-slab",
2874
+ "smallvec",
2875
+ "thread_local",
2876
+ "tracing",
2877
+ "tracing-core",
2878
+ "tracing-log",
2879
+ "tracing-serde",
2880
+ ]
2881
+
2882
+ [[package]]
2883
+ name = "try-lock"
2884
+ version = "0.2.4"
2885
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2886
+ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
2887
+
2888
+ [[package]]
2889
+ name = "typenum"
2890
+ version = "1.16.0"
2891
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2892
+ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
2893
+
2894
+ [[package]]
2895
+ name = "unicase"
2896
+ version = "2.6.0"
2897
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2898
+ checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
2899
+ dependencies = [
2900
+ "version_check",
2901
+ ]
2902
+
2903
+ [[package]]
2904
+ name = "unicode-bidi"
2905
+ version = "0.3.13"
2906
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2907
+ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
2908
+
2909
+ [[package]]
2910
+ name = "unicode-ident"
2911
+ version = "1.0.8"
2912
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2913
+ checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
2914
+
2915
+ [[package]]
2916
+ name = "unicode-normalization"
2917
+ version = "0.1.22"
2918
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2919
+ checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
2920
+ dependencies = [
2921
+ "tinyvec",
2922
+ ]
2923
+
2924
+ [[package]]
2925
+ name = "unicode-normalization-alignments"
2926
+ version = "0.1.12"
2927
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2928
+ checksum = "43f613e4fa046e69818dd287fdc4bc78175ff20331479dab6e1b0f98d57062de"
2929
+ dependencies = [
2930
+ "smallvec",
2931
+ ]
2932
+
2933
+ [[package]]
2934
+ name = "unicode-segmentation"
2935
+ version = "1.10.1"
2936
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2937
+ checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
2938
+
2939
+ [[package]]
2940
+ name = "unicode-width"
2941
+ version = "0.1.10"
2942
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2943
+ checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
2944
+
2945
+ [[package]]
2946
+ name = "unicode_categories"
2947
+ version = "0.1.1"
2948
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2949
+ checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
2950
+
2951
+ [[package]]
2952
+ name = "url"
2953
+ version = "2.3.1"
2954
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2955
+ checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
2956
+ dependencies = [
2957
+ "form_urlencoded",
2958
+ "idna",
2959
+ "percent-encoding",
2960
+ ]
2961
+
2962
+ [[package]]
2963
+ name = "utf8parse"
2964
+ version = "0.2.1"
2965
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2966
+ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
2967
+
2968
+ [[package]]
2969
+ name = "utoipa"
2970
+ version = "3.3.0"
2971
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2972
+ checksum = "68ae74ef183fae36d650f063ae7bde1cacbe1cd7e72b617cbe1e985551878b98"
2973
+ dependencies = [
2974
+ "indexmap",
2975
+ "serde",
2976
+ "serde_json",
2977
+ "utoipa-gen",
2978
+ ]
2979
+
2980
+ [[package]]
2981
+ name = "utoipa-gen"
2982
+ version = "3.3.0"
2983
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2984
+ checksum = "7ea8ac818da7e746a63285594cce8a96f5e00ee31994e655bd827569cb8b137b"
2985
+ dependencies = [
2986
+ "proc-macro-error",
2987
+ "proc-macro2",
2988
+ "quote",
2989
+ "syn 2.0.15",
2990
+ ]
2991
+
2992
+ [[package]]
2993
+ name = "utoipa-swagger-ui"
2994
+ version = "3.1.3"
2995
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2996
+ checksum = "062bba5a3568e126ac72049a63254f4cb1da2eb713db0c1ab2a4c76be191db8c"
2997
+ dependencies = [
2998
+ "axum",
2999
+ "mime_guess",
3000
+ "regex",
3001
+ "rust-embed",
3002
+ "serde",
3003
+ "serde_json",
3004
+ "utoipa",
3005
+ "zip",
3006
+ ]
3007
+
3008
+ [[package]]
3009
+ name = "valuable"
3010
+ version = "0.1.0"
3011
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3012
+ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
3013
+
3014
+ [[package]]
3015
+ name = "vcpkg"
3016
+ version = "0.2.15"
3017
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3018
+ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
3019
+
3020
+ [[package]]
3021
+ name = "vergen"
3022
+ version = "8.1.1"
3023
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3024
+ checksum = "c1b86a8af1dedf089b1c78338678e4c7492b6045649042d94faf19690499d236"
3025
+ dependencies = [
3026
+ "anyhow",
3027
+ "rustc_version",
3028
+ "rustversion",
3029
+ "sysinfo",
3030
+ "time",
3031
+ ]
3032
+
3033
+ [[package]]
3034
+ name = "version_check"
3035
+ version = "0.9.4"
3036
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3037
+ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
3038
+
3039
+ [[package]]
3040
+ name = "walkdir"
3041
+ version = "2.3.3"
3042
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3043
+ checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698"
3044
+ dependencies = [
3045
+ "same-file",
3046
+ "winapi-util",
3047
+ ]
3048
+
3049
+ [[package]]
3050
+ name = "want"
3051
+ version = "0.3.0"
3052
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3053
+ checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
3054
+ dependencies = [
3055
+ "log",
3056
+ "try-lock",
3057
+ ]
3058
+
3059
+ [[package]]
3060
+ name = "wasi"
3061
+ version = "0.10.2+wasi-snapshot-preview1"
3062
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3063
+ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
3064
+
3065
+ [[package]]
3066
+ name = "wasi"
3067
+ version = "0.11.0+wasi-snapshot-preview1"
3068
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3069
+ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
3070
+
3071
+ [[package]]
3072
+ name = "wasm-bindgen"
3073
+ version = "0.2.84"
3074
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3075
+ checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b"
3076
+ dependencies = [
3077
+ "cfg-if",
3078
+ "wasm-bindgen-macro",
3079
+ ]
3080
+
3081
+ [[package]]
3082
+ name = "wasm-bindgen-backend"
3083
+ version = "0.2.84"
3084
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3085
+ checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9"
3086
+ dependencies = [
3087
+ "bumpalo",
3088
+ "log",
3089
+ "once_cell",
3090
+ "proc-macro2",
3091
+ "quote",
3092
+ "syn 1.0.109",
3093
+ "wasm-bindgen-shared",
3094
+ ]
3095
+
3096
+ [[package]]
3097
+ name = "wasm-bindgen-futures"
3098
+ version = "0.4.34"
3099
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3100
+ checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454"
3101
+ dependencies = [
3102
+ "cfg-if",
3103
+ "js-sys",
3104
+ "wasm-bindgen",
3105
+ "web-sys",
3106
+ ]
3107
+
3108
+ [[package]]
3109
+ name = "wasm-bindgen-macro"
3110
+ version = "0.2.84"
3111
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3112
+ checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5"
3113
+ dependencies = [
3114
+ "quote",
3115
+ "wasm-bindgen-macro-support",
3116
+ ]
3117
+
3118
+ [[package]]
3119
+ name = "wasm-bindgen-macro-support"
3120
+ version = "0.2.84"
3121
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3122
+ checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
3123
+ dependencies = [
3124
+ "proc-macro2",
3125
+ "quote",
3126
+ "syn 1.0.109",
3127
+ "wasm-bindgen-backend",
3128
+ "wasm-bindgen-shared",
3129
+ ]
3130
+
3131
+ [[package]]
3132
+ name = "wasm-bindgen-shared"
3133
+ version = "0.2.84"
3134
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3135
+ checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
3136
+
3137
+ [[package]]
3138
+ name = "web-sys"
3139
+ version = "0.3.61"
3140
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3141
+ checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97"
3142
+ dependencies = [
3143
+ "js-sys",
3144
+ "wasm-bindgen",
3145
+ ]
3146
+
3147
+ [[package]]
3148
+ name = "which"
3149
+ version = "4.4.0"
3150
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3151
+ checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269"
3152
+ dependencies = [
3153
+ "either",
3154
+ "libc",
3155
+ "once_cell",
3156
+ ]
3157
+
3158
+ [[package]]
3159
+ name = "winapi"
3160
+ version = "0.3.9"
3161
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3162
+ checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
3163
+ dependencies = [
3164
+ "winapi-i686-pc-windows-gnu",
3165
+ "winapi-x86_64-pc-windows-gnu",
3166
+ ]
3167
+
3168
+ [[package]]
3169
+ name = "winapi-i686-pc-windows-gnu"
3170
+ version = "0.4.0"
3171
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3172
+ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
3173
+
3174
+ [[package]]
3175
+ name = "winapi-util"
3176
+ version = "0.1.5"
3177
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3178
+ checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
3179
+ dependencies = [
3180
+ "winapi",
3181
+ ]
3182
+
3183
+ [[package]]
3184
+ name = "winapi-x86_64-pc-windows-gnu"
3185
+ version = "0.4.0"
3186
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3187
+ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
3188
+
3189
+ [[package]]
3190
+ name = "windows-sys"
3191
+ version = "0.42.0"
3192
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3193
+ checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
3194
+ dependencies = [
3195
+ "windows_aarch64_gnullvm 0.42.2",
3196
+ "windows_aarch64_msvc 0.42.2",
3197
+ "windows_i686_gnu 0.42.2",
3198
+ "windows_i686_msvc 0.42.2",
3199
+ "windows_x86_64_gnu 0.42.2",
3200
+ "windows_x86_64_gnullvm 0.42.2",
3201
+ "windows_x86_64_msvc 0.42.2",
3202
+ ]
3203
+
3204
+ [[package]]
3205
+ name = "windows-sys"
3206
+ version = "0.45.0"
3207
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3208
+ checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
3209
+ dependencies = [
3210
+ "windows-targets 0.42.2",
3211
+ ]
3212
+
3213
+ [[package]]
3214
+ name = "windows-sys"
3215
+ version = "0.48.0"
3216
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3217
+ checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
3218
+ dependencies = [
3219
+ "windows-targets 0.48.0",
3220
+ ]
3221
+
3222
+ [[package]]
3223
+ name = "windows-targets"
3224
+ version = "0.42.2"
3225
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3226
+ checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
3227
+ dependencies = [
3228
+ "windows_aarch64_gnullvm 0.42.2",
3229
+ "windows_aarch64_msvc 0.42.2",
3230
+ "windows_i686_gnu 0.42.2",
3231
+ "windows_i686_msvc 0.42.2",
3232
+ "windows_x86_64_gnu 0.42.2",
3233
+ "windows_x86_64_gnullvm 0.42.2",
3234
+ "windows_x86_64_msvc 0.42.2",
3235
+ ]
3236
+
3237
+ [[package]]
3238
+ name = "windows-targets"
3239
+ version = "0.48.0"
3240
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3241
+ checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
3242
+ dependencies = [
3243
+ "windows_aarch64_gnullvm 0.48.0",
3244
+ "windows_aarch64_msvc 0.48.0",
3245
+ "windows_i686_gnu 0.48.0",
3246
+ "windows_i686_msvc 0.48.0",
3247
+ "windows_x86_64_gnu 0.48.0",
3248
+ "windows_x86_64_gnullvm 0.48.0",
3249
+ "windows_x86_64_msvc 0.48.0",
3250
+ ]
3251
+
3252
+ [[package]]
3253
+ name = "windows_aarch64_gnullvm"
3254
+ version = "0.42.2"
3255
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3256
+ checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
3257
+
3258
+ [[package]]
3259
+ name = "windows_aarch64_gnullvm"
3260
+ version = "0.48.0"
3261
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3262
+ checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
3263
+
3264
+ [[package]]
3265
+ name = "windows_aarch64_msvc"
3266
+ version = "0.42.2"
3267
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3268
+ checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
3269
+
3270
+ [[package]]
3271
+ name = "windows_aarch64_msvc"
3272
+ version = "0.48.0"
3273
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3274
+ checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
3275
+
3276
+ [[package]]
3277
+ name = "windows_i686_gnu"
3278
+ version = "0.42.2"
3279
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3280
+ checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
3281
+
3282
+ [[package]]
3283
+ name = "windows_i686_gnu"
3284
+ version = "0.48.0"
3285
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3286
+ checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
3287
+
3288
+ [[package]]
3289
+ name = "windows_i686_msvc"
3290
+ version = "0.42.2"
3291
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3292
+ checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
3293
+
3294
+ [[package]]
3295
+ name = "windows_i686_msvc"
3296
+ version = "0.48.0"
3297
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3298
+ checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
3299
+
3300
+ [[package]]
3301
+ name = "windows_x86_64_gnu"
3302
+ version = "0.42.2"
3303
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3304
+ checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
3305
+
3306
+ [[package]]
3307
+ name = "windows_x86_64_gnu"
3308
+ version = "0.48.0"
3309
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3310
+ checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
3311
+
3312
+ [[package]]
3313
+ name = "windows_x86_64_gnullvm"
3314
+ version = "0.42.2"
3315
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3316
+ checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
3317
+
3318
+ [[package]]
3319
+ name = "windows_x86_64_gnullvm"
3320
+ version = "0.48.0"
3321
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3322
+ checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
3323
+
3324
+ [[package]]
3325
+ name = "windows_x86_64_msvc"
3326
+ version = "0.42.2"
3327
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3328
+ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
3329
+
3330
+ [[package]]
3331
+ name = "windows_x86_64_msvc"
3332
+ version = "0.48.0"
3333
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3334
+ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
3335
+
3336
+ [[package]]
3337
+ name = "winreg"
3338
+ version = "0.10.1"
3339
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3340
+ checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
3341
+ dependencies = [
3342
+ "winapi",
3343
+ ]
3344
+
3345
+ [[package]]
3346
+ name = "xattr"
3347
+ version = "0.2.3"
3348
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3349
+ checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc"
3350
+ dependencies = [
3351
+ "libc",
3352
+ ]
3353
+
3354
+ [[package]]
3355
+ name = "zip"
3356
+ version = "0.6.4"
3357
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3358
+ checksum = "0445d0fbc924bb93539b4316c11afb121ea39296f99a3c4c9edad09e3658cdef"
3359
+ dependencies = [
3360
+ "aes",
3361
+ "byteorder",
3362
+ "bzip2",
3363
+ "constant_time_eq",
3364
+ "crc32fast",
3365
+ "crossbeam-utils",
3366
+ "flate2",
3367
+ "hmac",
3368
+ "pbkdf2",
3369
+ "sha1",
3370
+ "time",
3371
+ "zstd",
3372
+ ]
3373
+
3374
+ [[package]]
3375
+ name = "zstd"
3376
+ version = "0.11.2+zstd.1.5.2"
3377
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3378
+ checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4"
3379
+ dependencies = [
3380
+ "zstd-safe",
3381
+ ]
3382
+
3383
+ [[package]]
3384
+ name = "zstd-safe"
3385
+ version = "5.0.2+zstd.1.5.2"
3386
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3387
+ checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db"
3388
+ dependencies = [
3389
+ "libc",
3390
+ "zstd-sys",
3391
+ ]
3392
+
3393
+ [[package]]
3394
+ name = "zstd-sys"
3395
+ version = "2.0.8+zstd.1.5.5"
3396
+ source = "registry+https://github.com/rust-lang/crates.io-index"
3397
+ checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c"
3398
+ dependencies = [
3399
+ "cc",
3400
+ "libc",
3401
+ "pkg-config",
3402
+ ]
Cargo.toml ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [workspace]
2
+ members = [
3
+ "router",
4
+ "router/client",
5
+ "router/grpc-metadata",
6
+ "launcher"
7
+ ]
8
+ exclude = [
9
+ "benchmark"
10
+ ]
11
+
12
+ [profile.release]
13
+ debug = 1
14
+ incremental = true
15
+ lto = "off"
16
+ panic = "abort"
Dockerfile CHANGED
@@ -1,99 +1,179 @@
1
- FROM nvidia/cuda:11.3.1-base-ubuntu20.04
2
-
3
- ENV DEBIAN_FRONTEND=noninteractive \
4
- TZ=Europe/Paris
5
-
6
- # Remove any third-party apt sources to avoid issues with expiring keys.
7
- # Install some basic utilities
8
- RUN rm -f /etc/apt/sources.list.d/*.list && \
9
- apt-get update && apt-get install -y --no-install-recommends \
10
- curl \
11
- ca-certificates \
12
- sudo \
13
- git \
14
- git-lfs \
15
- zip \
16
- unzip \
17
- htop \
18
- bzip2 \
19
- libx11-6 \
20
- build-essential \
21
- libsndfile-dev \
22
- software-properties-common \
23
- && rm -rf /var/lib/apt/lists/*
24
-
25
- RUN add-apt-repository ppa:flexiondotorg/nvtop && \
26
- apt-get upgrade -y && \
27
- apt-get install -y --no-install-recommends nvtop
28
-
29
- RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - && \
30
- apt-get install -y nodejs && \
31
- npm install -g configurable-http-proxy
32
-
33
- # Create a working directory
34
- WORKDIR /app
35
-
36
- # Create a non-root user and switch to it
37
- RUN adduser --disabled-password --gecos '' --shell /bin/bash user \
38
- && chown -R user:user /app
39
- RUN echo "user ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/90-user
40
- USER user
41
-
42
- # All users can use /home/user as their home directory
43
- ENV HOME=/home/user
44
- RUN mkdir $HOME/.cache $HOME/.config \
45
- && chmod -R 777 $HOME
46
-
47
- # Set up the Conda environment
48
- ENV CONDA_AUTO_UPDATE_CONDA=false \
49
- PATH=$HOME/miniconda/bin:$PATH
50
- RUN curl -sLo ~/miniconda.sh https://repo.continuum.io/miniconda/Miniconda3-py39_4.10.3-Linux-x86_64.sh \
51
- && chmod +x ~/miniconda.sh \
52
- && ~/miniconda.sh -b -p ~/miniconda \
53
- && rm ~/miniconda.sh \
54
- && conda clean -ya
55
-
56
- WORKDIR $HOME/app
57
-
58
- #######################################
59
- # Start root user section
60
- #######################################
61
-
62
- USER root
63
-
64
- # User Debian packages
65
- ## Security warning : Potential user code executed as root (build time)
66
- RUN --mount=target=/root/packages.txt,source=packages.txt \
67
- apt-get update && \
68
- xargs -r -a /root/packages.txt apt-get install -y --no-install-recommends \
69
- && rm -rf /var/lib/apt/lists/*
70
-
71
- RUN --mount=target=/root/on_startup.sh,source=on_startup.sh,readwrite \
72
- bash /root/on_startup.sh
73
-
74
- #######################################
75
- # End root user section
76
- #######################################
77
-
78
- USER user
79
-
80
- # Python packages
81
- RUN --mount=target=requirements.txt,source=requirements.txt \
82
- pip install --no-cache-dir --upgrade -r requirements.txt
83
-
84
- # Copy the current directory contents into the container at $HOME/app setting the owner to the user
85
- COPY --chown=user . $HOME/app
86
-
87
- RUN chmod +x start_server.sh
88
-
89
- COPY --chown=user login.html /home/user/miniconda/lib/python3.9/site-packages/jupyter_server/templates/login.html
90
-
91
- ENV PYTHONUNBUFFERED=1 \
92
- GRADIO_ALLOW_FLAGGING=never \
93
- GRADIO_NUM_PORTS=1 \
94
- GRADIO_SERVER_NAME=0.0.0.0 \
95
- GRADIO_THEME=huggingface \
96
- SYSTEM=spaces \
97
- SHELL=/bin/bash
98
-
99
- CMD ["./start_server.sh"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Rust builder
2
+ FROM lukemathwalker/cargo-chef:latest-rust-1.69 AS chef
3
+ WORKDIR /usr/src
4
+
5
+ FROM chef as planner
6
+ COPY Cargo.toml Cargo.toml
7
+ COPY rust-toolchain.toml rust-toolchain.toml
8
+ COPY proto proto
9
+ COPY router router
10
+ COPY launcher launcher
11
+ RUN cargo chef prepare --recipe-path recipe.json
12
+
13
+ FROM chef AS builder
14
+
15
+ ARG GIT_SHA
16
+ ARG DOCKER_LABEL
17
+
18
+ RUN PROTOC_ZIP=protoc-21.12-linux-x86_64.zip && \
19
+ curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v21.12/$PROTOC_ZIP && \
20
+ unzip -o $PROTOC_ZIP -d /usr/local bin/protoc && \
21
+ unzip -o $PROTOC_ZIP -d /usr/local 'include/*' && \
22
+ rm -f $PROTOC_ZIP
23
+
24
+ COPY --from=planner /usr/src/recipe.json recipe.json
25
+ RUN cargo chef cook --release --recipe-path recipe.json
26
+
27
+ COPY Cargo.toml Cargo.toml
28
+ COPY rust-toolchain.toml rust-toolchain.toml
29
+ COPY proto proto
30
+ COPY router router
31
+ COPY launcher launcher
32
+ RUN cargo build --release
33
+
34
+ # Python builder
35
+ # Adapted from: https://github.com/pytorch/pytorch/blob/master/Dockerfile
36
+ FROM debian:bullseye-slim as pytorch-install
37
+
38
+ ARG PYTORCH_VERSION=2.0.0
39
+ ARG PYTHON_VERSION=3.9
40
+ ARG CUDA_VERSION=11.8
41
+ ARG MAMBA_VERSION=23.1.0-1
42
+ ARG CUDA_CHANNEL=nvidia
43
+ ARG INSTALL_CHANNEL=pytorch
44
+ # Automatically set by buildx
45
+ ARG TARGETPLATFORM
46
+
47
+ ENV PATH /opt/conda/bin:$PATH
48
+
49
+ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
50
+ build-essential \
51
+ ca-certificates \
52
+ ccache \
53
+ curl \
54
+ git && \
55
+ rm -rf /var/lib/apt/lists/*
56
+
57
+ # Install conda
58
+ # translating Docker's TARGETPLATFORM into mamba arches
59
+ RUN case ${TARGETPLATFORM} in \
60
+ "linux/arm64") MAMBA_ARCH=aarch64 ;; \
61
+ *) MAMBA_ARCH=x86_64 ;; \
62
+ esac && \
63
+ curl -fsSL -v -o ~/mambaforge.sh -O "https://github.com/conda-forge/miniforge/releases/download/${MAMBA_VERSION}/Mambaforge-${MAMBA_VERSION}-Linux-${MAMBA_ARCH}.sh"
64
+ RUN chmod +x ~/mambaforge.sh && \
65
+ bash ~/mambaforge.sh -b -p /opt/conda && \
66
+ rm ~/mambaforge.sh
67
+
68
+ # Install pytorch
69
+ # On arm64 we exit with an error code
70
+ RUN case ${TARGETPLATFORM} in \
71
+ "linux/arm64") exit 1 ;; \
72
+ *) /opt/conda/bin/conda update -y conda && \
73
+ /opt/conda/bin/conda install -c "${INSTALL_CHANNEL}" -c "${CUDA_CHANNEL}" -y "python=${PYTHON_VERSION}" pytorch==$PYTORCH_VERSION "pytorch-cuda=$(echo $CUDA_VERSION | cut -d'.' -f 1-2)" ;; \
74
+ esac && \
75
+ /opt/conda/bin/conda clean -ya
76
+
77
+ # CUDA kernels builder image
78
+ FROM pytorch-install as kernel-builder
79
+
80
+ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
81
+ ninja-build \
82
+ && rm -rf /var/lib/apt/lists/*
83
+
84
+ RUN /opt/conda/bin/conda install -c "nvidia/label/cuda-11.8.0" cuda==11.8 && \
85
+ /opt/conda/bin/conda clean -ya
86
+
87
+
88
+ # Build Flash Attention CUDA kernels
89
+ FROM kernel-builder as flash-att-builder
90
+
91
+ WORKDIR /usr/src
92
+
93
+ COPY server/Makefile-flash-att Makefile
94
+
95
+ # Build specific version of flash attention
96
+ RUN make build-flash-attention
97
+
98
+ # Build Transformers CUDA kernels
99
+ FROM kernel-builder as transformers-builder
100
+
101
+ WORKDIR /usr/src
102
+
103
+ COPY server/Makefile-transformers Makefile
104
+
105
+ # Build specific version of transformers
106
+ RUN BUILD_EXTENSIONS="True" make build-transformers
107
+
108
+ # Text Generation Inference base image
109
+ FROM debian:bullseye-slim as base
110
+
111
+ # Conda env
112
+ ENV PATH=/opt/conda/bin:$PATH \
113
+ CONDA_PREFIX=/opt/conda
114
+
115
+ # Text Generation Inference base env
116
+ ENV HUGGINGFACE_HUB_CACHE=/data \
117
+ HF_HUB_ENABLE_HF_TRANSFER=1 \
118
+ MODEL_ID=bigscience/bloom-560m \
119
+ QUANTIZE=false \
120
+ NUM_SHARD=1 \
121
+ PORT=80
122
+
123
+ LABEL com.nvidia.volumes.needed="nvidia_driver"
124
+
125
+ WORKDIR /usr/src
126
+
127
+ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
128
+ libssl-dev \
129
+ ca-certificates \
130
+ make \
131
+ && rm -rf /var/lib/apt/lists/*
132
+
133
+ # Copy conda with PyTorch installed
134
+ COPY --from=pytorch-install /opt/conda /opt/conda
135
+
136
+ # Copy build artifacts from flash attention builder
137
+ COPY --from=flash-att-builder /usr/src/flash-attention/build/lib.linux-x86_64-cpython-39 /opt/conda/lib/python3.9/site-packages
138
+ COPY --from=flash-att-builder /usr/src/flash-attention/csrc/layer_norm/build/lib.linux-x86_64-cpython-39 /opt/conda/lib/python3.9/site-packages
139
+ COPY --from=flash-att-builder /usr/src/flash-attention/csrc/rotary/build/lib.linux-x86_64-cpython-39 /opt/conda/lib/python3.9/site-packages
140
+
141
+ # Copy build artifacts from transformers builder
142
+ COPY --from=transformers-builder /usr/src/transformers /usr/src/transformers
143
+ COPY --from=transformers-builder /usr/src/transformers/build/lib.linux-x86_64-cpython-39/transformers /usr/src/transformers/src/transformers
144
+
145
+ # Install transformers dependencies
146
+ RUN cd /usr/src/transformers && pip install -e . --no-cache-dir && pip install einops --no-cache-dir
147
+
148
+ # Install server
149
+ COPY proto proto
150
+ COPY server server
151
+ COPY server/Makefile server/Makefile
152
+ RUN cd server && \
153
+ make gen-server && \
154
+ pip install -r requirements.txt && \
155
+ pip install ".[bnb, accelerate]" --no-cache-dir
156
+
157
+ # Install router
158
+ COPY --from=builder /usr/src/target/release/text-generation-router /usr/local/bin/text-generation-router
159
+ # Install launcher
160
+ COPY --from=builder /usr/src/target/release/text-generation-launcher /usr/local/bin/text-generation-launcher
161
+
162
+ # AWS Sagemaker compatbile image
163
+ FROM base as sagemaker
164
+
165
+ COPY sagemaker-entrypoint.sh entrypoint.sh
166
+ RUN chmod +x entrypoint.sh
167
+
168
+ # NVIDIA env vars
169
+ ENV NVIDIA_VISIBLE_DEVICES all
170
+ ENV NVIDIA_DRIVER_CAPABILITIES compute,utility
171
+ ENV LD_LIBRARY_PATH /usr/local/nvidia/lib:/usr/local/nvidia/lib64
172
+
173
+ ENTRYPOINT ["./entrypoint.sh"]
174
+
175
+ # Final image
176
+ FROM base
177
+
178
+ ENTRYPOINT ["text-generation-launcher"]
179
+ CMD ["--json-output"]
LICENSE ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright 2022 Hugging Face
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
Makefile ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ install-server:
2
+ cd server && make install
3
+
4
+ install-router:
5
+ cd router && cargo install --path .
6
+
7
+ install-launcher:
8
+ cd launcher && cargo install --path .
9
+
10
+ install-benchmark:
11
+ cd benchmark && cargo install --path .
12
+
13
+ install: install-server install-router install-launcher
14
+
15
+ server-dev:
16
+ cd server && make run-dev
17
+
18
+ router-dev:
19
+ cd router && cargo run -- --port 8080
20
+
21
+ integration-tests: install-router install-launcher
22
+ cargo test
23
+
24
+ python-server-tests:
25
+ HF_HUB_ENABLE_HF_TRANSFER=1 pytest server/tests
26
+
27
+ python-client-tests:
28
+ pytest clients/python/tests
29
+
30
+ python-tests: python-server-tests python-client-tests
31
+
32
+ run-bloom-560m:
33
+ text-generation-launcher --model-id bigscience/bloom-560m --num-shard 2 --port 8080
34
+
35
+ run-bloom-560m-quantize:
36
+ text-generation-launcher --model-id bigscience/bloom-560m --num-shard 2 --quantize --port 8080
37
+
38
+ download-bloom:
39
+ HF_HUB_ENABLE_HF_TRANSFER=1 text-generation-server download-weights bigscience/bloom
40
+
41
+ run-bloom:
42
+ text-generation-launcher --model-id bigscience/bloom --num-shard 8 --port 8080
43
+
44
+ run-bloom-quantize:
45
+ text-generation-launcher --model-id bigscience/bloom --num-shard 8 --quantize --port 8080
aml/deployment.yaml ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ $schema: https://azuremlschemas.azureedge.net/latest/managedOnlineDeployment.schema.json
2
+ name: bloom-deployment
3
+ endpoint_name: bloom-inference
4
+ model: azureml:bloom-safetensors:1
5
+ model_mount_path: /var/azureml-model
6
+ environment_variables:
7
+ WEIGHTS_CACHE_OVERRIDE: /var/azureml-model/bloom-safetensors
8
+ MODEL_ID: bigscience/bloom
9
+ NUM_SHARD: 8
10
+ environment:
11
+ image: db4c2190dd824d1f950f5d1555fbadf0.azurecr.io/text-generation-inference:0.2.0
12
+ inference_config:
13
+ liveness_route:
14
+ port: 80
15
+ path: /health
16
+ readiness_route:
17
+ port: 80
18
+ path: /health
19
+ scoring_route:
20
+ port: 80
21
+ path: /generate
22
+ instance_type: Standard_ND96amsr_A100_v4
23
+ request_settings:
24
+ request_timeout_ms: 90000
25
+ max_concurrent_requests_per_instance: 256
26
+ liveness_probe:
27
+ initial_delay: 600
28
+ timeout: 90
29
+ period: 120
30
+ success_threshold: 1
31
+ failure_threshold: 5
32
+ readiness_probe:
33
+ initial_delay: 600
34
+ timeout: 90
35
+ period: 120
36
+ success_threshold: 1
37
+ failure_threshold: 5
38
+ instance_count: 1
aml/endpoint.yaml ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ $schema: https://azuremlsdk2.blob.core.windows.net/latest/managedOnlineEndpoint.schema.json
2
+ name: bloom-inference
3
+ auth_mode: key
aml/model.yaml ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ $schema: https://azuremlschemas.azureedge.net/latest/model.schema.json
2
+ name: bloom-safetensors
3
+ path: /data/bloom-safetensors
assets/architecture.jpg ADDED
assets/benchmark.png ADDED
benchmark/Cargo.lock ADDED
@@ -0,0 +1,2884 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 3
4
+
5
+ [[package]]
6
+ name = "adler"
7
+ version = "1.0.2"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
10
+
11
+ [[package]]
12
+ name = "aes"
13
+ version = "0.7.5"
14
+ source = "registry+https://github.com/rust-lang/crates.io-index"
15
+ checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8"
16
+ dependencies = [
17
+ "cfg-if",
18
+ "cipher",
19
+ "cpufeatures",
20
+ "opaque-debug",
21
+ ]
22
+
23
+ [[package]]
24
+ name = "aho-corasick"
25
+ version = "0.7.20"
26
+ source = "registry+https://github.com/rust-lang/crates.io-index"
27
+ checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
28
+ dependencies = [
29
+ "memchr",
30
+ ]
31
+
32
+ [[package]]
33
+ name = "anstream"
34
+ version = "0.2.6"
35
+ source = "registry+https://github.com/rust-lang/crates.io-index"
36
+ checksum = "342258dd14006105c2b75ab1bd7543a03bdf0cfc94383303ac212a04939dff6f"
37
+ dependencies = [
38
+ "anstyle",
39
+ "anstyle-parse",
40
+ "anstyle-wincon",
41
+ "concolor-override",
42
+ "concolor-query",
43
+ "is-terminal",
44
+ "utf8parse",
45
+ ]
46
+
47
+ [[package]]
48
+ name = "anstyle"
49
+ version = "0.3.5"
50
+ source = "registry+https://github.com/rust-lang/crates.io-index"
51
+ checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2"
52
+
53
+ [[package]]
54
+ name = "anstyle-parse"
55
+ version = "0.1.1"
56
+ source = "registry+https://github.com/rust-lang/crates.io-index"
57
+ checksum = "a7d1bb534e9efed14f3e5f44e7dd1a4f709384023a4165199a4241e18dff0116"
58
+ dependencies = [
59
+ "utf8parse",
60
+ ]
61
+
62
+ [[package]]
63
+ name = "anstyle-wincon"
64
+ version = "0.2.0"
65
+ source = "registry+https://github.com/rust-lang/crates.io-index"
66
+ checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa"
67
+ dependencies = [
68
+ "anstyle",
69
+ "windows-sys 0.45.0",
70
+ ]
71
+
72
+ [[package]]
73
+ name = "anyhow"
74
+ version = "1.0.70"
75
+ source = "registry+https://github.com/rust-lang/crates.io-index"
76
+ checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4"
77
+
78
+ [[package]]
79
+ name = "async-stream"
80
+ version = "0.3.4"
81
+ source = "registry+https://github.com/rust-lang/crates.io-index"
82
+ checksum = "ad445822218ce64be7a341abfb0b1ea43b5c23aa83902542a4542e78309d8e5e"
83
+ dependencies = [
84
+ "async-stream-impl",
85
+ "futures-core",
86
+ "pin-project-lite",
87
+ ]
88
+
89
+ [[package]]
90
+ name = "async-stream-impl"
91
+ version = "0.3.4"
92
+ source = "registry+https://github.com/rust-lang/crates.io-index"
93
+ checksum = "e4655ae1a7b0cdf149156f780c5bf3f1352bc53cbd9e0a361a7ef7b22947e965"
94
+ dependencies = [
95
+ "proc-macro2",
96
+ "quote",
97
+ "syn 1.0.109",
98
+ ]
99
+
100
+ [[package]]
101
+ name = "async-trait"
102
+ version = "0.1.68"
103
+ source = "registry+https://github.com/rust-lang/crates.io-index"
104
+ checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842"
105
+ dependencies = [
106
+ "proc-macro2",
107
+ "quote",
108
+ "syn 2.0.11",
109
+ ]
110
+
111
+ [[package]]
112
+ name = "autocfg"
113
+ version = "1.1.0"
114
+ source = "registry+https://github.com/rust-lang/crates.io-index"
115
+ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
116
+
117
+ [[package]]
118
+ name = "average"
119
+ version = "0.13.1"
120
+ source = "registry+https://github.com/rust-lang/crates.io-index"
121
+ checksum = "843ec791d3f24503bbf72bbd5e49a3ab4dbb4bcd0a8ef6b0c908efa73caa27b1"
122
+ dependencies = [
123
+ "easy-cast",
124
+ "float-ord",
125
+ "num-traits",
126
+ ]
127
+
128
+ [[package]]
129
+ name = "axum"
130
+ version = "0.6.12"
131
+ source = "registry+https://github.com/rust-lang/crates.io-index"
132
+ checksum = "349f8ccfd9221ee7d1f3d4b33e1f8319b3a81ed8f61f2ea40b37b859794b4491"
133
+ dependencies = [
134
+ "async-trait",
135
+ "axum-core",
136
+ "bitflags",
137
+ "bytes",
138
+ "futures-util",
139
+ "http",
140
+ "http-body",
141
+ "hyper",
142
+ "itoa",
143
+ "matchit",
144
+ "memchr",
145
+ "mime",
146
+ "percent-encoding",
147
+ "pin-project-lite",
148
+ "rustversion",
149
+ "serde",
150
+ "sync_wrapper",
151
+ "tower",
152
+ "tower-layer",
153
+ "tower-service",
154
+ ]
155
+
156
+ [[package]]
157
+ name = "axum-core"
158
+ version = "0.3.3"
159
+ source = "registry+https://github.com/rust-lang/crates.io-index"
160
+ checksum = "b2f958c80c248b34b9a877a643811be8dbca03ca5ba827f2b63baf3a81e5fc4e"
161
+ dependencies = [
162
+ "async-trait",
163
+ "bytes",
164
+ "futures-util",
165
+ "http",
166
+ "http-body",
167
+ "mime",
168
+ "rustversion",
169
+ "tower-layer",
170
+ "tower-service",
171
+ ]
172
+
173
+ [[package]]
174
+ name = "base64"
175
+ version = "0.13.1"
176
+ source = "registry+https://github.com/rust-lang/crates.io-index"
177
+ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
178
+
179
+ [[package]]
180
+ name = "base64"
181
+ version = "0.21.0"
182
+ source = "registry+https://github.com/rust-lang/crates.io-index"
183
+ checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
184
+
185
+ [[package]]
186
+ name = "base64ct"
187
+ version = "1.6.0"
188
+ source = "registry+https://github.com/rust-lang/crates.io-index"
189
+ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
190
+
191
+ [[package]]
192
+ name = "bitflags"
193
+ version = "1.3.2"
194
+ source = "registry+https://github.com/rust-lang/crates.io-index"
195
+ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
196
+
197
+ [[package]]
198
+ name = "block-buffer"
199
+ version = "0.10.4"
200
+ source = "registry+https://github.com/rust-lang/crates.io-index"
201
+ checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
202
+ dependencies = [
203
+ "generic-array",
204
+ ]
205
+
206
+ [[package]]
207
+ name = "bumpalo"
208
+ version = "3.12.0"
209
+ source = "registry+https://github.com/rust-lang/crates.io-index"
210
+ checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
211
+
212
+ [[package]]
213
+ name = "byteorder"
214
+ version = "1.4.3"
215
+ source = "registry+https://github.com/rust-lang/crates.io-index"
216
+ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
217
+
218
+ [[package]]
219
+ name = "bytes"
220
+ version = "1.4.0"
221
+ source = "registry+https://github.com/rust-lang/crates.io-index"
222
+ checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
223
+
224
+ [[package]]
225
+ name = "bzip2"
226
+ version = "0.4.4"
227
+ source = "registry+https://github.com/rust-lang/crates.io-index"
228
+ checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8"
229
+ dependencies = [
230
+ "bzip2-sys",
231
+ "libc",
232
+ ]
233
+
234
+ [[package]]
235
+ name = "bzip2-sys"
236
+ version = "0.1.11+1.0.8"
237
+ source = "registry+https://github.com/rust-lang/crates.io-index"
238
+ checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc"
239
+ dependencies = [
240
+ "cc",
241
+ "libc",
242
+ "pkg-config",
243
+ ]
244
+
245
+ [[package]]
246
+ name = "cached-path"
247
+ version = "0.6.1"
248
+ source = "registry+https://github.com/rust-lang/crates.io-index"
249
+ checksum = "097968e38f1319207f057d0f4d76452e4f4f847a5de61c5215379f297fa034f3"
250
+ dependencies = [
251
+ "flate2",
252
+ "fs2",
253
+ "glob",
254
+ "indicatif 0.16.2",
255
+ "log",
256
+ "rand",
257
+ "reqwest",
258
+ "serde",
259
+ "serde_json",
260
+ "sha2",
261
+ "tar",
262
+ "tempfile",
263
+ "thiserror",
264
+ "zip",
265
+ ]
266
+
267
+ [[package]]
268
+ name = "cassowary"
269
+ version = "0.3.0"
270
+ source = "registry+https://github.com/rust-lang/crates.io-index"
271
+ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
272
+
273
+ [[package]]
274
+ name = "cc"
275
+ version = "1.0.79"
276
+ source = "registry+https://github.com/rust-lang/crates.io-index"
277
+ checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
278
+ dependencies = [
279
+ "jobserver",
280
+ ]
281
+
282
+ [[package]]
283
+ name = "cfg-if"
284
+ version = "1.0.0"
285
+ source = "registry+https://github.com/rust-lang/crates.io-index"
286
+ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
287
+
288
+ [[package]]
289
+ name = "cipher"
290
+ version = "0.3.0"
291
+ source = "registry+https://github.com/rust-lang/crates.io-index"
292
+ checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7"
293
+ dependencies = [
294
+ "generic-array",
295
+ ]
296
+
297
+ [[package]]
298
+ name = "clap"
299
+ version = "4.2.1"
300
+ source = "registry+https://github.com/rust-lang/crates.io-index"
301
+ checksum = "046ae530c528f252094e4a77886ee1374437744b2bff1497aa898bbddbbb29b3"
302
+ dependencies = [
303
+ "clap_builder",
304
+ "clap_derive",
305
+ "once_cell",
306
+ ]
307
+
308
+ [[package]]
309
+ name = "clap_builder"
310
+ version = "4.2.1"
311
+ source = "registry+https://github.com/rust-lang/crates.io-index"
312
+ checksum = "223163f58c9a40c3b0a43e1c4b50a9ce09f007ea2cb1ec258a687945b4b7929f"
313
+ dependencies = [
314
+ "anstream",
315
+ "anstyle",
316
+ "bitflags",
317
+ "clap_lex",
318
+ "strsim",
319
+ ]
320
+
321
+ [[package]]
322
+ name = "clap_derive"
323
+ version = "4.2.0"
324
+ source = "registry+https://github.com/rust-lang/crates.io-index"
325
+ checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4"
326
+ dependencies = [
327
+ "heck",
328
+ "proc-macro2",
329
+ "quote",
330
+ "syn 2.0.11",
331
+ ]
332
+
333
+ [[package]]
334
+ name = "clap_lex"
335
+ version = "0.4.1"
336
+ source = "registry+https://github.com/rust-lang/crates.io-index"
337
+ checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1"
338
+
339
+ [[package]]
340
+ name = "concolor-override"
341
+ version = "1.0.0"
342
+ source = "registry+https://github.com/rust-lang/crates.io-index"
343
+ checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f"
344
+
345
+ [[package]]
346
+ name = "concolor-query"
347
+ version = "0.3.3"
348
+ source = "registry+https://github.com/rust-lang/crates.io-index"
349
+ checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf"
350
+ dependencies = [
351
+ "windows-sys 0.45.0",
352
+ ]
353
+
354
+ [[package]]
355
+ name = "console"
356
+ version = "0.15.5"
357
+ source = "registry+https://github.com/rust-lang/crates.io-index"
358
+ checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60"
359
+ dependencies = [
360
+ "encode_unicode",
361
+ "lazy_static",
362
+ "libc",
363
+ "unicode-width",
364
+ "windows-sys 0.42.0",
365
+ ]
366
+
367
+ [[package]]
368
+ name = "constant_time_eq"
369
+ version = "0.1.5"
370
+ source = "registry+https://github.com/rust-lang/crates.io-index"
371
+ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
372
+
373
+ [[package]]
374
+ name = "core-foundation"
375
+ version = "0.9.3"
376
+ source = "registry+https://github.com/rust-lang/crates.io-index"
377
+ checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
378
+ dependencies = [
379
+ "core-foundation-sys",
380
+ "libc",
381
+ ]
382
+
383
+ [[package]]
384
+ name = "core-foundation-sys"
385
+ version = "0.8.3"
386
+ source = "registry+https://github.com/rust-lang/crates.io-index"
387
+ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
388
+
389
+ [[package]]
390
+ name = "cpufeatures"
391
+ version = "0.2.6"
392
+ source = "registry+https://github.com/rust-lang/crates.io-index"
393
+ checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181"
394
+ dependencies = [
395
+ "libc",
396
+ ]
397
+
398
+ [[package]]
399
+ name = "crc32fast"
400
+ version = "1.3.2"
401
+ source = "registry+https://github.com/rust-lang/crates.io-index"
402
+ checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
403
+ dependencies = [
404
+ "cfg-if",
405
+ ]
406
+
407
+ [[package]]
408
+ name = "crossbeam-channel"
409
+ version = "0.5.7"
410
+ source = "registry+https://github.com/rust-lang/crates.io-index"
411
+ checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c"
412
+ dependencies = [
413
+ "cfg-if",
414
+ "crossbeam-utils",
415
+ ]
416
+
417
+ [[package]]
418
+ name = "crossbeam-deque"
419
+ version = "0.8.3"
420
+ source = "registry+https://github.com/rust-lang/crates.io-index"
421
+ checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
422
+ dependencies = [
423
+ "cfg-if",
424
+ "crossbeam-epoch",
425
+ "crossbeam-utils",
426
+ ]
427
+
428
+ [[package]]
429
+ name = "crossbeam-epoch"
430
+ version = "0.9.14"
431
+ source = "registry+https://github.com/rust-lang/crates.io-index"
432
+ checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695"
433
+ dependencies = [
434
+ "autocfg",
435
+ "cfg-if",
436
+ "crossbeam-utils",
437
+ "memoffset",
438
+ "scopeguard",
439
+ ]
440
+
441
+ [[package]]
442
+ name = "crossbeam-utils"
443
+ version = "0.8.15"
444
+ source = "registry+https://github.com/rust-lang/crates.io-index"
445
+ checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
446
+ dependencies = [
447
+ "cfg-if",
448
+ ]
449
+
450
+ [[package]]
451
+ name = "crossterm"
452
+ version = "0.26.1"
453
+ source = "registry+https://github.com/rust-lang/crates.io-index"
454
+ checksum = "a84cda67535339806297f1b331d6dd6320470d2a0fe65381e79ee9e156dd3d13"
455
+ dependencies = [
456
+ "bitflags",
457
+ "crossterm_winapi",
458
+ "libc",
459
+ "mio",
460
+ "parking_lot",
461
+ "signal-hook",
462
+ "signal-hook-mio",
463
+ "winapi",
464
+ ]
465
+
466
+ [[package]]
467
+ name = "crossterm_winapi"
468
+ version = "0.9.0"
469
+ source = "registry+https://github.com/rust-lang/crates.io-index"
470
+ checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c"
471
+ dependencies = [
472
+ "winapi",
473
+ ]
474
+
475
+ [[package]]
476
+ name = "crypto-common"
477
+ version = "0.1.6"
478
+ source = "registry+https://github.com/rust-lang/crates.io-index"
479
+ checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
480
+ dependencies = [
481
+ "generic-array",
482
+ "typenum",
483
+ ]
484
+
485
+ [[package]]
486
+ name = "darling"
487
+ version = "0.14.4"
488
+ source = "registry+https://github.com/rust-lang/crates.io-index"
489
+ checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850"
490
+ dependencies = [
491
+ "darling_core",
492
+ "darling_macro",
493
+ ]
494
+
495
+ [[package]]
496
+ name = "darling_core"
497
+ version = "0.14.4"
498
+ source = "registry+https://github.com/rust-lang/crates.io-index"
499
+ checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0"
500
+ dependencies = [
501
+ "fnv",
502
+ "ident_case",
503
+ "proc-macro2",
504
+ "quote",
505
+ "strsim",
506
+ "syn 1.0.109",
507
+ ]
508
+
509
+ [[package]]
510
+ name = "darling_macro"
511
+ version = "0.14.4"
512
+ source = "registry+https://github.com/rust-lang/crates.io-index"
513
+ checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e"
514
+ dependencies = [
515
+ "darling_core",
516
+ "quote",
517
+ "syn 1.0.109",
518
+ ]
519
+
520
+ [[package]]
521
+ name = "dashmap"
522
+ version = "5.4.0"
523
+ source = "registry+https://github.com/rust-lang/crates.io-index"
524
+ checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc"
525
+ dependencies = [
526
+ "cfg-if",
527
+ "hashbrown",
528
+ "lock_api",
529
+ "once_cell",
530
+ "parking_lot_core",
531
+ ]
532
+
533
+ [[package]]
534
+ name = "derive_builder"
535
+ version = "0.12.0"
536
+ source = "registry+https://github.com/rust-lang/crates.io-index"
537
+ checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8"
538
+ dependencies = [
539
+ "derive_builder_macro",
540
+ ]
541
+
542
+ [[package]]
543
+ name = "derive_builder_core"
544
+ version = "0.12.0"
545
+ source = "registry+https://github.com/rust-lang/crates.io-index"
546
+ checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f"
547
+ dependencies = [
548
+ "darling",
549
+ "proc-macro2",
550
+ "quote",
551
+ "syn 1.0.109",
552
+ ]
553
+
554
+ [[package]]
555
+ name = "derive_builder_macro"
556
+ version = "0.12.0"
557
+ source = "registry+https://github.com/rust-lang/crates.io-index"
558
+ checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e"
559
+ dependencies = [
560
+ "derive_builder_core",
561
+ "syn 1.0.109",
562
+ ]
563
+
564
+ [[package]]
565
+ name = "digest"
566
+ version = "0.10.6"
567
+ source = "registry+https://github.com/rust-lang/crates.io-index"
568
+ checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
569
+ dependencies = [
570
+ "block-buffer",
571
+ "crypto-common",
572
+ "subtle",
573
+ ]
574
+
575
+ [[package]]
576
+ name = "dirs"
577
+ version = "4.0.0"
578
+ source = "registry+https://github.com/rust-lang/crates.io-index"
579
+ checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
580
+ dependencies = [
581
+ "dirs-sys",
582
+ ]
583
+
584
+ [[package]]
585
+ name = "dirs-sys"
586
+ version = "0.3.7"
587
+ source = "registry+https://github.com/rust-lang/crates.io-index"
588
+ checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
589
+ dependencies = [
590
+ "libc",
591
+ "redox_users",
592
+ "winapi",
593
+ ]
594
+
595
+ [[package]]
596
+ name = "easy-cast"
597
+ version = "0.4.4"
598
+ source = "registry+https://github.com/rust-lang/crates.io-index"
599
+ checksum = "4bd102ee8c418348759919b83b81cdbdc933ffe29740b903df448b4bafaa348e"
600
+ dependencies = [
601
+ "libm",
602
+ ]
603
+
604
+ [[package]]
605
+ name = "either"
606
+ version = "1.8.1"
607
+ source = "registry+https://github.com/rust-lang/crates.io-index"
608
+ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
609
+
610
+ [[package]]
611
+ name = "encode_unicode"
612
+ version = "0.3.6"
613
+ source = "registry+https://github.com/rust-lang/crates.io-index"
614
+ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
615
+
616
+ [[package]]
617
+ name = "encoding_rs"
618
+ version = "0.8.32"
619
+ source = "registry+https://github.com/rust-lang/crates.io-index"
620
+ checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394"
621
+ dependencies = [
622
+ "cfg-if",
623
+ ]
624
+
625
+ [[package]]
626
+ name = "errno"
627
+ version = "0.3.0"
628
+ source = "registry+https://github.com/rust-lang/crates.io-index"
629
+ checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0"
630
+ dependencies = [
631
+ "errno-dragonfly",
632
+ "libc",
633
+ "windows-sys 0.45.0",
634
+ ]
635
+
636
+ [[package]]
637
+ name = "errno-dragonfly"
638
+ version = "0.1.2"
639
+ source = "registry+https://github.com/rust-lang/crates.io-index"
640
+ checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
641
+ dependencies = [
642
+ "cc",
643
+ "libc",
644
+ ]
645
+
646
+ [[package]]
647
+ name = "esaxx-rs"
648
+ version = "0.1.8"
649
+ source = "registry+https://github.com/rust-lang/crates.io-index"
650
+ checksum = "1f748b253ceca9fed5f42f8b5ceb3851e93102199bc25b64b65369f76e5c0a35"
651
+ dependencies = [
652
+ "cc",
653
+ ]
654
+
655
+ [[package]]
656
+ name = "fastrand"
657
+ version = "1.9.0"
658
+ source = "registry+https://github.com/rust-lang/crates.io-index"
659
+ checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
660
+ dependencies = [
661
+ "instant",
662
+ ]
663
+
664
+ [[package]]
665
+ name = "filetime"
666
+ version = "0.2.20"
667
+ source = "registry+https://github.com/rust-lang/crates.io-index"
668
+ checksum = "8a3de6e8d11b22ff9edc6d916f890800597d60f8b2da1caf2955c274638d6412"
669
+ dependencies = [
670
+ "cfg-if",
671
+ "libc",
672
+ "redox_syscall 0.2.16",
673
+ "windows-sys 0.45.0",
674
+ ]
675
+
676
+ [[package]]
677
+ name = "fixedbitset"
678
+ version = "0.4.2"
679
+ source = "registry+https://github.com/rust-lang/crates.io-index"
680
+ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
681
+
682
+ [[package]]
683
+ name = "flate2"
684
+ version = "1.0.25"
685
+ source = "registry+https://github.com/rust-lang/crates.io-index"
686
+ checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841"
687
+ dependencies = [
688
+ "crc32fast",
689
+ "miniz_oxide",
690
+ ]
691
+
692
+ [[package]]
693
+ name = "float-ord"
694
+ version = "0.3.2"
695
+ source = "registry+https://github.com/rust-lang/crates.io-index"
696
+ checksum = "8ce81f49ae8a0482e4c55ea62ebbd7e5a686af544c00b9d090bba3ff9be97b3d"
697
+
698
+ [[package]]
699
+ name = "fnv"
700
+ version = "1.0.7"
701
+ source = "registry+https://github.com/rust-lang/crates.io-index"
702
+ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
703
+
704
+ [[package]]
705
+ name = "foreign-types"
706
+ version = "0.3.2"
707
+ source = "registry+https://github.com/rust-lang/crates.io-index"
708
+ checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
709
+ dependencies = [
710
+ "foreign-types-shared",
711
+ ]
712
+
713
+ [[package]]
714
+ name = "foreign-types-shared"
715
+ version = "0.1.1"
716
+ source = "registry+https://github.com/rust-lang/crates.io-index"
717
+ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
718
+
719
+ [[package]]
720
+ name = "form_urlencoded"
721
+ version = "1.1.0"
722
+ source = "registry+https://github.com/rust-lang/crates.io-index"
723
+ checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
724
+ dependencies = [
725
+ "percent-encoding",
726
+ ]
727
+
728
+ [[package]]
729
+ name = "fs2"
730
+ version = "0.4.3"
731
+ source = "registry+https://github.com/rust-lang/crates.io-index"
732
+ checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
733
+ dependencies = [
734
+ "libc",
735
+ "winapi",
736
+ ]
737
+
738
+ [[package]]
739
+ name = "futures"
740
+ version = "0.3.27"
741
+ source = "registry+https://github.com/rust-lang/crates.io-index"
742
+ checksum = "531ac96c6ff5fd7c62263c5e3c67a603af4fcaee2e1a0ae5565ba3a11e69e549"
743
+ dependencies = [
744
+ "futures-channel",
745
+ "futures-core",
746
+ "futures-executor",
747
+ "futures-io",
748
+ "futures-sink",
749
+ "futures-task",
750
+ "futures-util",
751
+ ]
752
+
753
+ [[package]]
754
+ name = "futures-channel"
755
+ version = "0.3.27"
756
+ source = "registry+https://github.com/rust-lang/crates.io-index"
757
+ checksum = "164713a5a0dcc3e7b4b1ed7d3b433cabc18025386f9339346e8daf15963cf7ac"
758
+ dependencies = [
759
+ "futures-core",
760
+ "futures-sink",
761
+ ]
762
+
763
+ [[package]]
764
+ name = "futures-core"
765
+ version = "0.3.27"
766
+ source = "registry+https://github.com/rust-lang/crates.io-index"
767
+ checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd"
768
+
769
+ [[package]]
770
+ name = "futures-executor"
771
+ version = "0.3.27"
772
+ source = "registry+https://github.com/rust-lang/crates.io-index"
773
+ checksum = "1997dd9df74cdac935c76252744c1ed5794fac083242ea4fe77ef3ed60ba0f83"
774
+ dependencies = [
775
+ "futures-core",
776
+ "futures-task",
777
+ "futures-util",
778
+ ]
779
+
780
+ [[package]]
781
+ name = "futures-io"
782
+ version = "0.3.27"
783
+ source = "registry+https://github.com/rust-lang/crates.io-index"
784
+ checksum = "89d422fa3cbe3b40dca574ab087abb5bc98258ea57eea3fd6f1fa7162c778b91"
785
+
786
+ [[package]]
787
+ name = "futures-macro"
788
+ version = "0.3.27"
789
+ source = "registry+https://github.com/rust-lang/crates.io-index"
790
+ checksum = "3eb14ed937631bd8b8b8977f2c198443447a8355b6e3ca599f38c975e5a963b6"
791
+ dependencies = [
792
+ "proc-macro2",
793
+ "quote",
794
+ "syn 1.0.109",
795
+ ]
796
+
797
+ [[package]]
798
+ name = "futures-sink"
799
+ version = "0.3.27"
800
+ source = "registry+https://github.com/rust-lang/crates.io-index"
801
+ checksum = "ec93083a4aecafb2a80a885c9de1f0ccae9dbd32c2bb54b0c3a65690e0b8d2f2"
802
+
803
+ [[package]]
804
+ name = "futures-task"
805
+ version = "0.3.27"
806
+ source = "registry+https://github.com/rust-lang/crates.io-index"
807
+ checksum = "fd65540d33b37b16542a0438c12e6aeead10d4ac5d05bd3f805b8f35ab592879"
808
+
809
+ [[package]]
810
+ name = "futures-util"
811
+ version = "0.3.27"
812
+ source = "registry+https://github.com/rust-lang/crates.io-index"
813
+ checksum = "3ef6b17e481503ec85211fed8f39d1970f128935ca1f814cd32ac4a6842e84ab"
814
+ dependencies = [
815
+ "futures-channel",
816
+ "futures-core",
817
+ "futures-io",
818
+ "futures-macro",
819
+ "futures-sink",
820
+ "futures-task",
821
+ "memchr",
822
+ "pin-project-lite",
823
+ "pin-utils",
824
+ "slab",
825
+ ]
826
+
827
+ [[package]]
828
+ name = "generic-array"
829
+ version = "0.14.7"
830
+ source = "registry+https://github.com/rust-lang/crates.io-index"
831
+ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
832
+ dependencies = [
833
+ "typenum",
834
+ "version_check",
835
+ ]
836
+
837
+ [[package]]
838
+ name = "getrandom"
839
+ version = "0.2.8"
840
+ source = "registry+https://github.com/rust-lang/crates.io-index"
841
+ checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
842
+ dependencies = [
843
+ "cfg-if",
844
+ "libc",
845
+ "wasi",
846
+ ]
847
+
848
+ [[package]]
849
+ name = "glob"
850
+ version = "0.3.1"
851
+ source = "registry+https://github.com/rust-lang/crates.io-index"
852
+ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
853
+
854
+ [[package]]
855
+ name = "grpc-metadata"
856
+ version = "0.1.0"
857
+ dependencies = [
858
+ "opentelemetry",
859
+ "tonic",
860
+ "tracing",
861
+ "tracing-opentelemetry",
862
+ ]
863
+
864
+ [[package]]
865
+ name = "h2"
866
+ version = "0.3.16"
867
+ source = "registry+https://github.com/rust-lang/crates.io-index"
868
+ checksum = "5be7b54589b581f624f566bf5d8eb2bab1db736c51528720b6bd36b96b55924d"
869
+ dependencies = [
870
+ "bytes",
871
+ "fnv",
872
+ "futures-core",
873
+ "futures-sink",
874
+ "futures-util",
875
+ "http",
876
+ "indexmap",
877
+ "slab",
878
+ "tokio",
879
+ "tokio-util",
880
+ "tracing",
881
+ ]
882
+
883
+ [[package]]
884
+ name = "hashbrown"
885
+ version = "0.12.3"
886
+ source = "registry+https://github.com/rust-lang/crates.io-index"
887
+ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
888
+
889
+ [[package]]
890
+ name = "heck"
891
+ version = "0.4.1"
892
+ source = "registry+https://github.com/rust-lang/crates.io-index"
893
+ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
894
+
895
+ [[package]]
896
+ name = "hermit-abi"
897
+ version = "0.2.6"
898
+ source = "registry+https://github.com/rust-lang/crates.io-index"
899
+ checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
900
+ dependencies = [
901
+ "libc",
902
+ ]
903
+
904
+ [[package]]
905
+ name = "hermit-abi"
906
+ version = "0.3.1"
907
+ source = "registry+https://github.com/rust-lang/crates.io-index"
908
+ checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
909
+
910
+ [[package]]
911
+ name = "hmac"
912
+ version = "0.12.1"
913
+ source = "registry+https://github.com/rust-lang/crates.io-index"
914
+ checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
915
+ dependencies = [
916
+ "digest",
917
+ ]
918
+
919
+ [[package]]
920
+ name = "http"
921
+ version = "0.2.9"
922
+ source = "registry+https://github.com/rust-lang/crates.io-index"
923
+ checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
924
+ dependencies = [
925
+ "bytes",
926
+ "fnv",
927
+ "itoa",
928
+ ]
929
+
930
+ [[package]]
931
+ name = "http-body"
932
+ version = "0.4.5"
933
+ source = "registry+https://github.com/rust-lang/crates.io-index"
934
+ checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
935
+ dependencies = [
936
+ "bytes",
937
+ "http",
938
+ "pin-project-lite",
939
+ ]
940
+
941
+ [[package]]
942
+ name = "httparse"
943
+ version = "1.8.0"
944
+ source = "registry+https://github.com/rust-lang/crates.io-index"
945
+ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
946
+
947
+ [[package]]
948
+ name = "httpdate"
949
+ version = "1.0.2"
950
+ source = "registry+https://github.com/rust-lang/crates.io-index"
951
+ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
952
+
953
+ [[package]]
954
+ name = "hyper"
955
+ version = "0.14.25"
956
+ source = "registry+https://github.com/rust-lang/crates.io-index"
957
+ checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899"
958
+ dependencies = [
959
+ "bytes",
960
+ "futures-channel",
961
+ "futures-core",
962
+ "futures-util",
963
+ "h2",
964
+ "http",
965
+ "http-body",
966
+ "httparse",
967
+ "httpdate",
968
+ "itoa",
969
+ "pin-project-lite",
970
+ "socket2",
971
+ "tokio",
972
+ "tower-service",
973
+ "tracing",
974
+ "want",
975
+ ]
976
+
977
+ [[package]]
978
+ name = "hyper-timeout"
979
+ version = "0.4.1"
980
+ source = "registry+https://github.com/rust-lang/crates.io-index"
981
+ checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
982
+ dependencies = [
983
+ "hyper",
984
+ "pin-project-lite",
985
+ "tokio",
986
+ "tokio-io-timeout",
987
+ ]
988
+
989
+ [[package]]
990
+ name = "hyper-tls"
991
+ version = "0.5.0"
992
+ source = "registry+https://github.com/rust-lang/crates.io-index"
993
+ checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
994
+ dependencies = [
995
+ "bytes",
996
+ "hyper",
997
+ "native-tls",
998
+ "tokio",
999
+ "tokio-native-tls",
1000
+ ]
1001
+
1002
+ [[package]]
1003
+ name = "ident_case"
1004
+ version = "1.0.1"
1005
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1006
+ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
1007
+
1008
+ [[package]]
1009
+ name = "idna"
1010
+ version = "0.3.0"
1011
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1012
+ checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
1013
+ dependencies = [
1014
+ "unicode-bidi",
1015
+ "unicode-normalization",
1016
+ ]
1017
+
1018
+ [[package]]
1019
+ name = "indexmap"
1020
+ version = "1.9.3"
1021
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1022
+ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
1023
+ dependencies = [
1024
+ "autocfg",
1025
+ "hashbrown",
1026
+ ]
1027
+
1028
+ [[package]]
1029
+ name = "indicatif"
1030
+ version = "0.15.0"
1031
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1032
+ checksum = "7baab56125e25686df467fe470785512329883aab42696d661247aca2a2896e4"
1033
+ dependencies = [
1034
+ "console",
1035
+ "lazy_static",
1036
+ "number_prefix 0.3.0",
1037
+ "regex",
1038
+ ]
1039
+
1040
+ [[package]]
1041
+ name = "indicatif"
1042
+ version = "0.16.2"
1043
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1044
+ checksum = "2d207dc617c7a380ab07ff572a6e52fa202a2a8f355860ac9c38e23f8196be1b"
1045
+ dependencies = [
1046
+ "console",
1047
+ "lazy_static",
1048
+ "number_prefix 0.4.0",
1049
+ "regex",
1050
+ ]
1051
+
1052
+ [[package]]
1053
+ name = "instant"
1054
+ version = "0.1.12"
1055
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1056
+ checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
1057
+ dependencies = [
1058
+ "cfg-if",
1059
+ ]
1060
+
1061
+ [[package]]
1062
+ name = "io-lifetimes"
1063
+ version = "1.0.9"
1064
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1065
+ checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb"
1066
+ dependencies = [
1067
+ "hermit-abi 0.3.1",
1068
+ "libc",
1069
+ "windows-sys 0.45.0",
1070
+ ]
1071
+
1072
+ [[package]]
1073
+ name = "ipnet"
1074
+ version = "2.7.2"
1075
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1076
+ checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f"
1077
+
1078
+ [[package]]
1079
+ name = "is-terminal"
1080
+ version = "0.4.6"
1081
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1082
+ checksum = "256017f749ab3117e93acb91063009e1f1bb56d03965b14c2c8df4eb02c524d8"
1083
+ dependencies = [
1084
+ "hermit-abi 0.3.1",
1085
+ "io-lifetimes",
1086
+ "rustix",
1087
+ "windows-sys 0.45.0",
1088
+ ]
1089
+
1090
+ [[package]]
1091
+ name = "itertools"
1092
+ version = "0.8.2"
1093
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1094
+ checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
1095
+ dependencies = [
1096
+ "either",
1097
+ ]
1098
+
1099
+ [[package]]
1100
+ name = "itertools"
1101
+ version = "0.9.0"
1102
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1103
+ checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
1104
+ dependencies = [
1105
+ "either",
1106
+ ]
1107
+
1108
+ [[package]]
1109
+ name = "itertools"
1110
+ version = "0.10.5"
1111
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1112
+ checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
1113
+ dependencies = [
1114
+ "either",
1115
+ ]
1116
+
1117
+ [[package]]
1118
+ name = "itoa"
1119
+ version = "1.0.6"
1120
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1121
+ checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
1122
+
1123
+ [[package]]
1124
+ name = "jobserver"
1125
+ version = "0.1.26"
1126
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1127
+ checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2"
1128
+ dependencies = [
1129
+ "libc",
1130
+ ]
1131
+
1132
+ [[package]]
1133
+ name = "js-sys"
1134
+ version = "0.3.61"
1135
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1136
+ checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730"
1137
+ dependencies = [
1138
+ "wasm-bindgen",
1139
+ ]
1140
+
1141
+ [[package]]
1142
+ name = "lazy_static"
1143
+ version = "1.4.0"
1144
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1145
+ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
1146
+
1147
+ [[package]]
1148
+ name = "libc"
1149
+ version = "0.2.140"
1150
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1151
+ checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
1152
+
1153
+ [[package]]
1154
+ name = "libm"
1155
+ version = "0.2.6"
1156
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1157
+ checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb"
1158
+
1159
+ [[package]]
1160
+ name = "linux-raw-sys"
1161
+ version = "0.3.0"
1162
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1163
+ checksum = "cd550e73688e6d578f0ac2119e32b797a327631a42f9433e59d02e139c8df60d"
1164
+
1165
+ [[package]]
1166
+ name = "lock_api"
1167
+ version = "0.4.9"
1168
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1169
+ checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
1170
+ dependencies = [
1171
+ "autocfg",
1172
+ "scopeguard",
1173
+ ]
1174
+
1175
+ [[package]]
1176
+ name = "log"
1177
+ version = "0.4.17"
1178
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1179
+ checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
1180
+ dependencies = [
1181
+ "cfg-if",
1182
+ ]
1183
+
1184
+ [[package]]
1185
+ name = "macro_rules_attribute"
1186
+ version = "0.1.3"
1187
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1188
+ checksum = "cf0c9b980bf4f3a37fd7b1c066941dd1b1d0152ce6ee6e8fe8c49b9f6810d862"
1189
+ dependencies = [
1190
+ "macro_rules_attribute-proc_macro",
1191
+ "paste",
1192
+ ]
1193
+
1194
+ [[package]]
1195
+ name = "macro_rules_attribute-proc_macro"
1196
+ version = "0.1.3"
1197
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1198
+ checksum = "58093314a45e00c77d5c508f76e77c3396afbbc0d01506e7fae47b018bac2b1d"
1199
+
1200
+ [[package]]
1201
+ name = "matchers"
1202
+ version = "0.1.0"
1203
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1204
+ checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
1205
+ dependencies = [
1206
+ "regex-automata",
1207
+ ]
1208
+
1209
+ [[package]]
1210
+ name = "matchit"
1211
+ version = "0.7.0"
1212
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1213
+ checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40"
1214
+
1215
+ [[package]]
1216
+ name = "memchr"
1217
+ version = "2.5.0"
1218
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1219
+ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
1220
+
1221
+ [[package]]
1222
+ name = "memoffset"
1223
+ version = "0.8.0"
1224
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1225
+ checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
1226
+ dependencies = [
1227
+ "autocfg",
1228
+ ]
1229
+
1230
+ [[package]]
1231
+ name = "mime"
1232
+ version = "0.3.17"
1233
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1234
+ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
1235
+
1236
+ [[package]]
1237
+ name = "minimal-lexical"
1238
+ version = "0.2.1"
1239
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1240
+ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
1241
+
1242
+ [[package]]
1243
+ name = "miniz_oxide"
1244
+ version = "0.6.2"
1245
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1246
+ checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
1247
+ dependencies = [
1248
+ "adler",
1249
+ ]
1250
+
1251
+ [[package]]
1252
+ name = "mio"
1253
+ version = "0.8.6"
1254
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1255
+ checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
1256
+ dependencies = [
1257
+ "libc",
1258
+ "log",
1259
+ "wasi",
1260
+ "windows-sys 0.45.0",
1261
+ ]
1262
+
1263
+ [[package]]
1264
+ name = "monostate"
1265
+ version = "0.1.6"
1266
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1267
+ checksum = "0230b703f1ac35df1e24f6d0d2255472bcccaf657ecdfa4f1fcbcad1ad5bb98a"
1268
+ dependencies = [
1269
+ "monostate-impl",
1270
+ "serde",
1271
+ ]
1272
+
1273
+ [[package]]
1274
+ name = "monostate-impl"
1275
+ version = "0.1.6"
1276
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1277
+ checksum = "8795add3e14028f11f8e848bd3294898a8294767b3776b6f733560d33bd2530b"
1278
+ dependencies = [
1279
+ "proc-macro2",
1280
+ "quote",
1281
+ "syn 2.0.11",
1282
+ ]
1283
+
1284
+ [[package]]
1285
+ name = "multimap"
1286
+ version = "0.8.3"
1287
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1288
+ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
1289
+
1290
+ [[package]]
1291
+ name = "native-tls"
1292
+ version = "0.2.11"
1293
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1294
+ checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
1295
+ dependencies = [
1296
+ "lazy_static",
1297
+ "libc",
1298
+ "log",
1299
+ "openssl",
1300
+ "openssl-probe",
1301
+ "openssl-sys",
1302
+ "schannel",
1303
+ "security-framework",
1304
+ "security-framework-sys",
1305
+ "tempfile",
1306
+ ]
1307
+
1308
+ [[package]]
1309
+ name = "nom"
1310
+ version = "7.1.3"
1311
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1312
+ checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
1313
+ dependencies = [
1314
+ "memchr",
1315
+ "minimal-lexical",
1316
+ ]
1317
+
1318
+ [[package]]
1319
+ name = "nu-ansi-term"
1320
+ version = "0.46.0"
1321
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1322
+ checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
1323
+ dependencies = [
1324
+ "overload",
1325
+ "winapi",
1326
+ ]
1327
+
1328
+ [[package]]
1329
+ name = "num-traits"
1330
+ version = "0.2.15"
1331
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1332
+ checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
1333
+ dependencies = [
1334
+ "autocfg",
1335
+ "libm",
1336
+ ]
1337
+
1338
+ [[package]]
1339
+ name = "num_cpus"
1340
+ version = "1.15.0"
1341
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1342
+ checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
1343
+ dependencies = [
1344
+ "hermit-abi 0.2.6",
1345
+ "libc",
1346
+ ]
1347
+
1348
+ [[package]]
1349
+ name = "number_prefix"
1350
+ version = "0.3.0"
1351
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1352
+ checksum = "17b02fc0ff9a9e4b35b3342880f48e896ebf69f2967921fe8646bf5b7125956a"
1353
+
1354
+ [[package]]
1355
+ name = "number_prefix"
1356
+ version = "0.4.0"
1357
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1358
+ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
1359
+
1360
+ [[package]]
1361
+ name = "once_cell"
1362
+ version = "1.17.1"
1363
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1364
+ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
1365
+
1366
+ [[package]]
1367
+ name = "onig"
1368
+ version = "6.4.0"
1369
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1370
+ checksum = "8c4b31c8722ad9171c6d77d3557db078cab2bd50afcc9d09c8b315c59df8ca4f"
1371
+ dependencies = [
1372
+ "bitflags",
1373
+ "libc",
1374
+ "once_cell",
1375
+ "onig_sys",
1376
+ ]
1377
+
1378
+ [[package]]
1379
+ name = "onig_sys"
1380
+ version = "69.8.1"
1381
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1382
+ checksum = "7b829e3d7e9cc74c7e315ee8edb185bf4190da5acde74afd7fc59c35b1f086e7"
1383
+ dependencies = [
1384
+ "cc",
1385
+ "pkg-config",
1386
+ ]
1387
+
1388
+ [[package]]
1389
+ name = "opaque-debug"
1390
+ version = "0.3.0"
1391
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1392
+ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
1393
+
1394
+ [[package]]
1395
+ name = "openssl"
1396
+ version = "0.10.48"
1397
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1398
+ checksum = "518915b97df115dd36109bfa429a48b8f737bd05508cf9588977b599648926d2"
1399
+ dependencies = [
1400
+ "bitflags",
1401
+ "cfg-if",
1402
+ "foreign-types",
1403
+ "libc",
1404
+ "once_cell",
1405
+ "openssl-macros",
1406
+ "openssl-sys",
1407
+ ]
1408
+
1409
+ [[package]]
1410
+ name = "openssl-macros"
1411
+ version = "0.1.0"
1412
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1413
+ checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
1414
+ dependencies = [
1415
+ "proc-macro2",
1416
+ "quote",
1417
+ "syn 1.0.109",
1418
+ ]
1419
+
1420
+ [[package]]
1421
+ name = "openssl-probe"
1422
+ version = "0.1.5"
1423
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1424
+ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
1425
+
1426
+ [[package]]
1427
+ name = "openssl-sys"
1428
+ version = "0.9.83"
1429
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1430
+ checksum = "666416d899cf077260dac8698d60a60b435a46d57e82acb1be3d0dad87284e5b"
1431
+ dependencies = [
1432
+ "autocfg",
1433
+ "cc",
1434
+ "libc",
1435
+ "pkg-config",
1436
+ "vcpkg",
1437
+ ]
1438
+
1439
+ [[package]]
1440
+ name = "opentelemetry"
1441
+ version = "0.18.0"
1442
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1443
+ checksum = "69d6c3d7288a106c0a363e4b0e8d308058d56902adefb16f4936f417ffef086e"
1444
+ dependencies = [
1445
+ "opentelemetry_api",
1446
+ "opentelemetry_sdk",
1447
+ ]
1448
+
1449
+ [[package]]
1450
+ name = "opentelemetry_api"
1451
+ version = "0.18.0"
1452
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1453
+ checksum = "c24f96e21e7acc813c7a8394ee94978929db2bcc46cf6b5014fc612bf7760c22"
1454
+ dependencies = [
1455
+ "fnv",
1456
+ "futures-channel",
1457
+ "futures-util",
1458
+ "indexmap",
1459
+ "js-sys",
1460
+ "once_cell",
1461
+ "pin-project-lite",
1462
+ "thiserror",
1463
+ ]
1464
+
1465
+ [[package]]
1466
+ name = "opentelemetry_sdk"
1467
+ version = "0.18.0"
1468
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1469
+ checksum = "1ca41c4933371b61c2a2f214bf16931499af4ec90543604ec828f7a625c09113"
1470
+ dependencies = [
1471
+ "async-trait",
1472
+ "crossbeam-channel",
1473
+ "dashmap",
1474
+ "fnv",
1475
+ "futures-channel",
1476
+ "futures-executor",
1477
+ "futures-util",
1478
+ "once_cell",
1479
+ "opentelemetry_api",
1480
+ "percent-encoding",
1481
+ "rand",
1482
+ "thiserror",
1483
+ ]
1484
+
1485
+ [[package]]
1486
+ name = "overload"
1487
+ version = "0.1.1"
1488
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1489
+ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
1490
+
1491
+ [[package]]
1492
+ name = "parking_lot"
1493
+ version = "0.12.1"
1494
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1495
+ checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
1496
+ dependencies = [
1497
+ "lock_api",
1498
+ "parking_lot_core",
1499
+ ]
1500
+
1501
+ [[package]]
1502
+ name = "parking_lot_core"
1503
+ version = "0.9.7"
1504
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1505
+ checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
1506
+ dependencies = [
1507
+ "cfg-if",
1508
+ "libc",
1509
+ "redox_syscall 0.2.16",
1510
+ "smallvec",
1511
+ "windows-sys 0.45.0",
1512
+ ]
1513
+
1514
+ [[package]]
1515
+ name = "password-hash"
1516
+ version = "0.4.2"
1517
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1518
+ checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700"
1519
+ dependencies = [
1520
+ "base64ct",
1521
+ "rand_core",
1522
+ "subtle",
1523
+ ]
1524
+
1525
+ [[package]]
1526
+ name = "paste"
1527
+ version = "1.0.12"
1528
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1529
+ checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79"
1530
+
1531
+ [[package]]
1532
+ name = "pbkdf2"
1533
+ version = "0.11.0"
1534
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1535
+ checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917"
1536
+ dependencies = [
1537
+ "digest",
1538
+ "hmac",
1539
+ "password-hash",
1540
+ "sha2",
1541
+ ]
1542
+
1543
+ [[package]]
1544
+ name = "percent-encoding"
1545
+ version = "2.2.0"
1546
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1547
+ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
1548
+
1549
+ [[package]]
1550
+ name = "petgraph"
1551
+ version = "0.6.3"
1552
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1553
+ checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4"
1554
+ dependencies = [
1555
+ "fixedbitset",
1556
+ "indexmap",
1557
+ ]
1558
+
1559
+ [[package]]
1560
+ name = "pin-project"
1561
+ version = "1.0.12"
1562
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1563
+ checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc"
1564
+ dependencies = [
1565
+ "pin-project-internal",
1566
+ ]
1567
+
1568
+ [[package]]
1569
+ name = "pin-project-internal"
1570
+ version = "1.0.12"
1571
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1572
+ checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"
1573
+ dependencies = [
1574
+ "proc-macro2",
1575
+ "quote",
1576
+ "syn 1.0.109",
1577
+ ]
1578
+
1579
+ [[package]]
1580
+ name = "pin-project-lite"
1581
+ version = "0.2.9"
1582
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1583
+ checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
1584
+
1585
+ [[package]]
1586
+ name = "pin-utils"
1587
+ version = "0.1.0"
1588
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1589
+ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
1590
+
1591
+ [[package]]
1592
+ name = "pkg-config"
1593
+ version = "0.3.26"
1594
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1595
+ checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
1596
+
1597
+ [[package]]
1598
+ name = "ppv-lite86"
1599
+ version = "0.2.17"
1600
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1601
+ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
1602
+
1603
+ [[package]]
1604
+ name = "prettyplease"
1605
+ version = "0.1.25"
1606
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1607
+ checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86"
1608
+ dependencies = [
1609
+ "proc-macro2",
1610
+ "syn 1.0.109",
1611
+ ]
1612
+
1613
+ [[package]]
1614
+ name = "proc-macro2"
1615
+ version = "1.0.54"
1616
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1617
+ checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534"
1618
+ dependencies = [
1619
+ "unicode-ident",
1620
+ ]
1621
+
1622
+ [[package]]
1623
+ name = "prost"
1624
+ version = "0.11.8"
1625
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1626
+ checksum = "e48e50df39172a3e7eb17e14642445da64996989bc212b583015435d39a58537"
1627
+ dependencies = [
1628
+ "bytes",
1629
+ "prost-derive",
1630
+ ]
1631
+
1632
+ [[package]]
1633
+ name = "prost-build"
1634
+ version = "0.11.8"
1635
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1636
+ checksum = "2c828f93f5ca4826f97fedcbd3f9a536c16b12cff3dbbb4a007f932bbad95b12"
1637
+ dependencies = [
1638
+ "bytes",
1639
+ "heck",
1640
+ "itertools 0.10.5",
1641
+ "lazy_static",
1642
+ "log",
1643
+ "multimap",
1644
+ "petgraph",
1645
+ "prettyplease",
1646
+ "prost",
1647
+ "prost-types",
1648
+ "regex",
1649
+ "syn 1.0.109",
1650
+ "tempfile",
1651
+ "which",
1652
+ ]
1653
+
1654
+ [[package]]
1655
+ name = "prost-derive"
1656
+ version = "0.11.8"
1657
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1658
+ checksum = "4ea9b0f8cbe5e15a8a042d030bd96668db28ecb567ec37d691971ff5731d2b1b"
1659
+ dependencies = [
1660
+ "anyhow",
1661
+ "itertools 0.10.5",
1662
+ "proc-macro2",
1663
+ "quote",
1664
+ "syn 1.0.109",
1665
+ ]
1666
+
1667
+ [[package]]
1668
+ name = "prost-types"
1669
+ version = "0.11.8"
1670
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1671
+ checksum = "379119666929a1afd7a043aa6cf96fa67a6dce9af60c88095a4686dbce4c9c88"
1672
+ dependencies = [
1673
+ "prost",
1674
+ ]
1675
+
1676
+ [[package]]
1677
+ name = "quote"
1678
+ version = "1.0.26"
1679
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1680
+ checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
1681
+ dependencies = [
1682
+ "proc-macro2",
1683
+ ]
1684
+
1685
+ [[package]]
1686
+ name = "rand"
1687
+ version = "0.8.5"
1688
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1689
+ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
1690
+ dependencies = [
1691
+ "libc",
1692
+ "rand_chacha",
1693
+ "rand_core",
1694
+ ]
1695
+
1696
+ [[package]]
1697
+ name = "rand_chacha"
1698
+ version = "0.3.1"
1699
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1700
+ checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
1701
+ dependencies = [
1702
+ "ppv-lite86",
1703
+ "rand_core",
1704
+ ]
1705
+
1706
+ [[package]]
1707
+ name = "rand_core"
1708
+ version = "0.6.4"
1709
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1710
+ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
1711
+ dependencies = [
1712
+ "getrandom",
1713
+ ]
1714
+
1715
+ [[package]]
1716
+ name = "ratatui"
1717
+ version = "0.20.1"
1718
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1719
+ checksum = "dcc0d032bccba900ee32151ec0265667535c230169f5a011154cdcd984e16829"
1720
+ dependencies = [
1721
+ "bitflags",
1722
+ "cassowary",
1723
+ "crossterm",
1724
+ "unicode-segmentation",
1725
+ "unicode-width",
1726
+ ]
1727
+
1728
+ [[package]]
1729
+ name = "rayon"
1730
+ version = "1.7.0"
1731
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1732
+ checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b"
1733
+ dependencies = [
1734
+ "either",
1735
+ "rayon-core",
1736
+ ]
1737
+
1738
+ [[package]]
1739
+ name = "rayon-cond"
1740
+ version = "0.1.0"
1741
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1742
+ checksum = "fd1259362c9065e5ea39a789ef40b1e3fd934c94beb7b5ab3ac6629d3b5e7cb7"
1743
+ dependencies = [
1744
+ "either",
1745
+ "itertools 0.8.2",
1746
+ "rayon",
1747
+ ]
1748
+
1749
+ [[package]]
1750
+ name = "rayon-core"
1751
+ version = "1.11.0"
1752
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1753
+ checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d"
1754
+ dependencies = [
1755
+ "crossbeam-channel",
1756
+ "crossbeam-deque",
1757
+ "crossbeam-utils",
1758
+ "num_cpus",
1759
+ ]
1760
+
1761
+ [[package]]
1762
+ name = "redox_syscall"
1763
+ version = "0.2.16"
1764
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1765
+ checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
1766
+ dependencies = [
1767
+ "bitflags",
1768
+ ]
1769
+
1770
+ [[package]]
1771
+ name = "redox_syscall"
1772
+ version = "0.3.5"
1773
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1774
+ checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
1775
+ dependencies = [
1776
+ "bitflags",
1777
+ ]
1778
+
1779
+ [[package]]
1780
+ name = "redox_users"
1781
+ version = "0.4.3"
1782
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1783
+ checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
1784
+ dependencies = [
1785
+ "getrandom",
1786
+ "redox_syscall 0.2.16",
1787
+ "thiserror",
1788
+ ]
1789
+
1790
+ [[package]]
1791
+ name = "regex"
1792
+ version = "1.7.3"
1793
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1794
+ checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d"
1795
+ dependencies = [
1796
+ "aho-corasick",
1797
+ "memchr",
1798
+ "regex-syntax",
1799
+ ]
1800
+
1801
+ [[package]]
1802
+ name = "regex-automata"
1803
+ version = "0.1.10"
1804
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1805
+ checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
1806
+ dependencies = [
1807
+ "regex-syntax",
1808
+ ]
1809
+
1810
+ [[package]]
1811
+ name = "regex-syntax"
1812
+ version = "0.6.29"
1813
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1814
+ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
1815
+
1816
+ [[package]]
1817
+ name = "reqwest"
1818
+ version = "0.11.16"
1819
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1820
+ checksum = "27b71749df584b7f4cac2c426c127a7c785a5106cc98f7a8feb044115f0fa254"
1821
+ dependencies = [
1822
+ "base64 0.21.0",
1823
+ "bytes",
1824
+ "encoding_rs",
1825
+ "futures-core",
1826
+ "futures-util",
1827
+ "h2",
1828
+ "http",
1829
+ "http-body",
1830
+ "hyper",
1831
+ "hyper-tls",
1832
+ "ipnet",
1833
+ "js-sys",
1834
+ "log",
1835
+ "mime",
1836
+ "native-tls",
1837
+ "once_cell",
1838
+ "percent-encoding",
1839
+ "pin-project-lite",
1840
+ "serde",
1841
+ "serde_json",
1842
+ "serde_urlencoded",
1843
+ "tokio",
1844
+ "tokio-native-tls",
1845
+ "tower-service",
1846
+ "url",
1847
+ "wasm-bindgen",
1848
+ "wasm-bindgen-futures",
1849
+ "web-sys",
1850
+ "winreg",
1851
+ ]
1852
+
1853
+ [[package]]
1854
+ name = "rustix"
1855
+ version = "0.37.5"
1856
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1857
+ checksum = "0e78cc525325c06b4a7ff02db283472f3c042b7ff0c391f96c6d5ac6f4f91b75"
1858
+ dependencies = [
1859
+ "bitflags",
1860
+ "errno",
1861
+ "io-lifetimes",
1862
+ "libc",
1863
+ "linux-raw-sys",
1864
+ "windows-sys 0.45.0",
1865
+ ]
1866
+
1867
+ [[package]]
1868
+ name = "rustversion"
1869
+ version = "1.0.12"
1870
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1871
+ checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06"
1872
+
1873
+ [[package]]
1874
+ name = "ryu"
1875
+ version = "1.0.13"
1876
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1877
+ checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
1878
+
1879
+ [[package]]
1880
+ name = "schannel"
1881
+ version = "0.1.21"
1882
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1883
+ checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3"
1884
+ dependencies = [
1885
+ "windows-sys 0.42.0",
1886
+ ]
1887
+
1888
+ [[package]]
1889
+ name = "scopeguard"
1890
+ version = "1.1.0"
1891
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1892
+ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
1893
+
1894
+ [[package]]
1895
+ name = "security-framework"
1896
+ version = "2.8.2"
1897
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1898
+ checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254"
1899
+ dependencies = [
1900
+ "bitflags",
1901
+ "core-foundation",
1902
+ "core-foundation-sys",
1903
+ "libc",
1904
+ "security-framework-sys",
1905
+ ]
1906
+
1907
+ [[package]]
1908
+ name = "security-framework-sys"
1909
+ version = "2.8.0"
1910
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1911
+ checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4"
1912
+ dependencies = [
1913
+ "core-foundation-sys",
1914
+ "libc",
1915
+ ]
1916
+
1917
+ [[package]]
1918
+ name = "serde"
1919
+ version = "1.0.159"
1920
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1921
+ checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065"
1922
+ dependencies = [
1923
+ "serde_derive",
1924
+ ]
1925
+
1926
+ [[package]]
1927
+ name = "serde_derive"
1928
+ version = "1.0.159"
1929
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1930
+ checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585"
1931
+ dependencies = [
1932
+ "proc-macro2",
1933
+ "quote",
1934
+ "syn 2.0.11",
1935
+ ]
1936
+
1937
+ [[package]]
1938
+ name = "serde_json"
1939
+ version = "1.0.95"
1940
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1941
+ checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744"
1942
+ dependencies = [
1943
+ "itoa",
1944
+ "ryu",
1945
+ "serde",
1946
+ ]
1947
+
1948
+ [[package]]
1949
+ name = "serde_urlencoded"
1950
+ version = "0.7.1"
1951
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1952
+ checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
1953
+ dependencies = [
1954
+ "form_urlencoded",
1955
+ "itoa",
1956
+ "ryu",
1957
+ "serde",
1958
+ ]
1959
+
1960
+ [[package]]
1961
+ name = "sha1"
1962
+ version = "0.10.5"
1963
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1964
+ checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
1965
+ dependencies = [
1966
+ "cfg-if",
1967
+ "cpufeatures",
1968
+ "digest",
1969
+ ]
1970
+
1971
+ [[package]]
1972
+ name = "sha2"
1973
+ version = "0.10.6"
1974
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1975
+ checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
1976
+ dependencies = [
1977
+ "cfg-if",
1978
+ "cpufeatures",
1979
+ "digest",
1980
+ ]
1981
+
1982
+ [[package]]
1983
+ name = "sharded-slab"
1984
+ version = "0.1.4"
1985
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1986
+ checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"
1987
+ dependencies = [
1988
+ "lazy_static",
1989
+ ]
1990
+
1991
+ [[package]]
1992
+ name = "signal-hook"
1993
+ version = "0.3.15"
1994
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1995
+ checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9"
1996
+ dependencies = [
1997
+ "libc",
1998
+ "signal-hook-registry",
1999
+ ]
2000
+
2001
+ [[package]]
2002
+ name = "signal-hook-mio"
2003
+ version = "0.2.3"
2004
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2005
+ checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
2006
+ dependencies = [
2007
+ "libc",
2008
+ "mio",
2009
+ "signal-hook",
2010
+ ]
2011
+
2012
+ [[package]]
2013
+ name = "signal-hook-registry"
2014
+ version = "1.4.1"
2015
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2016
+ checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
2017
+ dependencies = [
2018
+ "libc",
2019
+ ]
2020
+
2021
+ [[package]]
2022
+ name = "slab"
2023
+ version = "0.4.8"
2024
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2025
+ checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d"
2026
+ dependencies = [
2027
+ "autocfg",
2028
+ ]
2029
+
2030
+ [[package]]
2031
+ name = "smallvec"
2032
+ version = "1.10.0"
2033
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2034
+ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
2035
+
2036
+ [[package]]
2037
+ name = "socket2"
2038
+ version = "0.4.9"
2039
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2040
+ checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
2041
+ dependencies = [
2042
+ "libc",
2043
+ "winapi",
2044
+ ]
2045
+
2046
+ [[package]]
2047
+ name = "spm_precompiled"
2048
+ version = "0.1.4"
2049
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2050
+ checksum = "5851699c4033c63636f7ea4cf7b7c1f1bf06d0cc03cfb42e711de5a5c46cf326"
2051
+ dependencies = [
2052
+ "base64 0.13.1",
2053
+ "nom",
2054
+ "serde",
2055
+ "unicode-segmentation",
2056
+ ]
2057
+
2058
+ [[package]]
2059
+ name = "strsim"
2060
+ version = "0.10.0"
2061
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2062
+ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
2063
+
2064
+ [[package]]
2065
+ name = "subtle"
2066
+ version = "2.4.1"
2067
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2068
+ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
2069
+
2070
+ [[package]]
2071
+ name = "syn"
2072
+ version = "1.0.109"
2073
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2074
+ checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
2075
+ dependencies = [
2076
+ "proc-macro2",
2077
+ "quote",
2078
+ "unicode-ident",
2079
+ ]
2080
+
2081
+ [[package]]
2082
+ name = "syn"
2083
+ version = "2.0.11"
2084
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2085
+ checksum = "21e3787bb71465627110e7d87ed4faaa36c1f61042ee67badb9e2ef173accc40"
2086
+ dependencies = [
2087
+ "proc-macro2",
2088
+ "quote",
2089
+ "unicode-ident",
2090
+ ]
2091
+
2092
+ [[package]]
2093
+ name = "sync_wrapper"
2094
+ version = "0.1.2"
2095
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2096
+ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
2097
+
2098
+ [[package]]
2099
+ name = "tar"
2100
+ version = "0.4.38"
2101
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2102
+ checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6"
2103
+ dependencies = [
2104
+ "filetime",
2105
+ "libc",
2106
+ "xattr",
2107
+ ]
2108
+
2109
+ [[package]]
2110
+ name = "tempfile"
2111
+ version = "3.5.0"
2112
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2113
+ checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998"
2114
+ dependencies = [
2115
+ "cfg-if",
2116
+ "fastrand",
2117
+ "redox_syscall 0.3.5",
2118
+ "rustix",
2119
+ "windows-sys 0.45.0",
2120
+ ]
2121
+
2122
+ [[package]]
2123
+ name = "text-generation-benchmark"
2124
+ version = "0.1.0"
2125
+ dependencies = [
2126
+ "average",
2127
+ "clap",
2128
+ "crossterm",
2129
+ "float-ord",
2130
+ "ratatui",
2131
+ "serde",
2132
+ "serde_json",
2133
+ "text-generation-client",
2134
+ "thiserror",
2135
+ "tokenizers",
2136
+ "tokio",
2137
+ "tracing",
2138
+ "tracing-subscriber",
2139
+ ]
2140
+
2141
+ [[package]]
2142
+ name = "text-generation-client"
2143
+ version = "0.6.0"
2144
+ dependencies = [
2145
+ "futures",
2146
+ "grpc-metadata",
2147
+ "prost",
2148
+ "prost-build",
2149
+ "thiserror",
2150
+ "tokio",
2151
+ "tonic",
2152
+ "tonic-build",
2153
+ "tower",
2154
+ "tracing",
2155
+ "tracing-error",
2156
+ ]
2157
+
2158
+ [[package]]
2159
+ name = "thiserror"
2160
+ version = "1.0.40"
2161
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2162
+ checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
2163
+ dependencies = [
2164
+ "thiserror-impl",
2165
+ ]
2166
+
2167
+ [[package]]
2168
+ name = "thiserror-impl"
2169
+ version = "1.0.40"
2170
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2171
+ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
2172
+ dependencies = [
2173
+ "proc-macro2",
2174
+ "quote",
2175
+ "syn 2.0.11",
2176
+ ]
2177
+
2178
+ [[package]]
2179
+ name = "thread_local"
2180
+ version = "1.1.7"
2181
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2182
+ checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
2183
+ dependencies = [
2184
+ "cfg-if",
2185
+ "once_cell",
2186
+ ]
2187
+
2188
+ [[package]]
2189
+ name = "time"
2190
+ version = "0.3.20"
2191
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2192
+ checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890"
2193
+ dependencies = [
2194
+ "serde",
2195
+ "time-core",
2196
+ ]
2197
+
2198
+ [[package]]
2199
+ name = "time-core"
2200
+ version = "0.1.0"
2201
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2202
+ checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
2203
+
2204
+ [[package]]
2205
+ name = "tinyvec"
2206
+ version = "1.6.0"
2207
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2208
+ checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
2209
+ dependencies = [
2210
+ "tinyvec_macros",
2211
+ ]
2212
+
2213
+ [[package]]
2214
+ name = "tinyvec_macros"
2215
+ version = "0.1.1"
2216
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2217
+ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
2218
+
2219
+ [[package]]
2220
+ name = "tokenizers"
2221
+ version = "0.13.3"
2222
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2223
+ checksum = "5cf49017523bf0bc01c9966f172c5f120bbb7b96cccd1708772dd42e767fb9f5"
2224
+ dependencies = [
2225
+ "aho-corasick",
2226
+ "cached-path",
2227
+ "clap",
2228
+ "derive_builder",
2229
+ "dirs",
2230
+ "esaxx-rs",
2231
+ "getrandom",
2232
+ "indicatif 0.15.0",
2233
+ "itertools 0.9.0",
2234
+ "lazy_static",
2235
+ "log",
2236
+ "macro_rules_attribute",
2237
+ "monostate",
2238
+ "onig",
2239
+ "paste",
2240
+ "rand",
2241
+ "rayon",
2242
+ "rayon-cond",
2243
+ "regex",
2244
+ "regex-syntax",
2245
+ "reqwest",
2246
+ "serde",
2247
+ "serde_json",
2248
+ "spm_precompiled",
2249
+ "thiserror",
2250
+ "unicode-normalization-alignments",
2251
+ "unicode-segmentation",
2252
+ "unicode_categories",
2253
+ ]
2254
+
2255
+ [[package]]
2256
+ name = "tokio"
2257
+ version = "1.27.0"
2258
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2259
+ checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001"
2260
+ dependencies = [
2261
+ "autocfg",
2262
+ "bytes",
2263
+ "libc",
2264
+ "mio",
2265
+ "num_cpus",
2266
+ "parking_lot",
2267
+ "pin-project-lite",
2268
+ "signal-hook-registry",
2269
+ "socket2",
2270
+ "tokio-macros",
2271
+ "windows-sys 0.45.0",
2272
+ ]
2273
+
2274
+ [[package]]
2275
+ name = "tokio-io-timeout"
2276
+ version = "1.2.0"
2277
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2278
+ checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf"
2279
+ dependencies = [
2280
+ "pin-project-lite",
2281
+ "tokio",
2282
+ ]
2283
+
2284
+ [[package]]
2285
+ name = "tokio-macros"
2286
+ version = "2.0.0"
2287
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2288
+ checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce"
2289
+ dependencies = [
2290
+ "proc-macro2",
2291
+ "quote",
2292
+ "syn 2.0.11",
2293
+ ]
2294
+
2295
+ [[package]]
2296
+ name = "tokio-native-tls"
2297
+ version = "0.3.1"
2298
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2299
+ checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
2300
+ dependencies = [
2301
+ "native-tls",
2302
+ "tokio",
2303
+ ]
2304
+
2305
+ [[package]]
2306
+ name = "tokio-stream"
2307
+ version = "0.1.12"
2308
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2309
+ checksum = "8fb52b74f05dbf495a8fba459fdc331812b96aa086d9eb78101fa0d4569c3313"
2310
+ dependencies = [
2311
+ "futures-core",
2312
+ "pin-project-lite",
2313
+ "tokio",
2314
+ ]
2315
+
2316
+ [[package]]
2317
+ name = "tokio-util"
2318
+ version = "0.7.7"
2319
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2320
+ checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2"
2321
+ dependencies = [
2322
+ "bytes",
2323
+ "futures-core",
2324
+ "futures-sink",
2325
+ "pin-project-lite",
2326
+ "tokio",
2327
+ "tracing",
2328
+ ]
2329
+
2330
+ [[package]]
2331
+ name = "tonic"
2332
+ version = "0.8.3"
2333
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2334
+ checksum = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb"
2335
+ dependencies = [
2336
+ "async-stream",
2337
+ "async-trait",
2338
+ "axum",
2339
+ "base64 0.13.1",
2340
+ "bytes",
2341
+ "futures-core",
2342
+ "futures-util",
2343
+ "h2",
2344
+ "http",
2345
+ "http-body",
2346
+ "hyper",
2347
+ "hyper-timeout",
2348
+ "percent-encoding",
2349
+ "pin-project",
2350
+ "prost",
2351
+ "prost-derive",
2352
+ "tokio",
2353
+ "tokio-stream",
2354
+ "tokio-util",
2355
+ "tower",
2356
+ "tower-layer",
2357
+ "tower-service",
2358
+ "tracing",
2359
+ "tracing-futures",
2360
+ ]
2361
+
2362
+ [[package]]
2363
+ name = "tonic-build"
2364
+ version = "0.8.4"
2365
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2366
+ checksum = "5bf5e9b9c0f7e0a7c027dcfaba7b2c60816c7049171f679d99ee2ff65d0de8c4"
2367
+ dependencies = [
2368
+ "prettyplease",
2369
+ "proc-macro2",
2370
+ "prost-build",
2371
+ "quote",
2372
+ "syn 1.0.109",
2373
+ ]
2374
+
2375
+ [[package]]
2376
+ name = "tower"
2377
+ version = "0.4.13"
2378
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2379
+ checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
2380
+ dependencies = [
2381
+ "futures-core",
2382
+ "futures-util",
2383
+ "indexmap",
2384
+ "pin-project",
2385
+ "pin-project-lite",
2386
+ "rand",
2387
+ "slab",
2388
+ "tokio",
2389
+ "tokio-util",
2390
+ "tower-layer",
2391
+ "tower-service",
2392
+ "tracing",
2393
+ ]
2394
+
2395
+ [[package]]
2396
+ name = "tower-layer"
2397
+ version = "0.3.2"
2398
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2399
+ checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
2400
+
2401
+ [[package]]
2402
+ name = "tower-service"
2403
+ version = "0.3.2"
2404
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2405
+ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
2406
+
2407
+ [[package]]
2408
+ name = "tracing"
2409
+ version = "0.1.37"
2410
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2411
+ checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
2412
+ dependencies = [
2413
+ "cfg-if",
2414
+ "log",
2415
+ "pin-project-lite",
2416
+ "tracing-attributes",
2417
+ "tracing-core",
2418
+ ]
2419
+
2420
+ [[package]]
2421
+ name = "tracing-attributes"
2422
+ version = "0.1.23"
2423
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2424
+ checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
2425
+ dependencies = [
2426
+ "proc-macro2",
2427
+ "quote",
2428
+ "syn 1.0.109",
2429
+ ]
2430
+
2431
+ [[package]]
2432
+ name = "tracing-core"
2433
+ version = "0.1.30"
2434
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2435
+ checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
2436
+ dependencies = [
2437
+ "once_cell",
2438
+ "valuable",
2439
+ ]
2440
+
2441
+ [[package]]
2442
+ name = "tracing-error"
2443
+ version = "0.2.0"
2444
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2445
+ checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e"
2446
+ dependencies = [
2447
+ "tracing",
2448
+ "tracing-subscriber",
2449
+ ]
2450
+
2451
+ [[package]]
2452
+ name = "tracing-futures"
2453
+ version = "0.2.5"
2454
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2455
+ checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
2456
+ dependencies = [
2457
+ "pin-project",
2458
+ "tracing",
2459
+ ]
2460
+
2461
+ [[package]]
2462
+ name = "tracing-log"
2463
+ version = "0.1.3"
2464
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2465
+ checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
2466
+ dependencies = [
2467
+ "lazy_static",
2468
+ "log",
2469
+ "tracing-core",
2470
+ ]
2471
+
2472
+ [[package]]
2473
+ name = "tracing-opentelemetry"
2474
+ version = "0.18.0"
2475
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2476
+ checksum = "21ebb87a95ea13271332df069020513ab70bdb5637ca42d6e492dc3bbbad48de"
2477
+ dependencies = [
2478
+ "once_cell",
2479
+ "opentelemetry",
2480
+ "tracing",
2481
+ "tracing-core",
2482
+ "tracing-log",
2483
+ "tracing-subscriber",
2484
+ ]
2485
+
2486
+ [[package]]
2487
+ name = "tracing-serde"
2488
+ version = "0.1.3"
2489
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2490
+ checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1"
2491
+ dependencies = [
2492
+ "serde",
2493
+ "tracing-core",
2494
+ ]
2495
+
2496
+ [[package]]
2497
+ name = "tracing-subscriber"
2498
+ version = "0.3.16"
2499
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2500
+ checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70"
2501
+ dependencies = [
2502
+ "matchers",
2503
+ "nu-ansi-term",
2504
+ "once_cell",
2505
+ "regex",
2506
+ "serde",
2507
+ "serde_json",
2508
+ "sharded-slab",
2509
+ "smallvec",
2510
+ "thread_local",
2511
+ "tracing",
2512
+ "tracing-core",
2513
+ "tracing-log",
2514
+ "tracing-serde",
2515
+ ]
2516
+
2517
+ [[package]]
2518
+ name = "try-lock"
2519
+ version = "0.2.4"
2520
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2521
+ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
2522
+
2523
+ [[package]]
2524
+ name = "typenum"
2525
+ version = "1.16.0"
2526
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2527
+ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
2528
+
2529
+ [[package]]
2530
+ name = "unicode-bidi"
2531
+ version = "0.3.13"
2532
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2533
+ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
2534
+
2535
+ [[package]]
2536
+ name = "unicode-ident"
2537
+ version = "1.0.8"
2538
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2539
+ checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
2540
+
2541
+ [[package]]
2542
+ name = "unicode-normalization"
2543
+ version = "0.1.22"
2544
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2545
+ checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
2546
+ dependencies = [
2547
+ "tinyvec",
2548
+ ]
2549
+
2550
+ [[package]]
2551
+ name = "unicode-normalization-alignments"
2552
+ version = "0.1.12"
2553
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2554
+ checksum = "43f613e4fa046e69818dd287fdc4bc78175ff20331479dab6e1b0f98d57062de"
2555
+ dependencies = [
2556
+ "smallvec",
2557
+ ]
2558
+
2559
+ [[package]]
2560
+ name = "unicode-segmentation"
2561
+ version = "1.10.1"
2562
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2563
+ checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
2564
+
2565
+ [[package]]
2566
+ name = "unicode-width"
2567
+ version = "0.1.10"
2568
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2569
+ checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
2570
+
2571
+ [[package]]
2572
+ name = "unicode_categories"
2573
+ version = "0.1.1"
2574
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2575
+ checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
2576
+
2577
+ [[package]]
2578
+ name = "url"
2579
+ version = "2.3.1"
2580
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2581
+ checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
2582
+ dependencies = [
2583
+ "form_urlencoded",
2584
+ "idna",
2585
+ "percent-encoding",
2586
+ ]
2587
+
2588
+ [[package]]
2589
+ name = "utf8parse"
2590
+ version = "0.2.1"
2591
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2592
+ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
2593
+
2594
+ [[package]]
2595
+ name = "valuable"
2596
+ version = "0.1.0"
2597
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2598
+ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
2599
+
2600
+ [[package]]
2601
+ name = "vcpkg"
2602
+ version = "0.2.15"
2603
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2604
+ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
2605
+
2606
+ [[package]]
2607
+ name = "version_check"
2608
+ version = "0.9.4"
2609
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2610
+ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
2611
+
2612
+ [[package]]
2613
+ name = "want"
2614
+ version = "0.3.0"
2615
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2616
+ checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
2617
+ dependencies = [
2618
+ "log",
2619
+ "try-lock",
2620
+ ]
2621
+
2622
+ [[package]]
2623
+ name = "wasi"
2624
+ version = "0.11.0+wasi-snapshot-preview1"
2625
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2626
+ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
2627
+
2628
+ [[package]]
2629
+ name = "wasm-bindgen"
2630
+ version = "0.2.84"
2631
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2632
+ checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b"
2633
+ dependencies = [
2634
+ "cfg-if",
2635
+ "wasm-bindgen-macro",
2636
+ ]
2637
+
2638
+ [[package]]
2639
+ name = "wasm-bindgen-backend"
2640
+ version = "0.2.84"
2641
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2642
+ checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9"
2643
+ dependencies = [
2644
+ "bumpalo",
2645
+ "log",
2646
+ "once_cell",
2647
+ "proc-macro2",
2648
+ "quote",
2649
+ "syn 1.0.109",
2650
+ "wasm-bindgen-shared",
2651
+ ]
2652
+
2653
+ [[package]]
2654
+ name = "wasm-bindgen-futures"
2655
+ version = "0.4.34"
2656
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2657
+ checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454"
2658
+ dependencies = [
2659
+ "cfg-if",
2660
+ "js-sys",
2661
+ "wasm-bindgen",
2662
+ "web-sys",
2663
+ ]
2664
+
2665
+ [[package]]
2666
+ name = "wasm-bindgen-macro"
2667
+ version = "0.2.84"
2668
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2669
+ checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5"
2670
+ dependencies = [
2671
+ "quote",
2672
+ "wasm-bindgen-macro-support",
2673
+ ]
2674
+
2675
+ [[package]]
2676
+ name = "wasm-bindgen-macro-support"
2677
+ version = "0.2.84"
2678
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2679
+ checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
2680
+ dependencies = [
2681
+ "proc-macro2",
2682
+ "quote",
2683
+ "syn 1.0.109",
2684
+ "wasm-bindgen-backend",
2685
+ "wasm-bindgen-shared",
2686
+ ]
2687
+
2688
+ [[package]]
2689
+ name = "wasm-bindgen-shared"
2690
+ version = "0.2.84"
2691
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2692
+ checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
2693
+
2694
+ [[package]]
2695
+ name = "web-sys"
2696
+ version = "0.3.61"
2697
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2698
+ checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97"
2699
+ dependencies = [
2700
+ "js-sys",
2701
+ "wasm-bindgen",
2702
+ ]
2703
+
2704
+ [[package]]
2705
+ name = "which"
2706
+ version = "4.4.0"
2707
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2708
+ checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269"
2709
+ dependencies = [
2710
+ "either",
2711
+ "libc",
2712
+ "once_cell",
2713
+ ]
2714
+
2715
+ [[package]]
2716
+ name = "winapi"
2717
+ version = "0.3.9"
2718
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2719
+ checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
2720
+ dependencies = [
2721
+ "winapi-i686-pc-windows-gnu",
2722
+ "winapi-x86_64-pc-windows-gnu",
2723
+ ]
2724
+
2725
+ [[package]]
2726
+ name = "winapi-i686-pc-windows-gnu"
2727
+ version = "0.4.0"
2728
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2729
+ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
2730
+
2731
+ [[package]]
2732
+ name = "winapi-x86_64-pc-windows-gnu"
2733
+ version = "0.4.0"
2734
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2735
+ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
2736
+
2737
+ [[package]]
2738
+ name = "windows-sys"
2739
+ version = "0.42.0"
2740
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2741
+ checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
2742
+ dependencies = [
2743
+ "windows_aarch64_gnullvm",
2744
+ "windows_aarch64_msvc",
2745
+ "windows_i686_gnu",
2746
+ "windows_i686_msvc",
2747
+ "windows_x86_64_gnu",
2748
+ "windows_x86_64_gnullvm",
2749
+ "windows_x86_64_msvc",
2750
+ ]
2751
+
2752
+ [[package]]
2753
+ name = "windows-sys"
2754
+ version = "0.45.0"
2755
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2756
+ checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
2757
+ dependencies = [
2758
+ "windows-targets",
2759
+ ]
2760
+
2761
+ [[package]]
2762
+ name = "windows-targets"
2763
+ version = "0.42.2"
2764
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2765
+ checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
2766
+ dependencies = [
2767
+ "windows_aarch64_gnullvm",
2768
+ "windows_aarch64_msvc",
2769
+ "windows_i686_gnu",
2770
+ "windows_i686_msvc",
2771
+ "windows_x86_64_gnu",
2772
+ "windows_x86_64_gnullvm",
2773
+ "windows_x86_64_msvc",
2774
+ ]
2775
+
2776
+ [[package]]
2777
+ name = "windows_aarch64_gnullvm"
2778
+ version = "0.42.2"
2779
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2780
+ checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
2781
+
2782
+ [[package]]
2783
+ name = "windows_aarch64_msvc"
2784
+ version = "0.42.2"
2785
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2786
+ checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
2787
+
2788
+ [[package]]
2789
+ name = "windows_i686_gnu"
2790
+ version = "0.42.2"
2791
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2792
+ checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
2793
+
2794
+ [[package]]
2795
+ name = "windows_i686_msvc"
2796
+ version = "0.42.2"
2797
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2798
+ checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
2799
+
2800
+ [[package]]
2801
+ name = "windows_x86_64_gnu"
2802
+ version = "0.42.2"
2803
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2804
+ checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
2805
+
2806
+ [[package]]
2807
+ name = "windows_x86_64_gnullvm"
2808
+ version = "0.42.2"
2809
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2810
+ checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
2811
+
2812
+ [[package]]
2813
+ name = "windows_x86_64_msvc"
2814
+ version = "0.42.2"
2815
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2816
+ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
2817
+
2818
+ [[package]]
2819
+ name = "winreg"
2820
+ version = "0.10.1"
2821
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2822
+ checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
2823
+ dependencies = [
2824
+ "winapi",
2825
+ ]
2826
+
2827
+ [[package]]
2828
+ name = "xattr"
2829
+ version = "0.2.3"
2830
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2831
+ checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc"
2832
+ dependencies = [
2833
+ "libc",
2834
+ ]
2835
+
2836
+ [[package]]
2837
+ name = "zip"
2838
+ version = "0.6.4"
2839
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2840
+ checksum = "0445d0fbc924bb93539b4316c11afb121ea39296f99a3c4c9edad09e3658cdef"
2841
+ dependencies = [
2842
+ "aes",
2843
+ "byteorder",
2844
+ "bzip2",
2845
+ "constant_time_eq",
2846
+ "crc32fast",
2847
+ "crossbeam-utils",
2848
+ "flate2",
2849
+ "hmac",
2850
+ "pbkdf2",
2851
+ "sha1",
2852
+ "time",
2853
+ "zstd",
2854
+ ]
2855
+
2856
+ [[package]]
2857
+ name = "zstd"
2858
+ version = "0.11.2+zstd.1.5.2"
2859
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2860
+ checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4"
2861
+ dependencies = [
2862
+ "zstd-safe",
2863
+ ]
2864
+
2865
+ [[package]]
2866
+ name = "zstd-safe"
2867
+ version = "5.0.2+zstd.1.5.2"
2868
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2869
+ checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db"
2870
+ dependencies = [
2871
+ "libc",
2872
+ "zstd-sys",
2873
+ ]
2874
+
2875
+ [[package]]
2876
+ name = "zstd-sys"
2877
+ version = "2.0.8+zstd.1.5.5"
2878
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2879
+ checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c"
2880
+ dependencies = [
2881
+ "cc",
2882
+ "libc",
2883
+ "pkg-config",
2884
+ ]
benchmark/Cargo.toml ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ name = "text-generation-benchmark"
3
+ version = "0.1.0"
4
+ edition = "2021"
5
+ authors = ["Olivier Dehaene"]
6
+ description = "Text Generation Benchmarking tool"
7
+
8
+ [profile.release]
9
+ debug = 1
10
+ incremental = true
11
+ lto = "off"
12
+ panic = "abort"
13
+
14
+ [lib]
15
+ path = "src/lib.rs"
16
+
17
+ [[bin]]
18
+ name = "text-generation-benchmark"
19
+ path = "src/main.rs"
20
+
21
+ [dependencies]
22
+ average = "0.13"
23
+ clap = { version = "4.1.4", features = ["derive", "env"] }
24
+ crossterm = "0.26"
25
+ float-ord = "0.3.2"
26
+ serde = {version = "1.0.142", features = ["derive"]}
27
+ serde_json = "1.0"
28
+ text-generation-client = { path = "../router/client" }
29
+ thiserror = "1.0.38"
30
+ tokenizers = "0.13.3"
31
+ tokio = { version = "1.25.0", features = ["rt", "rt-multi-thread", "parking_lot", "signal", "sync"] }
32
+ tui = {package = "ratatui", version = "0.20", default-features = false, features = ["crossterm"]}
33
+ tracing = "0.1.37"
34
+ tracing-subscriber = { version = "0.3.16", features = ["json", "env-filter"] }
35
+
benchmark/rust-toolchain.toml ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ [toolchain]
2
+ channel = "1.67.0"
3
+ components = ["rustfmt", "clippy"]
benchmark/src/app.rs ADDED
@@ -0,0 +1,688 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /// Inspired by https://github.com/hatoo/oha/blob/bb989ea3cd77727e7743e7daa60a19894bb5e901/src/monitor.rs
2
+ use crate::generation::{Decode, Message, Prefill};
3
+ use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
4
+ use text_generation_client::ClientError;
5
+ use tokio::sync::mpsc;
6
+ use tui::backend::Backend;
7
+ use tui::layout::{Alignment, Constraint, Direction, Layout};
8
+ use tui::style::{Color, Modifier, Style};
9
+ use tui::text::{Span, Spans};
10
+ use tui::widgets::{
11
+ Axis, BarChart, Block, Borders, Chart, Dataset, Gauge, GraphType, Paragraph, Tabs,
12
+ };
13
+ use tui::{symbols, Frame};
14
+
15
+ /// TUI powered App
16
+ pub(crate) struct App {
17
+ pub(crate) running: bool,
18
+ completed_runs: Vec<usize>,
19
+ completed_batch: usize,
20
+ current_batch: usize,
21
+ current_tab: usize,
22
+ touched_tab: bool,
23
+ zoom: bool,
24
+ is_error: bool,
25
+ data: Data,
26
+ tokenizer_name: String,
27
+ sequence_length: u32,
28
+ decode_length: u32,
29
+ n_run: usize,
30
+ batch_size: Vec<u32>,
31
+ receiver: mpsc::Receiver<Result<Message, ClientError>>,
32
+ }
33
+
34
+ impl App {
35
+ pub(crate) fn new(
36
+ receiver: mpsc::Receiver<Result<Message, ClientError>>,
37
+ tokenizer_name: String,
38
+ sequence_length: u32,
39
+ decode_length: u32,
40
+ n_run: usize,
41
+ batch_size: Vec<u32>,
42
+ ) -> Self {
43
+ let data = Data::new(n_run, batch_size.len());
44
+ let current_tab = 0;
45
+
46
+ let completed_runs: Vec<usize> = (0..batch_size.len()).map(|_| 0).collect();
47
+ let completed_batch = 0;
48
+ let current_batch = 0;
49
+ let is_error = false;
50
+
51
+ Self {
52
+ running: true,
53
+ completed_runs,
54
+ completed_batch,
55
+ current_batch,
56
+ current_tab,
57
+ touched_tab: false,
58
+ zoom: false,
59
+ is_error,
60
+ data,
61
+ tokenizer_name,
62
+ sequence_length,
63
+ decode_length,
64
+ n_run,
65
+ batch_size,
66
+ receiver,
67
+ }
68
+ }
69
+
70
+ /// Handle crossterm key events
71
+ pub(crate) fn handle_key_event(&mut self, key_event: KeyEvent) {
72
+ match key_event {
73
+ // Increase and wrap tab
74
+ KeyEvent {
75
+ code: KeyCode::Right,
76
+ ..
77
+ }
78
+ | KeyEvent {
79
+ code: KeyCode::Tab, ..
80
+ } => {
81
+ self.touched_tab = true;
82
+ self.current_tab = (self.current_tab + 1) % self.batch_size.len();
83
+ }
84
+ // Decrease and wrap tab
85
+ KeyEvent {
86
+ code: KeyCode::Left,
87
+ ..
88
+ } => {
89
+ self.touched_tab = true;
90
+ if self.current_tab > 0 {
91
+ self.current_tab -= 1;
92
+ } else {
93
+ self.current_tab = self.batch_size.len() - 1;
94
+ }
95
+ }
96
+ // Zoom on throughput/latency fig
97
+ KeyEvent {
98
+ code: KeyCode::Char('+'),
99
+ ..
100
+ } => {
101
+ self.zoom = true;
102
+ }
103
+ // Unzoom on throughput/latency fig
104
+ KeyEvent {
105
+ code: KeyCode::Char('-'),
106
+ ..
107
+ } => {
108
+ self.zoom = false;
109
+ }
110
+ // Quit
111
+ KeyEvent {
112
+ code: KeyCode::Char('q'),
113
+ ..
114
+ }
115
+ | KeyEvent {
116
+ code: KeyCode::Char('c'),
117
+ modifiers: KeyModifiers::CONTROL,
118
+ ..
119
+ } => {
120
+ self.running = false;
121
+ }
122
+ _ => (),
123
+ }
124
+ }
125
+
126
+ /// Get all pending messages from generation task
127
+ pub(crate) fn tick(&mut self) {
128
+ while let Ok(message) = self.receiver.try_recv() {
129
+ match message {
130
+ Ok(message) => match message {
131
+ Message::Prefill(step) => self.data.push_prefill(step, self.current_batch),
132
+ Message::Decode(step) => self.data.push_decode(step, self.current_batch),
133
+ Message::EndRun => {
134
+ self.completed_runs[self.current_batch] += 1;
135
+ }
136
+ Message::EndBatch => {
137
+ self.data.end_batch(self.current_batch);
138
+ self.completed_batch += 1;
139
+
140
+ if self.current_batch < self.batch_size.len() - 1 {
141
+ // Only go to next tab if the user never touched the tab keys
142
+ if !self.touched_tab {
143
+ self.current_tab += 1;
144
+ }
145
+
146
+ self.current_batch += 1;
147
+ }
148
+ }
149
+ Message::Warmup => {}
150
+ },
151
+ Err(_) => self.is_error = true,
152
+ }
153
+ }
154
+ }
155
+
156
+ /// Render frame
157
+ pub fn render<B: Backend>(&mut self, f: &mut Frame<'_, B>) {
158
+ let batch_progress =
159
+ (self.completed_batch as f64 / self.batch_size.len() as f64).clamp(0.0, 1.0);
160
+ let run_progress =
161
+ (self.completed_runs[self.current_batch] as f64 / self.n_run as f64).clamp(0.0, 1.0);
162
+
163
+ // Vertical layout
164
+ let row5 = Layout::default()
165
+ .direction(Direction::Vertical)
166
+ .constraints(
167
+ [
168
+ Constraint::Length(1),
169
+ Constraint::Length(3),
170
+ Constraint::Length(3),
171
+ Constraint::Length(13),
172
+ Constraint::Min(10),
173
+ ]
174
+ .as_ref(),
175
+ )
176
+ .split(f.size());
177
+
178
+ // Top row horizontal layout
179
+ let top = Layout::default()
180
+ .direction(Direction::Horizontal)
181
+ .constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
182
+ .split(row5[2]);
183
+
184
+ // Mid row horizontal layout
185
+ let mid = Layout::default()
186
+ .direction(Direction::Horizontal)
187
+ .constraints(
188
+ [
189
+ Constraint::Percentage(25),
190
+ Constraint::Percentage(25),
191
+ Constraint::Percentage(25),
192
+ Constraint::Percentage(25),
193
+ ]
194
+ .as_ref(),
195
+ )
196
+ .split(row5[3]);
197
+
198
+ // Left mid row vertical layout
199
+ let prefill_text = Layout::default()
200
+ .direction(Direction::Vertical)
201
+ .constraints([Constraint::Length(8), Constraint::Length(5)].as_ref())
202
+ .split(mid[0]);
203
+
204
+ // Right mid row vertical layout
205
+ let decode_text = Layout::default()
206
+ .direction(Direction::Vertical)
207
+ .constraints([Constraint::Length(8), Constraint::Length(5)].as_ref())
208
+ .split(mid[2]);
209
+ let decode_text_latency = Layout::default()
210
+ .direction(Direction::Horizontal)
211
+ .constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
212
+ .split(decode_text[0]);
213
+
214
+ // Bottom row horizontal layout
215
+ let bottom = Layout::default()
216
+ .direction(Direction::Horizontal)
217
+ .constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
218
+ .split(row5[4]);
219
+
220
+ // Title
221
+ let title = Block::default()
222
+ .borders(Borders::NONE)
223
+ .title(format!(
224
+ "Model: {} | Sequence Length: {} | Decode Length: {}",
225
+ self.tokenizer_name, self.sequence_length, self.decode_length
226
+ ))
227
+ .style(
228
+ Style::default()
229
+ .add_modifier(Modifier::BOLD)
230
+ .fg(Color::White),
231
+ );
232
+ f.render_widget(title, row5[0]);
233
+
234
+ // Helper
235
+ let helper = Block::default()
236
+ .borders(Borders::NONE)
237
+ .title("<- | tab | ->: change batch tab | q / CTRL + c: quit | +/-: zoom")
238
+ .title_alignment(Alignment::Right)
239
+ .style(Style::default().fg(Color::White));
240
+ f.render_widget(helper, row5[0]);
241
+
242
+ // Batch tabs
243
+ let titles = self
244
+ .batch_size
245
+ .iter()
246
+ .map(|b| {
247
+ Spans::from(vec![Span::styled(
248
+ format!("Batch: {b}"),
249
+ Style::default().fg(Color::White),
250
+ )])
251
+ })
252
+ .collect();
253
+ let tabs = Tabs::new(titles)
254
+ .block(Block::default().borders(Borders::ALL).title("Tabs"))
255
+ .select(self.current_tab)
256
+ .style(Style::default().fg(Color::LightCyan))
257
+ .highlight_style(
258
+ Style::default()
259
+ .add_modifier(Modifier::BOLD)
260
+ .bg(Color::Black),
261
+ );
262
+ f.render_widget(tabs, row5[1]);
263
+
264
+ // Total progress bar
265
+ let color = if self.is_error {
266
+ Color::Red
267
+ } else {
268
+ Color::LightGreen
269
+ };
270
+ let batch_gauge = progress_gauge(
271
+ "Total Progress",
272
+ format!("{} / {}", self.completed_batch, self.batch_size.len()),
273
+ batch_progress,
274
+ color,
275
+ );
276
+ f.render_widget(batch_gauge, top[0]);
277
+
278
+ // Batch progress Bar
279
+ let color = if self.is_error {
280
+ Color::Red
281
+ } else {
282
+ Color::LightBlue
283
+ };
284
+ let run_gauge = progress_gauge(
285
+ "Batch Progress",
286
+ format!(
287
+ "{} / {}",
288
+ self.completed_runs[self.current_batch], self.n_run
289
+ ),
290
+ run_progress,
291
+ color,
292
+ );
293
+ f.render_widget(run_gauge, top[1]);
294
+
295
+ // Prefill text infos
296
+ let prefill_latency_block = latency_paragraph(
297
+ &mut self.data.prefill_latencies[self.current_tab],
298
+ "Prefill",
299
+ );
300
+ let prefill_throughput_block =
301
+ throughput_paragraph(&self.data.prefill_throughputs[self.current_tab], "Prefill");
302
+
303
+ f.render_widget(prefill_latency_block, prefill_text[0]);
304
+ f.render_widget(prefill_throughput_block, prefill_text[1]);
305
+
306
+ // Prefill latency histogram
307
+ let histo_width = 7;
308
+ let bins = if mid[1].width < 2 {
309
+ 0
310
+ } else {
311
+ (mid[1].width as usize - 2) / (histo_width + 1)
312
+ }
313
+ .max(2);
314
+
315
+ let histo_data =
316
+ latency_histogram_data(&self.data.prefill_latencies[self.current_tab], bins);
317
+ let histo_data_str: Vec<(&str, u64)> =
318
+ histo_data.iter().map(|(l, v)| (l.as_str(), *v)).collect();
319
+ let prefill_histogram =
320
+ latency_histogram(&histo_data_str, "Prefill").bar_width(histo_width as u16);
321
+ f.render_widget(prefill_histogram, mid[1]);
322
+
323
+ // Decode text info
324
+ let decode_latency_block = latency_paragraph(
325
+ &mut self.data.decode_latencies[self.current_tab],
326
+ "Decode Total",
327
+ );
328
+ let decode_token_latency_block = latency_paragraph(
329
+ &mut self.data.decode_token_latencies[self.current_tab],
330
+ "Decode Token",
331
+ );
332
+ let decode_throughput_block =
333
+ throughput_paragraph(&self.data.decode_throughputs[self.current_tab], "Decode");
334
+ f.render_widget(decode_latency_block, decode_text_latency[0]);
335
+ f.render_widget(decode_token_latency_block, decode_text_latency[1]);
336
+ f.render_widget(decode_throughput_block, decode_text[1]);
337
+
338
+ // Decode latency histogram
339
+ let histo_data =
340
+ latency_histogram_data(&self.data.decode_latencies[self.current_tab], bins);
341
+ let histo_data_str: Vec<(&str, u64)> =
342
+ histo_data.iter().map(|(l, v)| (l.as_str(), *v)).collect();
343
+ let decode_histogram =
344
+ latency_histogram(&histo_data_str, "Decode").bar_width(histo_width as u16);
345
+ f.render_widget(decode_histogram, mid[3]);
346
+
347
+ // Prefill latency/throughput chart
348
+ let prefill_latency_throughput_chart = latency_throughput_chart(
349
+ &self.data.prefill_batch_latency_throughput,
350
+ &self.batch_size,
351
+ self.zoom,
352
+ "Prefill",
353
+ );
354
+ f.render_widget(prefill_latency_throughput_chart, bottom[0]);
355
+
356
+ // Decode latency/throughput chart
357
+ let decode_latency_throughput_chart = latency_throughput_chart(
358
+ &self.data.decode_batch_latency_throughput,
359
+ &self.batch_size,
360
+ self.zoom,
361
+ "Decode",
362
+ );
363
+ f.render_widget(decode_latency_throughput_chart, bottom[1]);
364
+ }
365
+ }
366
+
367
+ /// App internal data struct
368
+ struct Data {
369
+ prefill_latencies: Vec<Vec<f64>>,
370
+ prefill_throughputs: Vec<Vec<f64>>,
371
+ decode_latencies: Vec<Vec<f64>>,
372
+ decode_token_latencies: Vec<Vec<f64>>,
373
+ decode_throughputs: Vec<Vec<f64>>,
374
+ prefill_batch_latency_throughput: Vec<(f64, f64)>,
375
+ decode_batch_latency_throughput: Vec<(f64, f64)>,
376
+ }
377
+
378
+ impl Data {
379
+ fn new(n_run: usize, n_batch: usize) -> Self {
380
+ let prefill_latencies: Vec<Vec<f64>> =
381
+ (0..n_batch).map(|_| Vec::with_capacity(n_run)).collect();
382
+ let prefill_throughputs: Vec<Vec<f64>> = prefill_latencies.clone();
383
+
384
+ let decode_latencies: Vec<Vec<f64>> = prefill_latencies.clone();
385
+ let decode_token_latencies: Vec<Vec<f64>> = decode_latencies.clone();
386
+ let decode_throughputs: Vec<Vec<f64>> = prefill_throughputs.clone();
387
+
388
+ let prefill_batch_latency_throughput: Vec<(f64, f64)> = Vec::with_capacity(n_batch);
389
+ let decode_batch_latency_throughput: Vec<(f64, f64)> =
390
+ prefill_batch_latency_throughput.clone();
391
+
392
+ Self {
393
+ prefill_latencies,
394
+ prefill_throughputs,
395
+ decode_latencies,
396
+ decode_token_latencies,
397
+ decode_throughputs,
398
+ prefill_batch_latency_throughput,
399
+ decode_batch_latency_throughput,
400
+ }
401
+ }
402
+
403
+ fn push_prefill(&mut self, prefill: Prefill, batch_idx: usize) {
404
+ let latency = prefill.latency.as_millis() as f64;
405
+ self.prefill_latencies[batch_idx].push(latency);
406
+ self.prefill_throughputs[batch_idx].push(prefill.throughput);
407
+ }
408
+
409
+ fn push_decode(&mut self, decode: Decode, batch_idx: usize) {
410
+ let latency = decode.latency.as_millis() as f64;
411
+ let token_latency = decode.token_latency.as_millis() as f64;
412
+ self.decode_latencies[batch_idx].push(latency);
413
+ self.decode_token_latencies[batch_idx].push(token_latency);
414
+ self.decode_throughputs[batch_idx].push(decode.throughput);
415
+ }
416
+
417
+ fn end_batch(&mut self, batch_idx: usize) {
418
+ self.prefill_batch_latency_throughput.push((
419
+ self.prefill_latencies[batch_idx].iter().sum::<f64>()
420
+ / self.prefill_latencies[batch_idx].len() as f64,
421
+ self.prefill_throughputs[batch_idx].iter().sum::<f64>()
422
+ / self.prefill_throughputs[batch_idx].len() as f64,
423
+ ));
424
+ self.decode_batch_latency_throughput.push((
425
+ self.decode_latencies[batch_idx].iter().sum::<f64>()
426
+ / self.decode_latencies[batch_idx].len() as f64,
427
+ self.decode_throughputs[batch_idx].iter().sum::<f64>()
428
+ / self.decode_throughputs[batch_idx].len() as f64,
429
+ ));
430
+ }
431
+ }
432
+
433
+ /// Progress bar
434
+ fn progress_gauge(title: &str, label: String, progress: f64, color: Color) -> Gauge {
435
+ Gauge::default()
436
+ .block(Block::default().title(title).borders(Borders::ALL))
437
+ .gauge_style(Style::default().fg(color))
438
+ .label(Span::raw(label))
439
+ .ratio(progress)
440
+ }
441
+
442
+ /// Throughput paragraph
443
+ fn throughput_paragraph<'a>(throughput: &Vec<f64>, name: &'static str) -> Paragraph<'a> {
444
+ // Throughput average/high/low texts
445
+ let throughput_texts = statis_spans(throughput, "tokens/secs");
446
+
447
+ // Throughput block
448
+ Paragraph::new(throughput_texts).block(
449
+ Block::default()
450
+ .title(Span::raw(format!("{name} Throughput")))
451
+ .borders(Borders::ALL),
452
+ )
453
+ }
454
+
455
+ /// Latency paragraph
456
+ fn latency_paragraph<'a>(latency: &mut Vec<f64>, name: &'static str) -> Paragraph<'a> {
457
+ // Latency average/high/low texts
458
+ let mut latency_texts = statis_spans(latency, "ms");
459
+
460
+ // Sort latency for percentiles
461
+ float_ord::sort(latency);
462
+ let latency_percentiles = crate::utils::percentiles(latency, &[50, 90, 99]);
463
+
464
+ // Latency p50/p90/p99 texts
465
+ let colors = vec![Color::LightGreen, Color::LightYellow, Color::LightRed];
466
+ for (i, (name, value)) in latency_percentiles.iter().enumerate() {
467
+ let span = Spans::from(vec![Span::styled(
468
+ format!("{name}: {value:.2} ms"),
469
+ Style::default().fg(colors[i]),
470
+ )]);
471
+ latency_texts.push(span);
472
+ }
473
+
474
+ Paragraph::new(latency_texts).block(
475
+ Block::default()
476
+ .title(Span::raw(format!("{name} Latency")))
477
+ .borders(Borders::ALL),
478
+ )
479
+ }
480
+
481
+ /// Average/High/Low spans
482
+ fn statis_spans<'a>(data: &Vec<f64>, unit: &'static str) -> Vec<Spans<'a>> {
483
+ vec![
484
+ Spans::from(vec![Span::styled(
485
+ format!(
486
+ "Average: {:.2} {unit}",
487
+ data.iter().sum::<f64>() / data.len() as f64
488
+ ),
489
+ Style::default().fg(Color::LightBlue),
490
+ )]),
491
+ Spans::from(vec![Span::styled(
492
+ format!(
493
+ "Lowest: {:.2} {unit}",
494
+ data.iter()
495
+ .min_by(|a, b| a.total_cmp(b))
496
+ .unwrap_or(&std::f64::NAN)
497
+ ),
498
+ Style::default().fg(Color::Reset),
499
+ )]),
500
+ Spans::from(vec![Span::styled(
501
+ format!(
502
+ "Highest: {:.2} {unit}",
503
+ data.iter()
504
+ .max_by(|a, b| a.total_cmp(b))
505
+ .unwrap_or(&std::f64::NAN)
506
+ ),
507
+ Style::default().fg(Color::Reset),
508
+ )]),
509
+ ]
510
+ }
511
+
512
+ /// Latency histogram data
513
+ fn latency_histogram_data(latency: &[f64], bins: usize) -> Vec<(String, u64)> {
514
+ let histo_data: Vec<(String, u64)> = {
515
+ let histo = crate::utils::histogram(latency, bins);
516
+ histo
517
+ .into_iter()
518
+ .map(|(label, v)| (format!("{label:.2}"), v as u64))
519
+ .collect()
520
+ };
521
+
522
+ histo_data
523
+ }
524
+
525
+ /// Latency Histogram
526
+ fn latency_histogram<'a>(
527
+ histo_data_str: &'a Vec<(&'a str, u64)>,
528
+ name: &'static str,
529
+ ) -> BarChart<'a> {
530
+ BarChart::default()
531
+ .block(
532
+ Block::default()
533
+ .title(format!("{name} latency histogram"))
534
+ .style(Style::default().fg(Color::LightYellow).bg(Color::Reset))
535
+ .borders(Borders::ALL),
536
+ )
537
+ .data(histo_data_str.as_slice())
538
+ }
539
+
540
+ /// Latency/Throughput chart
541
+ fn latency_throughput_chart<'a>(
542
+ latency_throughput: &'a Vec<(f64, f64)>,
543
+ batch_sizes: &'a [u32],
544
+ zoom: bool,
545
+ name: &'static str,
546
+ ) -> Chart<'a> {
547
+ let latency_iter = latency_throughput.iter().map(|(l, _)| l);
548
+ let throughput_iter = latency_throughput.iter().map(|(_, t)| t);
549
+
550
+ // Get extreme values
551
+ let min_latency: f64 = *latency_iter
552
+ .clone()
553
+ .min_by(|a, b| a.total_cmp(b))
554
+ .unwrap_or(&std::f64::NAN);
555
+ let max_latency: f64 = *latency_iter
556
+ .max_by(|a, b| a.total_cmp(b))
557
+ .unwrap_or(&std::f64::NAN);
558
+ let min_throughput: f64 = *throughput_iter
559
+ .clone()
560
+ .min_by(|a, b| a.total_cmp(b))
561
+ .unwrap_or(&std::f64::NAN);
562
+ let max_throughput: f64 = *throughput_iter
563
+ .max_by(|a, b| a.total_cmp(b))
564
+ .unwrap_or(&std::f64::NAN);
565
+
566
+ // Char min max values
567
+ let min_x = if zoom {
568
+ ((min_latency - 0.05 * min_latency) / 100.0).floor() * 100.0
569
+ } else {
570
+ 0.0
571
+ };
572
+ let max_x = ((max_latency + 0.05 * max_latency) / 100.0).ceil() * 100.0;
573
+ let step_x = (max_x - min_x) / 4.0;
574
+
575
+ // Chart min max values
576
+ let min_y = if zoom {
577
+ ((min_throughput - 0.05 * min_throughput) / 100.0).floor() * 100.0
578
+ } else {
579
+ 0.0
580
+ };
581
+ let max_y = ((max_throughput + 0.05 * max_throughput) / 100.0).ceil() * 100.0;
582
+ let step_y = (max_y - min_y) / 4.0;
583
+
584
+ // Labels
585
+ let mut x_labels = vec![Span::styled(
586
+ format!("{min_x:.2}"),
587
+ Style::default()
588
+ .add_modifier(Modifier::BOLD)
589
+ .fg(Color::Gray)
590
+ .bg(Color::Reset),
591
+ )];
592
+ for i in 0..3 {
593
+ x_labels.push(Span::styled(
594
+ format!("{:.2}", min_x + ((i + 1) as f64 * step_x)),
595
+ Style::default().fg(Color::Gray).bg(Color::Reset),
596
+ ));
597
+ }
598
+ x_labels.push(Span::styled(
599
+ format!("{max_x:.2}"),
600
+ Style::default()
601
+ .add_modifier(Modifier::BOLD)
602
+ .fg(Color::Gray)
603
+ .bg(Color::Reset),
604
+ ));
605
+
606
+ // Labels
607
+ let mut y_labels = vec![Span::styled(
608
+ format!("{min_y:.2}"),
609
+ Style::default()
610
+ .add_modifier(Modifier::BOLD)
611
+ .fg(Color::Gray)
612
+ .bg(Color::Reset),
613
+ )];
614
+ for i in 0..3 {
615
+ y_labels.push(Span::styled(
616
+ format!("{:.2}", min_y + ((i + 1) as f64 * step_y)),
617
+ Style::default().fg(Color::Gray).bg(Color::Reset),
618
+ ));
619
+ }
620
+ y_labels.push(Span::styled(
621
+ format!("{max_y:.2}"),
622
+ Style::default()
623
+ .add_modifier(Modifier::BOLD)
624
+ .fg(Color::Gray)
625
+ .bg(Color::Reset),
626
+ ));
627
+
628
+ // Chart dataset
629
+ let colors = color_vec();
630
+ let datasets: Vec<Dataset> = (0..latency_throughput.len())
631
+ .map(|i| {
632
+ let color_idx = i % colors.len();
633
+
634
+ Dataset::default()
635
+ .name(batch_sizes[i].to_string())
636
+ .marker(symbols::Marker::Block)
637
+ .style(Style::default().fg(colors[color_idx]))
638
+ .graph_type(GraphType::Scatter)
639
+ .data(&latency_throughput[i..(i + 1)])
640
+ })
641
+ .collect();
642
+
643
+ // Chart
644
+ Chart::new(datasets)
645
+ .style(Style::default().fg(Color::Cyan).bg(Color::Reset))
646
+ .block(
647
+ Block::default()
648
+ .title(Span::styled(
649
+ format!("{name} throughput over latency"),
650
+ Style::default().fg(Color::Gray).bg(Color::Reset),
651
+ ))
652
+ .borders(Borders::ALL),
653
+ )
654
+ .x_axis(
655
+ Axis::default()
656
+ .title("ms")
657
+ .style(Style::default().fg(Color::Gray).bg(Color::Reset))
658
+ .labels(x_labels)
659
+ .bounds([min_x, max_x]),
660
+ )
661
+ .y_axis(
662
+ Axis::default()
663
+ .title("tokens/secs")
664
+ .style(Style::default().fg(Color::Gray).bg(Color::Reset))
665
+ .labels(y_labels)
666
+ .bounds([min_y, max_y]),
667
+ )
668
+ }
669
+
670
+ // Colors for latency/throughput chart
671
+ fn color_vec() -> Vec<Color> {
672
+ vec![
673
+ Color::Red,
674
+ Color::Green,
675
+ Color::Yellow,
676
+ Color::Blue,
677
+ Color::Magenta,
678
+ Color::Cyan,
679
+ Color::Gray,
680
+ Color::DarkGray,
681
+ Color::LightRed,
682
+ Color::LightGreen,
683
+ Color::LightYellow,
684
+ Color::LightBlue,
685
+ Color::LightMagenta,
686
+ Color::LightCyan,
687
+ ]
688
+ }
benchmark/src/event.rs ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /// Inspired by https://github.com/orhun/rust-tui-template/blob/472aa515119d4c94903eac12d9784417281dc7f5/src/event.rs
2
+ use crossterm::event;
3
+ use std::time::{Duration, Instant};
4
+ use tokio::sync::{broadcast, mpsc};
5
+
6
+ /// Events
7
+ #[derive(Debug)]
8
+ pub(crate) enum Event {
9
+ /// Terminal tick.
10
+ Tick,
11
+ /// Key press.
12
+ Key(event::KeyEvent),
13
+ /// Terminal resize.
14
+ Resize(u16, u16),
15
+ }
16
+
17
+ pub(crate) async fn terminal_event_task(
18
+ fps: u32,
19
+ event_sender: mpsc::Sender<Event>,
20
+ mut shutdown_receiver: broadcast::Receiver<()>,
21
+ _shutdown_guard_sender: mpsc::Sender<()>,
22
+ ) {
23
+ // End task if a message is received on shutdown_receiver
24
+ // _shutdown_guard_sender will be dropped once the task is finished
25
+ tokio::select! {
26
+ _ = event_loop(fps, event_sender) => {
27
+ },
28
+ _ = shutdown_receiver.recv() => {}
29
+ }
30
+ }
31
+
32
+ /// Main event loop
33
+ async fn event_loop(fps: u32, event_sender: mpsc::Sender<Event>) {
34
+ // Frame budget
35
+ let per_frame = Duration::from_secs(1) / fps;
36
+
37
+ // When was last frame executed
38
+ let mut last_frame = Instant::now();
39
+
40
+ loop {
41
+ // Sleep to avoid blocking the thread for too long
42
+ if let Some(sleep) = per_frame.checked_sub(last_frame.elapsed()) {
43
+ tokio::time::sleep(sleep).await;
44
+ }
45
+
46
+ // Get crossterm event and send a new one over the channel
47
+ if event::poll(Duration::from_secs(0)).expect("no events available") {
48
+ match event::read().expect("unable to read event") {
49
+ event::Event::Key(e) => event_sender.send(Event::Key(e)).await.unwrap_or(()),
50
+ event::Event::Resize(w, h) => {
51
+ event_sender.send(Event::Resize(w, h)).await.unwrap_or(())
52
+ }
53
+ _ => (),
54
+ }
55
+ }
56
+
57
+ // Frame budget exceeded
58
+ if last_frame.elapsed() >= per_frame {
59
+ // Send tick
60
+ event_sender.send(Event::Tick).await.unwrap_or(());
61
+ // Rest last_frame time
62
+ last_frame = Instant::now();
63
+ }
64
+ }
65
+ }
benchmark/src/generation.rs ADDED
@@ -0,0 +1,226 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ use std::time::{Duration, Instant};
2
+ use text_generation_client::{
3
+ Batch, ClientError, NextTokenChooserParameters, Request, ShardedClient,
4
+ StoppingCriteriaParameters,
5
+ };
6
+ use tokenizers::{Tokenizer, TruncationDirection};
7
+ use tokio::sync::{broadcast, mpsc};
8
+
9
+ const LOREM_IPSUM: &str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
10
+
11
+ #[derive(Debug, Clone)]
12
+ pub(crate) struct Prefill {
13
+ pub(crate) latency: Duration,
14
+ pub(crate) throughput: f64,
15
+ }
16
+
17
+ #[derive(Debug, Clone)]
18
+ pub(crate) struct Decode {
19
+ pub(crate) latency: Duration,
20
+ pub(crate) token_latency: Duration,
21
+ pub(crate) throughput: f64,
22
+ }
23
+
24
+ #[derive(Debug)]
25
+ pub(crate) enum Message {
26
+ Warmup,
27
+ Prefill(Prefill),
28
+ Decode(Decode),
29
+ EndRun,
30
+ EndBatch,
31
+ }
32
+
33
+ /// Benchmarking task
34
+ #[allow(clippy::too_many_arguments)]
35
+ pub(crate) async fn generation_task(
36
+ tokenizer: Tokenizer,
37
+ batch_size: Vec<u32>,
38
+ sequence_length: u32,
39
+ decode_length: u32,
40
+ n_runs: usize,
41
+ warmups: usize,
42
+ client: ShardedClient,
43
+ run_sender: mpsc::Sender<Result<Message, ClientError>>,
44
+ mut shutdown_receiver: broadcast::Receiver<()>,
45
+ _shutdown_guard_sender: mpsc::Sender<()>,
46
+ ) {
47
+ // End task if a message is received on shutdown_receiver
48
+ // _shutdown_guard_sender will be dropped once the task is finished
49
+ tokio::select! {
50
+ res = generate_runs(tokenizer, batch_size, sequence_length, decode_length, n_runs, warmups, client, run_sender.clone()) => {
51
+ if let Err(err) = res {
52
+ run_sender.send(Err(err)).await.unwrap_or(());
53
+ }
54
+ },
55
+ _ = shutdown_receiver.recv() => {}
56
+ }
57
+ }
58
+
59
+ /// Benchmark prefill/decode
60
+ #[allow(clippy::too_many_arguments)]
61
+ async fn generate_runs(
62
+ tokenizer: Tokenizer,
63
+ batch_size: Vec<u32>,
64
+ sequence_length: u32,
65
+ decode_length: u32,
66
+ n_runs: usize,
67
+ warmups: usize,
68
+ mut client: ShardedClient,
69
+ run_sender: mpsc::Sender<Result<Message, ClientError>>,
70
+ ) -> Result<(), ClientError> {
71
+ // Create a dummy sequence
72
+ let sequence = create_sequence(sequence_length, tokenizer);
73
+
74
+ for b in batch_size {
75
+ // Warmups on batch size
76
+ for _ in 0..warmups {
77
+ let (_, decode_batch) = prefill(
78
+ sequence.clone(),
79
+ sequence_length,
80
+ b,
81
+ decode_length,
82
+ &mut client,
83
+ )
84
+ .await?;
85
+ let _ = decode(decode_batch, &mut client).await?;
86
+ // Send warmup message
87
+ run_sender.send(Ok(Message::Warmup)).await.unwrap_or(());
88
+ }
89
+
90
+ for _ in 0..n_runs {
91
+ let (prefill, decode_batch) = prefill(
92
+ sequence.clone(),
93
+ sequence_length,
94
+ b,
95
+ decode_length,
96
+ &mut client,
97
+ )
98
+ .await?;
99
+ // Send prefill message
100
+ run_sender
101
+ .send(Ok(Message::Prefill(prefill)))
102
+ .await
103
+ .unwrap_or(());
104
+
105
+ let decode = decode(decode_batch, &mut client).await?;
106
+
107
+ // Send decode message
108
+ run_sender
109
+ .send(Ok(Message::Decode(decode)))
110
+ .await
111
+ .unwrap_or(());
112
+
113
+ // Send run ended message
114
+ run_sender.send(Ok(Message::EndRun)).await.unwrap_or(());
115
+ }
116
+ // Batch ended
117
+ run_sender.send(Ok(Message::EndBatch)).await.unwrap_or(());
118
+ }
119
+ Ok(())
120
+ }
121
+
122
+ // Run a prefill step
123
+ async fn prefill(
124
+ sequence: String,
125
+ sequence_length: u32,
126
+ batch_size: u32,
127
+ decode_length: u32,
128
+ client: &mut ShardedClient,
129
+ ) -> Result<(Prefill, Batch), ClientError> {
130
+ // Create requests
131
+ let requests = (0..batch_size)
132
+ .map(|id| Request {
133
+ id: id.into(),
134
+ inputs: sequence.clone(),
135
+ truncate: sequence_length,
136
+ parameters: Some(NextTokenChooserParameters {
137
+ temperature: 1.0,
138
+ top_k: 0,
139
+ top_p: 1.0,
140
+ typical_p: 1.0,
141
+ do_sample: false,
142
+ seed: 0,
143
+ repetition_penalty: 1.0,
144
+ watermark: false,
145
+ }),
146
+ stopping_parameters: Some(StoppingCriteriaParameters {
147
+ max_new_tokens: decode_length,
148
+ stop_sequences: vec![],
149
+ ignore_eos_token: true, // Will not stop even if a eos token is generated
150
+ }),
151
+ })
152
+ .collect();
153
+
154
+ let batch = Batch {
155
+ id: 0,
156
+ requests,
157
+ size: batch_size,
158
+ max_tokens: batch_size * (sequence_length + decode_length),
159
+ };
160
+
161
+ // Run prefill
162
+ let start_time = Instant::now();
163
+ let (_, decode_batch) = client.prefill(batch.clone()).await?;
164
+
165
+ // Get latency
166
+ let latency = start_time.elapsed();
167
+
168
+ // Compute throughput from latency and batch size
169
+ let throughput = batch_size as f64 / latency.as_secs_f64();
170
+
171
+ // Decode batch cannot be empty
172
+ let decode_batch = decode_batch.expect("decode_batch is None. This is a bug.");
173
+
174
+ let step = Prefill {
175
+ latency,
176
+ throughput,
177
+ };
178
+
179
+ Ok((step, decode_batch))
180
+ }
181
+
182
+ /// Run a full decode
183
+ async fn decode(batch: Batch, client: &mut ShardedClient) -> Result<Decode, ClientError> {
184
+ let mut decode_length = 0;
185
+ let batch_size = batch.size;
186
+
187
+ let start_time = Instant::now();
188
+
189
+ // Full decode over decode length
190
+ let mut next_batch = Some(batch);
191
+ while let Some(batch) = next_batch {
192
+ let result = client.decode(vec![batch]).await?;
193
+ next_batch = result.1;
194
+ decode_length += 1;
195
+ }
196
+
197
+ // Get latency
198
+ let latency = start_time.elapsed();
199
+ let token_latency = latency / decode_length;
200
+
201
+ // Compute throughput from latency, batch size and decode length
202
+ let throughput = (batch_size * decode_length) as f64 / latency.as_secs_f64();
203
+
204
+ let step = Decode {
205
+ latency,
206
+ token_latency,
207
+ throughput,
208
+ };
209
+ Ok(step)
210
+ }
211
+
212
+ /// Create a dummy sequence of the correct length
213
+ fn create_sequence(sequence_length: u32, tokenizer: Tokenizer) -> String {
214
+ let lorem_ipsum_length = tokenizer.encode(LOREM_IPSUM, true).unwrap().len();
215
+ // Repeat lorem ipsum to cover sequence length
216
+ let string_sequence =
217
+ LOREM_IPSUM.repeat((0..sequence_length).step_by(lorem_ipsum_length).len());
218
+ // Encode sequence
219
+ let mut encoding = tokenizer.encode(string_sequence, true).unwrap();
220
+ // Truncate to sequence_length
221
+ encoding.truncate(sequence_length as usize, 0, TruncationDirection::Left);
222
+ // Decode
223
+ tokenizer
224
+ .decode(Vec::from(encoding.get_ids()), false)
225
+ .unwrap()
226
+ }
benchmark/src/lib.rs ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ mod app;
2
+ mod event;
3
+ mod generation;
4
+ mod utils;
5
+
6
+ use crate::app::App;
7
+ use crate::event::Event;
8
+ use crossterm::ExecutableCommand;
9
+ use std::io;
10
+ use text_generation_client::ShardedClient;
11
+ use tokenizers::Tokenizer;
12
+ use tokio::sync::{broadcast, mpsc};
13
+ use tui::backend::CrosstermBackend;
14
+ use tui::Terminal;
15
+
16
+ /// Run benchmarking app
17
+ #[allow(clippy::too_many_arguments)]
18
+ pub async fn run(
19
+ tokenizer_name: String,
20
+ tokenizer: Tokenizer,
21
+ batch_size: Vec<u32>,
22
+ sequence_length: u32,
23
+ decode_length: u32,
24
+ n_runs: usize,
25
+ warmups: usize,
26
+ client: ShardedClient,
27
+ ) -> Result<(), crossterm::ErrorKind> {
28
+ // Initialize terminal properties
29
+ crossterm::terminal::enable_raw_mode()?;
30
+ io::stdout().execute(crossterm::terminal::EnterAlternateScreen)?;
31
+ io::stdout().execute(crossterm::cursor::Hide)?;
32
+
33
+ // Initialize terminal
34
+ let mut terminal = {
35
+ let backend = CrosstermBackend::new(io::stdout());
36
+ Terminal::new(backend)?
37
+ };
38
+
39
+ // Create message channel between generation_task and app
40
+ let (run_sender, run_receiver) = mpsc::channel(8);
41
+ // Crossterm event channel
42
+ let (event_sender, mut event_receiver) = mpsc::channel(8);
43
+ // Shutdown channel to terminate tasks
44
+ let (shutdown_sender, _) = broadcast::channel(1);
45
+ // Channel to check if tasks terminated
46
+ let (shutdown_guard_sender, mut shutdown_guard_receiver) = mpsc::channel(1);
47
+
48
+ // Create generation task
49
+ tokio::spawn(generation::generation_task(
50
+ tokenizer,
51
+ batch_size.clone(),
52
+ sequence_length,
53
+ decode_length,
54
+ n_runs,
55
+ warmups,
56
+ client,
57
+ run_sender,
58
+ shutdown_sender.subscribe(),
59
+ shutdown_guard_sender.clone(),
60
+ ));
61
+
62
+ // Create event task
63
+ tokio::spawn(event::terminal_event_task(
64
+ 250,
65
+ event_sender,
66
+ shutdown_sender.subscribe(),
67
+ shutdown_guard_sender.clone(),
68
+ ));
69
+
70
+ // Drop our end of shutdown sender
71
+ drop(shutdown_guard_sender);
72
+
73
+ // Create App
74
+ let mut app = App::new(
75
+ run_receiver,
76
+ tokenizer_name,
77
+ sequence_length,
78
+ decode_length,
79
+ n_runs,
80
+ batch_size,
81
+ );
82
+
83
+ while app.running {
84
+ // Draw frame
85
+ terminal.draw(|frame| app.render(frame))?;
86
+
87
+ // Await a new event from event handling task
88
+ match event_receiver.recv().await {
89
+ None => break,
90
+ // Update app state
91
+ Some(event) => match event {
92
+ Event::Tick => app.tick(),
93
+ Event::Key(key_event) => app.handle_key_event(key_event),
94
+ _ => {}
95
+ },
96
+ }
97
+ }
98
+
99
+ // Ask tasks to shutdown
100
+ let _ = shutdown_sender.send(());
101
+ // Wait for tasks to shutdown
102
+ let _ = shutdown_guard_receiver.recv().await;
103
+
104
+ // Revert terminal to original view
105
+ io::stdout().execute(crossterm::terminal::LeaveAlternateScreen)?;
106
+ crossterm::terminal::disable_raw_mode()?;
107
+ io::stdout().execute(crossterm::cursor::Show)?;
108
+
109
+ Ok(())
110
+ }
benchmark/src/main.rs ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /// Text Generation Inference benchmarking tool
2
+ ///
3
+ /// Inspired by the great Oha app: https://github.com/hatoo/oha
4
+ /// and: https://github.com/orhun/rust-tui-template
5
+ use clap::Parser;
6
+ use std::path::Path;
7
+ use text_generation_client::ShardedClient;
8
+ use tokenizers::{FromPretrainedParameters, Tokenizer};
9
+ use tracing_subscriber::layer::SubscriberExt;
10
+ use tracing_subscriber::util::SubscriberInitExt;
11
+ use tracing_subscriber::EnvFilter;
12
+
13
+ /// App Configuration
14
+ #[derive(Parser, Debug)]
15
+ #[clap(author, version, about, long_about = None)]
16
+ struct Args {
17
+ #[clap(short, long, env)]
18
+ tokenizer_name: String,
19
+ #[clap(default_value = "main", long, env)]
20
+ revision: String,
21
+ #[clap(short, long)]
22
+ batch_size: Option<Vec<u32>>,
23
+ #[clap(default_value = "10", short, long, env)]
24
+ sequence_length: u32,
25
+ #[clap(default_value = "8", short, long, env)]
26
+ decode_length: u32,
27
+ #[clap(default_value = "10", short, long, env)]
28
+ runs: usize,
29
+ #[clap(default_value = "1", short, long, env)]
30
+ warmups: usize,
31
+ #[clap(default_value = "/tmp/text-generation-server-0", short, long, env)]
32
+ master_shard_uds_path: String,
33
+ }
34
+
35
+ fn main() -> Result<(), Box<dyn std::error::Error>> {
36
+ // Get args
37
+ let args = Args::parse();
38
+ // Pattern match configuration
39
+ let Args {
40
+ tokenizer_name,
41
+ revision,
42
+ batch_size,
43
+ sequence_length,
44
+ decode_length,
45
+ runs,
46
+ warmups,
47
+ master_shard_uds_path,
48
+ } = args;
49
+
50
+ let batch_size = batch_size.unwrap_or(vec![1, 2, 4, 8, 16, 32]);
51
+
52
+ init_logging();
53
+
54
+ // Tokenizer instance
55
+ // This will only be used to validate payloads
56
+ tracing::info!("Loading tokenizer");
57
+ let local_path = Path::new(&tokenizer_name);
58
+ let tokenizer =
59
+ if local_path.exists() && local_path.is_dir() && local_path.join("tokenizer.json").exists()
60
+ {
61
+ // Load local tokenizer
62
+ tracing::info!("Found local tokenizer");
63
+ Tokenizer::from_file(local_path.join("tokenizer.json")).unwrap()
64
+ } else {
65
+ tracing::info!("Downloading tokenizer");
66
+
67
+ // Parse Huggingface hub token
68
+ let auth_token = std::env::var("HUGGING_FACE_HUB_TOKEN").ok();
69
+
70
+ // Download and instantiate tokenizer
71
+ // We need to download it outside of the Tokio runtime
72
+ let params = FromPretrainedParameters {
73
+ revision,
74
+ auth_token,
75
+ ..Default::default()
76
+ };
77
+ Tokenizer::from_pretrained(tokenizer_name.clone(), Some(params)).unwrap()
78
+ };
79
+ tracing::info!("Tokenizer loaded");
80
+
81
+ // Launch Tokio runtime
82
+ tokio::runtime::Builder::new_multi_thread()
83
+ .enable_all()
84
+ .build()
85
+ .unwrap()
86
+ .block_on(async {
87
+ // Instantiate sharded client from the master unix socket
88
+ tracing::info!("Connect to model server");
89
+ let mut sharded_client = ShardedClient::connect_uds(master_shard_uds_path)
90
+ .await
91
+ .expect("Could not connect to server");
92
+ // Clear the cache; useful if the webserver rebooted
93
+ sharded_client
94
+ .clear_cache(None)
95
+ .await
96
+ .expect("Unable to clear cache");
97
+ tracing::info!("Connected");
98
+
99
+ // Run app
100
+ text_generation_benchmark::run(
101
+ tokenizer_name,
102
+ tokenizer,
103
+ batch_size,
104
+ sequence_length,
105
+ decode_length,
106
+ runs,
107
+ warmups,
108
+ sharded_client,
109
+ )
110
+ .await
111
+ .unwrap();
112
+ });
113
+ Ok(())
114
+ }
115
+
116
+ /// Init logging using LOG_LEVEL
117
+ fn init_logging() {
118
+ // STDOUT/STDERR layer
119
+ let fmt_layer = tracing_subscriber::fmt::layer()
120
+ .with_file(true)
121
+ .with_line_number(true);
122
+
123
+ // Filter events with LOG_LEVEL
124
+ let env_filter =
125
+ EnvFilter::try_from_env("LOG_LEVEL").unwrap_or_else(|_| EnvFilter::new("info"));
126
+
127
+ tracing_subscriber::registry()
128
+ .with(env_filter)
129
+ .with(fmt_layer)
130
+ .init();
131
+ }
benchmark/src/utils.rs ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /// MIT License
2
+ //
3
+ // Copyright (c) 2020 hatoo
4
+ //
5
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ // of this software and associated documentation files (the "Software"), to deal
7
+ // in the Software without restriction, including without limitation the rights
8
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ // copies of the Software, and to permit persons to whom the Software is
10
+ // furnished to do so, subject to the following conditions:
11
+ //
12
+ // The above copyright notice and this permission notice shall be included in all
13
+ // copies or substantial portions of the Software.
14
+ use std::collections::BTreeMap;
15
+
16
+ pub(crate) fn histogram(values: &[f64], bins: usize) -> Vec<(f64, usize)> {
17
+ assert!(bins >= 2);
18
+ let mut bucket: Vec<usize> = vec![0; bins];
19
+ let min = values.iter().collect::<average::Min>().min();
20
+ let max = values.iter().collect::<average::Max>().max();
21
+ let step = (max - min) / (bins - 1) as f64;
22
+
23
+ for &v in values {
24
+ let i = std::cmp::min(((v - min) / step).ceil() as usize, bins - 1);
25
+ bucket[i] += 1;
26
+ }
27
+
28
+ bucket
29
+ .into_iter()
30
+ .enumerate()
31
+ .map(|(i, v)| (min + step * i as f64, v))
32
+ .collect()
33
+ }
34
+
35
+ pub(crate) fn percentiles(values: &[f64], pecents: &[i32]) -> BTreeMap<String, f64> {
36
+ pecents
37
+ .iter()
38
+ .map(|&p| {
39
+ let i = (f64::from(p) / 100.0 * values.len() as f64) as usize;
40
+ (format!("p{p}"), *values.get(i).unwrap_or(&std::f64::NAN))
41
+ })
42
+ .collect()
43
+ }
clients/python/Makefile ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ unit-tests:
2
+ python -m pytest --cov=text_generation tests
3
+
4
+ install:
5
+ pip install pip --upgrade
6
+ pip install -e .
clients/python/poetry.lock ADDED
The diff for this file is too large to render. See raw diff
 
clients/python/pyproject.toml ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [tool.poetry]
2
+ name = "text-generation"
3
+ version = "0.5.1"
4
+ description = "Hugging Face Text Generation Python Client"
5
+ license = "Apache-2.0"
6
+ authors = ["Olivier Dehaene <olivier@huggingface.co>"]
7
+ maintainers = ["Olivier Dehaene <olivier@huggingface.co>"]
8
+ readme = "README.md"
9
+ homepage = "https://github.com/huggingface/text-generation-inference"
10
+ repository = "https://github.com/huggingface/text-generation-inference"
11
+
12
+
13
+ [tool.poetry.dependencies]
14
+ python = "^3.7"
15
+ pydantic = "^1.10"
16
+ aiohttp = "^3.8"
17
+ huggingface-hub = ">= 0.12, < 1.0"
18
+
19
+ [tool.poetry.dev-dependencies]
20
+ pytest = "^6.2.5"
21
+ pytest-asyncio = "^0.17.2"
22
+ pytest-cov = "^3.0.0"
23
+
24
+ [tool.pytest.ini_options]
25
+ asyncio_mode = "auto"
26
+
27
+ [build-system]
28
+ requires = ["poetry-core>=1.0.0"]
29
+ build-backend = "poetry.core.masonry.api"
clients/python/tests/conftest.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pytest
2
+
3
+ from text_generation import __version__
4
+ from huggingface_hub.utils import build_hf_headers
5
+
6
+
7
+ @pytest.fixture
8
+ def flan_t5_xxl():
9
+ return "google/flan-t5-xxl"
10
+
11
+
12
+ @pytest.fixture
13
+ def fake_model():
14
+ return "fake/model"
15
+
16
+
17
+ @pytest.fixture
18
+ def unsupported_model():
19
+ return "gpt2"
20
+
21
+
22
+ @pytest.fixture
23
+ def base_url():
24
+ return "https://api-inference.huggingface.co/models"
25
+
26
+
27
+ @pytest.fixture
28
+ def bloom_url(base_url, bloom_model):
29
+ return f"{base_url}/{bloom_model}"
30
+
31
+
32
+ @pytest.fixture
33
+ def flan_t5_xxl_url(base_url, flan_t5_xxl):
34
+ return f"{base_url}/{flan_t5_xxl}"
35
+
36
+
37
+ @pytest.fixture
38
+ def fake_url(base_url, fake_model):
39
+ return f"{base_url}/{fake_model}"
40
+
41
+
42
+ @pytest.fixture
43
+ def unsupported_url(base_url, unsupported_model):
44
+ return f"{base_url}/{unsupported_model}"
45
+
46
+
47
+ @pytest.fixture(scope="session")
48
+ def hf_headers():
49
+ return build_hf_headers(
50
+ library_name="text-generation-tests", library_version=__version__
51
+ )
clients/python/tests/test_client.py ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pytest
2
+
3
+ from text_generation import Client, AsyncClient
4
+ from text_generation.errors import NotFoundError, ValidationError
5
+ from text_generation.types import FinishReason, PrefillToken, Token
6
+
7
+
8
+ def test_generate(flan_t5_xxl_url, hf_headers):
9
+ client = Client(flan_t5_xxl_url, hf_headers)
10
+ response = client.generate("test", max_new_tokens=1)
11
+
12
+ assert response.generated_text == ""
13
+ assert response.details.finish_reason == FinishReason.Length
14
+ assert response.details.generated_tokens == 1
15
+ assert response.details.seed is None
16
+ assert len(response.details.prefill) == 1
17
+ assert response.details.prefill[0] == PrefillToken(id=0, text="<pad>", logprob=None)
18
+ assert len(response.details.tokens) == 1
19
+ assert response.details.tokens[0] == Token(
20
+ id=3, text="", logprob=-1.984375, special=False
21
+ )
22
+
23
+
24
+ def test_generate_best_of(flan_t5_xxl_url, hf_headers):
25
+ client = Client(flan_t5_xxl_url, hf_headers)
26
+ response = client.generate("test", max_new_tokens=1, best_of=2, do_sample=True)
27
+
28
+ assert response.details.seed is not None
29
+ assert response.details.best_of_sequences is not None
30
+ assert len(response.details.best_of_sequences) == 1
31
+ assert response.details.best_of_sequences[0].seed is not None
32
+
33
+
34
+ def test_generate_not_found(fake_url, hf_headers):
35
+ client = Client(fake_url, hf_headers)
36
+ with pytest.raises(NotFoundError):
37
+ client.generate("test")
38
+
39
+
40
+ def test_generate_validation_error(flan_t5_xxl_url, hf_headers):
41
+ client = Client(flan_t5_xxl_url, hf_headers)
42
+ with pytest.raises(ValidationError):
43
+ client.generate("test", max_new_tokens=10_000)
44
+
45
+
46
+ def test_generate_stream(flan_t5_xxl_url, hf_headers):
47
+ client = Client(flan_t5_xxl_url, hf_headers)
48
+ responses = [
49
+ response for response in client.generate_stream("test", max_new_tokens=1)
50
+ ]
51
+
52
+ assert len(responses) == 1
53
+ response = responses[0]
54
+
55
+ assert response.generated_text == ""
56
+ assert response.details.finish_reason == FinishReason.Length
57
+ assert response.details.generated_tokens == 1
58
+ assert response.details.seed is None
59
+
60
+
61
+ def test_generate_stream_not_found(fake_url, hf_headers):
62
+ client = Client(fake_url, hf_headers)
63
+ with pytest.raises(NotFoundError):
64
+ list(client.generate_stream("test"))
65
+
66
+
67
+ def test_generate_stream_validation_error(flan_t5_xxl_url, hf_headers):
68
+ client = Client(flan_t5_xxl_url, hf_headers)
69
+ with pytest.raises(ValidationError):
70
+ list(client.generate_stream("test", max_new_tokens=10_000))
71
+
72
+
73
+ @pytest.mark.asyncio
74
+ async def test_generate_async(flan_t5_xxl_url, hf_headers):
75
+ client = AsyncClient(flan_t5_xxl_url, hf_headers)
76
+ response = await client.generate("test", max_new_tokens=1)
77
+
78
+ assert response.generated_text == ""
79
+ assert response.details.finish_reason == FinishReason.Length
80
+ assert response.details.generated_tokens == 1
81
+ assert response.details.seed is None
82
+ assert len(response.details.prefill) == 1
83
+ assert response.details.prefill[0] == PrefillToken(id=0, text="<pad>", logprob=None)
84
+ assert len(response.details.tokens) == 1
85
+ assert response.details.tokens[0] == Token(
86
+ id=3, text="", logprob=-1.984375, special=False
87
+ )
88
+
89
+
90
+ @pytest.mark.asyncio
91
+ async def test_generate_async_best_of(flan_t5_xxl_url, hf_headers):
92
+ client = AsyncClient(flan_t5_xxl_url, hf_headers)
93
+ response = await client.generate(
94
+ "test", max_new_tokens=1, best_of=2, do_sample=True
95
+ )
96
+
97
+ assert response.details.seed is not None
98
+ assert response.details.best_of_sequences is not None
99
+ assert len(response.details.best_of_sequences) == 1
100
+ assert response.details.best_of_sequences[0].seed is not None
101
+
102
+
103
+ @pytest.mark.asyncio
104
+ async def test_generate_async_not_found(fake_url, hf_headers):
105
+ client = AsyncClient(fake_url, hf_headers)
106
+ with pytest.raises(NotFoundError):
107
+ await client.generate("test")
108
+
109
+
110
+ @pytest.mark.asyncio
111
+ async def test_generate_async_validation_error(flan_t5_xxl_url, hf_headers):
112
+ client = AsyncClient(flan_t5_xxl_url, hf_headers)
113
+ with pytest.raises(ValidationError):
114
+ await client.generate("test", max_new_tokens=10_000)
115
+
116
+
117
+ @pytest.mark.asyncio
118
+ async def test_generate_stream_async(flan_t5_xxl_url, hf_headers):
119
+ client = AsyncClient(flan_t5_xxl_url, hf_headers)
120
+ responses = [
121
+ response async for response in client.generate_stream("test", max_new_tokens=1)
122
+ ]
123
+
124
+ assert len(responses) == 1
125
+ response = responses[0]
126
+
127
+ assert response.generated_text == ""
128
+ assert response.details.finish_reason == FinishReason.Length
129
+ assert response.details.generated_tokens == 1
130
+ assert response.details.seed is None
131
+
132
+
133
+ @pytest.mark.asyncio
134
+ async def test_generate_stream_async_not_found(fake_url, hf_headers):
135
+ client = AsyncClient(fake_url, hf_headers)
136
+ with pytest.raises(NotFoundError):
137
+ async for _ in client.generate_stream("test"):
138
+ pass
139
+
140
+
141
+ @pytest.mark.asyncio
142
+ async def test_generate_stream_async_validation_error(flan_t5_xxl_url, hf_headers):
143
+ client = AsyncClient(flan_t5_xxl_url, hf_headers)
144
+ with pytest.raises(ValidationError):
145
+ async for _ in client.generate_stream("test", max_new_tokens=10_000):
146
+ pass
clients/python/tests/test_errors.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from text_generation.errors import (
2
+ parse_error,
3
+ GenerationError,
4
+ IncompleteGenerationError,
5
+ OverloadedError,
6
+ ValidationError,
7
+ BadRequestError,
8
+ ShardNotReadyError,
9
+ ShardTimeoutError,
10
+ NotFoundError,
11
+ RateLimitExceededError,
12
+ UnknownError,
13
+ )
14
+
15
+
16
+ def test_generation_error():
17
+ payload = {"error_type": "generation", "error": "test"}
18
+ assert isinstance(parse_error(400, payload), GenerationError)
19
+
20
+
21
+ def test_incomplete_generation_error():
22
+ payload = {"error_type": "incomplete_generation", "error": "test"}
23
+ assert isinstance(parse_error(400, payload), IncompleteGenerationError)
24
+
25
+
26
+ def test_overloaded_error():
27
+ payload = {"error_type": "overloaded", "error": "test"}
28
+ assert isinstance(parse_error(400, payload), OverloadedError)
29
+
30
+
31
+ def test_validation_error():
32
+ payload = {"error_type": "validation", "error": "test"}
33
+ assert isinstance(parse_error(400, payload), ValidationError)
34
+
35
+
36
+ def test_bad_request_error():
37
+ payload = {"error": "test"}
38
+ assert isinstance(parse_error(400, payload), BadRequestError)
39
+
40
+
41
+ def test_shard_not_ready_error():
42
+ payload = {"error": "test"}
43
+ assert isinstance(parse_error(403, payload), ShardNotReadyError)
44
+ assert isinstance(parse_error(424, payload), ShardNotReadyError)
45
+
46
+
47
+ def test_shard_timeout_error():
48
+ payload = {"error": "test"}
49
+ assert isinstance(parse_error(504, payload), ShardTimeoutError)
50
+
51
+
52
+ def test_not_found_error():
53
+ payload = {"error": "test"}
54
+ assert isinstance(parse_error(404, payload), NotFoundError)
55
+
56
+
57
+ def test_rate_limit_exceeded_error():
58
+ payload = {"error": "test"}
59
+ assert isinstance(parse_error(429, payload), RateLimitExceededError)
60
+
61
+
62
+ def test_unknown_error():
63
+ payload = {"error": "test"}
64
+ assert isinstance(parse_error(500, payload), UnknownError)
clients/python/tests/test_inference_api.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pytest
2
+
3
+ from text_generation import (
4
+ InferenceAPIClient,
5
+ InferenceAPIAsyncClient,
6
+ Client,
7
+ AsyncClient,
8
+ )
9
+ from text_generation.errors import NotSupportedError, NotFoundError
10
+ from text_generation.inference_api import check_model_support, deployed_models
11
+
12
+
13
+ def test_check_model_support(flan_t5_xxl, unsupported_model, fake_model):
14
+ assert check_model_support(flan_t5_xxl)
15
+ assert not check_model_support(unsupported_model)
16
+
17
+ with pytest.raises(NotFoundError):
18
+ check_model_support(fake_model)
19
+
20
+
21
+ def test_deployed_models():
22
+ deployed_models()
23
+
24
+
25
+ def test_client(flan_t5_xxl):
26
+ client = InferenceAPIClient(flan_t5_xxl)
27
+ assert isinstance(client, Client)
28
+
29
+
30
+ def test_client_unsupported_model(unsupported_model):
31
+ with pytest.raises(NotSupportedError):
32
+ InferenceAPIClient(unsupported_model)
33
+
34
+
35
+ def test_async_client(flan_t5_xxl):
36
+ client = InferenceAPIAsyncClient(flan_t5_xxl)
37
+ assert isinstance(client, AsyncClient)
38
+
39
+
40
+ def test_async_client_unsupported_model(unsupported_model):
41
+ with pytest.raises(NotSupportedError):
42
+ InferenceAPIAsyncClient(unsupported_model)
clients/python/tests/test_types.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pytest
2
+
3
+ from text_generation.types import Parameters, Request
4
+ from text_generation.errors import ValidationError
5
+
6
+
7
+ def test_parameters_validation():
8
+ # Test best_of
9
+ Parameters(best_of=1)
10
+ with pytest.raises(ValidationError):
11
+ Parameters(best_of=0)
12
+ with pytest.raises(ValidationError):
13
+ Parameters(best_of=-1)
14
+ Parameters(best_of=2, do_sample=True)
15
+ with pytest.raises(ValidationError):
16
+ Parameters(best_of=2)
17
+ with pytest.raises(ValidationError):
18
+ Parameters(best_of=2, seed=1)
19
+
20
+ # Test repetition_penalty
21
+ Parameters(repetition_penalty=1)
22
+ with pytest.raises(ValidationError):
23
+ Parameters(repetition_penalty=0)
24
+ with pytest.raises(ValidationError):
25
+ Parameters(repetition_penalty=-1)
26
+
27
+ # Test seed
28
+ Parameters(seed=1)
29
+ with pytest.raises(ValidationError):
30
+ Parameters(seed=-1)
31
+
32
+ # Test temperature
33
+ Parameters(temperature=1)
34
+ with pytest.raises(ValidationError):
35
+ Parameters(temperature=0)
36
+ with pytest.raises(ValidationError):
37
+ Parameters(temperature=-1)
38
+
39
+ # Test top_k
40
+ Parameters(top_k=1)
41
+ with pytest.raises(ValidationError):
42
+ Parameters(top_k=0)
43
+ with pytest.raises(ValidationError):
44
+ Parameters(top_k=-1)
45
+
46
+ # Test top_p
47
+ Parameters(top_p=0.5)
48
+ with pytest.raises(ValidationError):
49
+ Parameters(top_p=0)
50
+ with pytest.raises(ValidationError):
51
+ Parameters(top_p=-1)
52
+ with pytest.raises(ValidationError):
53
+ Parameters(top_p=1)
54
+
55
+ # Test truncate
56
+ Parameters(truncate=1)
57
+ with pytest.raises(ValidationError):
58
+ Parameters(truncate=0)
59
+ with pytest.raises(ValidationError):
60
+ Parameters(truncate=-1)
61
+
62
+ # Test typical_p
63
+ Parameters(typical_p=0.5)
64
+ with pytest.raises(ValidationError):
65
+ Parameters(typical_p=0)
66
+ with pytest.raises(ValidationError):
67
+ Parameters(typical_p=-1)
68
+ with pytest.raises(ValidationError):
69
+ Parameters(typical_p=1)
70
+
71
+
72
+ def test_request_validation():
73
+ Request(inputs="test")
74
+
75
+ with pytest.raises(ValidationError):
76
+ Request(inputs="")
77
+
78
+ Request(inputs="test", stream=True)
79
+ Request(inputs="test", parameters=Parameters(best_of=2, do_sample=True))
80
+
81
+ with pytest.raises(ValidationError):
82
+ Request(
83
+ inputs="test", parameters=Parameters(best_of=2, do_sample=True), stream=True
84
+ )
clients/python/text_generation/__init__.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2023 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ __version__ = "0.3.0"
16
+
17
+ from text_generation.client import Client, AsyncClient
18
+ from text_generation.inference_api import InferenceAPIClient, InferenceAPIAsyncClient
clients/python/text_generation/client.py ADDED
@@ -0,0 +1,481 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import requests
3
+
4
+ from aiohttp import ClientSession, ClientTimeout
5
+ from pydantic import ValidationError
6
+ from typing import Dict, Optional, List, AsyncIterator, Iterator
7
+
8
+ from text_generation.types import (
9
+ StreamResponse,
10
+ Response,
11
+ Request,
12
+ Parameters,
13
+ )
14
+ from text_generation.errors import parse_error
15
+
16
+
17
+ class Client:
18
+ """Client to make calls to a text-generation-inference instance
19
+
20
+ Example:
21
+
22
+ ```python
23
+ >>> from text_generation import Client
24
+
25
+ >>> client = Client("https://api-inference.huggingface.co/models/bigscience/bloomz")
26
+ >>> client.generate("Why is the sky blue?").generated_text
27
+ ' Rayleigh scattering'
28
+
29
+ >>> result = ""
30
+ >>> for response in client.generate_stream("Why is the sky blue?"):
31
+ >>> if not response.token.special:
32
+ >>> result += response.token.text
33
+ >>> result
34
+ ' Rayleigh scattering'
35
+ ```
36
+ """
37
+
38
+ def __init__(
39
+ self,
40
+ base_url: str,
41
+ headers: Optional[Dict[str, str]] = None,
42
+ cookies: Optional[Dict[str, str]] = None,
43
+ timeout: int = 10,
44
+ ):
45
+ """
46
+ Args:
47
+ base_url (`str`):
48
+ text-generation-inference instance base url
49
+ headers (`Optional[Dict[str, str]]`):
50
+ Additional headers
51
+ cookies (`Optional[Dict[str, str]]`):
52
+ Cookies to include in the requests
53
+ timeout (`int`):
54
+ Timeout in seconds
55
+ """
56
+ self.base_url = base_url
57
+ self.headers = headers
58
+ self.cookies = cookies
59
+ self.timeout = timeout
60
+
61
+ def generate(
62
+ self,
63
+ prompt: str,
64
+ do_sample: bool = False,
65
+ max_new_tokens: int = 20,
66
+ best_of: Optional[int] = None,
67
+ repetition_penalty: Optional[float] = None,
68
+ return_full_text: bool = False,
69
+ seed: Optional[int] = None,
70
+ stop_sequences: Optional[List[str]] = None,
71
+ temperature: Optional[float] = None,
72
+ top_k: Optional[int] = None,
73
+ top_p: Optional[float] = None,
74
+ truncate: Optional[int] = None,
75
+ typical_p: Optional[float] = None,
76
+ watermark: bool = False,
77
+ ) -> Response:
78
+ """
79
+ Given a prompt, generate the following text
80
+
81
+ Args:
82
+ prompt (`str`):
83
+ Input text
84
+ do_sample (`bool`):
85
+ Activate logits sampling
86
+ max_new_tokens (`int`):
87
+ Maximum number of generated tokens
88
+ best_of (`int`):
89
+ Generate best_of sequences and return the one if the highest token logprobs
90
+ repetition_penalty (`float`):
91
+ The parameter for repetition penalty. 1.0 means no penalty. See [this
92
+ paper](https://arxiv.org/pdf/1909.05858.pdf) for more details.
93
+ return_full_text (`bool`):
94
+ Whether to prepend the prompt to the generated text
95
+ seed (`int`):
96
+ Random sampling seed
97
+ stop_sequences (`List[str]`):
98
+ Stop generating tokens if a member of `stop_sequences` is generated
99
+ temperature (`float`):
100
+ The value used to module the logits distribution.
101
+ top_k (`int`):
102
+ The number of highest probability vocabulary tokens to keep for top-k-filtering.
103
+ top_p (`float`):
104
+ If set to < 1, only the smallest set of most probable tokens with probabilities that add up to `top_p` or
105
+ higher are kept for generation.
106
+ truncate (`int`):
107
+ Truncate inputs tokens to the given size
108
+ typical_p (`float`):
109
+ Typical Decoding mass
110
+ See [Typical Decoding for Natural Language Generation](https://arxiv.org/abs/2202.00666) for more information
111
+ watermark (`bool`):
112
+ Watermarking with [A Watermark for Large Language Models](https://arxiv.org/abs/2301.10226)
113
+
114
+ Returns:
115
+ Response: generated response
116
+ """
117
+ # Validate parameters
118
+ parameters = Parameters(
119
+ best_of=best_of,
120
+ details=True,
121
+ do_sample=do_sample,
122
+ max_new_tokens=max_new_tokens,
123
+ repetition_penalty=repetition_penalty,
124
+ return_full_text=return_full_text,
125
+ seed=seed,
126
+ stop=stop_sequences if stop_sequences is not None else [],
127
+ temperature=temperature,
128
+ top_k=top_k,
129
+ top_p=top_p,
130
+ truncate=truncate,
131
+ typical_p=typical_p,
132
+ watermark=watermark,
133
+ )
134
+ request = Request(inputs=prompt, stream=False, parameters=parameters)
135
+
136
+ resp = requests.post(
137
+ self.base_url,
138
+ json=request.dict(),
139
+ headers=self.headers,
140
+ cookies=self.cookies,
141
+ timeout=self.timeout,
142
+ )
143
+ payload = resp.json()
144
+ if resp.status_code != 200:
145
+ raise parse_error(resp.status_code, payload)
146
+ return Response(**payload[0])
147
+
148
+ def generate_stream(
149
+ self,
150
+ prompt: str,
151
+ do_sample: bool = False,
152
+ max_new_tokens: int = 20,
153
+ repetition_penalty: Optional[float] = None,
154
+ return_full_text: bool = False,
155
+ seed: Optional[int] = None,
156
+ stop_sequences: Optional[List[str]] = None,
157
+ temperature: Optional[float] = None,
158
+ top_k: Optional[int] = None,
159
+ top_p: Optional[float] = None,
160
+ truncate: Optional[int] = None,
161
+ typical_p: Optional[float] = None,
162
+ watermark: bool = False,
163
+ ) -> Iterator[StreamResponse]:
164
+ """
165
+ Given a prompt, generate the following stream of tokens
166
+
167
+ Args:
168
+ prompt (`str`):
169
+ Input text
170
+ do_sample (`bool`):
171
+ Activate logits sampling
172
+ max_new_tokens (`int`):
173
+ Maximum number of generated tokens
174
+ repetition_penalty (`float`):
175
+ The parameter for repetition penalty. 1.0 means no penalty. See [this
176
+ paper](https://arxiv.org/pdf/1909.05858.pdf) for more details.
177
+ return_full_text (`bool`):
178
+ Whether to prepend the prompt to the generated text
179
+ seed (`int`):
180
+ Random sampling seed
181
+ stop_sequences (`List[str]`):
182
+ Stop generating tokens if a member of `stop_sequences` is generated
183
+ temperature (`float`):
184
+ The value used to module the logits distribution.
185
+ top_k (`int`):
186
+ The number of highest probability vocabulary tokens to keep for top-k-filtering.
187
+ top_p (`float`):
188
+ If set to < 1, only the smallest set of most probable tokens with probabilities that add up to `top_p` or
189
+ higher are kept for generation.
190
+ truncate (`int`):
191
+ Truncate inputs tokens to the given size
192
+ typical_p (`float`):
193
+ Typical Decoding mass
194
+ See [Typical Decoding for Natural Language Generation](https://arxiv.org/abs/2202.00666) for more information
195
+ watermark (`bool`):
196
+ Watermarking with [A Watermark for Large Language Models](https://arxiv.org/abs/2301.10226)
197
+
198
+ Returns:
199
+ Iterator[StreamResponse]: stream of generated tokens
200
+ """
201
+ # Validate parameters
202
+ parameters = Parameters(
203
+ best_of=None,
204
+ details=True,
205
+ do_sample=do_sample,
206
+ max_new_tokens=max_new_tokens,
207
+ repetition_penalty=repetition_penalty,
208
+ return_full_text=return_full_text,
209
+ seed=seed,
210
+ stop=stop_sequences if stop_sequences is not None else [],
211
+ temperature=temperature,
212
+ top_k=top_k,
213
+ top_p=top_p,
214
+ truncate=truncate,
215
+ typical_p=typical_p,
216
+ watermark=watermark,
217
+ )
218
+ request = Request(inputs=prompt, stream=True, parameters=parameters)
219
+
220
+ resp = requests.post(
221
+ self.base_url,
222
+ json=request.dict(),
223
+ headers=self.headers,
224
+ cookies=self.cookies,
225
+ timeout=self.timeout,
226
+ stream=True,
227
+ )
228
+
229
+ if resp.status_code != 200:
230
+ raise parse_error(resp.status_code, resp.json())
231
+
232
+ # Parse ServerSentEvents
233
+ for byte_payload in resp.iter_lines():
234
+ # Skip line
235
+ if byte_payload == b"\n":
236
+ continue
237
+
238
+ payload = byte_payload.decode("utf-8")
239
+
240
+ # Event data
241
+ if payload.startswith("data:"):
242
+ # Decode payload
243
+ json_payload = json.loads(payload.lstrip("data:").rstrip("/n"))
244
+ # Parse payload
245
+ try:
246
+ response = StreamResponse(**json_payload)
247
+ except ValidationError:
248
+ # If we failed to parse the payload, then it is an error payload
249
+ raise parse_error(resp.status_code, json_payload)
250
+ yield response
251
+
252
+
253
+ class AsyncClient:
254
+ """Asynchronous Client to make calls to a text-generation-inference instance
255
+
256
+ Example:
257
+
258
+ ```python
259
+ >>> from text_generation import AsyncClient
260
+
261
+ >>> client = AsyncClient("https://api-inference.huggingface.co/models/bigscience/bloomz")
262
+ >>> response = await client.generate("Why is the sky blue?")
263
+ >>> response.generated_text
264
+ ' Rayleigh scattering'
265
+
266
+ >>> result = ""
267
+ >>> async for response in client.generate_stream("Why is the sky blue?"):
268
+ >>> if not response.token.special:
269
+ >>> result += response.token.text
270
+ >>> result
271
+ ' Rayleigh scattering'
272
+ ```
273
+ """
274
+
275
+ def __init__(
276
+ self,
277
+ base_url: str,
278
+ headers: Optional[Dict[str, str]] = None,
279
+ cookies: Optional[Dict[str, str]] = None,
280
+ timeout: int = 10,
281
+ ):
282
+ """
283
+ Args:
284
+ base_url (`str`):
285
+ text-generation-inference instance base url
286
+ headers (`Optional[Dict[str, str]]`):
287
+ Additional headers
288
+ cookies (`Optional[Dict[str, str]]`):
289
+ Cookies to include in the requests
290
+ timeout (`int`):
291
+ Timeout in seconds
292
+ """
293
+ self.base_url = base_url
294
+ self.headers = headers
295
+ self.cookies = cookies
296
+ self.timeout = ClientTimeout(timeout * 60)
297
+
298
+ async def generate(
299
+ self,
300
+ prompt: str,
301
+ do_sample: bool = False,
302
+ max_new_tokens: int = 20,
303
+ best_of: Optional[int] = None,
304
+ repetition_penalty: Optional[float] = None,
305
+ return_full_text: bool = False,
306
+ seed: Optional[int] = None,
307
+ stop_sequences: Optional[List[str]] = None,
308
+ temperature: Optional[float] = None,
309
+ top_k: Optional[int] = None,
310
+ top_p: Optional[float] = None,
311
+ truncate: Optional[int] = None,
312
+ typical_p: Optional[float] = None,
313
+ watermark: bool = False,
314
+ ) -> Response:
315
+ """
316
+ Given a prompt, generate the following text asynchronously
317
+
318
+ Args:
319
+ prompt (`str`):
320
+ Input text
321
+ do_sample (`bool`):
322
+ Activate logits sampling
323
+ max_new_tokens (`int`):
324
+ Maximum number of generated tokens
325
+ best_of (`int`):
326
+ Generate best_of sequences and return the one if the highest token logprobs
327
+ repetition_penalty (`float`):
328
+ The parameter for repetition penalty. 1.0 means no penalty. See [this
329
+ paper](https://arxiv.org/pdf/1909.05858.pdf) for more details.
330
+ return_full_text (`bool`):
331
+ Whether to prepend the prompt to the generated text
332
+ seed (`int`):
333
+ Random sampling seed
334
+ stop_sequences (`List[str]`):
335
+ Stop generating tokens if a member of `stop_sequences` is generated
336
+ temperature (`float`):
337
+ The value used to module the logits distribution.
338
+ top_k (`int`):
339
+ The number of highest probability vocabulary tokens to keep for top-k-filtering.
340
+ top_p (`float`):
341
+ If set to < 1, only the smallest set of most probable tokens with probabilities that add up to `top_p` or
342
+ higher are kept for generation.
343
+ truncate (`int`):
344
+ Truncate inputs tokens to the given size
345
+ typical_p (`float`):
346
+ Typical Decoding mass
347
+ See [Typical Decoding for Natural Language Generation](https://arxiv.org/abs/2202.00666) for more information
348
+ watermark (`bool`):
349
+ Watermarking with [A Watermark for Large Language Models](https://arxiv.org/abs/2301.10226)
350
+
351
+ Returns:
352
+ Response: generated response
353
+ """
354
+ # Validate parameters
355
+ parameters = Parameters(
356
+ best_of=best_of,
357
+ details=True,
358
+ do_sample=do_sample,
359
+ max_new_tokens=max_new_tokens,
360
+ repetition_penalty=repetition_penalty,
361
+ return_full_text=return_full_text,
362
+ seed=seed,
363
+ stop=stop_sequences if stop_sequences is not None else [],
364
+ temperature=temperature,
365
+ top_k=top_k,
366
+ top_p=top_p,
367
+ truncate=truncate,
368
+ typical_p=typical_p,
369
+ watermark=watermark,
370
+ )
371
+ request = Request(inputs=prompt, stream=False, parameters=parameters)
372
+
373
+ async with ClientSession(
374
+ headers=self.headers, cookies=self.cookies, timeout=self.timeout
375
+ ) as session:
376
+ async with session.post(self.base_url, json=request.dict()) as resp:
377
+ payload = await resp.json()
378
+
379
+ if resp.status != 200:
380
+ raise parse_error(resp.status, payload)
381
+ return Response(**payload[0])
382
+
383
+ async def generate_stream(
384
+ self,
385
+ prompt: str,
386
+ do_sample: bool = False,
387
+ max_new_tokens: int = 20,
388
+ repetition_penalty: Optional[float] = None,
389
+ return_full_text: bool = False,
390
+ seed: Optional[int] = None,
391
+ stop_sequences: Optional[List[str]] = None,
392
+ temperature: Optional[float] = None,
393
+ top_k: Optional[int] = None,
394
+ top_p: Optional[float] = None,
395
+ truncate: Optional[int] = None,
396
+ typical_p: Optional[float] = None,
397
+ watermark: bool = False,
398
+ ) -> AsyncIterator[StreamResponse]:
399
+ """
400
+ Given a prompt, generate the following stream of tokens asynchronously
401
+
402
+ Args:
403
+ prompt (`str`):
404
+ Input text
405
+ do_sample (`bool`):
406
+ Activate logits sampling
407
+ max_new_tokens (`int`):
408
+ Maximum number of generated tokens
409
+ repetition_penalty (`float`):
410
+ The parameter for repetition penalty. 1.0 means no penalty. See [this
411
+ paper](https://arxiv.org/pdf/1909.05858.pdf) for more details.
412
+ return_full_text (`bool`):
413
+ Whether to prepend the prompt to the generated text
414
+ seed (`int`):
415
+ Random sampling seed
416
+ stop_sequences (`List[str]`):
417
+ Stop generating tokens if a member of `stop_sequences` is generated
418
+ temperature (`float`):
419
+ The value used to module the logits distribution.
420
+ top_k (`int`):
421
+ The number of highest probability vocabulary tokens to keep for top-k-filtering.
422
+ top_p (`float`):
423
+ If set to < 1, only the smallest set of most probable tokens with probabilities that add up to `top_p` or
424
+ higher are kept for generation.
425
+ truncate (`int`):
426
+ Truncate inputs tokens to the given size
427
+ typical_p (`float`):
428
+ Typical Decoding mass
429
+ See [Typical Decoding for Natural Language Generation](https://arxiv.org/abs/2202.00666) for more information
430
+ watermark (`bool`):
431
+ Watermarking with [A Watermark for Large Language Models](https://arxiv.org/abs/2301.10226)
432
+
433
+ Returns:
434
+ AsyncIterator[StreamResponse]: stream of generated tokens
435
+ """
436
+ # Validate parameters
437
+ parameters = Parameters(
438
+ best_of=None,
439
+ details=True,
440
+ do_sample=do_sample,
441
+ max_new_tokens=max_new_tokens,
442
+ repetition_penalty=repetition_penalty,
443
+ return_full_text=return_full_text,
444
+ seed=seed,
445
+ stop=stop_sequences if stop_sequences is not None else [],
446
+ temperature=temperature,
447
+ top_k=top_k,
448
+ top_p=top_p,
449
+ truncate=truncate,
450
+ typical_p=typical_p,
451
+ watermark=watermark,
452
+ )
453
+ request = Request(inputs=prompt, stream=True, parameters=parameters)
454
+
455
+ async with ClientSession(
456
+ headers=self.headers, cookies=self.cookies, timeout=self.timeout
457
+ ) as session:
458
+ async with session.post(self.base_url, json=request.dict()) as resp:
459
+
460
+ if resp.status != 200:
461
+ raise parse_error(resp.status, await resp.json())
462
+
463
+ # Parse ServerSentEvents
464
+ async for byte_payload in resp.content:
465
+ # Skip line
466
+ if byte_payload == b"\n":
467
+ continue
468
+
469
+ payload = byte_payload.decode("utf-8")
470
+
471
+ # Event data
472
+ if payload.startswith("data:"):
473
+ # Decode payload
474
+ json_payload = json.loads(payload.lstrip("data:").rstrip("/n"))
475
+ # Parse payload
476
+ try:
477
+ response = StreamResponse(**json_payload)
478
+ except ValidationError:
479
+ # If we failed to parse the payload, then it is an error payload
480
+ raise parse_error(resp.status, json_payload)
481
+ yield response
clients/python/text_generation/errors.py ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Dict
2
+
3
+
4
+ # Text Generation Inference Errors
5
+ class ValidationError(Exception):
6
+ def __init__(self, message: str):
7
+ super().__init__(message)
8
+
9
+
10
+ class GenerationError(Exception):
11
+ def __init__(self, message: str):
12
+ super().__init__(message)
13
+
14
+
15
+ class OverloadedError(Exception):
16
+ def __init__(self, message: str):
17
+ super().__init__(message)
18
+
19
+
20
+ class IncompleteGenerationError(Exception):
21
+ def __init__(self, message: str):
22
+ super().__init__(message)
23
+
24
+
25
+ # API Inference Errors
26
+ class BadRequestError(Exception):
27
+ def __init__(self, message: str):
28
+ super().__init__(message)
29
+
30
+
31
+ class ShardNotReadyError(Exception):
32
+ def __init__(self, message: str):
33
+ super().__init__(message)
34
+
35
+
36
+ class ShardTimeoutError(Exception):
37
+ def __init__(self, message: str):
38
+ super().__init__(message)
39
+
40
+
41
+ class NotFoundError(Exception):
42
+ def __init__(self, message: str):
43
+ super().__init__(message)
44
+
45
+
46
+ class RateLimitExceededError(Exception):
47
+ def __init__(self, message: str):
48
+ super().__init__(message)
49
+
50
+
51
+ class NotSupportedError(Exception):
52
+ def __init__(self, model_id: str):
53
+ message = (
54
+ f"Model `{model_id}` is not available for inference with this client. \n"
55
+ "Use `huggingface_hub.inference_api.InferenceApi` instead."
56
+ )
57
+ super(NotSupportedError, self).__init__(message)
58
+
59
+
60
+ # Unknown error
61
+ class UnknownError(Exception):
62
+ def __init__(self, message: str):
63
+ super().__init__(message)
64
+
65
+
66
+ def parse_error(status_code: int, payload: Dict[str, str]) -> Exception:
67
+ """
68
+ Parse error given an HTTP status code and a json payload
69
+
70
+ Args:
71
+ status_code (`int`):
72
+ HTTP status code
73
+ payload (`Dict[str, str]`):
74
+ Json payload
75
+
76
+ Returns:
77
+ Exception: parsed exception
78
+
79
+ """
80
+ # Try to parse a Text Generation Inference error
81
+ message = payload["error"]
82
+ if "error_type" in payload:
83
+ error_type = payload["error_type"]
84
+ if error_type == "generation":
85
+ return GenerationError(message)
86
+ if error_type == "incomplete_generation":
87
+ return IncompleteGenerationError(message)
88
+ if error_type == "overloaded":
89
+ return OverloadedError(message)
90
+ if error_type == "validation":
91
+ return ValidationError(message)
92
+
93
+ # Try to parse a APIInference error
94
+ if status_code == 400:
95
+ return BadRequestError(message)
96
+ if status_code == 403 or status_code == 424:
97
+ return ShardNotReadyError(message)
98
+ if status_code == 504:
99
+ return ShardTimeoutError(message)
100
+ if status_code == 404:
101
+ return NotFoundError(message)
102
+ if status_code == 429:
103
+ return RateLimitExceededError(message)
104
+
105
+ # Fallback to an unknown error
106
+ return UnknownError(message)
clients/python/text_generation/inference_api.py ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import requests
3
+
4
+ from typing import Dict, Optional, List
5
+ from huggingface_hub.utils import build_hf_headers
6
+
7
+ from text_generation import Client, AsyncClient, __version__
8
+ from text_generation.types import DeployedModel
9
+ from text_generation.errors import NotSupportedError, parse_error
10
+
11
+ INFERENCE_ENDPOINT = os.environ.get(
12
+ "HF_INFERENCE_ENDPOINT", "https://api-inference.huggingface.co"
13
+ )
14
+
15
+
16
+ def deployed_models(headers: Optional[Dict] = None) -> List[DeployedModel]:
17
+ """
18
+ Get all currently deployed models with text-generation-inference-support
19
+
20
+ Returns:
21
+ List[DeployedModel]: list of all currently deployed models
22
+ """
23
+ resp = requests.get(
24
+ f"https://api-inference.huggingface.co/framework/text-generation-inference",
25
+ headers=headers,
26
+ timeout=5,
27
+ )
28
+
29
+ payload = resp.json()
30
+ if resp.status_code != 200:
31
+ raise parse_error(resp.status_code, payload)
32
+
33
+ models = [DeployedModel(**raw_deployed_model) for raw_deployed_model in payload]
34
+ return models
35
+
36
+
37
+ def check_model_support(repo_id: str, headers: Optional[Dict] = None) -> bool:
38
+ """
39
+ Check if a given model is supported by text-generation-inference
40
+
41
+ Returns:
42
+ bool: whether the model is supported by this client
43
+ """
44
+ resp = requests.get(
45
+ f"https://api-inference.huggingface.co/status/{repo_id}",
46
+ headers=headers,
47
+ timeout=5,
48
+ )
49
+
50
+ payload = resp.json()
51
+ if resp.status_code != 200:
52
+ raise parse_error(resp.status_code, payload)
53
+
54
+ framework = payload["framework"]
55
+ supported = framework == "text-generation-inference"
56
+ return supported
57
+
58
+
59
+ class InferenceAPIClient(Client):
60
+ """Client to make calls to the HuggingFace Inference API.
61
+
62
+ Only supports a subset of the available text-generation or text2text-generation models that are served using
63
+ text-generation-inference
64
+
65
+ Example:
66
+
67
+ ```python
68
+ >>> from text_generation import InferenceAPIClient
69
+
70
+ >>> client = InferenceAPIClient("bigscience/bloomz")
71
+ >>> client.generate("Why is the sky blue?").generated_text
72
+ ' Rayleigh scattering'
73
+
74
+ >>> result = ""
75
+ >>> for response in client.generate_stream("Why is the sky blue?"):
76
+ >>> if not response.token.special:
77
+ >>> result += response.token.text
78
+ >>> result
79
+ ' Rayleigh scattering'
80
+ ```
81
+ """
82
+
83
+ def __init__(self, repo_id: str, token: Optional[str] = None, timeout: int = 10):
84
+ """
85
+ Init headers and API information
86
+
87
+ Args:
88
+ repo_id (`str`):
89
+ Id of repository (e.g. `bigscience/bloom`).
90
+ token (`str`, `optional`):
91
+ The API token to use as HTTP bearer authorization. This is not
92
+ the authentication token. You can find the token in
93
+ https://huggingface.co/settings/token. Alternatively, you can
94
+ find both your organizations and personal API tokens using
95
+ `HfApi().whoami(token)`.
96
+ timeout (`int`):
97
+ Timeout in seconds
98
+ """
99
+
100
+ headers = build_hf_headers(
101
+ token=token, library_name="text-generation", library_version=__version__
102
+ )
103
+
104
+ # Text Generation Inference client only supports a subset of the available hub models
105
+ if not check_model_support(repo_id, headers):
106
+ raise NotSupportedError(repo_id)
107
+
108
+ base_url = f"{INFERENCE_ENDPOINT}/models/{repo_id}"
109
+
110
+ super(InferenceAPIClient, self).__init__(
111
+ base_url, headers=headers, timeout=timeout
112
+ )
113
+
114
+
115
+ class InferenceAPIAsyncClient(AsyncClient):
116
+ """Aynschronous Client to make calls to the HuggingFace Inference API.
117
+
118
+ Only supports a subset of the available text-generation or text2text-generation models that are served using
119
+ text-generation-inference
120
+
121
+ Example:
122
+
123
+ ```python
124
+ >>> from text_generation import InferenceAPIAsyncClient
125
+
126
+ >>> client = InferenceAPIAsyncClient("bigscience/bloomz")
127
+ >>> response = await client.generate("Why is the sky blue?")
128
+ >>> response.generated_text
129
+ ' Rayleigh scattering'
130
+
131
+ >>> result = ""
132
+ >>> async for response in client.generate_stream("Why is the sky blue?"):
133
+ >>> if not response.token.special:
134
+ >>> result += response.token.text
135
+ >>> result
136
+ ' Rayleigh scattering'
137
+ ```
138
+ """
139
+
140
+ def __init__(self, repo_id: str, token: Optional[str] = None, timeout: int = 10):
141
+ """
142
+ Init headers and API information
143
+
144
+ Args:
145
+ repo_id (`str`):
146
+ Id of repository (e.g. `bigscience/bloom`).
147
+ token (`str`, `optional`):
148
+ The API token to use as HTTP bearer authorization. This is not
149
+ the authentication token. You can find the token in
150
+ https://huggingface.co/settings/token. Alternatively, you can
151
+ find both your organizations and personal API tokens using
152
+ `HfApi().whoami(token)`.
153
+ timeout (`int`):
154
+ Timeout in seconds
155
+ """
156
+ headers = build_hf_headers(
157
+ token=token, library_name="text-generation", library_version=__version__
158
+ )
159
+
160
+ # Text Generation Inference client only supports a subset of the available hub models
161
+ if not check_model_support(repo_id, headers):
162
+ raise NotSupportedError(repo_id)
163
+
164
+ base_url = f"{INFERENCE_ENDPOINT}/models/{repo_id}"
165
+
166
+ super(InferenceAPIAsyncClient, self).__init__(
167
+ base_url, headers=headers, timeout=timeout
168
+ )
clients/python/text_generation/types.py ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from enum import Enum
2
+ from pydantic import BaseModel, validator
3
+ from typing import Optional, List
4
+
5
+ from text_generation.errors import ValidationError
6
+
7
+
8
+ class Parameters(BaseModel):
9
+ # Activate logits sampling
10
+ do_sample: bool = False
11
+ # Maximum number of generated tokens
12
+ max_new_tokens: int = 20
13
+ # The parameter for repetition penalty. 1.0 means no penalty.
14
+ # See [this paper](https://arxiv.org/pdf/1909.05858.pdf) for more details.
15
+ repetition_penalty: Optional[float] = None
16
+ # Whether to prepend the prompt to the generated text
17
+ return_full_text: bool = False
18
+ # Stop generating tokens if a member of `stop_sequences` is generated
19
+ stop: List[str] = []
20
+ # Random sampling seed
21
+ seed: Optional[int]
22
+ # The value used to module the logits distribution.
23
+ temperature: Optional[float]
24
+ # The number of highest probability vocabulary tokens to keep for top-k-filtering.
25
+ top_k: Optional[int]
26
+ # If set to < 1, only the smallest set of most probable tokens with probabilities that add up to `top_p` or
27
+ # higher are kept for generation.
28
+ top_p: Optional[float]
29
+ # truncate inputs tokens to the given size
30
+ truncate: Optional[int]
31
+ # Typical Decoding mass
32
+ # See [Typical Decoding for Natural Language Generation](https://arxiv.org/abs/2202.00666) for more information
33
+ typical_p: Optional[float]
34
+ # Generate best_of sequences and return the one if the highest token logprobs
35
+ best_of: Optional[int]
36
+ # Watermarking with [A Watermark for Large Language Models](https://arxiv.org/abs/2301.10226)
37
+ watermark: bool = False
38
+ # Get generation details
39
+ details: bool = False
40
+
41
+ @validator("best_of")
42
+ def valid_best_of(cls, field_value, values):
43
+ if field_value is not None:
44
+ if field_value <= 0:
45
+ raise ValidationError("`best_of` must be strictly positive")
46
+ if field_value > 1 and values["seed"] is not None:
47
+ raise ValidationError("`seed` must not be set when `best_of` is > 1")
48
+ sampling = (
49
+ values["do_sample"]
50
+ | (values["temperature"] is not None)
51
+ | (values["top_k"] is not None)
52
+ | (values["top_p"] is not None)
53
+ | (values["typical_p"] is not None)
54
+ )
55
+ if field_value > 1 and not sampling:
56
+ raise ValidationError("you must use sampling when `best_of` is > 1")
57
+
58
+ return field_value
59
+
60
+ @validator("repetition_penalty")
61
+ def valid_repetition_penalty(cls, v):
62
+ if v is not None and v <= 0:
63
+ raise ValidationError("`repetition_penalty` must be strictly positive")
64
+ return v
65
+
66
+ @validator("seed")
67
+ def valid_seed(cls, v):
68
+ if v is not None and v < 0:
69
+ raise ValidationError("`seed` must be positive")
70
+ return v
71
+
72
+ @validator("temperature")
73
+ def valid_temp(cls, v):
74
+ if v is not None and v <= 0:
75
+ raise ValidationError("`temperature` must be strictly positive")
76
+ return v
77
+
78
+ @validator("top_k")
79
+ def valid_top_k(cls, v):
80
+ if v is not None and v <= 0:
81
+ raise ValidationError("`top_k` must be strictly positive")
82
+ return v
83
+
84
+ @validator("top_p")
85
+ def valid_top_p(cls, v):
86
+ if v is not None and (v <= 0 or v >= 1.0):
87
+ raise ValidationError("`top_p` must be > 0.0 and < 1.0")
88
+ return v
89
+
90
+ @validator("truncate")
91
+ def valid_truncate(cls, v):
92
+ if v is not None and v <= 0:
93
+ raise ValidationError("`truncate` must be strictly positive")
94
+ return v
95
+
96
+ @validator("typical_p")
97
+ def valid_typical_p(cls, v):
98
+ if v is not None and (v <= 0 or v >= 1.0):
99
+ raise ValidationError("`typical_p` must be > 0.0 and < 1.0")
100
+ return v
101
+
102
+
103
+ class Request(BaseModel):
104
+ # Prompt
105
+ inputs: str
106
+ # Generation parameters
107
+ parameters: Optional[Parameters]
108
+ # Whether to stream output tokens
109
+ stream: bool = False
110
+
111
+ @validator("inputs")
112
+ def valid_input(cls, v):
113
+ if not v:
114
+ raise ValidationError("`inputs` cannot be empty")
115
+ return v
116
+
117
+ @validator("stream")
118
+ def valid_best_of_stream(cls, field_value, values):
119
+ parameters = values["parameters"]
120
+ if (
121
+ parameters is not None
122
+ and parameters.best_of is not None
123
+ and parameters.best_of > 1
124
+ and field_value
125
+ ):
126
+ raise ValidationError(
127
+ "`best_of` != 1 is not supported when `stream` == True"
128
+ )
129
+ return field_value
130
+
131
+
132
+ # Prompt tokens
133
+ class PrefillToken(BaseModel):
134
+ # Token ID from the model tokenizer
135
+ id: int
136
+ # Token text
137
+ text: str
138
+ # Logprob
139
+ # Optional since the logprob of the first token cannot be computed
140
+ logprob: Optional[float]
141
+
142
+
143
+ # Generated tokens
144
+ class Token(BaseModel):
145
+ # Token ID from the model tokenizer
146
+ id: int
147
+ # Token text
148
+ text: str
149
+ # Logprob
150
+ logprob: float
151
+ # Is the token a special token
152
+ # Can be used to ignore tokens when concatenating
153
+ special: bool
154
+
155
+
156
+ # Generation finish reason
157
+ class FinishReason(Enum):
158
+ # number of generated tokens == `max_new_tokens`
159
+ Length = "length"
160
+ # the model generated its end of sequence token
161
+ EndOfSequenceToken = "eos_token"
162
+ # the model generated a text included in `stop_sequences`
163
+ StopSequence = "stop_sequence"
164
+
165
+
166
+ # Additional sequences when using the `best_of` parameter
167
+ class BestOfSequence(BaseModel):
168
+ # Generated text
169
+ generated_text: str
170
+ # Generation finish reason
171
+ finish_reason: FinishReason
172
+ # Number of generated tokens
173
+ generated_tokens: int
174
+ # Sampling seed if sampling was activated
175
+ seed: Optional[int]
176
+ # Prompt tokens
177
+ prefill: List[PrefillToken]
178
+ # Generated tokens
179
+ tokens: List[Token]
180
+
181
+
182
+ # `generate` details
183
+ class Details(BaseModel):
184
+ # Generation finish reason
185
+ finish_reason: FinishReason
186
+ # Number of generated tokens
187
+ generated_tokens: int
188
+ # Sampling seed if sampling was activated
189
+ seed: Optional[int]
190
+ # Prompt tokens
191
+ prefill: List[PrefillToken]
192
+ # Generated tokens
193
+ tokens: List[Token]
194
+ # Additional sequences when using the `best_of` parameter
195
+ best_of_sequences: Optional[List[BestOfSequence]]
196
+
197
+
198
+ # `generate` return value
199
+ class Response(BaseModel):
200
+ # Generated text
201
+ generated_text: str
202
+ # Generation details
203
+ details: Details
204
+
205
+
206
+ # `generate_stream` details
207
+ class StreamDetails(BaseModel):
208
+ # Generation finish reason
209
+ finish_reason: FinishReason
210
+ # Number of generated tokens
211
+ generated_tokens: int
212
+ # Sampling seed if sampling was activated
213
+ seed: Optional[int]
214
+
215
+
216
+ # `generate_stream` return value
217
+ class StreamResponse(BaseModel):
218
+ # Generated token
219
+ token: Token
220
+ # Complete generated text
221
+ # Only available when the generation is finished
222
+ generated_text: Optional[str]
223
+ # Generation details
224
+ # Only available when the generation is finished
225
+ details: Optional[StreamDetails]
226
+
227
+
228
+ # Inference API currently deployed model
229
+ class DeployedModel(BaseModel):
230
+ model_id: str
231
+ sha: str
docs/index.html ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <html>
2
+ <head>
3
+ <!-- Load the latest Swagger UI code and style from npm using unpkg.com -->
4
+ <script src="https://unpkg.com/swagger-ui-dist@3/swagger-ui-bundle.js"></script>
5
+ <link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@3/swagger-ui.css"/>
6
+ <title>Text Generation Inference API</title>
7
+ </head>
8
+ <body>
9
+ <div id="swagger-ui"></div> <!-- Div to hold the UI component -->
10
+ <script>
11
+ window.onload = function () {
12
+ // Begin Swagger UI call region
13
+ const ui = SwaggerUIBundle({
14
+ url: "openapi.json", //Location of Open API spec in the repo
15
+ dom_id: '#swagger-ui',
16
+ deepLinking: true,
17
+ supportedSubmitMethods: [],
18
+ presets: [
19
+ SwaggerUIBundle.presets.apis,
20
+ SwaggerUIBundle.SwaggerUIStandalonePreset
21
+ ],
22
+ plugins: [
23
+ SwaggerUIBundle.plugins.DownloadUrl
24
+ ],
25
+ })
26
+ window.ui = ui
27
+ }
28
+ </script>
29
+ </body>
30
+ </html>
docs/openapi.json ADDED
@@ -0,0 +1,730 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "openapi": "3.0.3",
3
+ "info": {
4
+ "title": "Text Generation Inference",
5
+ "description": "Text Generation Webserver",
6
+ "contact": {
7
+ "name": "Olivier Dehaene"
8
+ },
9
+ "license": {
10
+ "name": "Apache 2.0",
11
+ "url": "https://www.apache.org/licenses/LICENSE-2.0"
12
+ },
13
+ "version": "0.6.0"
14
+ },
15
+ "paths": {
16
+ "/": {
17
+ "post": {
18
+ "tags": [
19
+ "Text Generation Inference"
20
+ ],
21
+ "summary": "Generate tokens if `stream == false` or a stream of token if `stream == true`",
22
+ "description": "Generate tokens if `stream == false` or a stream of token if `stream == true`",
23
+ "operationId": "compat_generate",
24
+ "requestBody": {
25
+ "content": {
26
+ "application/json": {
27
+ "schema": {
28
+ "$ref": "#/components/schemas/CompatGenerateRequest"
29
+ }
30
+ }
31
+ },
32
+ "required": true
33
+ },
34
+ "responses": {
35
+ "200": {
36
+ "description": "See /generate or /generate_stream"
37
+ },
38
+ "422": {
39
+ "description": "Input validation error",
40
+ "content": {
41
+ "application/json": {
42
+ "schema": {
43
+ "$ref": "#/components/schemas/ErrorResponse"
44
+ },
45
+ "example": {
46
+ "error": "Input validation error"
47
+ }
48
+ }
49
+ }
50
+ },
51
+ "424": {
52
+ "description": "Generation Error",
53
+ "content": {
54
+ "application/json": {
55
+ "schema": {
56
+ "$ref": "#/components/schemas/ErrorResponse"
57
+ },
58
+ "example": {
59
+ "error": "Request failed during generation"
60
+ }
61
+ }
62
+ }
63
+ },
64
+ "429": {
65
+ "description": "Model is overloaded",
66
+ "content": {
67
+ "application/json": {
68
+ "schema": {
69
+ "$ref": "#/components/schemas/ErrorResponse"
70
+ },
71
+ "example": {
72
+ "error": "Model is overloaded"
73
+ }
74
+ }
75
+ }
76
+ },
77
+ "500": {
78
+ "description": "Incomplete generation",
79
+ "content": {
80
+ "application/json": {
81
+ "schema": {
82
+ "$ref": "#/components/schemas/ErrorResponse"
83
+ },
84
+ "example": {
85
+ "error": "Incomplete generation"
86
+ }
87
+ }
88
+ }
89
+ }
90
+ }
91
+ }
92
+ },
93
+ "/generate": {
94
+ "post": {
95
+ "tags": [
96
+ "Text Generation Inference"
97
+ ],
98
+ "summary": "Generate tokens",
99
+ "description": "Generate tokens",
100
+ "operationId": "generate",
101
+ "requestBody": {
102
+ "content": {
103
+ "application/json": {
104
+ "schema": {
105
+ "$ref": "#/components/schemas/GenerateRequest"
106
+ }
107
+ }
108
+ },
109
+ "required": true
110
+ },
111
+ "responses": {
112
+ "200": {
113
+ "description": "Generated Text",
114
+ "content": {
115
+ "application/json": {
116
+ "schema": {
117
+ "$ref": "#/components/schemas/GenerateResponse"
118
+ }
119
+ }
120
+ }
121
+ },
122
+ "422": {
123
+ "description": "Input validation error",
124
+ "content": {
125
+ "application/json": {
126
+ "schema": {
127
+ "$ref": "#/components/schemas/ErrorResponse"
128
+ },
129
+ "example": {
130
+ "error": "Input validation error"
131
+ }
132
+ }
133
+ }
134
+ },
135
+ "424": {
136
+ "description": "Generation Error",
137
+ "content": {
138
+ "application/json": {
139
+ "schema": {
140
+ "$ref": "#/components/schemas/ErrorResponse"
141
+ },
142
+ "example": {
143
+ "error": "Request failed during generation"
144
+ }
145
+ }
146
+ }
147
+ },
148
+ "429": {
149
+ "description": "Model is overloaded",
150
+ "content": {
151
+ "application/json": {
152
+ "schema": {
153
+ "$ref": "#/components/schemas/ErrorResponse"
154
+ },
155
+ "example": {
156
+ "error": "Model is overloaded"
157
+ }
158
+ }
159
+ }
160
+ },
161
+ "500": {
162
+ "description": "Incomplete generation",
163
+ "content": {
164
+ "application/json": {
165
+ "schema": {
166
+ "$ref": "#/components/schemas/ErrorResponse"
167
+ },
168
+ "example": {
169
+ "error": "Incomplete generation"
170
+ }
171
+ }
172
+ }
173
+ }
174
+ }
175
+ }
176
+ },
177
+ "/generate_stream": {
178
+ "post": {
179
+ "tags": [
180
+ "Text Generation Inference"
181
+ ],
182
+ "summary": "Generate a stream of token using Server-Sent Events",
183
+ "description": "Generate a stream of token using Server-Sent Events",
184
+ "operationId": "generate_stream",
185
+ "requestBody": {
186
+ "content": {
187
+ "application/json": {
188
+ "schema": {
189
+ "$ref": "#/components/schemas/GenerateRequest"
190
+ }
191
+ }
192
+ },
193
+ "required": true
194
+ },
195
+ "responses": {
196
+ "200": {
197
+ "description": "Generated Text",
198
+ "content": {
199
+ "text/event-stream": {
200
+ "schema": {
201
+ "$ref": "#/components/schemas/StreamResponse"
202
+ }
203
+ }
204
+ }
205
+ },
206
+ "422": {
207
+ "description": "Input validation error",
208
+ "content": {
209
+ "text/event-stream": {
210
+ "schema": {
211
+ "$ref": "#/components/schemas/ErrorResponse"
212
+ },
213
+ "example": {
214
+ "error": "Input validation error"
215
+ }
216
+ }
217
+ }
218
+ },
219
+ "424": {
220
+ "description": "Generation Error",
221
+ "content": {
222
+ "text/event-stream": {
223
+ "schema": {
224
+ "$ref": "#/components/schemas/ErrorResponse"
225
+ },
226
+ "example": {
227
+ "error": "Request failed during generation"
228
+ }
229
+ }
230
+ }
231
+ },
232
+ "429": {
233
+ "description": "Model is overloaded",
234
+ "content": {
235
+ "text/event-stream": {
236
+ "schema": {
237
+ "$ref": "#/components/schemas/ErrorResponse"
238
+ },
239
+ "example": {
240
+ "error": "Model is overloaded"
241
+ }
242
+ }
243
+ }
244
+ },
245
+ "500": {
246
+ "description": "Incomplete generation",
247
+ "content": {
248
+ "text/event-stream": {
249
+ "schema": {
250
+ "$ref": "#/components/schemas/ErrorResponse"
251
+ },
252
+ "example": {
253
+ "error": "Incomplete generation"
254
+ }
255
+ }
256
+ }
257
+ }
258
+ }
259
+ }
260
+ },
261
+ "/info": {
262
+ "get": {
263
+ "tags": [
264
+ "Text Generation Inference"
265
+ ],
266
+ "summary": "Text Generation Inference endpoint info",
267
+ "description": "Text Generation Inference endpoint info",
268
+ "operationId": "get_model_info",
269
+ "responses": {
270
+ "200": {
271
+ "description": "Served model info",
272
+ "content": {
273
+ "application/json": {
274
+ "schema": {
275
+ "$ref": "#/components/schemas/Info"
276
+ }
277
+ }
278
+ }
279
+ }
280
+ }
281
+ }
282
+ },
283
+ "/metrics": {
284
+ "get": {
285
+ "tags": [
286
+ "Text Generation Inference"
287
+ ],
288
+ "summary": "Prometheus metrics scrape endpoint",
289
+ "description": "Prometheus metrics scrape endpoint",
290
+ "operationId": "metrics",
291
+ "responses": {
292
+ "200": {
293
+ "description": "Prometheus Metrics",
294
+ "content": {
295
+ "text/plain": {
296
+ "schema": {
297
+ "type": "string"
298
+ }
299
+ }
300
+ }
301
+ }
302
+ }
303
+ }
304
+ }
305
+ },
306
+ "components": {
307
+ "schemas": {
308
+ "BestOfSequence": {
309
+ "type": "object",
310
+ "required": [
311
+ "generated_text",
312
+ "finish_reason",
313
+ "generated_tokens",
314
+ "prefill",
315
+ "tokens"
316
+ ],
317
+ "properties": {
318
+ "finish_reason": {
319
+ "$ref": "#/components/schemas/FinishReason"
320
+ },
321
+ "generated_text": {
322
+ "type": "string",
323
+ "example": "test"
324
+ },
325
+ "generated_tokens": {
326
+ "type": "integer",
327
+ "format": "int32",
328
+ "example": 1,
329
+ "minimum": 0.0
330
+ },
331
+ "prefill": {
332
+ "type": "array",
333
+ "items": {
334
+ "$ref": "#/components/schemas/PrefillToken"
335
+ }
336
+ },
337
+ "seed": {
338
+ "type": "integer",
339
+ "format": "int64",
340
+ "example": 42,
341
+ "nullable": true,
342
+ "minimum": 0.0
343
+ },
344
+ "tokens": {
345
+ "type": "array",
346
+ "items": {
347
+ "$ref": "#/components/schemas/Token"
348
+ }
349
+ }
350
+ }
351
+ },
352
+ "CompatGenerateRequest": {
353
+ "type": "object",
354
+ "required": [
355
+ "inputs"
356
+ ],
357
+ "properties": {
358
+ "inputs": {
359
+ "type": "string",
360
+ "example": "My name is Olivier and I"
361
+ },
362
+ "parameters": {
363
+ "$ref": "#/components/schemas/GenerateParameters"
364
+ },
365
+ "stream": {
366
+ "type": "boolean"
367
+ }
368
+ }
369
+ },
370
+ "Details": {
371
+ "type": "object",
372
+ "required": [
373
+ "finish_reason",
374
+ "generated_tokens",
375
+ "prefill",
376
+ "tokens"
377
+ ],
378
+ "properties": {
379
+ "best_of_sequences": {
380
+ "type": "array",
381
+ "items": {
382
+ "$ref": "#/components/schemas/BestOfSequence"
383
+ },
384
+ "nullable": true
385
+ },
386
+ "finish_reason": {
387
+ "$ref": "#/components/schemas/FinishReason"
388
+ },
389
+ "generated_tokens": {
390
+ "type": "integer",
391
+ "format": "int32",
392
+ "example": 1,
393
+ "minimum": 0.0
394
+ },
395
+ "prefill": {
396
+ "type": "array",
397
+ "items": {
398
+ "$ref": "#/components/schemas/PrefillToken"
399
+ }
400
+ },
401
+ "seed": {
402
+ "type": "integer",
403
+ "format": "int64",
404
+ "example": 42,
405
+ "nullable": true,
406
+ "minimum": 0.0
407
+ },
408
+ "tokens": {
409
+ "type": "array",
410
+ "items": {
411
+ "$ref": "#/components/schemas/Token"
412
+ }
413
+ }
414
+ }
415
+ },
416
+ "ErrorResponse": {
417
+ "type": "object",
418
+ "required": [
419
+ "error",
420
+ "error_type"
421
+ ],
422
+ "properties": {
423
+ "error": {
424
+ "type": "string"
425
+ },
426
+ "error_type": {
427
+ "type": "string"
428
+ }
429
+ }
430
+ },
431
+ "FinishReason": {
432
+ "type": "string",
433
+ "enum": [
434
+ "length",
435
+ "eos_token",
436
+ "stop_sequence"
437
+ ]
438
+ },
439
+ "GenerateParameters": {
440
+ "type": "object",
441
+ "properties": {
442
+ "best_of": {
443
+ "type": "integer",
444
+ "default": "null",
445
+ "example": 1,
446
+ "nullable": true,
447
+ "minimum": 0.0,
448
+ "exclusiveMinimum": 0.0
449
+ },
450
+ "details": {
451
+ "type": "boolean",
452
+ "default": "true"
453
+ },
454
+ "do_sample": {
455
+ "type": "boolean",
456
+ "default": "false",
457
+ "example": true
458
+ },
459
+ "max_new_tokens": {
460
+ "type": "integer",
461
+ "format": "int32",
462
+ "default": "20",
463
+ "minimum": 0.0,
464
+ "exclusiveMaximum": 512.0,
465
+ "exclusiveMinimum": 0.0
466
+ },
467
+ "repetition_penalty": {
468
+ "type": "number",
469
+ "format": "float",
470
+ "default": "null",
471
+ "example": 1.03,
472
+ "nullable": true,
473
+ "exclusiveMinimum": 0.0
474
+ },
475
+ "return_full_text": {
476
+ "type": "boolean",
477
+ "default": "null",
478
+ "example": false,
479
+ "nullable": true
480
+ },
481
+ "seed": {
482
+ "type": "integer",
483
+ "format": "int64",
484
+ "default": "null",
485
+ "example": "null",
486
+ "nullable": true,
487
+ "minimum": 0.0,
488
+ "exclusiveMinimum": 0.0
489
+ },
490
+ "stop": {
491
+ "type": "array",
492
+ "items": {
493
+ "type": "string"
494
+ },
495
+ "example": [
496
+ "photographer"
497
+ ],
498
+ "maxItems": 4
499
+ },
500
+ "temperature": {
501
+ "type": "number",
502
+ "format": "float",
503
+ "default": "null",
504
+ "example": 0.5,
505
+ "nullable": true,
506
+ "exclusiveMinimum": 0.0
507
+ },
508
+ "top_k": {
509
+ "type": "integer",
510
+ "format": "int32",
511
+ "default": "null",
512
+ "example": 10,
513
+ "nullable": true,
514
+ "exclusiveMinimum": 0.0
515
+ },
516
+ "top_p": {
517
+ "type": "number",
518
+ "format": "float",
519
+ "default": "null",
520
+ "example": 0.95,
521
+ "nullable": true,
522
+ "maximum": 1.0,
523
+ "exclusiveMinimum": 0.0
524
+ },
525
+ "truncate": {
526
+ "type": "integer",
527
+ "default": "null",
528
+ "example": "null",
529
+ "nullable": true,
530
+ "minimum": 0.0
531
+ },
532
+ "typical_p": {
533
+ "type": "number",
534
+ "format": "float",
535
+ "default": "null",
536
+ "example": 0.95,
537
+ "nullable": true,
538
+ "maximum": 1.0,
539
+ "exclusiveMinimum": 0.0
540
+ },
541
+ "watermark": {
542
+ "type": "boolean",
543
+ "default": "false",
544
+ "example": true
545
+ }
546
+ }
547
+ },
548
+ "GenerateRequest": {
549
+ "type": "object",
550
+ "required": [
551
+ "inputs"
552
+ ],
553
+ "properties": {
554
+ "inputs": {
555
+ "type": "string",
556
+ "example": "My name is Olivier and I"
557
+ },
558
+ "parameters": {
559
+ "$ref": "#/components/schemas/GenerateParameters"
560
+ }
561
+ }
562
+ },
563
+ "GenerateResponse": {
564
+ "type": "object",
565
+ "required": [
566
+ "generated_text"
567
+ ],
568
+ "properties": {
569
+ "details": {
570
+ "allOf": [
571
+ {
572
+ "$ref": "#/components/schemas/Details"
573
+ }
574
+ ],
575
+ "nullable": true
576
+ },
577
+ "generated_text": {
578
+ "type": "string",
579
+ "example": "test"
580
+ }
581
+ }
582
+ },
583
+ "Info": {
584
+ "type": "object",
585
+ "required": [
586
+ "model_id",
587
+ "version"
588
+ ],
589
+ "properties": {
590
+ "model_id": {
591
+ "type": "string",
592
+ "example": "bigscience/blomm-560m"
593
+ },
594
+ "model_pipeline_tag": {
595
+ "type": "string",
596
+ "example": "text-generation",
597
+ "nullable": true
598
+ },
599
+ "model_sha": {
600
+ "type": "string",
601
+ "example": "e985a63cdc139290c5f700ff1929f0b5942cced2",
602
+ "nullable": true
603
+ },
604
+ "sha": {
605
+ "type": "string",
606
+ "example": "null",
607
+ "nullable": true
608
+ },
609
+ "version": {
610
+ "type": "string",
611
+ "example": "0.5.0"
612
+ }
613
+ }
614
+ },
615
+ "PrefillToken": {
616
+ "type": "object",
617
+ "required": [
618
+ "id",
619
+ "text",
620
+ "logprob"
621
+ ],
622
+ "properties": {
623
+ "id": {
624
+ "type": "integer",
625
+ "format": "int32",
626
+ "example": 0,
627
+ "minimum": 0.0
628
+ },
629
+ "logprob": {
630
+ "type": "number",
631
+ "format": "float",
632
+ "example": -0.34,
633
+ "nullable": true
634
+ },
635
+ "text": {
636
+ "type": "string",
637
+ "example": "test"
638
+ }
639
+ }
640
+ },
641
+ "StreamDetails": {
642
+ "type": "object",
643
+ "required": [
644
+ "finish_reason",
645
+ "generated_tokens"
646
+ ],
647
+ "properties": {
648
+ "finish_reason": {
649
+ "$ref": "#/components/schemas/FinishReason"
650
+ },
651
+ "generated_tokens": {
652
+ "type": "integer",
653
+ "format": "int32",
654
+ "example": 1,
655
+ "minimum": 0.0
656
+ },
657
+ "seed": {
658
+ "type": "integer",
659
+ "format": "int64",
660
+ "example": 42,
661
+ "nullable": true,
662
+ "minimum": 0.0
663
+ }
664
+ }
665
+ },
666
+ "StreamResponse": {
667
+ "type": "object",
668
+ "required": [
669
+ "token"
670
+ ],
671
+ "properties": {
672
+ "details": {
673
+ "allOf": [
674
+ {
675
+ "$ref": "#/components/schemas/StreamDetails"
676
+ }
677
+ ],
678
+ "nullable": true
679
+ },
680
+ "generated_text": {
681
+ "type": "string",
682
+ "default": "null",
683
+ "example": "test",
684
+ "nullable": true
685
+ },
686
+ "token": {
687
+ "$ref": "#/components/schemas/Token"
688
+ }
689
+ }
690
+ },
691
+ "Token": {
692
+ "type": "object",
693
+ "required": [
694
+ "id",
695
+ "text",
696
+ "logprob",
697
+ "special"
698
+ ],
699
+ "properties": {
700
+ "id": {
701
+ "type": "integer",
702
+ "format": "int32",
703
+ "example": 0,
704
+ "minimum": 0.0
705
+ },
706
+ "logprob": {
707
+ "type": "number",
708
+ "format": "float",
709
+ "example": -0.34,
710
+ "nullable": true
711
+ },
712
+ "special": {
713
+ "type": "boolean",
714
+ "example": "false"
715
+ },
716
+ "text": {
717
+ "type": "string",
718
+ "example": "test"
719
+ }
720
+ }
721
+ }
722
+ }
723
+ },
724
+ "tags": [
725
+ {
726
+ "name": "Text Generation Inference",
727
+ "description": "Hugging Face Text Generation Inference API"
728
+ }
729
+ ]
730
+ }
k6/load_test.js ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import http from 'k6/http';
2
+ import {check, sleep} from 'k6';
3
+
4
+ export const options = {
5
+ stages: [
6
+ {duration: '1m', target: 50},
7
+ {duration: '2m', target: 100},
8
+ {duration: '1m', target: 0},
9
+ ],
10
+ hosts: {
11
+ 'text-generation-inference.huggingface.co': '127.0.0.1:3000',
12
+ },
13
+ };
14
+ const SLEEP_DURATION = 1;
15
+
16
+ function greedy_example(inputs, max_new_tokens, name) {
17
+ let body = JSON.stringify({
18
+ inputs: inputs,
19
+ parameters: {
20
+ max_new_tokens: max_new_tokens,
21
+ do_sample: false,
22
+ }
23
+ });
24
+ let params = {
25
+ headers: {
26
+ 'Content-Type': 'application/json',
27
+ },
28
+ tags: {
29
+ name: name
30
+ }
31
+ };
32
+ return http.post('http://text-generation-inference.huggingface.co/generate', body, params);
33
+ }
34
+
35
+ function sample_example(inputs, max_new_tokens, name) {
36
+ let body = JSON.stringify({
37
+ inputs: inputs,
38
+ parameters: {
39
+ max_new_tokens: max_new_tokens,
40
+ do_sample: true,
41
+ top_p: 0.9,
42
+ seed: 0
43
+ }
44
+ });
45
+ let params = {
46
+ headers: {
47
+ 'Content-Type': 'application/json',
48
+ },
49
+ tags: {
50
+ name: name
51
+ }
52
+ };
53
+ return http.post('http://text-generation-inference.huggingface.co/generate', body, params);
54
+ }
55
+
56
+ export default function () {
57
+ const response_1 = sample_example('A "whatpu" is a small, furry animal native to Tanzania. An example of a sentence that uses the word whatpu is: We were traveling in Africa and we saw these very cute whatpus. To do a "farduddle" means to jump up and down really fast. An example of a sentence that uses the word farduddle is:', 32, 'example-1');
58
+ check(response_1, {
59
+ 'is status 200': (r) => r.status === 200,
60
+ });
61
+ sleep(SLEEP_DURATION);
62
+
63
+ const response_2 = sample_example("A poem about the beauty of science by Alfred Edgar Brittle\\nTitle: The Magic Craft\\nIn the old times", 50, "example-2");
64
+ check(response_2, {
65
+ 'is status 200': (r) => r.status === 200,
66
+ });
67
+ sleep(SLEEP_DURATION);
68
+
69
+ const response_3 = greedy_example("استخراج العدد العاملي في لغة بايثون: ", 30, "example-3");
70
+ check(response_3, {
71
+ 'is status 200': (r) => r.status === 200,
72
+ });
73
+ sleep(SLEEP_DURATION);
74
+
75
+ const response_4 = sample_example("Pour déguster un ortolan, il faut tout d'abord", 32, "example-4");
76
+ check(response_4, {
77
+ 'is status 200': (r) => r.status === 200,
78
+ });
79
+ sleep(SLEEP_DURATION);
80
+
81
+ const response_5 = sample_example("Traduce español de España a español de Argentina\nEl coche es rojo - el auto es rojo\nEl ordenador es nuevo - la computadora es nueva\nel boligrafo es negro -", 16, "example-5");
82
+ check(response_5, {
83
+ 'is status 200': (r) => r.status === 200,
84
+ });
85
+ sleep(SLEEP_DURATION);
86
+
87
+ const response_6 = sample_example("Question: If I put cheese into the fridge, will it melt?\nAnswer:", 32, "example-6");
88
+ check(response_6, {
89
+ 'is status 200': (r) => r.status === 200,
90
+ });
91
+ sleep(SLEEP_DURATION);
92
+
93
+ const response_7 = greedy_example("Question: Where does the Greek Goddess Persephone spend half of the year when she is not with her mother?\nAnswer:", 24, "example-7");
94
+ check(response_7, {
95
+ 'is status 200': (r) => r.status === 200,
96
+ });
97
+ sleep(SLEEP_DURATION);
98
+ }
launcher/Cargo.toml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ name = "text-generation-launcher"
3
+ version = "0.6.0"
4
+ edition = "2021"
5
+ authors = ["Olivier Dehaene"]
6
+ description = "Text Generation Launcher"
7
+
8
+ [dependencies]
9
+ clap = { version = "4.1.4", features = ["derive", "env"] }
10
+ ctrlc = { version = "3.2.5", features = ["termination"] }
11
+ serde = { version = "1.0.152", features = ["derive"] }
12
+ serde_json = "1.0.93"
13
+ subprocess = "0.2.9"
14
+ tracing = "0.1.37"
15
+ tracing-subscriber = { version = "0.3.16", features = ["json"] }
16
+
17
+ [dev-dependencies]
18
+ float_eq = "1.0.1"
19
+ reqwest = { version = "0.11.14", features = ["blocking", "json"] }
20
+
21
+ [build-dependencies]
22
+ vergen = { version = "8.0.0", features = ["build", "cargo", "git", "gitcl", "rustc", "si"] }
launcher/build.rs ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ use std::error::Error;
2
+ use vergen::EmitBuilder;
3
+
4
+ fn main() -> Result<(), Box<dyn Error>> {
5
+ // Emit cargo and rustc compile time values
6
+ EmitBuilder::builder().all_cargo().all_rustc().emit()?;
7
+
8
+ // Try to get the git sha from the local git repository
9
+ if EmitBuilder::builder()
10
+ .fail_on_error()
11
+ .git_sha(false)
12
+ .emit()
13
+ .is_err()
14
+ {
15
+ // Unable to get the git sha
16
+ if let Ok(sha) = std::env::var("GIT_SHA") {
17
+ // Set it from an env var
18
+ println!("cargo:rustc-env=VERGEN_GIT_SHA={sha}");
19
+ }
20
+ }
21
+
22
+ // Set docker label if present
23
+ if let Ok(label) = std::env::var("DOCKER_LABEL") {
24
+ // Set it from an env var
25
+ println!("cargo:rustc-env=DOCKER_LABEL={label}");
26
+ }
27
+
28
+ Ok(())
29
+ }
launcher/src/env_runtime.rs ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ use std::fmt;
2
+ use std::process::Command;
3
+
4
+ pub(crate) struct Env {
5
+ cargo_target: &'static str,
6
+ cargo_version: &'static str,
7
+ git_sha: &'static str,
8
+ docker_label: &'static str,
9
+ nvidia_env: String,
10
+ }
11
+
12
+ impl Env {
13
+ pub fn new() -> Self {
14
+ let nvidia_env = nvidia_smi();
15
+
16
+ Self {
17
+ nvidia_env: nvidia_env.unwrap_or("N/A".to_string()),
18
+ cargo_target: env!("VERGEN_CARGO_TARGET_TRIPLE"),
19
+ cargo_version: env!("VERGEN_RUSTC_SEMVER"),
20
+ git_sha: option_env!("VERGEN_GIT_SHA").unwrap_or("N/A"),
21
+ docker_label: option_env!("DOCKER_LABEL").unwrap_or("N/A"),
22
+ }
23
+ }
24
+ }
25
+
26
+ impl fmt::Display for Env {
27
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
28
+ writeln!(f, "Runtime environment:")?;
29
+
30
+ writeln!(f, "Target: {}", self.cargo_target)?;
31
+ writeln!(f, "Cargo version: {}", self.cargo_version)?;
32
+ writeln!(f, "Commit sha: {}", self.git_sha)?;
33
+ writeln!(f, "Docker label: {}", self.docker_label)?;
34
+ write!(f, "nvidia-smi:\n{}", self.nvidia_env)?;
35
+
36
+ Ok(())
37
+ }
38
+ }
39
+
40
+ fn nvidia_smi() -> Option<String> {
41
+ let output = Command::new("nvidia-smi").output().ok()?;
42
+ let nvidia_smi = String::from_utf8(output.stdout).ok()?;
43
+ let output = nvidia_smi.replace('\n', "\n ");
44
+ Some(output.trim().to_string())
45
+ }
launcher/src/main.rs ADDED
@@ -0,0 +1,925 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ use clap::Parser;
2
+ use serde::Deserialize;
3
+ use std::env;
4
+ use std::ffi::OsString;
5
+ use std::io::{BufRead, BufReader, Read};
6
+ use std::path::Path;
7
+ use std::sync::atomic::{AtomicBool, Ordering};
8
+ use std::sync::mpsc::TryRecvError;
9
+ use std::sync::Arc;
10
+ use std::sync::{mpsc, Mutex};
11
+ use std::thread;
12
+ use std::thread::sleep;
13
+ use std::time::{Duration, Instant};
14
+ use std::{fs, io};
15
+ use subprocess::{ExitStatus, Popen, PopenConfig, PopenError, Redirection};
16
+
17
+ mod env_runtime;
18
+
19
+ /// App Configuration
20
+ #[derive(Parser, Debug)]
21
+ #[clap(author, version, about, long_about = None)]
22
+ struct Args {
23
+ /// The name of the model to load.
24
+ /// Can be a MODEL_ID as listed on <https://hf.co/models> like
25
+ /// `gpt2` or `OpenAssistant/oasst-sft-1-pythia-12b`.
26
+ /// Or it can be a local directory containing the necessary files
27
+ /// as saved by `save_pretrained(...)` methods of transformers
28
+ #[clap(default_value = "bigscience/bloom-560m", long, env)]
29
+ model_id: String,
30
+
31
+ /// The actual revision of the model if you're referring to a model
32
+ /// on the hub. You can use a specific commit id or a branch like `refs/pr/2`.
33
+ #[clap(long, env)]
34
+ revision: Option<String>,
35
+
36
+ /// Wether to shard or not the model across multiple GPUs
37
+ /// By default text-generation-inference will use all available GPUs to run
38
+ /// the model. Setting it to `false` deactivates `num_shard`.
39
+ #[clap(long, env)]
40
+ sharded: Option<bool>,
41
+
42
+ /// The number of shards to use if you don't want to use all GPUs on a given machine.
43
+ /// You can use `CUDA_VISIBLE_DEVICE=0,1 text-generation-launcher... --num_shard 2`
44
+ /// and `CUDA_VISIBLE_DEVICE=2,3 text-generation-launcher... --num_shard 2` to
45
+ /// launch 2 copies with 2 shard each on a given machine with 4 GPUs for instance.
46
+ #[clap(long, env)]
47
+ num_shard: Option<usize>,
48
+
49
+ /// Wether you want the model to be quantized or not. This will use bitsandbytes for
50
+ /// quantization on the fly.
51
+ #[clap(long, env)]
52
+ quantize: bool,
53
+
54
+ /// The maximum amount of concurrent requests for this particular deployment.
55
+ /// Having a low limit will refuse clients requests instead of having them
56
+ /// wait for too long and is usually good to handle backpressure correctly.
57
+ #[clap(default_value = "128", long, env)]
58
+ max_concurrent_requests: usize,
59
+
60
+ /// This is the maximum allowed value for clients to set `best_of`.
61
+ /// Best of makes `n` generations at the same time, and return the best
62
+ /// in terms of overall log probability over the entire generated sequence
63
+ #[clap(default_value = "2", long, env)]
64
+ max_best_of: usize,
65
+
66
+ /// This is the maximum allowed value for clients to set `stop_sequences`.
67
+ /// Stop sequences are used to allow the model to stop on more than just
68
+ /// the EOS token, and enable more complex "prompting" where users can preprompt
69
+ /// the model in a specific way and define their "own" stop token aligned with
70
+ /// their prompt.
71
+ #[clap(default_value = "4", long, env)]
72
+ max_stop_sequences: usize,
73
+
74
+ /// This is the maximum allowed input length (expressed in number of tokens)
75
+ /// for users. The larger this value, the longer prompt users can send which
76
+ /// can impact the overall memory required to handle the load.
77
+ /// Please note that some models have a finite range of sequence they can handle.
78
+ #[clap(default_value = "1000", long, env)]
79
+ max_input_length: usize,
80
+
81
+ /// This is the most important value to set as it defines the "memory budget"
82
+ /// of running clients requests.
83
+ /// Clients will send input sequences and ask to generate `max_new_tokens`
84
+ /// on top. with a value of `1512` users can send either a prompt of
85
+ /// `1000` and ask for `512` new tokens, or send a prompt of `1` and ask for
86
+ /// `1511` max_new_tokens.
87
+ /// The larger this value, the larger amount each request will be in your RAM
88
+ /// and the less effective batching can be.
89
+ #[clap(default_value = "1512", long, env)]
90
+ max_total_tokens: usize,
91
+
92
+ /// The maximum allowed batch size during dynamic batching.
93
+ /// Using `max_batch_total_tokens` should be favored in general
94
+ /// as it's a finer way to control RAM usage.
95
+ #[clap(long, env)]
96
+ max_batch_size: Option<usize>,
97
+
98
+ /// This represents the ratio of waiting queries vs running queries where
99
+ /// you want to start considering pausing the running queries to include the waiting
100
+ /// ones into the same batch.
101
+ /// `waiting_served_ratio=1.2` Means when 12 queries are waiting and there's
102
+ /// only 10 queries left in the current batch we check if we can fit those 12
103
+ /// waiting queries into the batching strategy, and if yes, then batching happens
104
+ /// delaying the 10 running queries by a `prefill` run.
105
+ ///
106
+ /// This setting is only applied if there is room in the batch
107
+ /// as defined by `max_batch_total_tokens`.
108
+ #[clap(default_value = "1.2", long, env)]
109
+ waiting_served_ratio: f32,
110
+
111
+ /// **IMPORTANT** This is one critical control to allow maximum usage
112
+ /// of the available hardware.
113
+ ///
114
+ /// This represents the total amount of potential tokens within a batch.
115
+ /// When using padding (not recommended) this would be equivalent of
116
+ /// `batch_size` * `max_total_tokens`.
117
+ ///
118
+ /// However in the non-padded (flash attention) version this can be much finer.
119
+ ///
120
+ /// For `max_batch_total_tokens=1000`, you could fit `10` queries of `total_tokens=100`
121
+ /// or a single query of `1000` tokens.
122
+ ///
123
+ /// So you don't have to control that finely
124
+ /// `max_batch_size` or `max_total_tokens`. In fact you could mostly relax them if you
125
+ /// want maximum flexibility. However, for your users if they are asking for the full amount of
126
+ /// total tokens, they are likely to wait for a very long time to get a spot
127
+ /// in the batch (since they are going to be alone) so setting `max_batch_size`
128
+ /// and `max_total_tokens` can still be useful to prevent those long waiting times.
129
+ ///
130
+ /// Overall this number should be the largest possible amount that fits the
131
+ /// remaining memory (after the model is loaded). Since the actual memory overhead
132
+ /// depends on other parameters like if you're using quantization, flash attention
133
+ /// or the model implementation, text-generation-inference cannot infer this number
134
+ /// automatically.
135
+ #[clap(default_value = "32000", long, env)]
136
+ max_batch_total_tokens: u32,
137
+
138
+ /// This setting defines how many tokens can be passed before forcing the waiting
139
+ /// queries to be put on the batch (if the size of the batch allows for it).
140
+ /// New queries require 1 `prefill` forward, which is different from `decode`
141
+ /// and therefore you need to pause the running batch in order to run `prefill`
142
+ /// to create the correct values for the waiting queries to be able to join the batch.
143
+ ///
144
+ /// With a value too small, queries will always "steal" the compute to run `prefill`
145
+ /// and running queries will be delayed by a lot.
146
+ ///
147
+ /// With a value too big, waiting queries could wait for a very long time
148
+ /// before being allowed a slot in the running batch. If your server is busy
149
+ /// that means that requests that could run in ~2s on an empty server could
150
+ /// end up running in ~20s because the query had to wait for 18s.
151
+ ///
152
+ /// This number is expressed in number of tokens to make it a bit more
153
+ /// "model" agnostic, but what should really matter is the overall latency
154
+ /// for end users.
155
+ #[clap(default_value = "20", long, env)]
156
+ max_waiting_tokens: usize,
157
+ #[clap(default_value = "3000", long, short, env)]
158
+
159
+ /// The port to listen on.
160
+ port: u16,
161
+
162
+ /// The name of the socket for gRPC communication between the webserver
163
+ /// and the shards.
164
+ #[clap(default_value = "/tmp/text-generation-server", long, env)]
165
+ shard_uds_path: String,
166
+
167
+ /// The address the master shard will listen on. (setting used by torch distributed)
168
+ #[clap(default_value = "localhost", long, env)]
169
+ master_addr: String,
170
+
171
+ /// The address the master port will listen on. (setting used by torch distributed)
172
+ #[clap(default_value = "29500", long, env)]
173
+ master_port: usize,
174
+
175
+ /// The location of the huggingface hub cache.
176
+ /// Used to override the location if you want to provide a mounted disk for instance
177
+ #[clap(long, env)]
178
+ huggingface_hub_cache: Option<String>,
179
+
180
+ /// The location of the huggingface hub cache.
181
+ /// Used to override the location if you want to provide a mounted disk for instance
182
+ #[clap(long, env)]
183
+ weights_cache_override: Option<String>,
184
+
185
+ /// For some models (like bloom), text-generation-inference implemented custom
186
+ /// cuda kernels to speed up inference. Those kernels were only tested on A100.
187
+ /// Use this flag to disable them if you're running on different hardware and
188
+ /// encounter issues.
189
+ #[clap(long, env)]
190
+ disable_custom_kernels: bool,
191
+
192
+ /// Outputs the logs in JSON format (useful for telemetry)
193
+ #[clap(long, env)]
194
+ json_output: bool,
195
+
196
+ #[clap(long, env)]
197
+ otlp_endpoint: Option<String>,
198
+
199
+ #[clap(long, env)]
200
+ cors_allow_origin: Vec<String>,
201
+ #[clap(long, env)]
202
+ watermark_gamma: Option<f32>,
203
+ #[clap(long, env)]
204
+ watermark_delta: Option<f32>,
205
+
206
+ /// Display a lot of information about your runtime environment
207
+ #[clap(long, short, action)]
208
+ env: bool,
209
+ }
210
+
211
+ #[derive(Debug)]
212
+ enum ShardStatus {
213
+ Ready,
214
+ Failed((usize, String)),
215
+ }
216
+
217
+ #[allow(clippy::too_many_arguments)]
218
+ fn shard_manager(
219
+ model_id: String,
220
+ revision: Option<String>,
221
+ quantize: bool,
222
+ uds_path: String,
223
+ rank: usize,
224
+ world_size: usize,
225
+ master_addr: String,
226
+ master_port: usize,
227
+ huggingface_hub_cache: Option<String>,
228
+ weights_cache_override: Option<String>,
229
+ disable_custom_kernels: bool,
230
+ watermark_gamma: Option<f32>,
231
+ watermark_delta: Option<f32>,
232
+ otlp_endpoint: Option<String>,
233
+ status_sender: mpsc::Sender<ShardStatus>,
234
+ shutdown: Arc<Mutex<bool>>,
235
+ _shutdown_sender: mpsc::Sender<()>,
236
+ ) {
237
+ // Get UDS path
238
+ let uds_string = format!("{uds_path}-{rank}");
239
+ let uds = Path::new(&uds_string);
240
+ // Clean previous runs
241
+ fs::remove_file(uds).unwrap_or_default();
242
+
243
+ // Process args
244
+ let mut shard_argv = vec![
245
+ "text-generation-server".to_string(),
246
+ "serve".to_string(),
247
+ model_id,
248
+ "--uds-path".to_string(),
249
+ uds_path,
250
+ "--logger-level".to_string(),
251
+ "INFO".to_string(),
252
+ "--json-output".to_string(),
253
+ ];
254
+
255
+ // Activate tensor parallelism
256
+ if world_size > 1 {
257
+ shard_argv.push("--sharded".to_string());
258
+ }
259
+
260
+ if quantize {
261
+ shard_argv.push("--quantize".to_string())
262
+ }
263
+
264
+ // Model optional revision
265
+ if let Some(revision) = revision {
266
+ shard_argv.push("--revision".to_string());
267
+ shard_argv.push(revision)
268
+ }
269
+
270
+ // OpenTelemetry
271
+ if let Some(otlp_endpoint) = otlp_endpoint {
272
+ shard_argv.push("--otlp-endpoint".to_string());
273
+ shard_argv.push(otlp_endpoint);
274
+ }
275
+
276
+ // Copy current process env
277
+ let mut env: Vec<(OsString, OsString)> = env::vars_os().collect();
278
+
279
+ // Torch Distributed Env vars
280
+ env.push(("RANK".into(), rank.to_string().into()));
281
+ env.push(("WORLD_SIZE".into(), world_size.to_string().into()));
282
+ env.push(("MASTER_ADDR".into(), master_addr.into()));
283
+ env.push(("MASTER_PORT".into(), master_port.to_string().into()));
284
+ env.push(("NCCL_ASYNC_ERROR_HANDLING".into(), "1".into()));
285
+
286
+ // Safetensors load fast
287
+ env.push(("SAFETENSORS_FAST_GPU".into(), "1".into()));
288
+
289
+ // Enable hf transfer for insane download speeds
290
+ let enable_hf_transfer = env::var("HF_HUB_ENABLE_HF_TRANSFER").unwrap_or("1".to_string());
291
+ env.push((
292
+ "HF_HUB_ENABLE_HF_TRANSFER".into(),
293
+ enable_hf_transfer.into(),
294
+ ));
295
+
296
+ // Parse Inference API token
297
+ if let Ok(api_token) = env::var("HF_API_TOKEN") {
298
+ env.push(("HUGGING_FACE_HUB_TOKEN".into(), api_token.into()))
299
+ };
300
+
301
+ // If huggingface_hub_cache is some, pass it to the shard
302
+ // Useful when running inside a docker container
303
+ if let Some(huggingface_hub_cache) = huggingface_hub_cache {
304
+ env.push(("HUGGINGFACE_HUB_CACHE".into(), huggingface_hub_cache.into()));
305
+ };
306
+
307
+ // If weights_cache_override is some, pass it to the shard
308
+ // Useful when running inside a HuggingFace Inference Endpoint
309
+ if let Some(weights_cache_override) = weights_cache_override {
310
+ env.push((
311
+ "WEIGHTS_CACHE_OVERRIDE".into(),
312
+ weights_cache_override.into(),
313
+ ));
314
+ };
315
+
316
+ // If disable_custom_kernels is true, pass it to the shard as an env var
317
+ if disable_custom_kernels {
318
+ env.push(("DISABLE_CUSTOM_KERNELS".into(), "True".into()))
319
+ }
320
+
321
+ // Watermark Gamma
322
+ if let Some(watermark_gamma) = watermark_gamma {
323
+ env.push(("WATERMARK_GAMMA".into(), watermark_gamma.to_string().into()))
324
+ }
325
+
326
+ // Watermark Delta
327
+ if let Some(watermark_delta) = watermark_delta {
328
+ env.push(("WATERMARK_DELTA".into(), watermark_delta.to_string().into()))
329
+ }
330
+
331
+ // Start process
332
+ tracing::info!("Starting shard {rank}");
333
+ let mut p = match Popen::create(
334
+ &shard_argv,
335
+ PopenConfig {
336
+ stdout: Redirection::Pipe,
337
+ stderr: Redirection::Pipe,
338
+ // Needed for the shutdown procedure
339
+ setpgid: true,
340
+ // NCCL env vars
341
+ env: Some(env),
342
+ ..Default::default()
343
+ },
344
+ ) {
345
+ Ok(p) => p,
346
+ Err(err) => {
347
+ if let PopenError::IoError(ref err) = err {
348
+ if err.kind() == io::ErrorKind::NotFound {
349
+ tracing::error!("text-generation-server not found in PATH");
350
+ tracing::error!("Please install it with `make install-server`")
351
+ }
352
+ }
353
+ status_sender
354
+ .send(ShardStatus::Failed((rank, err.to_string())))
355
+ .unwrap();
356
+ return;
357
+ }
358
+ };
359
+
360
+ // Redirect STDOUT to the console
361
+ let shard_stdout = p.stdout.take().unwrap();
362
+
363
+ thread::spawn(move || {
364
+ // Enter shard-manager tracing span
365
+ let stdout = BufReader::new(shard_stdout);
366
+ let _span = tracing::span!(tracing::Level::INFO, "shard-manager", rank = rank).entered();
367
+ for line in stdout.lines() {
368
+ // Parse loguru logs
369
+ if let Ok(log) = serde_json::from_str::<PythonLogMessage>(&line.unwrap()) {
370
+ log.trace();
371
+ }
372
+ }
373
+ });
374
+
375
+ let mut ready = false;
376
+ let start_time = Instant::now();
377
+ let mut wait_time = Instant::now();
378
+ loop {
379
+ // Process exited
380
+ if p.poll().is_some() {
381
+ let mut err = String::new();
382
+ p.stderr.take().unwrap().read_to_string(&mut err).unwrap();
383
+ status_sender
384
+ .send(ShardStatus::Failed((rank, err)))
385
+ .unwrap();
386
+ return;
387
+ }
388
+
389
+ // We received a shutdown signal
390
+ if *shutdown.lock().unwrap() {
391
+ p.terminate().unwrap();
392
+ let _ = p.wait_timeout(Duration::from_secs(90));
393
+ tracing::info!("Shard {rank} terminated");
394
+ return;
395
+ }
396
+
397
+ // Shard is ready
398
+ if uds.exists() && !ready {
399
+ tracing::info!("Shard {rank} ready in {:?}", start_time.elapsed());
400
+ status_sender.send(ShardStatus::Ready).unwrap();
401
+ ready = true;
402
+ } else if !ready && wait_time.elapsed() > Duration::from_secs(10) {
403
+ tracing::info!("Waiting for shard {rank} to be ready...");
404
+ wait_time = Instant::now();
405
+ }
406
+ sleep(Duration::from_millis(100));
407
+ }
408
+ }
409
+
410
+ fn shutdown_shards(shutdown: Arc<Mutex<bool>>, shutdown_receiver: &mpsc::Receiver<()>) {
411
+ tracing::info!("Shutting down shards");
412
+ // Update shutdown value to true
413
+ // This will be picked up by the shard manager
414
+ {
415
+ let mut shutdown = shutdown.lock().unwrap();
416
+ *shutdown = true;
417
+ }
418
+
419
+ // Wait for shards to shutdown
420
+ // This will block till all shutdown_sender are dropped
421
+ let _ = shutdown_receiver.recv();
422
+ }
423
+
424
+ fn num_cuda_devices() -> Option<usize> {
425
+ if let Ok(cuda_visible_devices) = env::var("CUDA_VISIBLE_DEVICES") {
426
+ let n_devices = cuda_visible_devices.split(',').count();
427
+ return Some(n_devices);
428
+ }
429
+ None
430
+ }
431
+
432
+ #[derive(Deserialize)]
433
+ #[serde(rename_all = "UPPERCASE")]
434
+ enum PythonLogLevelEnum {
435
+ Trace,
436
+ Debug,
437
+ Info,
438
+ Success,
439
+ Warning,
440
+ Error,
441
+ Critical,
442
+ }
443
+
444
+ #[derive(Deserialize)]
445
+ struct PythonLogLevel {
446
+ name: PythonLogLevelEnum,
447
+ }
448
+
449
+ #[derive(Deserialize)]
450
+ struct PythonLogRecord {
451
+ level: PythonLogLevel,
452
+ }
453
+
454
+ #[derive(Deserialize)]
455
+ struct PythonLogMessage {
456
+ text: String,
457
+ record: PythonLogRecord,
458
+ }
459
+
460
+ impl PythonLogMessage {
461
+ fn trace(&self) {
462
+ match self.record.level.name {
463
+ PythonLogLevelEnum::Trace => tracing::trace!("{}", self.text),
464
+ PythonLogLevelEnum::Debug => tracing::debug!("{}", self.text),
465
+ PythonLogLevelEnum::Info => tracing::info!("{}", self.text),
466
+ PythonLogLevelEnum::Success => tracing::info!("{}", self.text),
467
+ PythonLogLevelEnum::Warning => tracing::warn!("{}", self.text),
468
+ PythonLogLevelEnum::Error => tracing::error!("{}", self.text),
469
+ PythonLogLevelEnum::Critical => tracing::error!("{}", self.text),
470
+ }
471
+ }
472
+ }
473
+
474
+ fn find_num_shards(sharded: Option<bool>, num_shard: Option<usize>) -> usize {
475
+ // get the number of shards given `sharded` and `num_shard`
476
+ let num_shard = match (sharded, num_shard) {
477
+ (Some(true), None) => {
478
+ // try to default to the number of available GPUs
479
+ tracing::info!("Parsing num_shard from CUDA_VISIBLE_DEVICES");
480
+ let n_devices =
481
+ num_cuda_devices().expect("--num-shard and CUDA_VISIBLE_DEVICES are not set");
482
+ if n_devices <= 1 {
483
+ panic!("`sharded` is true but only found {n_devices} CUDA devices");
484
+ }
485
+ n_devices
486
+ }
487
+ (Some(true), Some(num_shard)) => {
488
+ // we can't have only one shard while sharded
489
+ if num_shard <= 1 {
490
+ panic!("`sharded` is true but `num_shard` <= 1");
491
+ }
492
+ num_shard
493
+ }
494
+ (Some(false), Some(num_shard)) => num_shard,
495
+ (Some(false), None) => 1,
496
+ (None, None) => num_cuda_devices().unwrap_or(1),
497
+ (None, Some(num_shard)) => num_shard,
498
+ };
499
+ if num_shard < 1 {
500
+ panic!("`num_shard` cannot be < 1");
501
+ }
502
+ num_shard
503
+ }
504
+
505
+ #[derive(Debug)]
506
+ enum LauncherError {
507
+ DownloadError,
508
+ ShardCannotStart,
509
+ ShardDisconnected,
510
+ ShardFailed,
511
+ WebserverFailed,
512
+ WebserverCannotStart,
513
+ }
514
+
515
+ fn download_model(args: &Args, running: Arc<AtomicBool>) -> Result<(), LauncherError> {
516
+ let mut download_argv = vec![
517
+ "text-generation-server".to_string(),
518
+ "download-weights".to_string(),
519
+ args.model_id.to_string(),
520
+ "--extension".to_string(),
521
+ ".safetensors".to_string(),
522
+ "--logger-level".to_string(),
523
+ "INFO".to_string(),
524
+ "--json-output".to_string(),
525
+ ];
526
+
527
+ // Model optional revision
528
+ if let Some(revision) = &args.revision {
529
+ download_argv.push("--revision".to_string());
530
+ download_argv.push(revision.to_string())
531
+ }
532
+
533
+ // Copy current process env
534
+ let mut env: Vec<(OsString, OsString)> = env::vars_os().collect();
535
+
536
+ // If huggingface_hub_cache is set, pass it to the shard
537
+ // Useful when running inside a docker container
538
+ if let Some(ref huggingface_hub_cache) = args.huggingface_hub_cache {
539
+ env.push(("HUGGINGFACE_HUB_CACHE".into(), huggingface_hub_cache.into()));
540
+ };
541
+
542
+ // Enable hf transfer for insane download speeds
543
+ let enable_hf_transfer = env::var("HF_HUB_ENABLE_HF_TRANSFER").unwrap_or("1".to_string());
544
+ env.push((
545
+ "HF_HUB_ENABLE_HF_TRANSFER".into(),
546
+ enable_hf_transfer.into(),
547
+ ));
548
+
549
+ // Parse Inference API token
550
+ if let Ok(api_token) = env::var("HF_API_TOKEN") {
551
+ env.push(("HUGGING_FACE_HUB_TOKEN".into(), api_token.into()))
552
+ };
553
+
554
+ // Start process
555
+ tracing::info!("Starting download process.");
556
+ let mut download_process = match Popen::create(
557
+ &download_argv,
558
+ PopenConfig {
559
+ stdout: Redirection::Pipe,
560
+ stderr: Redirection::Pipe,
561
+ // Needed for the shutdown procedure
562
+ setpgid: true,
563
+ env: Some(env),
564
+ ..Default::default()
565
+ },
566
+ ) {
567
+ Ok(p) => p,
568
+ Err(err) => {
569
+ if let PopenError::IoError(ref err) = err {
570
+ if err.kind() == io::ErrorKind::NotFound {
571
+ tracing::error!("text-generation-server not found in PATH");
572
+ tracing::error!("Please install it with `make install-server`")
573
+ }
574
+ }
575
+ return Err(LauncherError::DownloadError);
576
+ }
577
+ };
578
+
579
+ // Redirect STDOUT to the console
580
+ let download_stdout = download_process.stdout.take().unwrap();
581
+ thread::spawn(move || {
582
+ // Enter download tracing span
583
+ let stdout = BufReader::new(download_stdout);
584
+ let _span = tracing::span!(tracing::Level::INFO, "download").entered();
585
+ for line in stdout.lines() {
586
+ // Parse loguru logs
587
+ if let Ok(log) = serde_json::from_str::<PythonLogMessage>(&line.unwrap()) {
588
+ log.trace();
589
+ }
590
+ }
591
+ });
592
+
593
+ loop {
594
+ if let Some(status) = download_process.poll() {
595
+ match status {
596
+ ExitStatus::Exited(exit_code) => {
597
+ if exit_code == 0 {
598
+ tracing::info!("Successfully downloaded weights.");
599
+ break;
600
+ } else {
601
+ let mut err = String::new();
602
+ download_process
603
+ .stderr
604
+ .take()
605
+ .unwrap()
606
+ .read_to_string(&mut err)
607
+ .unwrap();
608
+ tracing::error!("Download encountered an error: {err}");
609
+ return Err(LauncherError::DownloadError);
610
+ }
611
+ }
612
+ _ => {
613
+ tracing::error!("Download process exited with an unknown status.");
614
+ return Err(LauncherError::DownloadError);
615
+ }
616
+ }
617
+ }
618
+ if !running.load(Ordering::SeqCst) {
619
+ download_process.terminate().unwrap();
620
+ tracing::info!("Waiting for download process to gracefully shutdown");
621
+ download_process
622
+ .wait_timeout(Duration::from_secs(90))
623
+ .unwrap();
624
+ tracing::info!("Download process terminated");
625
+ return Ok(());
626
+ }
627
+ sleep(Duration::from_millis(100));
628
+ }
629
+ Ok(())
630
+ }
631
+
632
+ #[allow(clippy::too_many_arguments)]
633
+ fn spawn_shards(
634
+ num_shard: usize,
635
+ args: &Args,
636
+ shutdown: Arc<Mutex<bool>>,
637
+ shutdown_receiver: &mpsc::Receiver<()>,
638
+ shutdown_sender: mpsc::Sender<()>,
639
+ status_receiver: &mpsc::Receiver<ShardStatus>,
640
+ status_sender: mpsc::Sender<ShardStatus>,
641
+ running: Arc<AtomicBool>,
642
+ ) -> Result<(), LauncherError> {
643
+ // Start shard processes
644
+ for rank in 0..num_shard {
645
+ let model_id = args.model_id.clone();
646
+ let revision = args.revision.clone();
647
+ let uds_path = args.shard_uds_path.clone();
648
+ let master_addr = args.master_addr.clone();
649
+ let huggingface_hub_cache = args.huggingface_hub_cache.clone();
650
+ let weights_cache_override = args.weights_cache_override.clone();
651
+ let status_sender = status_sender.clone();
652
+ let shutdown = shutdown.clone();
653
+ let shutdown_sender = shutdown_sender.clone();
654
+ let otlp_endpoint = args.otlp_endpoint.clone();
655
+ let quantize = args.quantize;
656
+ let master_port = args.master_port;
657
+ let disable_custom_kernels = args.disable_custom_kernels;
658
+ let watermark_gamma = args.watermark_gamma;
659
+ let watermark_delta = args.watermark_delta;
660
+ thread::spawn(move || {
661
+ shard_manager(
662
+ model_id,
663
+ revision,
664
+ quantize,
665
+ uds_path,
666
+ rank,
667
+ num_shard,
668
+ master_addr,
669
+ master_port,
670
+ huggingface_hub_cache,
671
+ weights_cache_override,
672
+ disable_custom_kernels,
673
+ watermark_gamma,
674
+ watermark_delta,
675
+ otlp_endpoint,
676
+ status_sender,
677
+ shutdown,
678
+ shutdown_sender,
679
+ )
680
+ });
681
+ }
682
+ drop(shutdown_sender);
683
+
684
+ // Wait for shard to start
685
+ let mut shard_ready = 0;
686
+ while running.load(Ordering::SeqCst) {
687
+ match status_receiver.try_recv() {
688
+ Ok(ShardStatus::Ready) => {
689
+ shard_ready += 1;
690
+ if shard_ready == num_shard {
691
+ break;
692
+ }
693
+ }
694
+ Err(TryRecvError::Empty) => {
695
+ sleep(Duration::from_millis(100));
696
+ }
697
+ Ok(ShardStatus::Failed((rank, err))) => {
698
+ tracing::error!("Shard {} failed to start:\n{}", rank, err);
699
+ shutdown_shards(shutdown, shutdown_receiver);
700
+ return Err(LauncherError::ShardCannotStart);
701
+ }
702
+ Err(TryRecvError::Disconnected) => {
703
+ tracing::error!("Shard status channel disconnected");
704
+ shutdown_shards(shutdown, shutdown_receiver);
705
+ return Err(LauncherError::ShardDisconnected);
706
+ }
707
+ }
708
+ }
709
+ Ok(())
710
+ }
711
+
712
+ fn spawn_webserver(
713
+ args: Args,
714
+ shutdown: Arc<Mutex<bool>>,
715
+ shutdown_receiver: &mpsc::Receiver<()>,
716
+ ) -> Result<Popen, LauncherError> {
717
+ // All shard started
718
+ // Start webserver
719
+ tracing::info!("Starting Webserver");
720
+ let mut argv = vec![
721
+ "text-generation-router".to_string(),
722
+ "--max-concurrent-requests".to_string(),
723
+ args.max_concurrent_requests.to_string(),
724
+ "--max-best-of".to_string(),
725
+ args.max_best_of.to_string(),
726
+ "--max-stop-sequences".to_string(),
727
+ args.max_stop_sequences.to_string(),
728
+ "--max-input-length".to_string(),
729
+ args.max_input_length.to_string(),
730
+ "--max-total-tokens".to_string(),
731
+ args.max_total_tokens.to_string(),
732
+ "--waiting-served-ratio".to_string(),
733
+ args.waiting_served_ratio.to_string(),
734
+ "--max-waiting-tokens".to_string(),
735
+ args.max_waiting_tokens.to_string(),
736
+ "--port".to_string(),
737
+ args.port.to_string(),
738
+ "--master-shard-uds-path".to_string(),
739
+ format!("{}-0", args.shard_uds_path),
740
+ "--tokenizer-name".to_string(),
741
+ args.model_id,
742
+ ];
743
+
744
+ // Deprecate max_batch_size
745
+ if let Some(max_batch_size) = args.max_batch_size {
746
+ argv.push("--max-batch-size".to_string());
747
+ argv.push(max_batch_size.to_string())
748
+ } else {
749
+ argv.push("--max-batch-total-tokens".to_string());
750
+ argv.push(args.max_batch_total_tokens.to_string())
751
+ }
752
+
753
+ // Model optional revision
754
+ if let Some(ref revision) = args.revision {
755
+ argv.push("--revision".to_string());
756
+ argv.push(revision.to_string())
757
+ }
758
+
759
+ if args.json_output {
760
+ argv.push("--json-output".to_string());
761
+ }
762
+
763
+ // OpenTelemetry
764
+ if let Some(otlp_endpoint) = args.otlp_endpoint {
765
+ argv.push("--otlp-endpoint".to_string());
766
+ argv.push(otlp_endpoint);
767
+ }
768
+
769
+ // CORS origins
770
+ for origin in args.cors_allow_origin.into_iter() {
771
+ argv.push("--cors-allow-origin".to_string());
772
+ argv.push(origin);
773
+ }
774
+
775
+ // Copy current process env
776
+ let mut env: Vec<(OsString, OsString)> = env::vars_os().collect();
777
+
778
+ // Parse Inference API token
779
+ if let Ok(api_token) = env::var("HF_API_TOKEN") {
780
+ env.push(("HUGGING_FACE_HUB_TOKEN".into(), api_token.into()))
781
+ };
782
+
783
+ let mut webserver = match Popen::create(
784
+ &argv,
785
+ PopenConfig {
786
+ stdout: Redirection::Pipe,
787
+ stderr: Redirection::Pipe,
788
+ // Needed for the shutdown procedure
789
+ setpgid: true,
790
+ env: Some(env),
791
+ ..Default::default()
792
+ },
793
+ ) {
794
+ Ok(p) => p,
795
+ Err(err) => {
796
+ tracing::error!("Failed to start webserver: {}", err);
797
+ if let PopenError::IoError(err) = err {
798
+ if err.kind() == io::ErrorKind::NotFound {
799
+ tracing::error!("text-generation-router not found in PATH");
800
+ tracing::error!("Please install it with `make install-router`")
801
+ }
802
+ } else {
803
+ tracing::error!("{}", err);
804
+ }
805
+
806
+ shutdown_shards(shutdown, shutdown_receiver);
807
+ return Err(LauncherError::WebserverCannotStart);
808
+ }
809
+ };
810
+
811
+ // Redirect STDOUT and STDERR to the console
812
+ let webserver_stdout = webserver.stdout.take().unwrap();
813
+ let webserver_stderr = webserver.stderr.take().unwrap();
814
+
815
+ thread::spawn(move || {
816
+ let stdout = BufReader::new(webserver_stdout);
817
+ let stderr = BufReader::new(webserver_stderr);
818
+ for line in stdout.lines() {
819
+ println!("{}", line.unwrap());
820
+ }
821
+ for line in stderr.lines() {
822
+ println!("{}", line.unwrap());
823
+ }
824
+ });
825
+ Ok(webserver)
826
+ }
827
+
828
+ fn main() -> Result<(), LauncherError> {
829
+ // Pattern match configuration
830
+ let args = Args::parse();
831
+
832
+ if args.json_output {
833
+ tracing_subscriber::fmt().json().init();
834
+ } else {
835
+ tracing_subscriber::fmt().compact().init();
836
+ }
837
+
838
+ if args.env {
839
+ let env_runtime = env_runtime::Env::new();
840
+ tracing::info!("{}", env_runtime);
841
+ }
842
+
843
+ tracing::info!("{:?}", args);
844
+
845
+ let num_shard = find_num_shards(args.sharded, args.num_shard);
846
+ if num_shard > 1 {
847
+ tracing::info!("Sharding model on {num_shard} processes");
848
+ }
849
+
850
+ // Signal handler
851
+ let running = Arc::new(AtomicBool::new(true));
852
+ let r = running.clone();
853
+ ctrlc::set_handler(move || {
854
+ r.store(false, Ordering::SeqCst);
855
+ })
856
+ .expect("Error setting Ctrl-C handler");
857
+
858
+ // Check if model_id is a local model
859
+ let local_path = Path::new(&args.model_id);
860
+ let is_local_model = local_path.exists() && local_path.is_dir();
861
+
862
+ // Download weights for sharded models
863
+ if !is_local_model && args.weights_cache_override.is_none() && num_shard > 1 {
864
+ download_model(&args, running.clone())?;
865
+ }
866
+
867
+ // Shared shutdown bool
868
+ let shutdown = Arc::new(Mutex::new(false));
869
+ // Shared shutdown channel
870
+ // When shutting down, the main thread will wait for all senders to be dropped
871
+ let (shutdown_sender, shutdown_receiver) = mpsc::channel();
872
+
873
+ // Shared channel to track shard status
874
+ let (status_sender, status_receiver) = mpsc::channel();
875
+
876
+ spawn_shards(
877
+ num_shard,
878
+ &args,
879
+ shutdown.clone(),
880
+ &shutdown_receiver,
881
+ shutdown_sender,
882
+ &status_receiver,
883
+ status_sender,
884
+ running.clone(),
885
+ )?;
886
+
887
+ // We might have received a termination signal
888
+ if !running.load(Ordering::SeqCst) {
889
+ shutdown_shards(shutdown, &shutdown_receiver);
890
+ return Ok(());
891
+ }
892
+
893
+ let mut webserver = spawn_webserver(args, shutdown.clone(), &shutdown_receiver)?;
894
+
895
+ // Default exit code
896
+ let mut exit_code = Ok(());
897
+
898
+ while running.load(Ordering::SeqCst) {
899
+ if let Ok(ShardStatus::Failed((rank, err))) = status_receiver.try_recv() {
900
+ tracing::error!("Shard {rank} failed:\n{err}");
901
+ exit_code = Err(LauncherError::ShardFailed);
902
+ break;
903
+ };
904
+
905
+ match webserver.poll() {
906
+ Some(_) => {
907
+ tracing::error!("Webserver Crashed");
908
+ shutdown_shards(shutdown, &shutdown_receiver);
909
+ return Err(LauncherError::WebserverFailed);
910
+ }
911
+ None => {
912
+ sleep(Duration::from_millis(100));
913
+ }
914
+ };
915
+ }
916
+
917
+ // Graceful termination
918
+ webserver.terminate().unwrap();
919
+ tracing::info!("Waiting for webserver to gracefully shutdown");
920
+ webserver.wait_timeout(Duration::from_secs(90)).unwrap();
921
+ tracing::info!("Webserver terminated");
922
+ shutdown_shards(shutdown, &shutdown_receiver);
923
+
924
+ exit_code
925
+ }
launcher/tests/bloom_560m.json ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "generated_text": ".get(\"action\");\n if (action == null) {\n throw new RuntimeException",
3
+ "details": {
4
+ "finish_reason": "length",
5
+ "generated_tokens": 20,
6
+ "seed": null,
7
+ "prefill": [
8
+ {
9
+ "id": 10264,
10
+ "text": "Test",
11
+ "logprob": null
12
+ },
13
+ {
14
+ "id": 8821,
15
+ "text": " request",
16
+ "logprob": -11.894989
17
+ }
18
+ ],
19
+ "tokens": [
20
+ {
21
+ "id": 17,
22
+ "text": ".",
23
+ "logprob": -1.8267672,
24
+ "special": false
25
+ },
26
+ {
27
+ "id": 1587,
28
+ "text": "get",
29
+ "logprob": -2.4674969,
30
+ "special": false
31
+ },
32
+ {
33
+ "id": 11,
34
+ "text": "(",
35
+ "logprob": -1.906001,
36
+ "special": false
37
+ },
38
+ {
39
+ "id": 5,
40
+ "text": "\"",
41
+ "logprob": -1.2279545,
42
+ "special": false
43
+ },
44
+ {
45
+ "id": 4899,
46
+ "text": "action",
47
+ "logprob": -4.170299,
48
+ "special": false
49
+ },
50
+ {
51
+ "id": 5,
52
+ "text": "\"",
53
+ "logprob": -0.32478866,
54
+ "special": false
55
+ },
56
+ {
57
+ "id": 12,
58
+ "text": ")",
59
+ "logprob": -1.0773665,
60
+ "special": false
61
+ },
62
+ {
63
+ "id": 30,
64
+ "text": ";",
65
+ "logprob": -0.27640742,
66
+ "special": false
67
+ },
68
+ {
69
+ "id": 837,
70
+ "text": "\n ",
71
+ "logprob": -1.6970354,
72
+ "special": false
73
+ },
74
+ {
75
+ "id": 1320,
76
+ "text": " if",
77
+ "logprob": -1.4495516,
78
+ "special": false
79
+ },
80
+ {
81
+ "id": 375,
82
+ "text": " (",
83
+ "logprob": -0.23609057,
84
+ "special": false
85
+ },
86
+ {
87
+ "id": 4899,
88
+ "text": "action",
89
+ "logprob": -1.1916996,
90
+ "special": false
91
+ },
92
+ {
93
+ "id": 3535,
94
+ "text": " ==",
95
+ "logprob": -0.8918753,
96
+ "special": false
97
+ },
98
+ {
99
+ "id": 5109,
100
+ "text": " null",
101
+ "logprob": -0.3933342,
102
+ "special": false
103
+ },
104
+ {
105
+ "id": 12,
106
+ "text": ")",
107
+ "logprob": -0.43212673,
108
+ "special": false
109
+ },
110
+ {
111
+ "id": 731,
112
+ "text": " {",
113
+ "logprob": -0.17702064,
114
+ "special": false
115
+ },
116
+ {
117
+ "id": 1260,
118
+ "text": "\n ",
119
+ "logprob": -0.07027565,
120
+ "special": false
121
+ },
122
+ {
123
+ "id": 10519,
124
+ "text": " throw",
125
+ "logprob": -1.3915029,
126
+ "special": false
127
+ },
128
+ {
129
+ "id": 2084,
130
+ "text": " new",
131
+ "logprob": -0.04201372,
132
+ "special": false
133
+ },
134
+ {
135
+ "id": 150858,
136
+ "text": " RuntimeException",
137
+ "logprob": -1.7329919,
138
+ "special": false
139
+ }
140
+ ]
141
+ }
142
+ }
launcher/tests/integration_tests.rs ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ use float_eq::assert_float_eq;
2
+ use serde::Deserialize;
3
+ use serde_json::Value;
4
+ use std::fs::File;
5
+ use std::io::{BufRead, BufReader};
6
+ use std::path::PathBuf;
7
+ use std::thread;
8
+ use std::thread::sleep;
9
+ use std::time::Duration;
10
+ use subprocess::{Popen, PopenConfig, Redirection};
11
+
12
+ #[derive(Deserialize)]
13
+ pub struct Token {
14
+ id: u32,
15
+ text: String,
16
+ logprob: Option<f32>,
17
+ special: bool,
18
+ }
19
+
20
+ #[derive(Deserialize)]
21
+ struct Details {
22
+ finish_reason: String,
23
+ generated_tokens: u32,
24
+ tokens: Vec<Token>,
25
+ }
26
+
27
+ #[derive(Deserialize)]
28
+ struct GeneratedText {
29
+ generated_text: String,
30
+ details: Details,
31
+ }
32
+
33
+ fn start_launcher(model_id: String, num_shard: usize, port: usize, master_port: usize) -> Popen {
34
+ let argv = vec![
35
+ "text-generation-launcher".to_string(),
36
+ "--model-id".to_string(),
37
+ model_id.clone(),
38
+ "--num-shard".to_string(),
39
+ num_shard.to_string(),
40
+ "--port".to_string(),
41
+ port.to_string(),
42
+ "--master-port".to_string(),
43
+ master_port.to_string(),
44
+ "--shard-uds-path".to_string(),
45
+ format!("/tmp/test-{}-{}-{}", num_shard, port, master_port),
46
+ ];
47
+
48
+ let mut launcher = Popen::create(
49
+ &argv,
50
+ PopenConfig {
51
+ stdout: Redirection::Pipe,
52
+ stderr: Redirection::Merge,
53
+ ..Default::default()
54
+ },
55
+ )
56
+ .expect("Could not start launcher");
57
+
58
+ // Redirect STDOUT and STDERR to the console
59
+ // (STDERR is merged into STDOUT)
60
+ let launcher_stdout = launcher.stdout.take().unwrap();
61
+
62
+ thread::spawn(move || {
63
+ let stdout = BufReader::new(launcher_stdout);
64
+ for line in stdout.lines() {
65
+ println!("{}", line.unwrap());
66
+ }
67
+ });
68
+
69
+ for _ in 0..60 {
70
+ let health = reqwest::blocking::get(format!("http://localhost:{}/health", port));
71
+ if health.is_ok() {
72
+ return launcher;
73
+ }
74
+ sleep(Duration::from_secs(2));
75
+ }
76
+
77
+ launcher.terminate().unwrap();
78
+ launcher.wait().unwrap();
79
+ panic!("failed to launch {}", model_id)
80
+ }
81
+
82
+ fn test_model(
83
+ model_id: String,
84
+ num_shard: usize,
85
+ port: usize,
86
+ master_port: usize,
87
+ ) -> GeneratedText {
88
+ let mut launcher = start_launcher(model_id, num_shard, port, master_port);
89
+
90
+ let data = r#"
91
+ {
92
+ "inputs": "Test request",
93
+ "parameters": {
94
+ "details": true
95
+ }
96
+ }"#;
97
+ let req: Value = serde_json::from_str(data).unwrap();
98
+
99
+ let client = reqwest::blocking::Client::new();
100
+ let res = client
101
+ .post(format!("http://localhost:{}/generate", port))
102
+ .json(&req)
103
+ .send();
104
+
105
+ launcher.terminate().unwrap();
106
+ launcher.wait().unwrap();
107
+
108
+ let result: GeneratedText = res.unwrap().json().unwrap();
109
+ result
110
+ }
111
+
112
+ fn read_json(name: &str) -> GeneratedText {
113
+ let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
114
+ d.push("tests/");
115
+ d.push(name);
116
+
117
+ let file = File::open(d).unwrap();
118
+ let reader = BufReader::new(file);
119
+
120
+ let result: GeneratedText = serde_json::from_reader(reader).unwrap();
121
+ result
122
+ }
123
+
124
+ fn compare_results(result: GeneratedText, expected: GeneratedText) {
125
+ assert_eq!(result.generated_text, expected.generated_text);
126
+ assert_eq!(result.details.finish_reason, expected.details.finish_reason);
127
+ assert_eq!(
128
+ result.details.generated_tokens,
129
+ expected.details.generated_tokens
130
+ );
131
+
132
+ for (token, expected_token) in result
133
+ .details
134
+ .tokens
135
+ .into_iter()
136
+ .zip(expected.details.tokens.into_iter())
137
+ {
138
+ assert_eq!(token.id, expected_token.id);
139
+ assert_eq!(token.text, expected_token.text);
140
+ assert_eq!(token.special, expected_token.special);
141
+ if let Some(logprob) = token.logprob {
142
+ let expected_logprob = expected_token.logprob.unwrap();
143
+ assert_float_eq!(logprob, expected_logprob, abs <= 0.001);
144
+ } else {
145
+ assert_eq!(token.logprob, expected_token.logprob);
146
+ }
147
+ }
148
+ }
149
+
150
+ #[test]
151
+ fn test_bloom_560m() {
152
+ let expected = read_json("bloom_560m.json");
153
+
154
+ let result = test_model("bigscience/bloom-560m".to_string(), 1, 3000, 29500);
155
+ compare_results(result, expected);
156
+ }
157
+
158
+ #[test]
159
+ fn test_bloom_560m_distributed() {
160
+ let expected = read_json("bloom_560m.json");
161
+
162
+ let result = test_model("bigscience/bloom-560m".to_string(), 2, 3001, 29501);
163
+ compare_results(result, expected);
164
+ }
165
+
166
+ #[test]
167
+ fn test_mt0_base() {
168
+ let expected = read_json("mt0_base.json");
169
+
170
+ let result = test_model("bigscience/mt0-base".to_string(), 1, 3002, 29502);
171
+ compare_results(result, expected);
172
+ }
launcher/tests/mt0_base.json ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "generated_text": "\"\"\"Test the contents of the contents of the contents. \"\"\" test_test",
3
+ "details": {
4
+ "finish_reason": "length",
5
+ "generated_tokens": 20,
6
+ "seed": null,
7
+ "prefill": [
8
+ {
9
+ "id": 0,
10
+ "text": "<pad>",
11
+ "logprob": null
12
+ }
13
+ ],
14
+ "tokens": [
15
+ {
16
+ "id": 259,
17
+ "text": "",
18
+ "logprob": -1.3656927,
19
+ "special": false
20
+ },
21
+ {
22
+ "id": 215100,
23
+ "text": "\"\"\"",
24
+ "logprob": -2.6551573,
25
+ "special": false
26
+ },
27
+ {
28
+ "id": 46138,
29
+ "text": "Test",
30
+ "logprob": -1.8059857,
31
+ "special": false
32
+ },
33
+ {
34
+ "id": 287,
35
+ "text": " the",
36
+ "logprob": -1.2102449,
37
+ "special": false
38
+ },
39
+ {
40
+ "id": 259,
41
+ "text": " ",
42
+ "logprob": -1.6057279,
43
+ "special": false
44
+ },
45
+ {
46
+ "id": 49076,
47
+ "text": "contents",
48
+ "logprob": -3.6060903,
49
+ "special": false
50
+ },
51
+ {
52
+ "id": 304,
53
+ "text": " of",
54
+ "logprob": -0.5270343,
55
+ "special": false
56
+ },
57
+ {
58
+ "id": 287,
59
+ "text": " the",
60
+ "logprob": -0.62522805,
61
+ "special": false
62
+ },
63
+ {
64
+ "id": 259,
65
+ "text": " ",
66
+ "logprob": -1.4069618,
67
+ "special": false
68
+ },
69
+ {
70
+ "id": 49076,
71
+ "text": "contents",
72
+ "logprob": -2.621994,
73
+ "special": false
74
+ },
75
+ {
76
+ "id": 304,
77
+ "text": " of",
78
+ "logprob": -1.3172221,
79
+ "special": false
80
+ },
81
+ {
82
+ "id": 287,
83
+ "text": " the",
84
+ "logprob": -0.3501925,
85
+ "special": false
86
+ },
87
+ {
88
+ "id": 259,
89
+ "text": " ",
90
+ "logprob": -0.7219573,
91
+ "special": false
92
+ },
93
+ {
94
+ "id": 49076,
95
+ "text": "contents",
96
+ "logprob": -1.0494149,
97
+ "special": false
98
+ },
99
+ {
100
+ "id": 260,
101
+ "text": ".",
102
+ "logprob": -1.0803378,
103
+ "special": false
104
+ },
105
+ {
106
+ "id": 259,
107
+ "text": " ",
108
+ "logprob": -0.32933083,
109
+ "special": false
110
+ },
111
+ {
112
+ "id": 215100,
113
+ "text": "\"\"\"",
114
+ "logprob": -0.11268901,
115
+ "special": false
116
+ },
117
+ {
118
+ "id": 2978,
119
+ "text": " test",
120
+ "logprob": -1.5846587,
121
+ "special": false
122
+ },
123
+ {
124
+ "id": 290,
125
+ "text": "_",
126
+ "logprob": -0.49796978,
127
+ "special": false
128
+ },
129
+ {
130
+ "id": 4125,
131
+ "text": "test",
132
+ "logprob": -2.0026445,
133
+ "special": false
134
+ }
135
+ ]
136
+ }
137
+ }
proto/generate.proto ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ syntax = "proto3";
2
+
3
+ package generate.v1;
4
+
5
+ service TextGenerationService {
6
+ /// Model Info
7
+ rpc Info (InfoRequest) returns (InfoResponse) {}
8
+ /// Service discovery
9
+ rpc ServiceDiscovery (ServiceDiscoveryRequest) returns (ServiceDiscoveryResponse) {}
10
+ /// Empties batch cache
11
+ rpc ClearCache (ClearCacheRequest) returns (ClearCacheResponse);
12
+ /// Remove requests from a cached batch
13
+ rpc FilterBatch (FilterBatchRequest) returns (FilterBatchResponse);
14
+ /// Prefill batch and decode first token
15
+ rpc Prefill (PrefillRequest) returns (PrefillResponse);
16
+ /// Decode token for a list of prefilled batches
17
+ rpc Decode (DecodeRequest) returns (DecodeResponse);
18
+ /// Health check
19
+ rpc Health (HealthRequest) returns (HealthResponse);
20
+ }
21
+
22
+ message HealthRequest {}
23
+ message HealthResponse {}
24
+
25
+ /// Empty request
26
+ message InfoRequest {}
27
+
28
+ message InfoResponse {
29
+ bool requires_padding = 1;
30
+ string dtype = 2;
31
+ string device_type = 3;
32
+ }
33
+
34
+ /// Empty request
35
+ message ServiceDiscoveryRequest {}
36
+
37
+ message ServiceDiscoveryResponse {
38
+ /// Other shards urls
39
+ repeated string urls = 1;
40
+ }
41
+
42
+ message ClearCacheRequest {
43
+ /// Optional batch id
44
+ optional uint64 id = 1;
45
+ }
46
+
47
+ /// Empty response
48
+ message ClearCacheResponse {}
49
+
50
+ message NextTokenChooserParameters {
51
+ /// exponential scaling output probability distribution
52
+ float temperature = 1;
53
+ /// restricting to the k highest probability elements
54
+ uint32 top_k = 2;
55
+ /// restricting to top tokens summing to prob_cut_off <= prob_cut_off
56
+ float top_p = 3;
57
+ /// restricting to top tokens summing to prob_cut_off <= prob_cut_off
58
+ float typical_p = 4;
59
+ /// apply sampling on the logits
60
+ bool do_sample = 5;
61
+ /// random seed for sampling
62
+ uint64 seed = 6;
63
+ /// repetition penalty
64
+ float repetition_penalty = 7;
65
+ /// token watermarking using "A Watermark for Large Language Models"
66
+ bool watermark = 8;
67
+ }
68
+
69
+ message StoppingCriteriaParameters {
70
+ /// Maximum number of generated tokens
71
+ uint32 max_new_tokens = 1;
72
+ /// Optional stopping sequences
73
+ repeated string stop_sequences = 2;
74
+ /// Ignore end of sequence token
75
+ /// used for benchmarking
76
+ bool ignore_eos_token = 3;
77
+ }
78
+
79
+ message Request {
80
+ /// Request ID
81
+ uint64 id = 1;
82
+ /// The generation context
83
+ string inputs = 2;
84
+ /// Context truncation
85
+ uint32 truncate = 3;
86
+ /// Next Token Chooser Parameters
87
+ NextTokenChooserParameters parameters = 4;
88
+ /// Stopping Criteria Parameters
89
+ StoppingCriteriaParameters stopping_parameters = 5;
90
+ }
91
+
92
+ message Batch {
93
+ /// Batch ID
94
+ uint64 id = 1;
95
+ /// Individual requests
96
+ repeated Request requests = 2;
97
+ /// Batch size (==len(requests))
98
+ uint32 size = 3;
99
+ /// Maximum number of tokens this batch will grow to
100
+ uint32 max_tokens = 4;
101
+ }
102
+
103
+ enum FinishReason {
104
+ FINISH_REASON_LENGTH = 0;
105
+ FINISH_REASON_EOS_TOKEN = 1;
106
+ FINISH_REASON_STOP_SEQUENCE = 2;
107
+ }
108
+
109
+ message GeneratedText {
110
+ /// Output
111
+ string text = 1;
112
+ /// Number of generated tokens
113
+ uint32 generated_tokens = 2;
114
+ /// Finish reason
115
+ FinishReason finish_reason = 3;
116
+ /// Seed
117
+ optional uint64 seed = 4;
118
+ }
119
+
120
+ message PrefillTokens {
121
+ /// Prefill Token IDs
122
+ repeated uint32 ids = 1;
123
+ /// Prefill Logprobs
124
+ repeated float logprobs = 2;
125
+ /// Prefill tokens
126
+ repeated string texts = 3;
127
+ }
128
+
129
+ message Generation {
130
+ /// Request ID
131
+ uint64 request_id = 1;
132
+ /// Prefill tokens (optional)
133
+ PrefillTokens prefill_tokens = 2;
134
+ /// Token ID
135
+ uint32 token_id = 3;
136
+ /// Logprob
137
+ float token_logprob = 4;
138
+ /// Text
139
+ string token_text = 5;
140
+ /// Is it a special token
141
+ bool token_is_special = 6;
142
+ /// Complete generated text
143
+ GeneratedText generated_text = 7;
144
+ }
145
+
146
+ message FilterBatchRequest {
147
+ /// Batch ID
148
+ uint64 batch_id = 1;
149
+ /// Requests to keep
150
+ repeated Request keep_requests = 2;
151
+ }
152
+
153
+ message FilterBatchResponse {
154
+ /// Filtered Batch (cached)
155
+ Batch batch = 1;
156
+ }
157
+
158
+
159
+ message PrefillRequest {
160
+ /// Batch
161
+ Batch batch = 1;
162
+ }
163
+
164
+ message PrefillResponse {
165
+ /// Generation
166
+ repeated Generation generations = 1;
167
+ /// Next batch (cached)
168
+ optional Batch batch = 2;
169
+ }
170
+
171
+ message DecodeRequest {
172
+ /// Cached batches
173
+ repeated Batch batches = 1;
174
+ }
175
+
176
+ message DecodeResponse {
177
+ /// Decodes
178
+ repeated Generation generations = 1;
179
+ /// Next batch (cached)
180
+ optional Batch batch = 2;
181
+ }
router/Cargo.toml ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ name = "text-generation-router"
3
+ version = "0.6.0"
4
+ edition = "2021"
5
+ authors = ["Olivier Dehaene"]
6
+ description = "Text Generation Webserver"
7
+ build = "build.rs"
8
+
9
+ [lib]
10
+ path = "src/lib.rs"
11
+
12
+ [[bin]]
13
+ name = "text-generation-router"
14
+ path = "src/main.rs"
15
+
16
+ [dependencies]
17
+ async-stream = "0.3.3"
18
+ axum = { version = "0.6.4", features = ["json"] }
19
+ axum-tracing-opentelemetry = "0.10.0"
20
+ text-generation-client = { path = "client" }
21
+ clap = { version = "4.1.4", features = ["derive", "env"] }
22
+ flume = "0.10.14"
23
+ futures = "0.3.26"
24
+ metrics = "0.20.1"
25
+ metrics-exporter-prometheus = { version = "0.11.0", features = [] }
26
+ nohash-hasher = "0.2.0"
27
+ opentelemetry = { version = "0.18.0", features = ["rt-tokio"] }
28
+ opentelemetry-otlp = "0.11.0"
29
+ rand = "0.8.5"
30
+ reqwest = { version = "0.11.14", features = [] }
31
+ serde = "1.0.152"
32
+ serde_json = "1.0.93"
33
+ thiserror = "1.0.38"
34
+ tokenizers = "0.13.3"
35
+ tokio = { version = "1.25.0", features = ["rt", "rt-multi-thread", "parking_lot", "signal", "sync"] }
36
+ tower-http = { version = "0.4.0", features = ["cors"] }
37
+ tracing = "0.1.37"
38
+ tracing-opentelemetry = "0.18.0"
39
+ tracing-subscriber = { version = "0.3.16", features = ["json", "env-filter"] }
40
+ utoipa = { version = "3.0.1", features = ["axum_extras"] }
41
+ utoipa-swagger-ui = { version = "3.0.2", features = ["axum"] }
42
+
43
+ [build-dependencies]
44
+ vergen = { version = "8.0.0", features = ["build", "git", "gitcl"] }
router/build.rs ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ use std::error::Error;
2
+ use vergen::EmitBuilder;
3
+
4
+ fn main() -> Result<(), Box<dyn Error>> {
5
+ // Try to get the git sha from the local git repository
6
+ if EmitBuilder::builder()
7
+ .fail_on_error()
8
+ .git_sha(false)
9
+ .emit()
10
+ .is_err()
11
+ {
12
+ // Unable to get the git sha
13
+ if let Ok(sha) = std::env::var("GIT_SHA") {
14
+ // Set it from an env var
15
+ println!("cargo:rustc-env=VERGEN_GIT_SHA={sha}");
16
+ }
17
+ }
18
+
19
+ // Set docker label if present
20
+ if let Ok(label) = std::env::var("DOCKER_LABEL") {
21
+ // Set it from an env var
22
+ println!("cargo:rustc-env=DOCKER_LABEL={label}");
23
+ }
24
+
25
+ Ok(())
26
+ }
router/client/Cargo.toml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ name = "text-generation-client"
3
+ version = "0.6.0"
4
+ edition = "2021"
5
+
6
+ [dependencies]
7
+ futures = "^0.3"
8
+ grpc-metadata = { path = "../grpc-metadata" }
9
+ prost = "^0.11"
10
+ thiserror = "^1.0"
11
+ tokio = { version = "^1.25", features = ["sync"] }
12
+ tonic = "^0.8"
13
+ tower = "^0.4"
14
+ tracing = "^0.1"
15
+ tracing-error = "^0.2"
16
+
17
+ [build-dependencies]
18
+ tonic-build = "0.8.4"
19
+ prost-build = "0.11.6"
router/client/build.rs ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ use std::fs;
2
+
3
+ fn main() -> Result<(), Box<dyn std::error::Error>> {
4
+ println!("cargo:rerun-if-changed=../../proto/generate.proto");
5
+ fs::create_dir("src/pb").unwrap_or(());
6
+
7
+ let mut config = prost_build::Config::new();
8
+ config.protoc_arg("--experimental_allow_proto3_optional");
9
+
10
+ tonic_build::configure()
11
+ .build_client(true)
12
+ .build_server(false)
13
+ .out_dir("src/pb")
14
+ .include_file("mod.rs")
15
+ .compile_with_config(config, &["../../proto/generate.proto"], &["../../proto"])
16
+ .unwrap_or_else(|e| panic!("protobuf compilation failed: {e}"));
17
+
18
+ Ok(())
19
+ }
router/client/src/client.rs ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /// Single shard Client
2
+ use crate::pb::generate::v1::text_generation_service_client::TextGenerationServiceClient;
3
+ use crate::pb::generate::v1::*;
4
+ use crate::Result;
5
+ use grpc_metadata::InjectTelemetryContext;
6
+ use tonic::transport::{Channel, Uri};
7
+ use tracing::instrument;
8
+
9
+ /// Text Generation Inference gRPC client
10
+ #[derive(Debug, Clone)]
11
+ pub struct Client {
12
+ stub: TextGenerationServiceClient<Channel>,
13
+ }
14
+
15
+ impl Client {
16
+ /// Returns a client connected to the given url
17
+ pub async fn connect(uri: Uri) -> Result<Self> {
18
+ let channel = Channel::builder(uri).connect().await?;
19
+
20
+ Ok(Self {
21
+ stub: TextGenerationServiceClient::new(channel),
22
+ })
23
+ }
24
+
25
+ /// Returns a client connected to the given unix socket
26
+ pub async fn connect_uds(path: String) -> Result<Self> {
27
+ let channel = Channel::from_shared("http://[::]:50051".to_string())
28
+ .unwrap()
29
+ .connect_with_connector(tower::service_fn(move |_: Uri| {
30
+ tokio::net::UnixStream::connect(path.clone())
31
+ }))
32
+ .await?;
33
+
34
+ Ok(Self {
35
+ stub: TextGenerationServiceClient::new(channel),
36
+ })
37
+ }
38
+
39
+ /// Returns a list of uris or unix sockets of all shards
40
+ #[instrument(skip(self))]
41
+ pub async fn service_discovery(&mut self) -> Result<Vec<String>> {
42
+ let request = tonic::Request::new(ServiceDiscoveryRequest {}).inject_context();
43
+ let response = self.stub.service_discovery(request).await?;
44
+ let urls = response
45
+ .into_inner()
46
+ .urls
47
+ .into_iter()
48
+ // Remove unix socket prefix
49
+ .map(|url| match url.strip_prefix("unix://") {
50
+ None => url,
51
+ Some(stripped_url) => stripped_url.to_string(),
52
+ })
53
+ .collect();
54
+ Ok(urls)
55
+ }
56
+
57
+ /// Get model info
58
+ #[instrument(skip(self))]
59
+ pub async fn info(&mut self) -> Result<InfoResponse> {
60
+ let request = tonic::Request::new(InfoRequest {}).inject_context();
61
+ let response = self.stub.info(request).await?.into_inner();
62
+ Ok(response)
63
+ }
64
+
65
+ /// Get model health
66
+ #[instrument(skip(self))]
67
+ pub async fn health(&mut self) -> Result<HealthResponse> {
68
+ let request = tonic::Request::new(HealthRequest {}).inject_context();
69
+ let response = self.stub.health(request).await?.into_inner();
70
+ Ok(response)
71
+ }
72
+
73
+ /// Clear the past generations cache
74
+ #[instrument(skip(self))]
75
+ pub async fn clear_cache(&mut self, batch_id: Option<u64>) -> Result<()> {
76
+ let request = tonic::Request::new(ClearCacheRequest { id: batch_id }).inject_context();
77
+ self.stub.clear_cache(request).await?;
78
+ Ok(())
79
+ }
80
+
81
+ /// Filter a cached batch
82
+ #[instrument(skip(self))]
83
+ pub async fn filter_batch(
84
+ &mut self,
85
+ batch_id: u64,
86
+ keep_requests: Vec<Request>,
87
+ ) -> Result<Option<Batch>> {
88
+ let request = tonic::Request::new(FilterBatchRequest {
89
+ batch_id,
90
+ keep_requests,
91
+ })
92
+ .inject_context();
93
+ let filtered_batch = self.stub.filter_batch(request).await?.into_inner();
94
+ Ok(filtered_batch.batch)
95
+ }
96
+
97
+ /// Generate one token for each request in the given batch
98
+ ///
99
+ /// Returns Generation for each request in batch
100
+ /// and the next cached batch
101
+ #[instrument(skip_all, fields(id = &batch.id, size = &batch.size))]
102
+ pub async fn prefill(&mut self, batch: Batch) -> Result<(Vec<Generation>, Option<Batch>)> {
103
+ let request = tonic::Request::new(PrefillRequest { batch: Some(batch) }).inject_context();
104
+ let response = self.stub.prefill(request).await?.into_inner();
105
+ Ok((response.generations, response.batch))
106
+ }
107
+
108
+ /// Generate one token for each request in the given cached batches
109
+ ///
110
+ /// Returns Generation for each request in batches
111
+ /// and the next cached batch
112
+ #[instrument(skip_all, fields(size = batches.iter().map(|batch|{batch.size}).sum::<u32>()))]
113
+ pub async fn decode(
114
+ &mut self,
115
+ batches: Vec<Batch>,
116
+ ) -> Result<(Vec<Generation>, Option<Batch>)> {
117
+ let request = tonic::Request::new(DecodeRequest { batches }).inject_context();
118
+ let response = self.stub.decode(request).await?.into_inner();
119
+ Ok((response.generations, response.batch))
120
+ }
121
+ }
router/client/src/lib.rs ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! Text Generation gRPC client library
2
+
3
+ mod client;
4
+ #[allow(clippy::derive_partial_eq_without_eq)]
5
+ mod pb;
6
+ mod sharded_client;
7
+
8
+ pub use client::Client;
9
+ pub use pb::generate::v1::HealthResponse;
10
+ pub use pb::generate::v1::InfoResponse as ShardInfo;
11
+ pub use pb::generate::v1::{
12
+ Batch, FinishReason, GeneratedText, Generation, NextTokenChooserParameters, PrefillTokens,
13
+ Request, StoppingCriteriaParameters,
14
+ };
15
+ pub use sharded_client::ShardedClient;
16
+ use thiserror::Error;
17
+ use tonic::transport;
18
+ use tonic::Status;
19
+
20
+ #[derive(Error, Debug, Clone)]
21
+ pub enum ClientError {
22
+ #[error("Could not connect to Text Generation server: {0}")]
23
+ Connection(String),
24
+ #[error("Server error: {0}")]
25
+ Generation(String),
26
+ }
27
+
28
+ impl From<Status> for ClientError {
29
+ fn from(err: Status) -> Self {
30
+ let err = Self::Generation(err.message().to_string());
31
+ tracing::error!("{err}");
32
+ err
33
+ }
34
+ }
35
+
36
+ impl From<transport::Error> for ClientError {
37
+ fn from(err: transport::Error) -> Self {
38
+ let err = Self::Connection(err.to_string());
39
+ tracing::error!("{err}");
40
+ err
41
+ }
42
+ }
43
+
44
+ pub type Result<T> = std::result::Result<T, ClientError>;