bergson 2.2.4__tar.gz → 2.3.1__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 (180) hide show
  1. {bergson-2.2.4 → bergson-2.3.1}/PKG-INFO +1 -1
  2. {bergson-2.2.4 → bergson-2.3.1}/bergson/__init__.py +1 -1
  3. {bergson-2.2.4 → bergson-2.3.1}/bergson/config/config.py +10 -1
  4. {bergson-2.2.4 → bergson-2.3.1}/bergson/data.py +29 -7
  5. {bergson-2.2.4 → bergson-2.3.1}/bergson/hessians/pipeline.py +3 -3
  6. {bergson-2.2.4 → bergson-2.3.1}/bergson/utils/worker_utils.py +27 -11
  7. {bergson-2.2.4 → bergson-2.3.1}/bergson.egg-info/PKG-INFO +1 -1
  8. {bergson-2.2.4 → bergson-2.3.1}/bergson.egg-info/SOURCES.txt +1 -0
  9. {bergson-2.2.4 → bergson-2.3.1}/pyproject.toml +1 -1
  10. {bergson-2.2.4 → bergson-2.3.1}/tests/test_advantages.py +55 -0
  11. bergson-2.3.1/tests/test_select_split.py +39 -0
  12. {bergson-2.2.4 → bergson-2.3.1}/LICENSE +0 -0
  13. {bergson-2.2.4 → bergson-2.3.1}/README.md +0 -0
  14. {bergson-2.2.4 → bergson-2.3.1}/bergson/__main__.py +0 -0
  15. {bergson-2.2.4 → bergson-2.3.1}/bergson/approx_unrolling/adam_preconditioner.py +0 -0
  16. {bergson-2.2.4 → bergson-2.3.1}/bergson/approx_unrolling/approx_unrolling_math.py +0 -0
  17. {bergson-2.2.4 → bergson-2.3.1}/bergson/approx_unrolling/pipeline.py +0 -0
  18. {bergson-2.2.4 → bergson-2.3.1}/bergson/approx_unrolling/precompute_checkpoints.py +0 -0
  19. {bergson-2.2.4 → bergson-2.3.1}/bergson/approx_unrolling/segment_aggregation.py +0 -0
  20. {bergson-2.2.4 → bergson-2.3.1}/bergson/approx_unrolling/train_cfg_io.py +0 -0
  21. {bergson-2.2.4 → bergson-2.3.1}/bergson/build.py +0 -0
  22. {bergson-2.2.4 → bergson-2.3.1}/bergson/builder.py +0 -0
  23. {bergson-2.2.4 → bergson-2.3.1}/bergson/cli/__init__.py +0 -0
  24. {bergson-2.2.4 → bergson-2.3.1}/bergson/cli/commands.py +0 -0
  25. {bergson-2.2.4 → bergson-2.3.1}/bergson/cli/trackstar.py +0 -0
  26. {bergson-2.2.4 → bergson-2.3.1}/bergson/cli/trak.py +0 -0
  27. {bergson-2.2.4 → bergson-2.3.1}/bergson/collection.py +0 -0
  28. {bergson-2.2.4 → bergson-2.3.1}/bergson/collector/__init__.py +0 -0
  29. {bergson-2.2.4 → bergson-2.3.1}/bergson/collector/collector.py +0 -0
  30. {bergson-2.2.4 → bergson-2.3.1}/bergson/collector/dist_autocorrelation_gradient_collector.py +0 -0
  31. {bergson-2.2.4 → bergson-2.3.1}/bergson/collector/gradient_collectors.py +0 -0
  32. {bergson-2.2.4 → bergson-2.3.1}/bergson/collector/in_memory_collector.py +0 -0
  33. {bergson-2.2.4 → bergson-2.3.1}/bergson/collector/projection_matrix.py +0 -0
  34. {bergson-2.2.4 → bergson-2.3.1}/bergson/config/__init__.py +0 -0
  35. {bergson-2.2.4 → bergson-2.3.1}/bergson/config/config_io.py +0 -0
  36. {bergson-2.2.4 → bergson-2.3.1}/bergson/config/validation.py +0 -0
  37. {bergson-2.2.4 → bergson-2.3.1}/bergson/diagnose.py +0 -0
  38. {bergson-2.2.4 → bergson-2.3.1}/bergson/distributed.py +0 -0
  39. {bergson-2.2.4 → bergson-2.3.1}/bergson/format.py +0 -0
  40. {bergson-2.2.4 → bergson-2.3.1}/bergson/gradients.py +0 -0
  41. {bergson-2.2.4 → bergson-2.3.1}/bergson/hessians/apply_hessian.py +0 -0
  42. {bergson-2.2.4 → bergson-2.3.1}/bergson/hessians/astra.py +0 -0
  43. {bergson-2.2.4 → bergson-2.3.1}/bergson/hessians/autocorrelation.py +0 -0
  44. {bergson-2.2.4 → bergson-2.3.1}/bergson/hessians/eigenvectors.py +0 -0
  45. {bergson-2.2.4 → bergson-2.3.1}/bergson/hessians/hessian_approximations.py +0 -0
  46. {bergson-2.2.4 → bergson-2.3.1}/bergson/hessians/inversion.py +0 -0
  47. {bergson-2.2.4 → bergson-2.3.1}/bergson/hessians/kfac.py +0 -0
  48. {bergson-2.2.4 → bergson-2.3.1}/bergson/hessians/preconditioner.py +0 -0
  49. {bergson-2.2.4 → bergson-2.3.1}/bergson/hessians/shampoo.py +0 -0
  50. {bergson-2.2.4 → bergson-2.3.1}/bergson/hessians/sharded_computation.py +0 -0
  51. {bergson-2.2.4 → bergson-2.3.1}/bergson/hessians/tkfac.py +0 -0
  52. {bergson-2.2.4 → bergson-2.3.1}/bergson/huggingface.py +0 -0
  53. {bergson-2.2.4 → bergson-2.3.1}/bergson/magic/__init__.py +0 -0
  54. {bergson-2.2.4 → bergson-2.3.1}/bergson/magic/cli.py +0 -0
  55. {bergson-2.2.4 → bergson-2.3.1}/bergson/magic/config.py +0 -0
  56. {bergson-2.2.4 → bergson-2.3.1}/bergson/magic/data_stream.py +0 -0
  57. {bergson-2.2.4 → bergson-2.3.1}/bergson/magic/dtensor_patch.py +0 -0
  58. {bergson-2.2.4 → bergson-2.3.1}/bergson/magic/fsdp.py +0 -0
  59. {bergson-2.2.4 → bergson-2.3.1}/bergson/magic/grad_accum.py +0 -0
  60. {bergson-2.2.4 → bergson-2.3.1}/bergson/magic/metasmoothness.py +0 -0
  61. {bergson-2.2.4 → bergson-2.3.1}/bergson/magic/optim.py +0 -0
  62. {bergson-2.2.4 → bergson-2.3.1}/bergson/magic/rtl_tqdm.py +0 -0
  63. {bergson-2.2.4 → bergson-2.3.1}/bergson/magic/score_plot.py +0 -0
  64. {bergson-2.2.4 → bergson-2.3.1}/bergson/magic/shard_load.py +0 -0
  65. {bergson-2.2.4 → bergson-2.3.1}/bergson/magic/swap.py +0 -0
  66. {bergson-2.2.4 → bergson-2.3.1}/bergson/magic/trainer.py +0 -0
  67. {bergson-2.2.4 → bergson-2.3.1}/bergson/moe.py +0 -0
  68. {bergson-2.2.4 → bergson-2.3.1}/bergson/process_autocorrelation.py +0 -0
  69. {bergson-2.2.4 → bergson-2.3.1}/bergson/process_grads.py +0 -0
  70. {bergson-2.2.4 → bergson-2.3.1}/bergson/query/__init__.py +0 -0
  71. {bergson-2.2.4 → bergson-2.3.1}/bergson/query/attributor.py +0 -0
  72. {bergson-2.2.4 → bergson-2.3.1}/bergson/query/faiss_index.py +0 -0
  73. {bergson-2.2.4 → bergson-2.3.1}/bergson/query/query_index.py +0 -0
  74. {bergson-2.2.4 → bergson-2.3.1}/bergson/recall/__init__.py +0 -0
  75. {bergson-2.2.4 → bergson-2.3.1}/bergson/recall/facts.py +0 -0
  76. {bergson-2.2.4 → bergson-2.3.1}/bergson/recall/generate.py +0 -0
  77. {bergson-2.2.4 → bergson-2.3.1}/bergson/recall/recall.py +0 -0
  78. {bergson-2.2.4 → bergson-2.3.1}/bergson/score/__init__.py +0 -0
  79. {bergson-2.2.4 → bergson-2.3.1}/bergson/score/candidates.py +0 -0
  80. {bergson-2.2.4 → bergson-2.3.1}/bergson/score/output_influence.py +0 -0
  81. {bergson-2.2.4 → bergson-2.3.1}/bergson/score/score.py +0 -0
  82. {bergson-2.2.4 → bergson-2.3.1}/bergson/score/score_writer.py +0 -0
  83. {bergson-2.2.4 → bergson-2.3.1}/bergson/score/scorer.py +0 -0
  84. {bergson-2.2.4 → bergson-2.3.1}/bergson/utils/__init__.py +0 -0
  85. {bergson-2.2.4 → bergson-2.3.1}/bergson/utils/batch_size.py +0 -0
  86. {bergson-2.2.4 → bergson-2.3.1}/bergson/utils/csv_writer.py +0 -0
  87. {bergson-2.2.4 → bergson-2.3.1}/bergson/utils/gradcheck.py +0 -0
  88. {bergson-2.2.4 → bergson-2.3.1}/bergson/utils/load_from_optimizer.py +0 -0
  89. {bergson-2.2.4 → bergson-2.3.1}/bergson/utils/logger.py +0 -0
  90. {bergson-2.2.4 → bergson-2.3.1}/bergson/utils/logging.py +0 -0
  91. {bergson-2.2.4 → bergson-2.3.1}/bergson/utils/math.py +0 -0
  92. {bergson-2.2.4 → bergson-2.3.1}/bergson/utils/peft.py +0 -0
  93. {bergson-2.2.4 → bergson-2.3.1}/bergson/utils/step_state.py +0 -0
  94. {bergson-2.2.4 → bergson-2.3.1}/bergson/utils/trainer_export.py +0 -0
  95. {bergson-2.2.4 → bergson-2.3.1}/bergson/utils/utils.py +0 -0
  96. {bergson-2.2.4 → bergson-2.3.1}/bergson/validate.py +0 -0
  97. {bergson-2.2.4 → bergson-2.3.1}/bergson.egg-info/dependency_links.txt +0 -0
  98. {bergson-2.2.4 → bergson-2.3.1}/bergson.egg-info/entry_points.txt +0 -0
  99. {bergson-2.2.4 → bergson-2.3.1}/bergson.egg-info/requires.txt +0 -0
  100. {bergson-2.2.4 → bergson-2.3.1}/bergson.egg-info/top_level.txt +0 -0
  101. {bergson-2.2.4 → bergson-2.3.1}/setup.cfg +0 -0
  102. {bergson-2.2.4 → bergson-2.3.1}/tests/test_adam_state_loading.py +0 -0
  103. {bergson-2.2.4 → bergson-2.3.1}/tests/test_approx_unrolling_checkpoint_parse.py +0 -0
  104. {bergson-2.2.4 → bergson-2.3.1}/tests/test_attention_head_normalizers.py +0 -0
  105. {bergson-2.2.4 → bergson-2.3.1}/tests/test_attribute_tokens.py +0 -0
  106. {bergson-2.2.4 → bergson-2.3.1}/tests/test_attributor.py +0 -0
  107. {bergson-2.2.4 → bergson-2.3.1}/tests/test_auto_batch_size.py +0 -0
  108. {bergson-2.2.4 → bergson-2.3.1}/tests/test_bank_loss_cache.py +0 -0
  109. {bergson-2.2.4 → bergson-2.3.1}/tests/test_banked_model_loading.py +0 -0
  110. {bergson-2.2.4 → bergson-2.3.1}/tests/test_batch_size_invariance.py +0 -0
  111. {bergson-2.2.4 → bergson-2.3.1}/tests/test_build.py +0 -0
  112. {bergson-2.2.4 → bergson-2.3.1}/tests/test_builder.py +0 -0
  113. {bergson-2.2.4 → bergson-2.3.1}/tests/test_candidates.py +0 -0
  114. {bergson-2.2.4 → bergson-2.3.1}/tests/test_ckpt_avg_query_grads.py +0 -0
  115. {bergson-2.2.4 → bergson-2.3.1}/tests/test_cli.py +0 -0
  116. {bergson-2.2.4 → bergson-2.3.1}/tests/test_compute_lambda.py +0 -0
  117. {bergson-2.2.4 → bergson-2.3.1}/tests/test_config_runner.py +0 -0
  118. {bergson-2.2.4 → bergson-2.3.1}/tests/test_contrast.py +0 -0
  119. {bergson-2.2.4 → bergson-2.3.1}/tests/test_data.py +0 -0
  120. {bergson-2.2.4 → bergson-2.3.1}/tests/test_ddp.py +0 -0
  121. {bergson-2.2.4 → bergson-2.3.1}/tests/test_diagnose.py +0 -0
  122. {bergson-2.2.4 → bergson-2.3.1}/tests/test_distributed_batch_budget.py +0 -0
  123. {bergson-2.2.4 → bergson-2.3.1}/tests/test_distributed_cap.py +0 -0
  124. {bergson-2.2.4 → bergson-2.3.1}/tests/test_distributed_failure.py +0 -0
  125. {bergson-2.2.4 → bergson-2.3.1}/tests/test_distributed_magic.py +0 -0
  126. {bergson-2.2.4 → bergson-2.3.1}/tests/test_epoch_shuffle.py +0 -0
  127. {bergson-2.2.4 → bergson-2.3.1}/tests/test_faiss_ann_cpu_load.py +0 -0
  128. {bergson-2.2.4 → bergson-2.3.1}/tests/test_force_math_sdp.py +0 -0
  129. {bergson-2.2.4 → bergson-2.3.1}/tests/test_format.py +0 -0
  130. {bergson-2.2.4 → bergson-2.3.1}/tests/test_global_kfac.py +0 -0
  131. {bergson-2.2.4 → bergson-2.3.1}/tests/test_global_projection.py +0 -0
  132. {bergson-2.2.4 → bergson-2.3.1}/tests/test_grad_clipping.py +0 -0
  133. {bergson-2.2.4 → bergson-2.3.1}/tests/test_gradcheck.py +0 -0
  134. {bergson-2.2.4 → bergson-2.3.1}/tests/test_gradients.py +0 -0
  135. {bergson-2.2.4 → bergson-2.3.1}/tests/test_hessian.py +0 -0
  136. {bergson-2.2.4 → bergson-2.3.1}/tests/test_launch_devices.py +0 -0
  137. {bergson-2.2.4 → bergson-2.3.1}/tests/test_log_fn.py +0 -0
  138. {bergson-2.2.4 → bergson-2.3.1}/tests/test_logit_scale.py +0 -0
  139. {bergson-2.2.4 → bergson-2.3.1}/tests/test_magic.py +0 -0
  140. {bergson-2.2.4 → bergson-2.3.1}/tests/test_metasmoothness.py +0 -0
  141. {bergson-2.2.4 → bergson-2.3.1}/tests/test_moe.py +0 -0
  142. {bergson-2.2.4 → bergson-2.3.1}/tests/test_multi_query_validate.py +0 -0
  143. {bergson-2.2.4 → bergson-2.3.1}/tests/test_multinode.py +0 -0
  144. {bergson-2.2.4 → bergson-2.3.1}/tests/test_muon.py +0 -0
  145. {bergson-2.2.4 → bergson-2.3.1}/tests/test_normalizer.py +0 -0
  146. {bergson-2.2.4 → bergson-2.3.1}/tests/test_outer_product_gradients.py +0 -0
  147. {bergson-2.2.4 → bergson-2.3.1}/tests/test_output_influence.py +0 -0
  148. {bergson-2.2.4 → bergson-2.3.1}/tests/test_padding.py +0 -0
  149. {bergson-2.2.4 → bergson-2.3.1}/tests/test_per_query_magic.py +0 -0
  150. {bergson-2.2.4 → bergson-2.3.1}/tests/test_per_token_lds.py +0 -0
  151. {bergson-2.2.4 → bergson-2.3.1}/tests/test_pretokenized.py +0 -0
  152. {bergson-2.2.4 → bergson-2.3.1}/tests/test_process_autocorrelation.py +0 -0
  153. {bergson-2.2.4 → bergson-2.3.1}/tests/test_projection_inner_products.py +0 -0
  154. {bergson-2.2.4 → bergson-2.3.1}/tests/test_projection_matrix.py +0 -0
  155. {bergson-2.2.4 → bergson-2.3.1}/tests/test_projection_settings.py +0 -0
  156. {bergson-2.2.4 → bergson-2.3.1}/tests/test_query_batching_invariance.py +0 -0
  157. {bergson-2.2.4 → bergson-2.3.1}/tests/test_query_loss_padding.py +0 -0
  158. {bergson-2.2.4 → bergson-2.3.1}/tests/test_query_set_config.py +0 -0
  159. {bergson-2.2.4 → bergson-2.3.1}/tests/test_recall.py +0 -0
  160. {bergson-2.2.4 → bergson-2.3.1}/tests/test_reduce.py +0 -0
  161. {bergson-2.2.4 → bergson-2.3.1}/tests/test_save_mode_final.py +0 -0
  162. {bergson-2.2.4 → bergson-2.3.1}/tests/test_score.py +0 -0
  163. {bergson-2.2.4 → bergson-2.3.1}/tests/test_score_plot.py +0 -0
  164. {bergson-2.2.4 → bergson-2.3.1}/tests/test_score_writer_dist.py +0 -0
  165. {bergson-2.2.4 → bergson-2.3.1}/tests/test_shard_load.py +0 -0
  166. {bergson-2.2.4 → bergson-2.3.1}/tests/test_source_fisher_normalization.py +0 -0
  167. {bergson-2.2.4 → bergson-2.3.1}/tests/test_source_optimizer_variants.py +0 -0
  168. {bergson-2.2.4 → bergson-2.3.1}/tests/test_source_resume_polarity.py +0 -0
  169. {bergson-2.2.4 → bergson-2.3.1}/tests/test_source_trainer_integration.py +0 -0
  170. {bergson-2.2.4 → bergson-2.3.1}/tests/test_step_matrix.py +0 -0
  171. {bergson-2.2.4 → bergson-2.3.1}/tests/test_step_state.py +0 -0
  172. {bergson-2.2.4 → bergson-2.3.1}/tests/test_tokenize.py +0 -0
  173. {bergson-2.2.4 → bergson-2.3.1}/tests/test_trainer_callback.py +0 -0
  174. {bergson-2.2.4 → bergson-2.3.1}/tests/test_trak.py +0 -0
  175. {bergson-2.2.4 → bergson-2.3.1}/tests/test_truncation.py +0 -0
  176. {bergson-2.2.4 → bergson-2.3.1}/tests/test_validate_filter.py +0 -0
  177. {bergson-2.2.4 → bergson-2.3.1}/tests/test_validate_routing.py +0 -0
  178. {bergson-2.2.4 → bergson-2.3.1}/tests/test_validation_config.py +0 -0
  179. {bergson-2.2.4 → bergson-2.3.1}/tests/test_wandb_logging.py +0 -0
  180. {bergson-2.2.4 → bergson-2.3.1}/tests/test_weighted_ce.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bergson
