tracebloc 2.0.0__tar.gz → 3.0.0__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 (225) hide show
  1. {tracebloc-2.0.0 → tracebloc-3.0.0}/PKG-INFO +1 -1
  2. {tracebloc-2.0.0 → tracebloc-3.0.0}/pyproject.toml +3 -9
  3. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/_deprecation.py +0 -1
  4. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/compat/deprecation.py +0 -35
  5. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/exceptions.py +0 -4
  6. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/linking/augmentation_methods.py +1 -1
  7. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/linking/data_methods.py +1 -1
  8. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/linking/model_dataset.py +26 -19
  9. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/linking/training_methods.py +3 -1
  10. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/linking/user_methods.py +1 -1
  11. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/training/memory_estimate.py +41 -34
  12. tracebloc-3.0.0/tracebloc/training/memory_sizing.py +295 -0
  13. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/training/submitter.py +3 -5
  14. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/training/summary.py +26 -4
  15. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/user_methods.py +3 -1
  16. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/user.py +3 -5
  17. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/validation/header_rules.py +23 -7
  18. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/validation/rewriter.py +11 -0
  19. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc.egg-info/PKG-INFO +1 -1
  20. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc.egg-info/SOURCES.txt +1 -0
  21. {tracebloc-2.0.0 → tracebloc-3.0.0}/MANIFEST.in +0 -0
  22. {tracebloc-2.0.0 → tracebloc-3.0.0}/README.md +0 -0
  23. {tracebloc-2.0.0 → tracebloc-3.0.0}/license.txt +0 -0
  24. {tracebloc-2.0.0 → tracebloc-3.0.0}/setup.cfg +0 -0
  25. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/__init__.py +0 -0
  26. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/_framework_utils.py +0 -0
  27. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/_http_utils.py +0 -0
  28. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/_link_answer.py +0 -0
  29. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/_link_regeneration.py +0 -0
  30. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/_linking.py +0 -0
  31. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/_raw_width_note.py +0 -0
  32. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/_stored_link.py +0 -0
  33. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/_upload_conversion.py +0 -0
  34. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/api/__init__.py +0 -0
  35. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/api/experiment_status.py +0 -0
  36. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/api/responses.py +0 -0
  37. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/auth/__init__.py +0 -0
  38. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/auth/env_login.py +0 -0
  39. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/checks.py +0 -0
  40. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/client.py +0 -0
  41. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/compat/__init__.py +0 -0
  42. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/compat/frameworks.py +0 -0
  43. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/config.py +0 -0
  44. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/contracts/stage_urls.v1.json +0 -0
  45. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/contracts/stage_urls.v1.source.json +0 -0
  46. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/contracts/survival_payload.py +0 -0
  47. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/contracts/training_requirements.source.json +0 -0
  48. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/contracts/training_requirements.txt +0 -0
  49. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/__init__.py +0 -0
  50. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/acceptance.py +0 -0
  51. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/families/__init__.py +0 -0
  52. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/families/hf/__init__.py +0 -0
  53. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/families/hf/_build.py +0 -0
  54. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/families/hf/_model_type.py +0 -0
  55. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/families/tabular.py +0 -0
  56. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/families/vision/__init__.py +0 -0
  57. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/families/vision/_matching.py +0 -0
  58. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/gate.py +0 -0
  59. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/heads.py +0 -0
  60. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/interfaces.py +0 -0
  61. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/licence/__init__.py +0 -0
  62. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/licence/spdx.py +0 -0
  63. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/outputs.py +0 -0
  64. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/owncode/__init__.py +0 -0
  65. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/owncode/arguments.py +0 -0
  66. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/owncode/assemble.py +0 -0
  67. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/owncode/checkpoint.py +0 -0
  68. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/owncode/gate_rules.py +0 -0
  69. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/owncode/generate.py +0 -0
  70. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/owncode/head.py +0 -0
  71. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/owncode/import_check.py +0 -0
  72. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/owncode/layer0.py +0 -0
  73. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/owncode/live.py +0 -0
  74. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/owncode/model_class.py +0 -0
  75. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/owncode/remote.py +0 -0
  76. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/owncode/repo.py +0 -0
  77. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/owncode/shake.py +0 -0
  78. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/owncode/source_tree.py +0 -0
  79. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/package.py +0 -0
  80. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/padding.py +0 -0
  81. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/report.py +0 -0
  82. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/tokenizers.py +0 -0
  83. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/convert/training_versions.py +0 -0
  84. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/datasets/__init__.py +0 -0
  85. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/datasets/base.py +0 -0
  86. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/datasets/detection.py +0 -0
  87. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/datasets/keypoint_detection.py +0 -0
  88. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/datasets/semantic_segmentation.py +0 -0
  89. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/datasets/tabular.py +0 -0
  90. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/datasets/text.py +0 -0
  91. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/datasets/time_series.py +0 -0
  92. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/datasets/time_to_event.py +0 -0
  93. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/downloads/lifelines_weights.py +0 -0
  94. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/downloads/seed_weights.py +0 -0
  95. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/env_login.py +0 -0
  96. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/fetch.py +0 -0
  97. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/inference.py +0 -0
  98. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/library_fetch.py +0 -0
  99. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/lifelines_weights.py +0 -0
  100. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/link_model_dataset.py +0 -0
  101. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/linking/__init__.py +0 -0
  102. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/linking/answer.py +0 -0
  103. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/linking/check_model.py +0 -0
  104. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/linking/conversion.py +0 -0
  105. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/linking/library.py +0 -0
  106. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/linking/regeneration.py +0 -0
  107. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/linking/response.py +0 -0
  108. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/linking/stored.py +0 -0
  109. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/notebook/__init__.py +0 -0
  110. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/notebook/templates/_partials.tpl +0 -0
  111. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/notebook/templates/embeddings.tpl +0 -0
  112. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/notebook/templates/nlp_finetune.tpl +0 -0
  113. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/notebook/templates/nlp_generative.tpl +0 -0
  114. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/notebook/templates/survival.tpl +0 -0
  115. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/notebook/templates/tabular_timeseries.tpl +0 -0
  116. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/notebook/templates/vision_from_scratch.tpl +0 -0
  117. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/raw_mode/__init__.py +0 -0
  118. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/raw_mode/classes.py +0 -0
  119. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/raw_mode/declaration.py +0 -0
  120. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/raw_mode/fitted_model.py +0 -0
  121. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/raw_mode/frame_recording.py +0 -0
  122. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/raw_mode/link_check.py +0 -0
  123. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/raw_mode/pairs.py +0 -0
  124. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/raw_mode/schema.py +0 -0
  125. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/raw_mode/seed_prefixes.py +0 -0
  126. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/raw_mode/sklearn_check.py +0 -0
  127. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/raw_mode/survival.py +0 -0
  128. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/raw_mode/torch_checks.py +0 -0
  129. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/raw_mode/width_note.py +0 -0
  130. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/raw_mode_frame.py +0 -0
  131. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/raw_mode_seed.py +0 -0
  132. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/raw_mode_survival.py +0 -0
  133. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/raw_mode_torch.py +0 -0
  134. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/seed_weights.py +0 -0
  135. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/training/__init__.py +0 -0
  136. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/training/augmentation.py +0 -0
  137. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/training/callbacks.py +0 -0
  138. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/training/converted.py +0 -0
  139. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/training/features.py +0 -0
  140. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/training/image_channels.py +0 -0
  141. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/training/image_size.py +0 -0
  142. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/training/link_total.py +0 -0
  143. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/training/lora.py +0 -0
  144. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/training/lora_validation.py +0 -0
  145. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/training/loss.py +0 -0
  146. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/training/loss_policy.py +0 -0
  147. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/training/loss_source.py +0 -0
  148. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/training/plan.py +0 -0
  149. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/training/preprocessing.py +0 -0
  150. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/training/shape.py +0 -0
  151. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/training/subdataset.py +0 -0
  152. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/__init__.py +0 -0
  153. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/lifelines_time_to_event.py +0 -0
  154. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/loss_config.py +0 -0
  155. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/model_params.py +0 -0
  156. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/model_upload.py +0 -0
  157. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/nlp_probes.py +0 -0
  158. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/scikit_survival_time_to_event.py +0 -0
  159. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/sequence_length.py +0 -0
  160. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/skl_tabular_base.py +0 -0
  161. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/skl_tabular_classifier.py +0 -0
  162. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/skl_tabular_regression.py +0 -0
  163. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/statistical_base.py +0 -0
  164. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/survival_base.py +0 -0
  165. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/torch_causal_language_modeler.py +0 -0
  166. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/torch_embeddings.py +0 -0
  167. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/torch_handler.py +0 -0
  168. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/torch_image_classifier.py +0 -0
  169. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/torch_key_point_detector.py +0 -0
  170. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/torch_masked_language_modeler.py +0 -0
  171. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/torch_multi_label_text_classifier.py +0 -0
  172. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/torch_nlp_base.py +0 -0
  173. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/torch_object_detector.py +0 -0
  174. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/torch_semantic_segmentation.py +0 -0
  175. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/torch_sentence_pair_classifier.py +0 -0
  176. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/torch_seq2seq_modeler.py +0 -0
  177. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/torch_tabular_classifier.py +0 -0
  178. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/torch_tabular_regression.py +0 -0
  179. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/torch_text_classifier.py +0 -0
  180. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/torch_text_regressor.py +0 -0
  181. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/torch_time_series_classifier.py +0 -0
  182. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/torch_time_series_forecaster.py +0 -0
  183. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/torch_time_to_event.py +0 -0
  184. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/torch_token_classifier.py +0 -0
  185. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/weight_loaders.py +0 -0
  186. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/weights_averaging.py +0 -0
  187. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/weights_check.py +0 -0
  188. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/upload/weights_parts.py +0 -0
  189. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/__init__.py +0 -0
  190. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/class_order.py +0 -0
  191. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/constants.py +0 -0
  192. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/custom_loss_probe.py +0 -0
  193. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/data_probes.py +0 -0
  194. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/declared_classes.py +0 -0
  195. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/declared_cls.py +0 -0
  196. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/detection_utils.py +0 -0
  197. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/device.py +0 -0
  198. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/entry_point.py +0 -0
  199. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/errors.py +0 -0
  200. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/feature_dict.py +0 -0
  201. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/general_utils.py +0 -0
  202. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/key_point_detection_utils.py +0 -0
  203. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/model_loading.py +0 -0
  204. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/model_params.py +0 -0
  205. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/registry.py +0 -0
  206. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/resources.py +0 -0
  207. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/safetensors_io.py +0 -0
  208. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/semantic_segmentation_utils.py +0 -0
  209. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/tabular_classification_utils.py +0 -0
  210. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/tabular_custom_loss_utils.py +0 -0
  211. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/tabular_regression_utils.py +0 -0
  212. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/text_classification_utils.py +0 -0
  213. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/time_series_utils.py +0 -0
  214. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/time_to_event_utils.py +0 -0
  215. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/utils/warnings_once.py +0 -0
  216. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/validation/__init__.py +0 -0
  217. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/validation/checker.py +0 -0
  218. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/validation/estimator_checks.py +0 -0
  219. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/validation/lifelines_checks.py +0 -0
  220. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/validation/pytorch_checks.py +0 -0
  221. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/validation/scikit_survival_checks.py +0 -0
  222. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc/validation/sklearn_checks.py +0 -0
  223. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc.egg-info/dependency_links.txt +0 -0
  224. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc.egg-info/requires.txt +0 -0
  225. {tracebloc-2.0.0 → tracebloc-3.0.0}/tracebloc.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tracebloc
