slide2vec 7.1.1__tar.gz → 7.1.3__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 (191) hide show
  1. {slide2vec-7.1.1 → slide2vec-7.1.3}/PKG-INFO +29 -68
  2. {slide2vec-7.1.1 → slide2vec-7.1.3}/README.md +4 -0
  3. slide2vec-7.1.3/pyproject.toml +264 -0
  4. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/__init__.py +1 -1
  5. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/__init__.py +2 -0
  6. slide2vec-7.1.3/slide2vec/encoders/code.py +102 -0
  7. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/dinov3.py +1 -3
  8. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/moozy/loading.py +1 -1
  9. slide2vec-7.1.3/slide2vec/encoders/models/prism2.py +172 -0
  10. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/inference.py +7 -2
  11. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/dense_image_recipe.py +8 -0
  12. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/feature_identity.py +18 -10
  13. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec.egg-info/PKG-INFO +29 -68
  14. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec.egg-info/SOURCES.txt +2 -0
  15. slide2vec-7.1.3/slide2vec.egg-info/requires.txt +66 -0
  16. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_dense_image_resume.py +5 -0
  17. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_dense_image_shard.py +2 -0
  18. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_dense_stage.py +16 -0
  19. slide2vec-7.1.3/tests/test_encoder_code.py +241 -0
  20. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_encoder_plugins.py +9 -1
  21. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_feature_identity.py +106 -13
  22. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_isight.py +1 -1
  23. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_mascaret.py +5 -3
  24. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_output_consistency.py +3 -0
  25. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_phaet.py +5 -3
  26. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_pooled_identity_api.py +12 -1
  27. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_prism2.py +95 -0
  28. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_soma_migration.py +1 -0
  29. slide2vec-7.1.1/pyproject.toml +0 -204
  30. slide2vec-7.1.1/slide2vec/encoders/models/prism2.py +0 -94
  31. slide2vec-7.1.1/slide2vec.egg-info/requires.txt +0 -109
  32. {slide2vec-7.1.1 → slide2vec-7.1.3}/LICENSE +0 -0
  33. {slide2vec-7.1.1 → slide2vec-7.1.3}/setup.cfg +0 -0
  34. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/__main__.py +0 -0
  35. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/_cufile.py +0 -0
  36. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/api.py +0 -0
  37. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/artifacts.py +0 -0
  38. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/cli.py +0 -0
  39. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/configs/__init__.py +0 -0
  40. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/configs/default.yaml +0 -0
  41. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/configs/resources.py +0 -0
  42. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/cufile.json +0 -0
  43. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/data/__init__.py +0 -0
  44. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/data/dataset.py +0 -0
  45. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/data/tile_reader.py +0 -0
  46. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/data/tile_store.py +0 -0
  47. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/distributed/__init__.py +0 -0
  48. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/distributed/dense_image_worker.py +0 -0
  49. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/distributed/dense_worker.py +0 -0
  50. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/distributed/direct_embed_worker.py +0 -0
  51. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/distributed/image_worker.py +0 -0
  52. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/distributed/pin_gpu.py +0 -0
  53. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/distributed/pipeline_worker.py +0 -0
  54. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/distributed/worker_entry.py +0 -0
  55. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/base.py +0 -0
  56. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/__init__.py +0 -0
  57. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/conch.py +0 -0
  58. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/dinov2.py +0 -0
  59. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/genbio.py +0 -0
  60. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/gigapath.py +0 -0
  61. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/gpfm.py +0 -0
  62. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/hibou.py +0 -0
  63. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/hoptimus.py +0 -0
  64. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/isight.py +0 -0
  65. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/lunit.py +0 -0
  66. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/mettle.py +0 -0
  67. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/midnight.py +0 -0
  68. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/moozy/__init__.py +0 -0
  69. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/moozy/blocks.py +0 -0
  70. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/moozy/case.py +0 -0
  71. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/moozy/slide.py +0 -0
  72. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/moozy/types.py +0 -0
  73. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/mstar.py +0 -0
  74. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/musk.py +0 -0
  75. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/phikon.py +0 -0
  76. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/prism.py +0 -0
  77. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/prost40m.py +0 -0
  78. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/rudolfv2.py +0 -0
  79. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/titan.py +0 -0
  80. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/uni.py +0 -0
  81. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/virchow.py +0 -0
  82. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/models/waiv.py +0 -0
  83. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/registry.py +0 -0
  84. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/encoders/validation.py +0 -0
  85. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/progress.py +0 -0
  86. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/__init__.py +0 -0
  87. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/artifacts_collect.py +0 -0
  88. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/batching.py +0 -0
  89. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/cpu_budget.py +0 -0
  90. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/dense_encode.py +0 -0
  91. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/dense_encoder_input.py +0 -0
  92. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/dense_image_reading.py +0 -0
  93. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/dense_image_shard.py +0 -0
  94. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/dense_image_stage.py +0 -0
  95. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/dense_regions.py +0 -0
  96. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/dense_shard.py +0 -0
  97. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/dense_sliding.py +0 -0
  98. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/dense_stage.py +0 -0
  99. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/distributed.py +0 -0
  100. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/distributed_stage.py +0 -0
  101. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/effective_encoder_input.py +0 -0
  102. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/embedding.py +0 -0
  103. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/embedding_persist.py +0 -0
  104. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/embedding_pipeline.py +0 -0
  105. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/encoder_input_contract.py +0 -0
  106. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/hierarchical.py +0 -0
  107. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/image_shard.py +0 -0
  108. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/image_specs.py +0 -0
  109. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/image_stage.py +0 -0
  110. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/manifest.py +0 -0
  111. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/model_settings.py +0 -0
  112. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/patient_pipeline.py +0 -0
  113. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/persist_callbacks.py +0 -0
  114. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/persistence.py +0 -0
  115. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/pooled_encoder_input.py +0 -0
  116. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/preprocessing.py +0 -0
  117. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/process_list.py +0 -0
  118. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/progress_bridge.py +0 -0
  119. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/registry.py +0 -0
  120. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/serialization.py +0 -0
  121. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/sharding.py +0 -0
  122. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/slide_encode.py +0 -0
  123. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/tiling.py +0 -0
  124. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/tiling_pipeline.py +0 -0
  125. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/types.py +0 -0
  126. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/runtime/worker_io.py +0 -0
  127. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/utils/__init__.py +0 -0
  128. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/utils/config.py +0 -0
  129. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/utils/coordinates.py +0 -0
  130. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/utils/log_utils.py +0 -0
  131. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/utils/tiling_io.py +0 -0
  132. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec/utils/utils.py +0 -0
  133. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec.egg-info/dependency_links.txt +0 -0
  134. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec.egg-info/entry_points.txt +0 -0
  135. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec.egg-info/not-zip-safe +0 -0
  136. {slide2vec-7.1.1 → slide2vec-7.1.3}/slide2vec.egg-info/top_level.txt +0 -0
  137. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_attention_extraction.py +0 -0
  138. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_benchmark_tooling.py +0 -0
  139. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_cli_noninteractive.py +0 -0
  140. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_cufile_compat_mode.py +0 -0
  141. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_dense_encode_kit.py +0 -0
  142. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_dense_encoder_input.py +0 -0
  143. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_dense_extraction.py +0 -0
  144. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_dense_image_reading.py +0 -0
  145. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_dense_image_stage.py +0 -0
  146. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_dense_regions.py +0 -0
  147. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_dense_shard.py +0 -0
  148. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_dense_sliding.py +0 -0
  149. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_dense_source_spacing.py +0 -0
  150. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_dense_worker.py +0 -0
  151. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_dinov2_natimage.py +0 -0
  152. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_dinov3_natimage.py +0 -0
  153. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_drop_in_encoders.py +0 -0
  154. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_encoder_capabilities.py +0 -0
  155. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_encoder_input_contract.py +0 -0
  156. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_encoder_preprocessing.py +0 -0
  157. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_encoder_provider_failures.py +0 -0
  158. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_encoder_registry.py +0 -0
  159. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_execution_options.py +0 -0
  160. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_gigapath.py +0 -0
  161. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_gpfm_genbio_heavy.py +0 -0
  162. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_hierarchical_encoding.py +0 -0
  163. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_hs2p5_integration.py +0 -0
  164. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_hs2p_package_cutover.py +0 -0
  165. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_image_shard.py +0 -0
  166. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_image_stage.py +0 -0
  167. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_inference_benchmark.py +0 -0
  168. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_load_model_hf_auth.py +0 -0
  169. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_mettle.py +0 -0
  170. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_on_slide_persisted.py +0 -0
  171. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_patch_size_metadata.py +0 -0
  172. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_patient_annotation_sampling.py +0 -0
  173. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_patient_manifest.py +0 -0
  174. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_patient_tiling_only.py +0 -0
  175. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_pooled_encoder_input.py +0 -0
  176. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_pooled_geometry.py +0 -0
  177. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_prism.py +0 -0
  178. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_process_list_performance.py +0 -0
  179. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_progress.py +0 -0
  180. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_regression_core.py +0 -0
  181. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_regression_inference.py +0 -0
  182. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_regression_models.py +0 -0
  183. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_rudolfv2.py +0 -0
  184. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_runtime_batching.py +0 -0
  185. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_sharding.py +0 -0
  186. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_slide_coordinate_preparation.py +0 -0
  187. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_slide_latents.py +0 -0
  188. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_tile_store.py +0 -0
  189. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_tiling_pipeline.py +0 -0
  190. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_titan.py +0 -0
  191. {slide2vec-7.1.1 → slide2vec-7.1.3}/tests/test_worker_gpu_pinning.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: slide2vec