3
- Version: 2.2.4
3
+ Version: 2.3.1
4
4
  Summary: Tracing the memory of neural nets with data attribution
5
5
  License: MIT License
6
6
  Keywords: interpretability,explainable-ai
@@ -1,4 +1,4 @@
1
- __version__ = "2.2.4"
1
+ __version__ = "2.3.1"
2
2
 
3
3
  import logging
4
4
 
@@ -52,8 +52,13 @@ class DataConfig(Serializable):
52
52
  When specified, gradients are calculated using the policy
53
53
  gradient loss from Dr. GRPO. https://arxiv.org/abs/2503.20783"""
54
54
 
55
+ advantage_column: str = ""
56
+ """Optional column in the dataset that contains per-example advantages, e.g.
57
+ those logged by a GRPO trainer. When specified, gradients are calculated using
58
+ the Dr. GRPO policy gradient loss."""
59
+
55
60
  skip_nan_rewards: bool = False
56
- """Whether to skip examples with NaN rewards."""
61
+ """Whether to skip examples with NaN rewards or advantages."""
57
62
 
58
63
  truncation: bool = False
59
64
  """Whether to truncate long documents to fit the token budget."""
@@ -73,6 +78,10 @@ class DataConfig(Serializable):
73
78
  sequences of this length. Incompatible with truncation and format_template."""
74
79
 
75
80
  def __post_init__(self):
81
+ if self.reward_column and self.advantage_column:
82
+ raise ValueError(
83
+ "reward_column and advantage_column cannot both be specified"
84
+ )
76
85
  if self.chunk_length > 0:
77
86
  if self.truncation:
78
87
  raise ValueError("chunk_length and truncation cannot both be True")
@@ -18,6 +18,7 @@ from datasets import (
18
18
  Dataset,
19
19
  DatasetDict,
20
20
  IterableDatasetDict,
21
+ ReadInstruction,
21
22
  concatenate_datasets,
22
23
  load_dataset,
23
24
  load_from_disk,
@@ -452,6 +453,7 @@ def load_data_string(
452
453
  data_kwargs: str = "",
453
454
  ) -> Dataset:
454
455
  """Load a dataset from a string identifier or path."""
456
+ from_disk = False
455
457
  if data_str.endswith(".csv"):
456
458
  ds = load_dataset("csv", data_files=data_str, split=split)
457
459
  elif data_str.endswith(".json") or data_str.endswith(".jsonl"):
@@ -461,6 +463,7 @@ def load_data_string(
461
463
  or (Path(data_str) / "dataset_dict.json").exists()
462
464
  ):
463
465
  ds = load_from_disk(data_str, keep_in_memory=False)
466
+ from_disk = True
464
467
  else:
465
468
  try:
466
469
  kwargs = simple_parse_kwargs_string(data_kwargs)
@@ -474,21 +477,40 @@ def load_data_string(
474
477
  # Automatically use load_from_disk if appropriate
475
478
  if "load_from_disk" in str(e):
476
479
  ds = load_from_disk(data_str, keep_in_memory=False)
480
+ from_disk = True
477
481
  else:
478
482
  raise e
479
483
 
480
- if isinstance(ds, DatasetDict):
481
- if "[" in split or "+" in split:
482
- raise NotImplementedError(
483
- f"Split slicing/concatenation expressions are not supported "
484
- f"for load_from_disk paths: {split!r}"
485
- )
486
- ds = ds[split]
484
+ if from_disk:
485
+ ds = select_split(ds, split)
487
486
 
488
487
  ds = assert_type(Dataset, ds)
489
488
  return ds
490
489
 
491
490
 
491
+ def select_split(ds: Dataset | DatasetDict, split: str) -> Dataset:
492
+ """The rows ``split`` names, in ``load_dataset``'s split syntax (such as
493
+ ``train[:100]`` or ``train[:10%]+test``), of a dataset from ``load_from_disk``.
494
+
495
+ A single saved dataset has no split names, so each part of ``split`` slices
496
+ the whole of it.
497
+ """
498
+ if "[" not in split and "+" not in split:
499
+ return ds[split] if isinstance(ds, DatasetDict) else ds
500
+
501
+ names = [part.split("[")[0].strip() for part in split.split("+")]
502
+ lengths = {
503
+ name: len(ds[name] if isinstance(ds, DatasetDict) else ds) for name in names
504
+ }
505
+ parts = [
506
+ (ds[i.splitname] if isinstance(ds, DatasetDict) else ds).select(
507
+ range(i.from_, i.to)
508
+ )
509
+ for i in ReadInstruction.from_spec(split).to_absolute(lengths)
510
+ ]
511
+ return parts[0] if len(parts) == 1 else concatenate_datasets(parts)
512
+
513
+
492
514
  def load_gradients(root_dir: Path | str) -> np.memmap:
493
515
  """Map the gradients stored in `root_dir` into memory as a flat