3
- Version: 2.0.0
3
+ Version: 3.0.0
4
4
  Summary: Build AI with anyone. On data that can't move. SDK for the tracebloc collaborative AI workspace.
5
5
  Author-email: tracebloc <lukas@tracebloc.io>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "tracebloc"
7
- version = "2.0.0"
7
+ version = "3.0.0"
8
8
  description = "Build AI with anyone. On data that can't move. SDK for the tracebloc collaborative AI workspace."
9
9
  license = "MIT"
10
10
  license-files = ["license.txt"]
@@ -231,14 +231,8 @@ select = ["N"]
231
231
  ignore = ["N812"]
232
232
 
233
233
  [tool.ruff.lint.per-file-ignores]
234
- # Deprecation helpers: lowercase class name is intentional (decorator-like
235
- # descriptor), and module-level __getattr__/__dir__ are PEP 562 dunders.
236
- "tracebloc/compat/deprecation.py" = ["N801", "N807"]
237
-
238
- # Deprecated camelCase class/method aliases are preserved until 1.0.0.
239
- # SDK.2c (class) and SDK.2d (method) aliases land as class-scope mixedCase.
240
- "tracebloc/linking/model_dataset.py" = ["N815"]
241
- "tracebloc/user.py" = ["N815"]
234
+ # Deprecation helpers: module-level __getattr__/__dir__ are PEP 562 dunders.
235
+ "tracebloc/compat/deprecation.py" = ["N807"]
242
236
 