3
- Version: 7.1.1
3
+ Version: 7.1.3
4
4
  Summary: Embedding of whole slide images with Foundation Models
5
5
  Author-email: Clément Grisi <clement.grisi@radboudumc.nl>
6
6
  License-Expression: Apache-2.0
@@ -11,94 +11,51 @@ Classifier: Programming Language :: Python :: 3 :: Only
11
11
  Classifier: Programming Language :: Python :: 3.10
12
12
  Classifier: Programming Language :: Python :: 3.11
13
13
  Classifier: Programming Language :: Python :: 3.12
14
- Classifier: Programming Language :: Python :: 3.13
15
14
  Requires-Python: >=3.10
16
15
  Description-Content-Type: text/markdown
17
16
  License-File: LICENSE
18
17
  Requires-Dist: hs2p[asap,cucim,openslide,sam2,tifffile,vips]>=6.1.0
19
18
  Requires-Dist: omegaconf
20
19
  Requires-Dist: matplotlib
21
- Requires-Dist: numpy<2
22
20
  Requires-Dist: pandas
23
21
  Requires-Dist: pillow
24
22
  Requires-Dist: rich
25
23
  Requires-Dist: torch
26
24
  Requires-Dist: torchvision
27
- Requires-Dist: transformers
25
+ Requires-Dist: transformers<5,>=4.47
28
26
  Requires-Dist: wandb