494
516
  ``(num_grads, total_grad_dim)`` array, with modules laid out in
@@ -17,7 +17,7 @@ from ..config.config_io import save_run_config
17
17
  from ..data import create_index, load_gradients
18
18
  from ..distributed import launch_distributed_run
19
19
  from ..score.score import score_dataset
20
- from ..utils.step_state import partial_path, prepare_step
20
+ from ..utils.step_state import partial_path, prepare_step, promote_step
21
21
  from ..utils.worker_utils import validate_run_path
22
22
  from .apply_hessian import EkfacConfig, apply_worker
23
23
  from .astra import AstraPaths, astra_worker
@@ -139,7 +139,7 @@ def hessian_pipeline(
139
139
  index_cfg.distributed,
140
140
  )
141
141
  if index_cfg.distributed.rank == 0:
142
- shutil.move(ekfac_cfg.run_path, transformed_query_path)
142
+ promote_step(transformed_query_path)
143
143
 
144
144
  astra_cfg = hessian_pipeline_cfg.astra
145
145
  if astra_cfg.num_steps > 0:
@@ -217,4 +217,4 @@ def _run_astra(
217
217
  ],
218
218
  index_cfg.distributed,
219
219
  )
220
- shutil.move(part, out_path)
220
+ promote_step(out_path)
@@ -347,7 +347,9 @@ def filter_by_max_tokens(ds: Dataset, cfg: AttributionConfig) -> Dataset:
347
347
  return ds