243
237
  # YOLO / vision math uses single-letter S, B, C, H, W variables per ML
244
238
  # convention (grid size, boxes, classes, height, width).
@@ -5,7 +5,6 @@ imports from the new module.
5
5
  """
6
6
 
7
7
  from tracebloc.compat.deprecation import ( # noqa: F401 (re-export, RFC-0348 C.3)
8
- deprecated_method_alias,
9
8
  deprecated_aliases,
10
9
  discard_removed_kwarg,
11
10
  _Sentinel,
@@ -24,41 +24,6 @@ import warnings
24
24
  from typing import Callable, Dict, Tuple
25
25
 
26
26
 
27
- class deprecated_method_alias:
28
- """Descriptor exposing an old-name method as a forwarder to a new-name method.
29
-
30
- Class-body usage::
31
-
32
- class User:
33
- def upload_model(self, ...): ...
34
-
35
- uploadModel = deprecated_method_alias("upload_model")
36
-
37
- Accessing the old name emits a single ``DeprecationWarning``
38
- naming both the old and new method, then returns the new bound
39
- method — so calls still reach the new implementation. Old names
40
- are removed in 1.0.0.
41
- """
42
-
43
- def __init__(self, new_name: str) -> None:
44
- self._new_name = new_name
45
- self._old_name = ""
46
-
47
- def __set_name__(self, owner: type, name: str) -> None:
48
- self._old_name = name
49
-
50
- def __get__(self, instance, owner=None):
51
- if instance is None:
52
- return self
53
- warnings.warn(
54
- f"{self._old_name}() is deprecated; use {self._new_name}() instead. "
55
- f"The old name will be removed in 1.0.0.",
56
- DeprecationWarning,
57
- stacklevel=2,
58
- )
59
- return getattr(instance, self._new_name)
60
-
61
-
62
27
  def deprecated_aliases(
63
28
  mapping: Dict[str, str],
64
29
  ) -> Tuple[Callable[[str], object], Callable[[], list]]:
@@ -99,10 +99,6 @@ class RawModeCheckError(DatasetLinkingError):
99
99
  preparation or output the platform cannot score."""
