speedy-utils 2.0.4__tar.gz → 2.0.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. speedy_utils-2.0.6/CLAUDE.md +220 -0
  2. speedy_utils-2.0.6/PKG-INFO +670 -0
  3. speedy_utils-2.0.6/README.md +617 -0
  4. speedy_utils-2.0.6/debug/test_qwen3_generate.md +50 -0
  5. speedy_utils-2.0.6/docs/GENERATE_QUICKREF.md +138 -0
  6. speedy_utils-2.0.6/docs/MIGRATION_THINKING.md +109 -0
  7. speedy_utils-2.0.6/docs/TDD.md +76 -0
  8. speedy_utils-2.0.6/docs/TOKENIZATION.md +105 -0
  9. speedy_utils-2.0.6/docs/TOKENIZATION_IMPLEMENTATION.md +76 -0
  10. speedy_utils-2.0.6/examples/llm_public_api_example.ipynb +164 -0
  11. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/pyproject.toml +13 -12
  12. speedy_utils-2.0.6/src/datasets_utils/__init__.py +25 -0
  13. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/llm_utils/lm/llm.py +2 -1
  14. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/llm_utils/lm/llm_qwen3.py +216 -172
  15. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/llm_utils/lm/openai_memoize.py +2 -3
  16. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/__imports.py +0 -7
  17. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/__init__.py +0 -86
  18. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/common/utils_cache.py +1 -1
  19. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/common/utils_io.py +24 -3
  20. speedy_utils-2.0.6/src/vision_utils/README.md +122 -0
  21. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/llm_utils/test_llm_mixins.py +517 -36
  22. speedy_utils-2.0.6/tests/test_identify.py +258 -0
  23. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/test_import_time.py +2 -2
  24. speedy_utils-2.0.6/tests/test_load_jsonl.py +213 -0
  25. speedy_utils-2.0.6/tests/test_memoize.py +311 -0
  26. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/test_tokenization.py +8 -5
  27. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/uv.lock +28 -2
  28. speedy_utils-2.0.4/CLAUDE.md +0 -237
  29. speedy_utils-2.0.4/PKG-INFO +0 -712
  30. speedy_utils-2.0.4/README.md +0 -659
  31. speedy_utils-2.0.4/debug/test_qwen3_generate.md +0 -87
  32. speedy_utils-2.0.4/docs/GENERATE_QUICKREF.md +0 -133
  33. speedy_utils-2.0.4/docs/MIGRATION_THINKING.md +0 -73
  34. speedy_utils-2.0.4/docs/TOKENIZATION.md +0 -325
  35. speedy_utils-2.0.4/docs/TOKENIZATION_IMPLEMENTATION.md +0 -104
  36. speedy_utils-2.0.4/examples/llm_public_api_example.ipynb +0 -273
  37. speedy_utils-2.0.4/experiments/exp1/test.png +0 -0
  38. speedy_utils-2.0.4/src/vision_utils/README.md +0 -202
  39. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.codex +0 -0
  40. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.githooks/pre-commit +0 -0
  41. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.githooks/pre-push +0 -0
  42. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.github/prompts/improveParallelErrorHandling.prompt.md +0 -0
  43. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.github/skills/caching-utilities/SKILL.md +0 -0
  44. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.github/skills/caching-utilities/examples/caching_example.py +0 -0
  45. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.github/skills/dataset-processing-multiprocessing/CONFIG_REFERENCE.md +0 -0
  46. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.github/skills/dataset-processing-multiprocessing/SKILL.md +0 -0
  47. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.github/skills/dataset-processing-multiprocessing/example_tokenize_pack.py +0 -0
  48. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.github/skills/edit-llm-inference-style/SKILL.md +0 -0
  49. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.github/skills/io-utilities/SKILL.md +0 -0
  50. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.github/skills/io-utilities/examples/io_example.py +0 -0
  51. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.github/skills/llm-integration/SKILL.md +0 -0
  52. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.github/skills/llm-integration/examples/llm_example.py +0 -0
  53. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.github/skills/make-vscode-happy/SKILL.md +0 -0
  54. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.github/skills/make-vscode-happy/references/diagnostic-playbook.md +0 -0
  55. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.github/skills/multi-threading-processing/SKILL.md +0 -0
  56. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.github/skills/ray-distributed-computing/SKILL.md +0 -0
  57. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.github/skills/skill-creation/SKILL.md +0 -0
  58. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.github/skills/vision-utilities/SKILL.md +0 -0
  59. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.github/skills/vision-utilities/examples/vision_example.py +0 -0
  60. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.github/workflows/publish.yml +0 -0
  61. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.gitignore +0 -0
  62. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/.pre-commit-config.yaml +0 -0
  63. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/AGENTS.md +0 -0
  64. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/CODING_STYLE.md +0 -0
  65. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/bumpversion.sh +0 -0
  66. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/debug/debug_generate_response.py +0 -0
  67. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/debug/debug_n_param.py +0 -0
  68. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/debug/debug_n_structure.py +0 -0
  69. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/debug/integration_test.py +0 -0
  70. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/debug/multi_thread.py +0 -0
  71. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/debug/test_decode_api.py +0 -0
  72. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/debug/test_endpoints.py +0 -0
  73. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/debug/test_generate.py +0 -0
  74. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/debug/test_generate_endpoint.py +0 -0
  75. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/debug/test_qwen3_generate.py +0 -0
  76. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/docs/PR_LIBRARY_ERROR_HANDLING_REFACTOR_PLAN.md +0 -0
  77. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/examples/generate_example.py +0 -0
  78. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/examples/model_specific_thinking_example.py +0 -0
  79. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/examples/tokenization_example.py +0 -0
  80. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/examples/vision_utils_example.py +0 -0
  81. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/experiments/exp1/dockerfile +0 -0
  82. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/experiments/exp1/run_in_docker.sh +0 -0
  83. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/notebooks/demo_multi_process.py +0 -0
  84. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/notebooks/llm_utils/llm_as_a_judge.ipynb +0 -0
  85. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/notebooks/test.ipynb +0 -0
  86. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/pyrightconfig.json +0 -0
  87. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/ruff.toml +0 -0
  88. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/scripts/bug_simple.py +0 -0
  89. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/scripts/debug_import_time.py +0 -0
  90. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/scripts/debug_multi_process.py +0 -0
  91. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/scripts/deploy.sh +0 -0
  92. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/scripts/imports.sh +0 -0
  93. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/scripts/install_hooks.sh +0 -0
  94. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/scripts/test.py +0 -0
  95. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/scripts/test_error_handling.py +0 -0
  96. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/scripts/test_import_time_vision.py +0 -0
  97. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/scripts/test_locals.py +0 -0
  98. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/scripts/test_ray_mp.py +0 -0
  99. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/setup.cfg +0 -0
  100. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/datasets_utils/convert_to_arrow.py +0 -0
  101. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/datasets_utils/viz_chat.py +0 -0
  102. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/llm_utils/__init__.py +0 -0
  103. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/llm_utils/_traceback.py +0 -0
  104. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/llm_utils/chat_format/__init__.py +0 -0
  105. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/llm_utils/chat_format/display.py +0 -0
  106. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/llm_utils/chat_format/transform.py +0 -0
  107. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/llm_utils/chat_format/utils.py +0 -0
  108. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/llm_utils/lm/__init__.py +0 -0
  109. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/llm_utils/lm/base_prompt_builder.py +0 -0
  110. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/llm_utils/lm/llm_signature.py +0 -0
  111. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/llm_utils/lm/lm_base.py +0 -0
  112. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/llm_utils/lm/signature.py +0 -0
  113. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/llm_utils/lm/utils.py +0 -0
  114. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/llm_utils/scripts/sp_chat.py +0 -0
  115. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/llm_utils/utils.py +0 -0
  116. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/common/__init__.py +0 -0
  117. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/common/clock.py +0 -0
  118. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/common/exceptions.py +0 -0
  119. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/common/function_decorator.py +0 -0
  120. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/common/logger.py +0 -0
  121. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/common/notebook_utils.py +0 -0
  122. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/common/patcher.py +0 -0
  123. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/common/report_manager.py +0 -0
  124. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/common/utils_error.py +0 -0
  125. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/common/utils_misc.py +0 -0
  126. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/common/utils_print.py +0 -0
  127. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/multi_worker/__init__.py +0 -0
  128. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/multi_worker/_mp_backends.py +0 -0
  129. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/multi_worker/_mp_progress.py +0 -0
  130. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/multi_worker/_mp_spawn.py +0 -0
  131. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/multi_worker/_multi_process.py +0 -0
  132. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/multi_worker/common.py +0 -0
  133. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/multi_worker/dataset_sharding.py +0 -0
  134. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/multi_worker/process.py +0 -0
  135. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/multi_worker/thread.py +0 -0
  136. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/scripts/__init__.py +0 -0
  137. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/scripts/kill_mpython.py +0 -0
  138. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/scripts/mpython.py +0 -0
  139. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/scripts/openapi_client_codegen.py +0 -0
  140. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/speedy_utils/scripts/prefetch_large_model.py +0 -0
  141. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/vision_utils/__init__.py +0 -0
  142. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/vision_utils/io_utils.py +0 -0
  143. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/src/vision_utils/plot.py +0 -0
  144. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/import_all.py +0 -0
  145. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/import_time_report.py +0 -0
  146. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/llm_utils/test_llm_call_contract.py +0 -0
  147. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/llm_utils/test_llm_signature.py +0 -0
  148. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/llm_utils/test_openai_memoize_completion_cache.py +0 -0
  149. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/llm_utils/test_openai_proxy_localhost.py +0 -0
  150. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/llm_utils/test_public_api.py +0 -0
  151. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/llm_utils/test_sp_chat.py +0 -0
  152. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/sample_objects.py +0 -0
  153. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/test.py +0 -0
  154. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/test_logger.py +0 -0
  155. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/test_logger_format.py +0 -0
  156. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/test_memoize_typing.py +0 -0
  157. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/test_mp_no_main_guard.py +0 -0
  158. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/test_mpython.py +0 -0
  159. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/test_multi_process.py +0 -0
  160. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/test_multi_thread.py +0 -0
  161. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/test_multithread_error_trace.py +0 -0
  162. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/test_prefetch_large_model.py +0 -0
  163. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/test_process.py +0 -0
  164. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/test_process_update.py +0 -0
  165. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/test_thread.py +0 -0
  166. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/test_utils_io.py +0 -0
  167. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tests/test_viz_chat.py +0 -0
  168. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tools/check_syntax.py +0 -0
  169. {speedy_utils-2.0.4 → speedy_utils-2.0.6}/tools/uv_test.sh +0 -0