29
27
  Requires-Dist: einops
30
- Requires-Dist: timm>=1.0.3
28
+ Requires-Dist: einops-exts
29
+ Requires-Dist: timm>=1.0.20
31
30
  Requires-Dist: huggingface_hub
32
- Provides-Extra: hoptimus
33
- Requires-Dist: torch>=2.0; extra == "hoptimus"
34
- Requires-Dist: torchvision>=0.15.0; extra == "hoptimus"
35
- Requires-Dist: xformers>=0.0.18; extra == "hoptimus"
36
- Provides-Extra: virchow
37
- Requires-Dist: timm>=1.0.3; extra == "virchow"
38
- Requires-Dist: torch>=2.0; extra == "virchow"
39
- Provides-Extra: uni
40
- Requires-Dist: torch>=2.0; extra == "uni"
41
- Requires-Dist: timm>=1.0.3; extra == "uni"
42
- Requires-Dist: xformers>=0.0.18; extra == "uni"
31
+ Requires-Dist: packaging
43
32
  Provides-Extra: prism
44
- Requires-Dist: transformers~=4.53.0; extra == "prism"
45
- Requires-Dist: torch<2.8,>=2.3; extra == "prism"
46
- Requires-Dist: einops==0.8.0; extra == "prism"
47
- Requires-Dist: environs==11.0.0; extra == "prism"
48
- Requires-Dist: sacremoses==0.1.1; extra == "prism"
49
- Requires-Dist: xformers==0.0.31; extra == "prism"
33
+ Requires-Dist: torch>=2.3; extra == "prism"
34
+ Requires-Dist: environs; extra == "prism"
35
+ Requires-Dist: sacremoses; extra == "prism"
50
36
  Provides-Extra: prism2
51
37
  Requires-Dist: torch>=2.3; extra == "prism2"
52
- Requires-Dist: transformers==4.51.3; extra == "prism2"
53
- Requires-Dist: safetensors; extra == "prism2"
54
- Requires-Dist: einops; extra == "prism2"
55
- Requires-Dist: flash-attn>=2.6.3; extra == "prism2"
56
- Provides-Extra: hibou
57
- Requires-Dist: scipy~=1.8.1; extra == "hibou"
58
- Requires-Dist: scikit-image~=0.19.3; extra == "hibou"
59
- Provides-Extra: moozy
60
- Requires-Dist: huggingface_hub<1.0,>=0.30.0; extra == "moozy"
38
+ Requires-Dist: transformers<5,>=4.51; extra == "prism2"
61
39
  Provides-Extra: titan