348
348
 
349
349
 
350
- def max_tokens_for_model(tokenizer, model_str: str, revision: str | None) -> int:
350
+ def max_tokens_for_model(
351
+ tokenizer, model_str: str, revision: str | None, trust_remote_code: bool = False
352
+ ) -> int:
351
353
  # You might think model_max_length should always be the same as
352
354
  # max_position_embeddings, but some models (e.g. Pythia!) have a smaller
353
355
  # max_position_embeddings than model_max_length, so we need to check both.
@@ -360,7 +362,9 @@ def max_tokens_for_model(tokenizer, model_str: str, revision: str | None) -> int
360
362
  except ValueError:
361
363
  pass
362
364
 
363
- model_cfg = AutoConfig.from_pretrained(model_str, revision=revision)
365
+ model_cfg = AutoConfig.from_pretrained(
366
+ model_str, revision=revision, trust_remote_code=trust_remote_code
367
+ )
364
368
  model_max_length = getattr(tokenizer, "model_max_length", BIG_NUM)
365
369
  max_pos_emb = getattr(model_cfg, "max_position_embeddings", BIG_NUM)
366
370
  return min(model_max_length, max_pos_emb)
@@ -377,7 +381,12 @@ def setup_data_pipeline(
377
381
  data_cfg.dataset, data_cfg.split, data_cfg.subset, data_cfg.data_kwargs
378
382
  )