@@ -0,0 +1,220 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance for working in this repository.
4
+
5
+ ## Development Commands
6
+
7
+ ```bash
8
+ # Install dependencies
9
+ uv sync
10
+
11
+ # Run tests
12
+ ./tools/uv_test.sh -n 32
13
+
14
+ # Run a single test file
15
+ ./tools/uv_test.sh tests/test_thread.py
16
+
17
+ # Run with verbose output
18
+ ./tools/uv_test.sh -v
19
+
20
+ # Check import time for the exported packages
21
+ uv run python scripts/debug_import_time.py speedy_utils llm_utils vision_utils \
22
+ --max-total-sec 0.4 --top 12 --min-sec 0.01 --no-stdlib
23
+
24
+ # Lint and format
25
+ uv run ruff check .
26
+ uv run ruff format .
27
+
28
+ # Pyright / Pylance parity check
29
+ uv run python tools/check_syntax.py
30
+
31
+ # Bump version (runs tests, then commits and pushes)
32
+ ./bumpversion.sh patch # or minor / major
33
+
34
+ # Deploy to PyPI (requires PYPI_API_TOKEN)
35
+ ./scripts/deploy.sh
36
+ ```
37
+
38
+ ## TDD and Regression Test Policy
39
+
40
+ Use Red -> Green -> Refactor for bug fixes:
41
+
42
+ 1. write a failing regression test that reproduces the shipped bug
43
+ 2. confirm it fails for the right reason
44
+ 3. implement the minimal fix
45
+ 4. refactor with tests still green
46
+
47
+ Regression tests in this repo should be:
48
+
49
+ - deterministic (no flaky random/time/network behavior)
50
+ - focused on public APIs and observable outputs
51
+ - scoped to one failure reason per test
52
+ - named after the behavior/bug, not generic labels
53
+ - fast and isolated so they run in normal dev loops
54
+
55
+ See `docs/TDD.md` for the full checklist and examples.
56
+
57
+ ## Performance Requirement: Import Time < 0.4s
58
+
59
+ The repository hook budget is `0.4s` for the exported packages checked by
60
+ `.githooks/pre-commit`:
61
+
62
+ - `speedy_utils`
63
+ - `llm_utils`
64
+ - `vision_utils`
65
+
66
+ Use the shared helper when import time regresses:
67
+
68
+ ```bash
69
+ uv run python scripts/debug_import_time.py speedy_utils llm_utils vision_utils \
70
+ --max-total-sec 0.4 --top 12 --min-sec 0.01 --no-stdlib
71
+ ```
72
+
73
+ Current code structure keeps the budget by avoiding heavy external imports at
74
+ module import time.
75
+
76
+ ### What to keep lazy
77
+
78
+ These imports are intentionally kept behind helpers or function scope because
79
+ they are expensive enough to matter for import time:
80
+
81
+ - `torch`
82
+ - `pandas`
83
+ - `matplotlib`
84
+ - `IPython`
85
+ - tokenizer-loading code in `Qwen3LLM`
86
+
87
+ ### How the current code does it
88
+
89
+ - `speedy_utils.__init__` imports lightweight internal modules directly.
90
+ - heavy external helpers live in `speedy_utils.__imports`.
91
+ - `llm_utils.__init__` exports selected public classes and helpers directly.
92
+ - `vision_utils` keeps plotting and image backends lazy inside function bodies.
93
+
94
+ Do not add new top-level imports for heavy third-party libraries in public
95
+ package `__init__.py` files unless you have rechecked import-time impact.
96
+
97
+ ### Hook vs test budget
98
+
99
+ The pre-commit hook is stricter than the regression test:
100
+
101
+ - `.githooks/pre-commit` enforces `0.4s`
102
+ - `tests/test_import_time.py` currently guards `speedy_utils` at `1.0s`
103
+
104
+ Treat the hook budget as the real policy.
105
+
106
+ ## Architecture
107
+
108
+ ### Package Structure
109
+
110
+ The wheel currently ships four packages from `src/`:
111
+
112
+ - `speedy_utils`: caching, file I/O, formatting, timing, and parallel helpers
113
+ - `llm_utils`: OpenAI-compatible LLM wrappers, memoized clients, chat-format helpers
114
+ - `vision_utils`: image loading, notebook plotting, and mmap-backed image datasets
115
+ - `datasets_utils`: dataset inspection helpers such as `viz_chat`
116
+
117
+ ### Important Modules
118
+
119
+ - `src/speedy_utils/common/utils_cache.py`
120
+ - `memoize`, `imemoize`, `identify`
121
+ - default disk cache root: `~/.cache/speedy_cache`
122
+ - `src/speedy_utils/common/utils_io.py`
123
+ - `load_jsonl`, `fast_load_jsonl`, `load_json_or_pickle`, `load_by_ext`
124
+ - `src/speedy_utils/multi_worker/thread.py`
125
+ - `multi_thread`
126
+ - `src/speedy_utils/multi_worker/_multi_process.py`
127
+ - `multi_process`
128
+ - `src/llm_utils/lm/llm.py`
129
+ - `LLM.chat_completion`, `LLM.generate`, `LLM.pydantic_parse`, `LLM.inspect_history`
130
+ - `src/llm_utils/lm/llm_signature.py`
131
+ - `LLMSignature`
132
+ - `src/llm_utils/lm/llm_qwen3.py`
133
+ - `Qwen3LLM`, `complete_until`, `complete_reasoning`, `complete_content`
134
+ - `src/vision_utils/io_utils.py`
135
+ - `read_images`, `read_images_cpu`, `read_images_gpu`, `ImageMmap`, `ImageMmapDynamic`
136
+ - `src/vision_utils/plot.py`
137
+ - `plot_images_notebook`
138
+ - `src/datasets_utils/viz_chat.py`
139
+ - dataset and conversation inspection CLI
140
+
141
+ ## Public API Notes
142
+
143
+ ### `speedy_utils`
144
+
145
+ - `memoize` supports sync and async functions.
146
+ - `load_json_or_pickle` is for `.json` and pickle-like files.
147
+ - use `load_jsonl` or `fast_load_jsonl` for JSONL.
148
+ - `multi_process(num_procs=None)` currently normalizes to `1`; it does not auto-pick a process count.
149
+
150
+ ### `llm_utils`
151
+
152
+ - `LLM()` defaults to the chat path.
153
+ - `LLM.generate()` uses the completions API and returns a `CompletionChoice`-like object.
154
+ - `LLM.generate()` expects a string prompt and only supports `n=1`.
155
+ - `LLM.pydantic_parse()` is the structured-output API.
156
+ - `LLM(..., return_dict=True)` returns a normalized dict with `completion`, `message`, `messages`, and `parsed`.
157
+ - `LLMSignature` defaults structured outputs to the signature's output model.
158
+ - `Qwen3LLM.chat_completion()` returns an OpenAI-style `ChatCompletionMessage` with optional dynamic attrs such as `reasoning_content`, `usage`, and `call_count`.
159
+ - `Qwen3LLM.complete_until()` returns a continuation-state object, not a `ChatCompletionMessage`.
160
+
161
+ ### `vision_utils`
162
+
163
+ - `read_images*()` returns `dict[path, ndarray | None]`.
164
+ - `plot_images_notebook()` expects arrays/tensors or lists/tuples of arrays.
165
+ - if you loaded images with `read_images*()`, pass `list(images.values())` to the plotter.
166
+ - `ImageMmap` and `ImageMmapDynamic` take image-path sequences and build cache files as needed.
167
+
168
+ ## CLI Tools
169
+
170
+ Registered console scripts in `pyproject.toml`:
171
+
172
+ - `mpython`
173
+ - `kill-mpython`
174
+ - `sp_chat`
175
+ - `spu-prefetch-large-model`
176
+ - `viz_chat`
177
+ - `openapi_client_codegen`
178
+
179
+ ## Code Style
180
+
181
+ - Line length: `88`
182
+ - Quote style: double quotes
183
+ - Ruff is the formatter and linter
184
+ - Avoid unnecessary wrappers and ceremony; see `CODING_STYLE.md`
185
+ - Keep public docs/examples aligned with tests and current implementation, not with historical helper scripts
186
+
187
+ ## Type Checking with Pyright
188
+
189
+ Use:
190
+
191
+ ```bash
192
+ uv run python tools/check_syntax.py
193
+ ```
194
+
195
+ This mirrors what VS Code Pylance reports for the configured project files.
196
+
197
+ ### pyright config (`pyrightconfig.json`)
198
+
199
+ Current notable suppressions:
200
+
201
+ | Rule | Why suppressed |
202
+ |------|----------------|
203
+ | `reportMissingImports` | Optional GPU and backend dependencies are not always installed |
204
+ | `reportAttributeAccessIssue` | OpenAI response models and runtime message objects gain dynamic attrs such as `usage`, `reasoning_content`, and `call_count` |
205
+ | `reportUnsupportedDunderAll` | Some modules rely on broad export patterns that are noisy for pyright |
206
+
207
+ ### Common annotation patterns in this repo
208
+
209
+ - use string literal `"tqdm"` when needed in type hints
210
+ - put `Awaitable[R]` overloads before generic `R` overloads
211
+ - use `# type: ignore[attr-defined]` for dynamic OpenAI message attrs where necessary
212
+ - keep dataset `__getitem__` overrides narrow and explicit
213
+
214
+ ## Version Management
215
+
216
+ Version lives in `pyproject.toml`. `./bumpversion.sh` currently:
217
+
218
+ 1. runs tests
219
+ 2. bumps the package version
220
+ 3. commits and pushes