62
- Requires-Dist: torch==2.0.1; extra == "titan"
63
- Requires-Dist: timm==1.0.3; extra == "titan"
64
- Requires-Dist: einops==0.6.1; extra == "titan"
65
- Requires-Dist: einops-exts==0.0.4; extra == "titan"
66
- Requires-Dist: transformers==4.46.0; extra == "titan"
40
+ Requires-Dist: einops; extra == "titan"
41
+ Requires-Dist: einops-exts; extra == "titan"
42
+ Requires-Dist: timm>=1.0.3; extra == "titan"
43
+ Requires-Dist: transformers<5,>=4.46; extra == "titan"
67
44
  Provides-Extra: waiv
68
- Requires-Dist: transformers<6,>=5.14; extra == "waiv"
69
- Requires-Dist: safetensors>=0.8; extra == "waiv"
70
- Requires-Dist: huggingface_hub==1.25.1; extra == "waiv"
45
+ Requires-Dist: transformers>=4.57; extra == "waiv"
46
+ Provides-Extra: flash-attn
47
+ Requires-Dist: flash-attn>=2.6.3; extra == "flash-attn"
48
+ Provides-Extra: xformers
49
+ Requires-Dist: xformers; extra == "xformers"
71
50
  Provides-Extra: fm
72
- Requires-Dist: omegaconf>=2.3.0; extra == "fm"
73
- Requires-Dist: matplotlib; extra == "fm"
74
- Requires-Dist: numpy<2; extra == "fm"
75
- Requires-Dist: pandas; extra == "fm"
76
- Requires-Dist: pillow; extra == "fm"
77
- Requires-Dist: rich; extra == "fm"
78
- Requires-Dist: hs2p[asap,cucim,openslide,sam2,tifffile,vips]>=6.1.0; extra == "fm"
79
- Requires-Dist: wandb; extra == "fm"
80
- Requires-Dist: torch<2.8,>=2.3; extra == "fm"
81
- Requires-Dist: torchvision>=0.18.0; extra == "fm"
82
- Requires-Dist: einops>=0.8.0; extra == "fm"
83
- Requires-Dist: timm>=1.0.20; extra == "fm"
84
- Requires-Dist: huggingface_hub<1.0,>=0.30.0; extra == "fm"
85
- Requires-Dist: environs; extra == "fm"
86
- Requires-Dist: einops-exts>=0.0.4; extra == "fm"
87
- Requires-Dist: transformers>=4.53; extra == "fm"
88
- Requires-Dist: sacremoses; extra == "fm"
89
- Requires-Dist: xformers>=0.0.31; extra == "fm"
90
- Requires-Dist: scipy>=1.8.1; extra == "fm"
91
- Requires-Dist: scikit-image>=0.19.3; extra == "fm"
92
- Requires-Dist: torchmetrics>=0.10.3; extra == "fm"
93
- Requires-Dist: fvcore; extra == "fm"
94
- Requires-Dist: iopath; extra == "fm"
95
- Requires-Dist: webdataset; extra == "fm"
96
- Requires-Dist: scikit-survival; extra == "fm"
97
- Requires-Dist: scikit-learn; extra == "fm"
51
+ Requires-Dist: slide2vec[prism,prism2,titan,waiv]; extra == "fm"
98
52
  Requires-Dist: fairscale; extra == "fm"
99
- Requires-Dist: packaging==23.2; extra == "fm"
100
- Requires-Dist: ninja==1.11.1.1; extra == "fm"
101
- Requires-Dist: psutil<6; extra == "fm"
53
+ Provides-Extra: cpu
54
+ Requires-Dist: torch; extra == "cpu"
55
+ Requires-Dist: torchvision; extra == "cpu"
56
+ Provides-Extra: cu128
57
+ Requires-Dist: torch; extra == "cu128"
58
+ Requires-Dist: torchvision; extra == "cu128"
102
59
  Provides-Extra: docs
103
60
  Requires-Dist: sphinx>=8.1; extra == "docs"
104
61
  Requires-Dist: furo; extra == "docs"
@@ -131,6 +88,10 @@ pip install slide2vec
131
88
 