379
383
  tokenizer = AutoTokenizer.from_pretrained(cfg.tokenizer or cfg.model)
380
- max_model_length = max_tokens_for_model(tokenizer, cfg.model, cfg.revision)
384
+ trust_remote_code = bool(
385
+ simple_parse_kwargs_string(cfg.model_kwargs).get("trust_remote_code", False)
386
+ )
387
+ max_model_length = max_tokens_for_model(
388
+ tokenizer, cfg.model, cfg.revision, trust_remote_code
389
+ )
381
390
 
382
391
  if data_cfg.chunk_length > 0:
383
392
  # Sanity check
@@ -449,23 +458,28 @@ def setup_data_pipeline(
449
458
  f"Consider increasing --token_batch_size or using --truncation."
450
459
  )
451
460
 
452
- if data_cfg.reward_column:
461
+ value_column = data_cfg.reward_column or data_cfg.advantage_column
462
+ if value_column:
453
463
  assert isinstance(ds, Dataset), "Dataset required for advantage estimation"
454
464
 
455
- rewards = np.array(ds[data_cfg.reward_column], dtype=np.float64)
456
- nan_mask = np.isnan(rewards)
465
+ values = np.array(ds[value_column], dtype=np.float64)
466
+ nan_mask = np.isnan(values)
457
467
  if nan_mask.any():