100
100
 
101
101
 
102
- class TrainingPlanError(TraceblocError):
103
- """Raised when a training plan configuration is invalid."""
104
-
105
-
106
102
  class UnsupportedPairError(TraceblocError, ValueError):
107
103
  """Raised when a ``(category, framework)`` pair is not one the SDK trains."""
108
104
 
@@ -9,7 +9,7 @@ import os
9
9
  import json
10
10
  from termcolor import colored
11
11
  import numbers
12
- from tracebloc.compat.deprecation import deprecated_method_alias, discard_removed_kwarg
12
+ from tracebloc.compat.deprecation import discard_removed_kwarg
13
13
  from tracebloc.training import subdataset
14
14
  from tracebloc.training.subdataset import class_set_error, dataset_error, request_error
15
15
  from tracebloc.training.image_channels import image_channel_check
@@ -9,7 +9,7 @@ import os
9
9
  import json
10
10
  from termcolor import colored
11
11
  import numbers
12
- from tracebloc.compat.deprecation import deprecated_method_alias, discard_removed_kwarg
12
+ from tracebloc.compat.deprecation import discard_removed_kwarg
13
13
  from tracebloc.training import subdataset
14
14
  from tracebloc.training.subdataset import class_set_error, dataset_error, request_error
15
15
  from tracebloc.training.image_channels import image_channel_check
@@ -4,7 +4,7 @@ import os
4
4
  import json
5
5
  from termcolor import colored
6
6
  import numbers
7
- from tracebloc.compat.deprecation import deprecated_method_alias, discard_removed_kwarg
7
+ from tracebloc.compat.deprecation import discard_removed_kwarg
8
8
  from tracebloc.training import subdataset
9
9
  from tracebloc.training.subdataset import class_set_error, dataset_error, request_error
10
10
  from tracebloc.training.image_channels import image_channel_check
@@ -120,6 +120,7 @@ class LinkModelDataset(DataPlanMethods, TrainingPlanMethods, AugmentationMethods
120
120
  "class_order",
121
121
  "conversion",
122
122
  "dataset_sequence_length",
123
+ "max_batch_size",
123
124
  },
124
125
  )
125
126
  self._framework = kwargs["framework"]
@@ -154,6 +155,12 @@ class LinkModelDataset(DataPlanMethods, TrainingPlanMethods, AugmentationMethods
154
155
  self._num_classes = kwargs["num_classes"]
155
156
  self._class_names = kwargs["class_names"]
156
157
  self._batch_size = kwargs["batch_size"]
158
+ # The model file's max_batch_size, and whether batch_size() or
159
+ # enable_lora() set a value: see tracebloc.training.memory_sizing.
160
+ self._max_batch_size = kwargs.get("max_batch_size")
161
+ self._batch_explicit = False
162
+ self._lora_explicit = False
163
+ self._memory_refusal = None
157
164
  # The model's declared num_feature_points (keypoints / tabular columns /
158
165
  # time-series features), threaded from upload so link-time validation
159
166
  # handlers build dummy data with the right dimension. ``_data_shape`` is
@@ -277,6 +284,12 @@ class LinkModelDataset(DataPlanMethods, TrainingPlanMethods, AugmentationMethods
277
284
  from tracebloc.training.submitter import ExperimentSubmitter
278
285
 
279
286
  self._submitter = ExperimentSubmitter(facade=self)
287
+ from tracebloc.training.memory_sizing import announce, size_plan
288
+
289
+ self._sizing = size_plan(self)
290
+ line = announce(self._sizing)
291
+ if line:
292
+ print(colored(line, "yellow"), "\n")
280
293
 
281
294
  def reset_training_plan(self) -> None:
282
295
  self._callbacks_cfg.reset()
@@ -285,6 +298,8 @@ class LinkModelDataset(DataPlanMethods, TrainingPlanMethods, AugmentationMethods
285
298
  self._training_dataset_size = self.default_dict["total_dataset_size"]
286
299
  self._training_classes = self.default_dict["class_names"]
287
300
  self._batch_size = self.default_dict["batch_size"]
301
+ self._batch_explicit = False
302
+ self._lora_explicit = False
288
303
  self._aug.reset()
289
304
  self._layers_non_trainable = ""
290
305
  self._metrics = str(["accuracy"])
@@ -315,6 +330,10 @@ class LinkModelDataset(DataPlanMethods, TrainingPlanMethods, AugmentationMethods
315
330
  self._error_method = []
316
331
  self._eligibility_passed = True
317
332
  self._validate_image_channels()
333
+ from tracebloc.training.memory_sizing import size_plan
334
+
335
+ self._memory_refusal = None
336
+ self._sizing = size_plan(self)
318
337
  print("Training Plan Parameters reset")
319
338
 
320
339
  def _print_error(self, method, error):
@@ -408,13 +427,15 @@ class LinkModelDataset(DataPlanMethods, TrainingPlanMethods, AugmentationMethods
408
427
 
409
428
  def plan(self) -> dict:
410
429
  """The applied plan, JSON-serialisable: ``{cycles, epochs, batch_size,
411
- eligible, errors: [{method, message}]}``; prints nothing."""
430
+ sizing, eligible, errors: [{method, message}]}``, where ``sizing`` is
431
+ what memory sizing chose (``{outcome, lora, note}``) or ``None``;
432
+ prints nothing."""
412
433
  return self._summary().plan()
413
434
 
414
435
  def memory_check(self) -> dict | None:
415
- """Peak-memory estimate vs the client's per-run limit: ``{estimate_gib,
416
- terms_gib, limit_gib, warning}`` (``warning``: what ``start()`` prints,
417
- else ``None``), or ``None`` if unsized. Never raises (backend#5165)."""
436
+ """Peak-memory estimate vs each training's memory: ``{estimate_gib,
437
+ terms_gib, limit_gib, warning}`` (``warning``: why ``start()`` refuses
438
+ the plan, else ``None``), or ``None`` if unsized. Never raises."""
418
439
  return self._submitter.memory_check()
419
440
 
420
441
  def get_function_name(self, method_object) -> str:
@@ -439,20 +460,6 @@ class LinkModelDataset(DataPlanMethods, TrainingPlanMethods, AugmentationMethods
439
460
  """Rich HTML rendering of the current training plan for Jupyter."""
440
461
  return self._summary().repr_html()
441
462
 
442
- # --- Deprecated camelCase method aliases (removed in 1.0.0) -----------
443
- resetTrainingPlan = deprecated_method_alias("reset_training_plan")
444
- trainingClasses = deprecated_method_alias("training_classes")
445
- dataType = deprecated_method_alias("data_type")
446
- experimentName = deprecated_method_alias("experiment_name")
447
- learningRate = deprecated_method_alias("learning_rate")
448
- lossFunction = deprecated_method_alias("loss_function")
449
- layersFreeze = deprecated_method_alias("layers_freeze")
450
- terminateOnNaNCallback = deprecated_method_alias("terminate_on_nan_callback")
451
- modelCheckpointCallback = deprecated_method_alias("model_checkpoint_callback")
452
- earlystopCallback = deprecated_method_alias("early_stop_callback")
453
- reducelrCallback = deprecated_method_alias("reduce_lr_callback")
454
- getTrainingPlan = deprecated_method_alias("get_training_plan")
455
-
456
463
 
457
464
  # --- Deprecated class alias (removed in 1.0.0) ---
458
465
  from tracebloc.compat.deprecation import deprecated_aliases
@@ -9,7 +9,7 @@ import os
9
9
  import json
10
10
  from termcolor import colored
11
11
  import numbers
12
- from tracebloc.compat.deprecation import deprecated_method_alias, discard_removed_kwarg
12
+ from tracebloc.compat.deprecation import discard_removed_kwarg
13
13
  from tracebloc.training import subdataset
14
14
  from tracebloc.training.subdataset import class_set_error, dataset_error, request_error
15
15
  from tracebloc.training.image_channels import image_channel_check
@@ -76,6 +76,7 @@ class TrainingPlanMethods:
76
76
  """The run's batch size; the model file's ``batch_size`` is the default."""
77
77
  if self._plan.batch_size(batch_size):
78
78
  self._batch_size = batch_size
79
+ self._batch_explicit = True
79
80
 
80
81
  def epochs(self, epochs: int) -> None:
81
82
  """
@@ -341,6 +342,7 @@ class TrainingPlanMethods:
341
342
  )
342
343
  return
343
344
  self._lora.enable_lora(lora_enable)
345
+ self._lora_explicit = True
344
346
 
345
347
  def set_lora_parameters(
346
348
  self, lora_r: int, lora_alpha: int, lora_dropout: float, q_lora: bool
@@ -13,7 +13,6 @@ import rich
13
13
 
14
14
  from tracebloc.compat.deprecation import (
15
15
  UNSET,
16
- deprecated_method_alias,
17
16
  resolve_renamed_kwarg,
18
17
  )
19
18
  from tracebloc.linking.response import (
@@ -137,6 +136,7 @@ class UserLinkMethods:
137
136
  data_shape=self._User__data_shape,
138
137
  num_feature_points=self._User__num_feature_points,
139
138
  batch_size=self._User__batch_size,
139
+ max_batch_size=getattr(self, "_User__max_batch_size", None),
140
140
  model_path=self._User__model_path,
141
141
  # LinkModelDataset still spells this keyword ``environment`` — its
142
142
  # internal plumbing carries the stage *value* and is deliberately
@@ -1,11 +1,11 @@
1
- """Peak-memory estimate for one training run, and the warning when it may not fit.
1
+ """Peak-memory estimate for one training, and why a plan does not fit.
2
2
 
3
3
  WHY (tracebloc/backend#5165). A causal-LM run (distilgpt2, batch 8, sequence
4
4
  128, no LoRA) was OOM-killed three times at a client's 3 GiB per-run limit, and
5
- nothing said beforehand that it would not fit. ``start()`` now puts the run's
6
- estimated PEAK next to what the client gives each run, and warns. It never
7
- blocks: the estimate is an estimate, and the limit is the data owner's
8
- (``tb resources set``), not ours to override.
5
+ nothing said beforehand that it would not fit. The plan is now sized to the
6
+ memory each training gets (``tracebloc.training.memory_sizing``), and
7
+ ``start()`` refuses one that does not fit: the limit is the data owner's
8
+ (``tracebloc resources set``), not ours to override.
9
9
 
10
10
  WHAT IS COUNTED. Bytes resident at the worst moment of a cycle, PyTorch only
11
11
  (the other frameworks have no comparable state to count, so they get no
@@ -17,9 +17,9 @@ estimate rather than a guess):
17
17
  model state and step transients, which leaves ~1 GiB here.
18
18
  ``weights`` every parameter, ``DTYPE_BYTES`` each (fp32 training).
19
19
  ``gradients`` one per TRAINABLE parameter.
20
- ``optimizer`` per trainable parameter: 2 states for the Adam family, 1 for
21
- the rest (SGD's momentum buffer, RMSprop's square average);
22
- an optimizer we do not know counts as Adam.
20
+ ``optimizer`` per trainable parameter, the parameter-sized tensors the
21
+ optimizer keeps (``_OPTIMIZER_STATES``); an optimizer not
22
+ listed there counts as Adam.
23
23
  ``activations`` what autograd keeps for backward. Text: the transformer
24
24
  estimate of Korthikanti et al. 2022 (arXiv:2205.05198),
25
25
  ``17·s·h + 2.5·a·s²`` elements per layer per sample, at
@@ -30,24 +30,23 @@ estimate rather than a guess):
30
30
  ``LOGITS_COPIES`` (4) times: the logits, the shifted copy
31
31
  the causal loss makes, log-softmax, and its gradient.
32
32
  Masked / causal LM and seq2seq only.
33
- ``save`` end of each cycle the engine merges and clones the full
34
- state dict, converts it to numpy and serializes it
35
- (tracebloc-engine#1513): ``SAVE_COPIES`` (3) more copies of
36
- the weights.
33
+ ``save`` end of each cycle the engine writes the weights from views
34
+ of the model's storage, or a delta built one key at a time
35
+ (fp16, sparse, under one copy); ``safetensors`` before 0.8
36
+ flattens that payload once more to write it. ``SAVE_COPIES``
37
+ (1) copy of the weights covers both.
37
38
 
38
- PEAK, NOT AVERAGE. The step's transients and the save's copies are ADDED,
39
- not maxed: CPU RSS does not drop after a step (the allocator keeps the freed
40
- pages), so the save lands on top of the step's high-water mark. That is how
41
- the measured run 2 died at 3 GiB while its 30-second samples never passed
42
- 1.88 GiB.
39
+ PEAK, NOT AVERAGE. The step's transients and the save's copy are ADDED, not
40
+ maxed: CPU RSS does not drop after a step (the allocator keeps the freed
41
+ pages), so the save lands on top of the step's high-water mark.
43
42
 
44
43
  LoRA. Trainable parameters are the adapters the engine would add: ``r·(in +
45
44
  out)`` per ``nn.Linear`` (the engine adapts ``nn.Linear`` only). Activations
46
45
  are still counted in full, which over-counts when the adapters sit only near
47
46
  the output; conservative on purpose.
48
47
 
49
- WARN, AT A MARGIN. The estimate cannot see allocator fragmentation or short
50
- evaluation spikes, so it warns from ``WARN_FRACTION`` (90%) of the limit up.
48
+ FIT, AT A MARGIN. The estimate cannot see allocator fragmentation or short
49
+ evaluation spikes, so a plan fits only below ``WARN_FRACTION`` (90%) of the limit.
51
50
  """
52
51
 
53
52
  from __future__ import annotations
@@ -75,7 +74,7 @@ GB = 1000**3
75
74
  RUNTIME_BYTES = 1 * GIB
76
75
  DTYPE_BYTES = 4
77
76
  LOGITS_COPIES = 4
78
- SAVE_COPIES = 3
77
+ SAVE_COPIES = 1
79
78
  IMAGE_ACTIVATION_FACTOR = 100
80
79
  WARN_FRACTION = 0.9
81
80
 
@@ -97,10 +96,21 @@ _IMAGE_CATEGORIES = frozenset(
97
96
  KEYPOINT_DETECTION,
98
97
  }
99
98
  )
100
- _ONE_STATE_OPTIMIZERS = frozenset(
101
- {"sgd", "rmsprop", "adagrad", "adadelta", "asgd", "rprop", "lion"}
102
- )
103
- _NO_STATE_OPTIMIZERS = frozenset({"lbfgs"})
99
+ #: Parameter-sized state tensors per parameter, for every optimizer the engine
100
+ #: builds, as it builds them: ``torch.optim.<Name>(params, lr=...)``, so SGD has
101
+ #: torch's default momentum 0 and keeps no momentum buffer.
102
+ _OPTIMIZER_STATES = {
103
+ "sgd": 0,
104
+ "adam": 2,
105
+ "adamw": 2,
106
+ "adamax": 2,
107
+ "adadelta": 2,
108
+ "rprop": 2,
109
+ "rmsprop": 1,
110
+ "adagrad": 1,
111
+ "asgd": 1,
112
+ }
113
+ _UNKNOWN_OPTIMIZER_STATES = 2
104
114
 
105
115
 
106
116
  @dataclass(frozen=True)
@@ -193,11 +203,7 @@ def describe_model(model: Any) -> ModelShape | None:
193
203
 
194
204
  def _optimizer_states(optimizer: Any) -> int:
195
205
  name = str(optimizer or "").strip().lower()
196
- if name in _NO_STATE_OPTIMIZERS:
197
- return 0
198
- if name in _ONE_STATE_OPTIMIZERS:
199
- return 1
200
- return 2 # the Adam family, and anything we do not recognise
206
+ return _OPTIMIZER_STATES.get(name, _UNKNOWN_OPTIMIZER_STATES)
201
207
 
202
208
 
203
209
  def _lora_trainable(shape: ModelShape, rank: int) -> int:
@@ -316,7 +322,8 @@ def needed_bytes(estimate: MemoryEstimate, where: str = "memory") -> int:
316
322
  def memory_fit_warning(
317
323
  estimate: MemoryEstimate, limit_bytes: int, where: str = "memory"
318
324
  ) -> str | None:
319
- """The warning to print, or ``None`` when the estimate fits with margin."""
325
+ """Why the plan does not fit ``limit_bytes``, or ``None`` when it fits with
326
+ margin. ``start()`` refuses a plan with this message (``memory_sizing``)."""
320
327
  needed = needed_bytes(estimate, where)
321
328
  if needed < WARN_FRACTION * limit_bytes:
322
329
  return None
@@ -331,14 +338,14 @@ def memory_fit_warning(
331
338
  if text and not estimate.inputs.get("lora"):
332
339
  fixes.append("turn on LoRA")
333
340
  if where != "GPU memory":
334
- fixes.append("raise the limit with `tb resources set --memory`")
341
+ fixes.append("raise the limit with `tracebloc resources set --memory`")
335
342
  advice = (
336
343
  fixes[0] if len(fixes) == 1 else ", ".join(fixes[:-1]) + ", or " + fixes[-1]
337
344
  )
338
345
  return (
339
- f"Memory warning: this run may need ~{needed / GIB:.1f} GiB of {where} "
340
- f"at its peak; your client gives each run {limit_bytes / GIB:.1f} GiB. "
341
- f"It may be killed for running out of memory. To fit, {advice}."
346
+ f"This training needs about {needed / GIB:.1f} GiB of {where} at its "
347
+ f"peak, and the smallest secure environment it trains on gives each "
348
+ f"training {limit_bytes / GIB:.1f} GiB. To fit, {advice}."
342
349
  )
343
350
 
344
351