132
89
  Many models need additional dependencies available through `pip install "slide2vec[fm]"`. See the [model installation guide](https://clemsgrs.github.io/slide2vec/models.html#model-installation) for model-specific extras, separate environments, and upstream packages.
133
90
 
91
+ ### Reproducible model environments
92
+
93
+ The repository ships a `uv.lock` file that pins every package for each extra. From a checkout, `uv sync --extra cu128 --extra fm` installs the exact locked stack (use `--extra cpu` for CPU-only PyTorch). Add `--extra flash-attn` for PRISM2 and `gigapath-slide`. The Docker image is built from the same lock; its `SLIDE2VEC_EXTRAS` build argument selects the extras, for example `--build-arg SLIDE2VEC_EXTRAS="cu128"` for the base install only.
94
+
134
95
  For gated models such as Virchow2, request access on the model's Hugging Face page and authenticate with `hf auth login` or an `HF_TOKEN` environment variable.
135
96
 
136
97
  ## Embed a slide
@@ -15,6 +15,10 @@ pip install slide2vec
15
15
 
16
16
  Many models need additional dependencies available through `pip install "slide2vec[fm]"`. See the [model installation guide](https://clemsgrs.github.io/slide2vec/models.html#model-installation) for model-specific extras, separate environments, and upstream packages.
17
17
 
18
+ ### Reproducible model environments
19
+
20
+ The repository ships a `uv.lock` file that pins every package for each extra. From a checkout, `uv sync --extra cu128 --extra fm` installs the exact locked stack (use `--extra cpu` for CPU-only PyTorch). Add `--extra flash-attn` for PRISM2 and `gigapath-slide`. The Docker image is built from the same lock; its `SLIDE2VEC_EXTRAS` build argument selects the extras, for example `--build-arg SLIDE2VEC_EXTRAS="cu128"` for the base install only.
21
+
18
22
  For gated models such as Virchow2, request access on the model's Hugging Face page and authenticate with `hf auth login` or an `HF_TOKEN` environment variable.
19
23
 
20
24
  ## Embed a slide
@@ -0,0 +1,264 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "slide2vec"
7
+ version = "7.1.3"
8
+ description = "Embedding of whole slide images with Foundation Models"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "Apache-2.0"
12
+ authors = [
13
+ { name = "Clément Grisi", email = "clement.grisi@radboudumc.nl" },
14
+ ]
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3 :: Only",
18
+ "Programming Language :: Python :: 3.10",
19
+ "Programming Language :: Python :: 3.11",
20
+ "Programming Language :: Python :: 3.12",
21
+ ]
22
+ dependencies = [
23
+ "hs2p[asap,cucim,openslide,sam2,tifffile,vips]>=6.1.0",
24
+ "omegaconf",
25
+ "matplotlib",
26
+ "pandas",
27
+ "pillow",
28
+ "rich",
29
+ "torch",
30
+ "torchvision",
31
+ # <5: Hibou's remote code imports transformers.onnx and
32
+ # pytorch_utils.find_pruneable_heads_and_indices, both removed in v5.
33
+ # >=4.47: PRISM's configuring_prism.py needs sub_configs / base_config_key.
34
+ "transformers>=4.47,<5",
35
+ "wandb",
36
+ "einops",
37
+ # TITAN remote code (used by the built-in conchv15 preset) imports it.
38
+ "einops-exts",
39
+ # first release that registers vit_base_patch16_dinov3
40
+ "timm>=1.0.20",
41
+ "huggingface_hub",
42
+ "packaging",
43
+ ]
44
+
45
+ [project.urls]
46
+ Homepage = "https://github.com/clemsgrs/slide2vec"
47
+ "Bug Tracker" = "https://github.com/clemsgrs/slide2vec/issues"
48
+
49
+ [project.scripts]
50
+ slide2vec = "slide2vec.cli:entrypoint"
51
+
52
+ # Rule for extras: lower bounds only. An exact or upper pin is kept only when it
53
+ # is structural (the model's code breaks outside it); the reason sits next to
54
+ # the pin. A model whose stack conflicts with the shared stack gets its own
55
+ # extra and a uv conflict below. numpy<2 comes from hs2p[asap].
56
+ [project.optional-dependencies]
57
+ prism = [
58
+ # perceiver.py calls torch.nn.attention.sdpa_kernel with a list (absent in 2.2)
59
+ "torch>=2.3",
60
+ "environs",
61
+ "sacremoses",
62
+ ]
63
+ prism2 = [
64
+ "torch>=2.3",
65
+ # the text (diagnostic) variant calls a Phi3Model helper whose signature
66
+ # changed in 4.52 and which 4.53 removed; slide2vec.encoders.models.prism2
67
+ # vendors it, so no upper bound. PRISM2 also imports flash_attn: add the
68
+ # flash-attn extra (CUDA only, so not pulled in here)
69
+ "transformers>=4.51,<5",
70
+ ]
71
+ titan = [
72
+ "einops",
73
+ "einops-exts",
74
+ "timm>=1.0.3",
75
+ "transformers>=4.46,<5",
76
+ ]
77
+ waiv = [
78
+ # phaet and mascaret load with zero missing keys at the pinned revisions
79
+ "transformers>=4.57",
80
+ ]
81
+ # gigapath-slide needs flash-attn on GPUs with compute capability above 7
82
+ flash-attn = [
83
+ "flash-attn>=2.6.3",
84
+ ]
85
+ xformers = [
86
+ # optional: PRISM's PERCEIVER_MEM_EFF_ATTN path; gigapath-slide needs it
87
+ # on GPUs with compute capability 7 or below. Unpinned: each xformers
88
+ # build pins its torch.
89
+ "xformers",
90
+ ]
91
+ fm = [
92
+ "slide2vec[prism,prism2,titan,waiv]",
93
+ # hard import in MUSK and gigapath-slide
94
+ "fairscale",
95
+ ]
96
+ # torch wheel flavour for uv; when neither is selected torch comes from PyPI
97
+ cpu = [
98
+ "torch",
99
+ "torchvision",
100
+ ]
101
+ cu128 = [
102
+ "torch",
103
+ "torchvision",
104
+ ]
105
+ docs = [
106
+ "sphinx>=8.1",
107
+ "furo",
108
+ "myst-parser",
109
+ "sphinx-copybutton",
110
+ "sphinx-autodoc-typehints",
111
+ ]
112
+ testing = [
113
+ "pytest>=6.0",
114
+ "pytest-cov>=2.0",
115
+ "mypy>=0.910",
116
+ "flake8>=3.9",
117
+ "flake8-pyproject>=1.2.3",
118
+ "tox>=3.24",
119
+ ]
120
+
121
+ [dependency-groups]
122
+ dev = [
123
+ "pytest>=6.0",
124
+ "pytest-cov>=2.0",
125
+ "mypy>=0.910",
126
+ "flake8>=3.9",
127
+ "flake8-pyproject>=1.2.3",
128
+ "tox>=3.24",
129
+ # tests/test_encoder_plugins.py installs a plugin with `python -m pip`;
130
+ # uv environments ship without pip
131
+ "pip",
132
+ ]
133
+ docs = [
134
+ "sphinx>=8.1",
135
+ "furo",
136
+ "myst-parser",
137
+ "sphinx-copybutton",
138
+ "sphinx-autodoc-typehints",
139
+ ]
140
+ # encoder packages that are not on PyPI (musk, conch, gigapath-slide, sam2)
141
+ models-git = [
142
+ "musk",
143
+ "conch",
144
+ "gigapath",
145
+ "sam-2",
146
+ ]
147
+
148
+ [tool.uv]
149
+ # ASAP and cucim are Linux-only. numpy<2 (from hs2p[asap]) has no wheels for
150
+ # Python 3.13+, so the lock covers Python 3.10 to 3.12.
151
+ environments = ["sys_platform == 'linux' and python_full_version < '3.13'"]
152
+ # Lock-only: the cu128 index stops at torch 2.11. Hold the CPU and PyPI forks at
153
+ # the same release so the CPU CI image tests the torch the CUDA image ships.
154
+ # This is not part of the published metadata.
155
+ constraint-dependencies = ["torch<2.12"]
156
+ conflicts = [
157
+ [
158
+ { extra = "cpu" },
159
+ { extra = "cu128" },
160
+ ],
161
+ ]
162
+
163
+ # flash-attn ships only an sdist whose build imports torch; declare its metadata
164
+ # so uv can lock it without building it
165
+ [[tool.uv.dependency-metadata]]
166
+ name = "flash-attn"
167
+ requires-dist = ["torch", "einops"]
168
+
169
+ # flash-attn's setup.py imports torch, packaging, wheel and psutil. Build it in
170
+ # an isolated environment that holds the same torch as the runtime environment.
171
+ [tool.uv.extra-build-dependencies]
172
+ flash-attn = [
173
+ { requirement = "torch", match-runtime = true },
174
+ "packaging",
175
+ "psutil",
176
+ "wheel",
177
+ "ninja",
178
+ ]
179
+
180
+ [tool.uv.sources]
181
+ torch = [
182
+ { index = "pytorch-cpu", extra = "cpu" },
183
+ { index = "pytorch-cu128", extra = "cu128" },
184
+ ]
185
+ torchvision = [
186
+ { index = "pytorch-cpu", extra = "cpu" },
187
+ { index = "pytorch-cu128", extra = "cu128" },
188
+ ]
189
+ musk = { git = "https://github.com/lilab-stanford/MUSK.git" }
190
+ conch = { git = "https://github.com/Mahmoodlab/CONCH.git" }
191
+ gigapath = { git = "https://github.com/prov-gigapath/prov-gigapath.git" }
192
+ sam-2 = { git = "https://github.com/facebookresearch/sam2.git" }
193
+
194
+ [[tool.uv.index]]
195
+ name = "pytorch-cpu"
196
+ url = "https://download.pytorch.org/whl/cpu"
197
+ explicit = true
198
+
199
+ [[tool.uv.index]]
200
+ name = "pytorch-cu128"
201
+ url = "https://download.pytorch.org/whl/cu128"
202
+ explicit = true
203
+
204
+ [tool.setuptools]
205
+ include-package-data = true
206
+ zip-safe = false
207
+
208
+ [tool.setuptools.packages.find]
209
+ include = ["slide2vec*"]
210
+
211
+ [tool.setuptools.package-data]
212
+ slide2vec = ["py.typed", "cufile.json"]
213
+ "slide2vec.configs" = ["*.yaml"]
214
+
215
+ [tool.pytest.ini_options]
216
+ addopts = "--cov=slide2vec -m 'not gpu_integration'"
217
+ testpaths = [
218
+ "tests",
219
+ ]
220
+ markers = [
221
+ "heavy: real-weight foundation-model inference on CPU; minutes per test. Excluded from the PR suite except the PRISM consistency test; run all of them through the manual heavy workflow (.github/workflows/nightly-heavy.yaml).",
222
+ "gpu_integration: real one-GPU versus multi-GPU parity; requires at least two visible CUDA devices. Run explicitly with `CUDA_VISIBLE_DEVICES=0,1 python -m pytest -m gpu_integration --no-cov`.",
223
+ ]
224
+
225
+ [tool.mypy]
226
+ mypy_path = "."
227
+ check_untyped_defs = true
228
+ disallow_any_generics = true
229
+ ignore_missing_imports = true
230
+ no_implicit_optional = true
231
+ show_error_codes = true
232
+ strict_equality = true
233
+ warn_redundant_casts = true
234
+ warn_return_any = true
235
+ warn_unreachable = true
236
+ warn_unused_configs = true
237
+ no_implicit_reexport = true
238
+
239
+ [tool.flake8]
240
+ max-line-length = 160
241
+
242
+ [tool.bumpver]
243
+ current_version = "7.1.3"
244
+ version_pattern = "MAJOR.MINOR.PATCH"
245
+ commit = false
246
+ tag = false
247
+ push = false
248
+ files = [
249
+ "pyproject.toml",
250
+ "slide2vec/__init__.py",
251
+ "docs/conf.py",
252
+ ]
253
+
254
+ [tool.bumpver.file_patterns]
255
+ "pyproject.toml" = [
256
+ '^current_version = "{version}"$',
257
+ '^version = "{version}"$',
258
+ ]
259
+ "slide2vec/__init__.py" = [
260
+ '^__version__ = "{version}"$',
261
+ ]
262
+ "docs/conf.py" = [
263
+ '^release = "{version}"$',
264
+ ]
@@ -36,7 +36,7 @@ from slide2vec.encoders import (
36
36
  )
37
37
 
38
38
 
39
- __version__ = "7.1.1"
39
+ __version__ = "7.1.3"
40
40
 
41
41
  __all__ = [
42
42
  "Model",
@@ -16,6 +16,7 @@ from slide2vec.encoders.base import (
16
16
  resolve_recommended_dynamic_img_size,
17
17
  resolve_requested_output_variant,
18
18
  )
19
+ from slide2vec.encoders.code import encoder_code
19
20
  from slide2vec.encoders.registry import (
20
21
  EncoderCapabilities,
21
22
  EncoderProviderDiagnostic,
@@ -42,6 +43,7 @@ __all__ = [
42
43
  "reshape_tokens_to_grid",
43
44
  "resolve_recommended_dynamic_img_size",
44
45
  "resolve_requested_output_variant",
46
+ "encoder_code",
45
47
  "encoder_registry",
46
48
  "list_encoder_provider_diagnostics",
47
49
  "normalize_patch_size",
@@ -0,0 +1,102 @@
1
+ """The code a registered encoder runs, as the feature identity records it."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Mapping
6
+ import functools
7
+ import hashlib
8
+ from importlib import metadata as importlib_metadata
9
+ import inspect
10
+ import json
11
+ from pathlib import Path
12
+ import re
13
+ import sys
14
+ from typing import Any
15
+
16
+ from slide2vec.encoders.registry import encoder_registry
17
+
18
+
19
+ def encoder_code(name: str) -> dict[str, Any]:
20
+ """Return the code block of the registered encoder *name*.
21
+
22
+ ``object`` is the encoder class's ``module.qualname``. ``fingerprint`` is the
23
+ version of the non-editable installed distribution, other than slide2vec, whose
24
+ ``RECORD`` lists the file that defines the class; otherwise the SHA-256 of that
25
+ file, hashed on every call; ``None`` when there is no file (a class defined in a
26
+ notebook cell). ``source`` is the registry's ``source``. Reads the registry entry
27
+ only: the encoder is not instantiated and no weights are loaded.
28
+ """
29
+ encoder_cls = encoder_registry.require(name)
30
+ return {
31
+ "object": f"{encoder_cls.__module__}.{encoder_cls.__qualname__}",
32
+ "fingerprint": _fingerprint(encoder_cls),
33
+ "source": encoder_registry.info(name)["source"],
34
+ }
35
+
36
+
37
+ def _fingerprint(encoder_cls: type) -> str | None:
38
+ path = _source_file(encoder_cls)
39
+ if path is None:
40
+ return None
41
+ distribution = _installed_distribution(encoder_cls.__module__, path)
42
+ return _sha256(path) if distribution is None else distribution.version
43
+
44
+
45
+ def _installed_distribution(module: str, path: Path) -> importlib_metadata.Distribution | None:
46
+ """The non-editable installed distribution, other than slide2vec, whose ``RECORD``
47
+ lists *path*, or ``None``.
48
+
49
+ slide2vec is left out so that a built-in encoder's identity changes only when a
50
+ release changes its file. The distributions of a namespace package share its
51
+ top-level name and its install directory, so the top-level name only narrows the
52
+ candidates.
53
+ """
54
+ top = module.split(".", 1)[0]
55
+ for name in _packages_distributions(tuple(sys.path)).get(top, ()):
56
+ if re.sub(r"[-_.]+", "-", name).lower() == "slide2vec":
57
+ continue
58
+ try:
59
+ distribution = importlib_metadata.distribution(name)
60
+ except importlib_metadata.PackageNotFoundError:
61
+ continue
62
+ if distribution.read_text("RECORD") is None or _is_editable(distribution):
63
+ continue
64
+ try:
65
+ relative = path.relative_to(Path(distribution.locate_file("")).resolve())
66
+ except ValueError:
67
+ continue
68
+ if relative.as_posix() in {file.as_posix() for file in distribution.files or ()}:
69
+ return distribution
70
+ return None
71
+
72
+
73
+ def _is_editable(distribution) -> bool:
74
+ """Whether *distribution* is an editable install, as its ``direct_url.json`` records."""
75
+ try:
76
+ payload = json.loads(distribution.read_text("direct_url.json") or "{}")
77
+ except json.JSONDecodeError:
78
+ return False
79
+ return isinstance(payload, dict) and bool((payload.get("dir_info") or {}).get("editable"))
80
+
81
+
82
+ @functools.lru_cache(maxsize=1)
83
+ def _packages_distributions(path: tuple[str, ...]) -> Mapping[str, list[str]]:
84
+ """Top-level package -> distributions on the import *path*, scanned once per path."""
85
+ return importlib_metadata.packages_distributions()
86
+
87
+
88
+ def _source_file(encoder_cls: type) -> Path | None:
89
+ """The file that defines *encoder_cls*, or ``None`` (a notebook cell)."""
90
+ try:
91
+ path = Path(inspect.getsourcefile(encoder_cls) or inspect.getfile(encoder_cls))
92
+ except (TypeError, OSError):
93
+ return None
94
+ return path.resolve() if path.is_file() else None
95
+
96
+
97
+ def _sha256(path: Path) -> str:
98
+ digest = hashlib.sha256()
99
+ with path.open("rb") as handle:
100
+ for chunk in iter(lambda: handle.read(1024 * 1024), b""):
101
+ digest.update(chunk)
102
+ return digest.hexdigest()
@@ -36,9 +36,7 @@ def require_timm_for_dinov3() -> None:
36
36
  if Version(timm.__version__) < Version(_MIN_TIMM_VERSION):
37
37
  raise ImportError(
38
38
  f"dinov3-vitb16 requires timm>={_MIN_TIMM_VERSION} (the DINOv3 "
39
- f"architectures were added in that release); found timm=={timm.__version__}. "
40
- "Note that the 'titan' extra pins timm==1.0.3 and cannot be installed "
41
- "alongside dinov3-vitb16."
39
+ f"architectures were added in that release); found timm=={timm.__version__}."
42
40
  )
43
41
 
44
42
 
@@ -79,7 +79,7 @@ def load_moozy_inference_components(device: torch.device) -> MoozyInferenceCompo
79
79
  except Exception as exc:
80
80
  raise RuntimeError(
81
81
  "huggingface_hub is required for bundled MOOZY inference support. "
82
- "Install it with: pip install 'slide2vec[moozy]'"
82
+ "Install it with: pip install huggingface_hub"
83
83
  ) from exc
84
84
 
85
85
  checkpoint_path = hf_hub_download(repo_id=_HF_REPO_ID, filename=_HF_CHECKPOINT)