458
468
  if data_cfg.skip_nan_rewards:
459
- print(f"Warning: Filtering out {nan_mask.sum()} rows with NaN rewards")
469
+ print(f"Warning: Filtering out {nan_mask.sum()} rows with NaN values")
460
470
  ds = ds.filter(lambda _, idx: not nan_mask[idx], with_indices=True)
461
471
  else:
462
- raise ValueError(
463
- f"Reward column '{data_cfg.reward_column}' contains NaN values"
464
- )
472
+ raise ValueError(f"Column '{value_column}' contains NaN values")
465
473
 
474
+ if data_cfg.reward_column:
475
+ advantages = estimate_advantage(ds, data_cfg)
476
+ else:
477
+ advantages = ds[data_cfg.advantage_column][:]
478
+ if "advantage" in ds.column_names:
479
+ ds = ds.remove_columns("advantage")
466
480
  ds = ds.add_column(
467
481
  "advantage",
468
- estimate_advantage(ds, data_cfg),
482
+ advantages,
469
483
  new_fingerprint="advantage", # type: ignore
470
484
  )
471
485
 
@@ -475,6 +489,8 @@ def setup_data_pipeline(
475
489
 
476
490
  # Remove extraneous columns
477
491
  keep = {"length", "input_ids", "labels"}
492
+ if value_column:
493
+ keep.add("advantage")
478
494
  remove_columns -= keep
479
495
  remove_columns &= set(ds.column_names)
480
496
  if remove_columns:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bergson
3
- Version: 2.2.4
3
+ Version: 2.3.1
4
4
  Summary: Tracing the memory of neural nets with data attribution
5
5
  License: MIT License
6
6
  Keywords: interpretability,explainable-ai
@@ -159,6 +159,7 @@ tests/test_save_mode_final.py
159
159
  tests/test_score.py
160
160
  tests/test_score_plot.py
161
161
  tests/test_score_writer_dist.py
162
+ tests/test_select_split.py
162
163
  tests/test_shard_load.py
163
164
  tests/test_source_fisher_normalization.py
164
165
  tests/test_source_optimizer_variants.py
@@ -37,7 +37,7 @@ dependencies = [
37
37
  "bitsandbytes",
38
38
  "huggingface-hub>=1.13.0",
39
39
  ]
40
- version = "2.2.4"
40
+ version = "2.3.1"
41
41
  [project.optional-dependencies]
42
42
  dev = [
43
43
  "pre-commit",
@@ -1,5 +1,6 @@
1
1
  import json
2
2
 
3
+ import pytest
3
4
  from datasets import Dataset
4
5
 
5
6
  from bergson.config import DataConfig, IndexConfig
@@ -83,3 +84,57 @@ def test_advantages_computed_with_drop_columns(tmp_path):
83
84
  # "foo bar" group mean = 15.0: advantages = [-5.0, 5.0]
84
85
  assert abs(advantages[2] - (-5.0)) < 1e-9
85
86
  assert abs(advantages[3] - 5.0) < 1e-9
87
+
88
+
89
+ def _pipeline_advantages(tmp_path, rows, **data_kwargs):
90
+ path = tmp_path / "rows.json"
91
+ path.write_text("\n".join(json.dumps(r) for r in rows))
92
+ cfg = IndexConfig(
93
+ run_path=str(tmp_path / "run"),
94
+ model="EleutherAI/pythia-14m",
95
+ token_batch_size=2048,
96
+ data=DataConfig(dataset=str(path), **data_kwargs),
97
+ )
98
+ ds, _ = setup_data_pipeline(cfg)
99
+ return ds["advantage"]
100
+
101
+
102
+ def test_advantage_column_used_as_given(tmp_path):
103
+ rows = [
104
+ {"text": "hello world", "adv": 0.5},
105
+ {"text": "hello world", "adv": 2.0},
106
+ {"text": "foo bar", "adv": -1.5},
107
+ ]
108
+ assert _pipeline_advantages(tmp_path, rows, advantage_column="adv") == [
109
+ 0.5,
110
+ 2.0,
111
+ -1.5,
112
+ ]
113
+
114
+
115
+ def test_existing_advantage_column(tmp_path):
116
+ """A dataset column named "advantage" can be the advantage column, and is
117
+ replaced by the estimate when rewards are given."""
118
+ rows = [
119
+ {"text": "hello world", "advantage": 0.5, "reward": 1.0},
120
+ {"text": "hello world", "advantage": 2.0, "reward": 3.0},
121
+ ]
122
+ assert _pipeline_advantages(tmp_path, rows, advantage_column="advantage") == [
123
+ 0.5,
124
+ 2.0,
125
+ ]
126
+ assert _pipeline_advantages(tmp_path, rows, reward_column="reward") == [-1.0, 1.0]
127
+
128
+
129
+ def test_nan_advantages(tmp_path):
130
+ rows = [{"text": "hello world", "adv": 1.0}, {"text": "foo bar", "adv": None}]
131
+ with pytest.raises(ValueError, match="Column 'adv' contains NaN"):
132
+ _pipeline_advantages(tmp_path, rows, advantage_column="adv")
133
+ assert _pipeline_advantages(
134
+ tmp_path, rows, advantage_column="adv", skip_nan_rewards=True
135
+ ) == [1.0]
136
+
137
+
138
+ def test_conflicting_advantage_config():
139
+ with pytest.raises(ValueError, match="cannot both be specified"):
140
+ DataConfig(reward_column="reward", advantage_column="adv")
@@ -0,0 +1,39 @@
1
+ from datasets import Dataset, DatasetDict
2
+
3
+ from bergson.data import load_data_string
4
+
5
+
6
+ def _saved(tmp_path, ds):
7
+ path = str(tmp_path / "ds")
8
+ ds.save_to_disk(path)
9
+ return path
10
+
11
+
12
+ def test_saved_dataset_takes_split_slices(tmp_path):
13
+ path = _saved(tmp_path, Dataset.from_dict({"x": list(range(10))}))
14
+
15
+ assert load_data_string(path, "train")["x"] == list(range(10))
16
+ assert load_data_string(path, "train[:3]")["x"] == [0, 1, 2]
17
+ assert load_data_string(path, "train[50%:60%]")["x"] == [5]
18
+ assert load_data_string(path, "train[8:]+train[:1]")["x"] == [8, 9, 0]
19
+
20
+
21
+ def test_saved_dataset_dict_takes_split_slices(tmp_path):
22
+ path = _saved(
23
+ tmp_path,
24
+ DatasetDict(
25
+ train=Dataset.from_dict({"x": list(range(10))}),
26
+ test=Dataset.from_dict({"x": list(range(100, 104))}),
27
+ ),
28
+ )
29
+
30
+ assert load_data_string(path, "test")["x"] == [100, 101, 102, 103]
31
+ assert load_data_string(path, "test[:2]")["x"] == [100, 101]
32
+ assert load_data_string(path, "train[:1]+test[-1:]")["x"] == [0, 103]
33
+
34
+
35
+ def test_loaded_split_is_sliced_once(tmp_path):
36
+ path = tmp_path / "rows.csv"
37
+ path.write_text("x\n" + "\n".join(str(i) for i in range(8)) + "\n")
38
+
39
+ assert load_data_string(str(path), "train[:50%]")["x"] == [0, 1, 2, 3]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes