From e1a833c34f452cd8600ced532d3e158a60a084c1 Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 25 Sep 2025 12:00:36 -0700 Subject: [PATCH 01/99] tested converstion to "forward" decoder --- .../utils/convert_to_circuit_tracer.py | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 crosslayer_transcoder/utils/convert_to_circuit_tracer.py diff --git a/crosslayer_transcoder/utils/convert_to_circuit_tracer.py b/crosslayer_transcoder/utils/convert_to_circuit_tracer.py new file mode 100644 index 0000000..698d8c2 --- /dev/null +++ b/crosslayer_transcoder/utils/convert_to_circuit_tracer.py @@ -0,0 +1,73 @@ +# simple file to convert the lightning model to a circuit-tracer model +from typing import Union + +from einops import einops +import torch +from torch.export.graph_signature import OutputKind + +from crosslayer_transcoder.model.clt import CrosslayerDecoder +from crosslayer_transcoder.model.clt_lightning import ( + CrossLayerTranscoderModule, + JumpReLUCrossLayerTranscoderModule, + TopKCrossLayerTranscoderModule, +) + + +CLTModule = Union[ + CrossLayerTranscoderModule, + JumpReLUCrossLayerTranscoderModule, + TopKCrossLayerTranscoderModule, +] + + +def convert_decoder(decoder: CrosslayerDecoder): + # TODO: convert the CLT to a circuit tracing CLT shape + # our decoder shape: [i+1, d_features, d_acts] + # expected W_{i} shape: [d_features, n_layers - i, d_acts] + # From [here](https://github.com/safety-research/circuit-tracer/blob/2eff952df66400eeb1066595dc5567a7203c6acd/circuit_tracer/transcoder/cross_layer_transcoder.py#L103C38-L103C73) + # + + d_feats = decoder.d_features + d_acts = decoder.d_acts + n_layers = decoder.n_layers + + # layer i decoder mat of shape [d_feats, n_layers - i, d_acts] + decoder_dict = {} + + for i in range(n_layers): + output_dec_i = torch.zeros([d_feats, n_layers - i, d_acts]) + + for k in range(i, n_layers): + # get decoder mat for layer i --> k + decoder_w_k = decoder.get_parameter(f"W_{k}") + dec_i_k = decoder_w_k[i, ...] + assert dec_i_k.shape == ( + d_feats, + d_acts, + ) + output_dec_i[:, k - i, ...] = dec_i_k + + decoder_dict[f"W_dec_{i}"] = output_dec_i + + return decoder_dict + + +def convert_encoder(): + pass + + +# def convert_model_to_circuit_tracer(lightning_module: CLTModule): +def convert_model_to_circuit_tracer(): + # convert the lightning model to the circuit-tracer compatible shape + + mock_decoder = CrosslayerDecoder(728, 1023, 12) + + ct_decoder_dict = convert_decoder(mock_decoder) + + print(len(ct_decoder_dict)) + print(ct_decoder_dict["W_dec_0"].shape) + pass + + +if __name__ == "__main__": + convert_model_to_circuit_tracer() From 8774ddd6547d898ea936441cec2e88428e878df1 Mon Sep 17 00:00:00 2001 From: jiito Date: Fri, 26 Sep 2025 09:04:56 -0700 Subject: [PATCH 02/99] successful integration test --- .../utils/convert_to_circuit_tracer.py | 194 ++++++++++++--- pyproject.toml | 4 + tests/test_circuit_tracer_integration.py | 27 +++ uv.lock | 226 +++++++++++++++++- 4 files changed, 402 insertions(+), 49 deletions(-) create mode 100644 tests/test_circuit_tracer_integration.py diff --git a/crosslayer_transcoder/utils/convert_to_circuit_tracer.py b/crosslayer_transcoder/utils/convert_to_circuit_tracer.py index 698d8c2..f610ad1 100644 --- a/crosslayer_transcoder/utils/convert_to_circuit_tracer.py +++ b/crosslayer_transcoder/utils/convert_to_circuit_tracer.py @@ -1,18 +1,26 @@ # simple file to convert the lightning model to a circuit-tracer model -from typing import Union +import os +from pathlib import Path +from typing import List, Union -from einops import einops +from huggingface_hub import upload_folder import torch +import yaml +from einops import einops +from safetensors.torch import save_file from torch.export.graph_signature import OutputKind -from crosslayer_transcoder.model.clt import CrosslayerDecoder +from crosslayer_transcoder.model.clt import ( + CrosslayerDecoder, + Encoder, + SimpleCrossLayerTranscoder, +) from crosslayer_transcoder.model.clt_lightning import ( CrossLayerTranscoderModule, JumpReLUCrossLayerTranscoderModule, TopKCrossLayerTranscoderModule, ) - CLTModule = Union[ CrossLayerTranscoderModule, JumpReLUCrossLayerTranscoderModule, @@ -20,54 +28,168 @@ ] -def convert_decoder(decoder: CrosslayerDecoder): - # TODO: convert the CLT to a circuit tracing CLT shape - # our decoder shape: [i+1, d_features, d_acts] - # expected W_{i} shape: [d_features, n_layers - i, d_acts] - # From [here](https://github.com/safety-research/circuit-tracer/blob/2eff952df66400eeb1066595dc5567a7203c6acd/circuit_tracer/transcoder/cross_layer_transcoder.py#L103C38-L103C73) - # +def add_decoder_bias(d: List[dict], decoder: CrosslayerDecoder): + for i in range(decoder.n_layers): + d[i][f"b_dec_{i}"] = ( + decoder.b[i].cpu() if hasattr(decoder, "b") else torch.zeros(decoder.d_acts) + ) + return d - d_feats = decoder.d_features - d_acts = decoder.d_acts - n_layers = decoder.n_layers - # layer i decoder mat of shape [d_feats, n_layers - i, d_acts] - decoder_dict = {} +def save_decoder_dict(decoder_dict: dict, path: str): + for key, value in decoder_dict.items(): + save_file({key: value}, f"{path}/{key}.safetensors") - for i in range(n_layers): - output_dec_i = torch.zeros([d_feats, n_layers - i, d_acts]) - for k in range(i, n_layers): +def convert_model_to_circuit_tracer( + lightning_module: CLTModule, + save_dir: str, + feature_input_hook: str = "blocks.{layer}.hook_resid_pre", + feature_output_hook: str = "blocks.{layer}.hook_mlp_out", +): + # convert the lightning model to the circuit-tracer compatible shape + save_path = Path(save_dir) + save_path.mkdir(parents=True, exist_ok=True) + + encoder = lightning_module.model.encoder + decoder = lightning_module.model.decoder + n_layers = encoder.n_layers + d_acts = encoder.d_acts # -> d_model + d_features = encoder.d_features # -> d_transcoder + + for source_layer in range(encoder.n_layers): + # encoder + layer_encoder_dict = { + f"W_enc_{source_layer}": encoder.W[source_layer] + .T.contiguous() + .cpu(), # Transpose! + f"b_enc_{source_layer}": ( + encoder.b[source_layer].cpu() + if hasattr(encoder, "b") + else torch.zeros(encoder.d_features) + ), + f"b_dec_{source_layer}": ( + decoder.b[source_layer].cpu() + if hasattr(decoder, "b") + else torch.zeros(d_acts) + ), + # TODO: add non-lin params like threshold + } + + # TODO: check names + save_file(layer_encoder_dict, f"{save_path}/W_enc_{source_layer}.safetensors") + + # decoder + output_dec_i = torch.zeros([d_features, n_layers - source_layer, d_acts]) + + for k in range(source_layer, n_layers): # get decoder mat for layer i --> k decoder_w_k = decoder.get_parameter(f"W_{k}") - dec_i_k = decoder_w_k[i, ...] + dec_i_k = decoder_w_k[source_layer, ...] assert dec_i_k.shape == ( - d_feats, + d_features, d_acts, ) - output_dec_i[:, k - i, ...] = dec_i_k - - decoder_dict[f"W_dec_{i}"] = output_dec_i + output_dec_i[:, k - source_layer, ...] = dec_i_k.cpu() - return decoder_dict + decoder_dict = {f"W_dec_{source_layer}": output_dec_i} + save_file(decoder_dict, f"{save_path}/W_dec_{source_layer}.safetensors") -def convert_encoder(): - pass + # Create config + config = { + "model_kind": "cross_layer_transcoder", + "feature_input_hook": feature_input_hook, + "feature_output_hook": feature_output_hook, + } + with open(save_path / "config.yaml", "w") as f: + yaml.dump(config, f, default_flow_style=False) -# def convert_model_to_circuit_tracer(lightning_module: CLTModule): -def convert_model_to_circuit_tracer(): - # convert the lightning model to the circuit-tracer compatible shape - - mock_decoder = CrosslayerDecoder(728, 1023, 12) - ct_decoder_dict = convert_decoder(mock_decoder) +def upload_to_hub(save_dir: str, repo_id: str, repo_type: str = "model"): + from huggingface_hub import upload_folder - print(len(ct_decoder_dict)) - print(ct_decoder_dict["W_dec_0"].shape) - pass + print(f"Uploading {save_dir} to {repo_id} ({repo_type})") + upload_folder(folder_path=save_dir, repo_id=repo_id, repo_type=repo_type) if __name__ == "__main__": - convert_model_to_circuit_tracer() + from crosslayer_transcoder.model.clt_lightning import CrossLayerTranscoderModule + from crosslayer_transcoder.model.clt import ( + CrossLayerTranscoder, + Encoder, + CrosslayerDecoder, + ) + from crosslayer_transcoder.model.jumprelu import JumpReLU + from crosslayer_transcoder.model.standardize import ( + DimensionwiseInputStandardizer, + DimensionwiseOutputStandardizer, + ) + from crosslayer_transcoder.metrics.replacement_model_accuracy import ( + ReplacementModelAccuracy, + ) + from crosslayer_transcoder.metrics.dead_features import DeadFeatures + + # Create components based on default.yaml config + encoder = Encoder(d_acts=768, d_features=10_000, n_layers=12) + + decoder = CrosslayerDecoder(d_acts=768, d_features=10_000, n_layers=12) + + nonlinearity = JumpReLU(theta=0.03, bandwidth=0.01, n_layers=12, d_features=10_000) + + input_standardizer = DimensionwiseInputStandardizer(n_layers=12, activation_dim=768) + + output_standardizer = DimensionwiseOutputStandardizer( + n_layers=12, activation_dim=768 + ) + + model = CrossLayerTranscoder( + encoder=encoder, + decoder=decoder, + nonlinearity=nonlinearity, + input_standardizer=input_standardizer, + output_standardizer=output_standardizer, + ) + + # replacement_model = ReplacementModelAccuracy( + # model_name="openai-community/gpt2", device_map="mps", loader_batch_size=2 + # ) + + dead_features = DeadFeatures( + n_features=10_000, + n_layers=12, + return_per_layer=True, + return_log_freqs=True, + return_neuron_indices=True, + ) + + clt_module = CrossLayerTranscoderModule( + model=model, + # replacement_model=replacement_model, + dead_features=dead_features, + learning_rate=1e-4, + compile=True, + lr_decay_step=80_000, + lr_decay_factor=0.1, + compute_dead_features=True, + compute_dead_features_every=500, + ) + + convert_model_to_circuit_tracer(clt_module, "clt_module") + + upload_folder( + folder_path="clt_module", repo_id="jiito/clt_test_gpt2_zero", repo_type="model" + ) + upload_folder( + folder_path="clt_module/encoder", + path_in_repo="encoder", + repo_id="jiito/clt_test_gpt2_zero", + repo_type="model", + ) + upload_folder( + folder_path="clt_module/decoder", + path_in_repo="decoder", + repo_id="jiito/clt_test_gpt2_zero", + repo_type="model", + ) diff --git a/pyproject.toml b/pyproject.toml index 9077485..cbe532e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,8 +30,12 @@ dev = [ "jupyterlab>=4.4.2", "ipykernel>=6.29.5", "pytest>=8.4.1", + "circuit-tracer" ] +[tool.uv.sources] +circuit-tracer = { path = "../circuit-tracer", editable = true } + [project.scripts] clt = "crosslayer_transcoder.main:main" diff --git a/tests/test_circuit_tracer_integration.py b/tests/test_circuit_tracer_integration.py new file mode 100644 index 0000000..cb7e4a8 --- /dev/null +++ b/tests/test_circuit_tracer_integration.py @@ -0,0 +1,27 @@ +from circuit_tracer.utils.hf_utils import load_transcoder_from_hub +import torch + + +def validate_upload(repo_id: str): + """Verify uploaded model loads correctly.""" + + # Load from HuggingFace + transcoder, config = load_transcoder_from_hub( + repo_id, + device=torch.device("cpu"), + dtype=torch.float32, + lazy_encoder=False, + lazy_decoder=False, + ) + + print( + f"✓ Dimensions: {transcoder.n_layers}L x {transcoder.d_transcoder}F x {transcoder.d_model}D" + ) + print(f"✓ Encoder weights match") + print(f"✓ Config: {config['model_kind']}") + + +if __name__ == "__main__": + validate_upload( + repo_id="jiito/clt_test_gpt2_zero", + ) diff --git a/uv.lock b/uv.lock index 5cd028c..f54c919 100644 --- a/uv.lock +++ b/uv.lock @@ -202,6 +202,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537, upload-time = "2025-02-01T15:17:37.39Z" }, ] +[[package]] +name = "beartype" +version = "0.14.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/89/3b/9ecfc75d1f8bb75cbdc87fcb3df7c6ec4bc8f7481cb7102859ade1736c9d/beartype-0.14.1.tar.gz", hash = "sha256:23df4715d19cebb2ce60e53c3cf44cd925843f00c71938222d777ea6332de3cb", size = 964899, upload-time = "2023-06-07T05:38:56.905Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f6/db/8d01583b4175e0e45a6e6cd0c28db2dae38ffe5477141a7ac3a5a09c8bb9/beartype-0.14.1-py3-none-any.whl", hash = "sha256:0f70fccdb8eb6d7ddfaa3ffe3a0b66cf2edeb13452bd71ad46615775c2fa34f6", size = 739737, upload-time = "2023-06-07T05:38:54.076Z" }, +] + [[package]] name = "beautifulsoup4" version = "4.13.4" @@ -215,6 +224,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/50/cd/30110dc0ffcf3b131156077b90e9f60ed75711223f306da4db08eff8403b/beautifulsoup4-4.13.4-py3-none-any.whl", hash = "sha256:9bbbb14bfde9d79f38b8cd5f8c7c85f4b8f2523190ebed90e950a8dea4cb1c4b", size = 187285, upload-time = "2025-04-15T17:05:12.221Z" }, ] +[[package]] +name = "better-abc" +version = "0.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8b/72/3d630f781659015357cc08cad32aa636b252e007df0bae31184a3d872427/better-abc-0.0.3.tar.gz", hash = "sha256:a880fd6bc9675da2ec991e8712a555bffa0f12722efed78c739f78343cf989f6", size = 2852, upload-time = "2020-11-10T22:47:31.303Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/e8/7d00a23039ab74c5741736ce05d7700eb6237e83747aac4df07a5bf2d074/better_abc-0.0.3-py3-none-any.whl", hash = "sha256:3ae73b473fbeb536a548f542984976e80b821676ae6e18f14e24d8e180647187", size = 3475, upload-time = "2020-11-10T22:47:30.354Z" }, +] + [[package]] name = "bidict" version = "0.23.1" @@ -294,6 +312,46 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/20/94/c5790835a017658cbfabd07f3bfb549140c3ac458cfc196323996b10095a/charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0", size = 52626, upload-time = "2025-05-02T08:34:40.053Z" }, ] +[[package]] +name = "circuit-tracer" +version = "0.1.0" +source = { editable = "../circuit-tracer" } +dependencies = [ + { name = "einops" }, + { name = "huggingface-hub" }, + { name = "ipykernel" }, + { name = "ipywidgets" }, + { name = "numpy" }, + { name = "pydantic" }, + { name = "safetensors" }, + { name = "tokenizers" }, + { name = "torch" }, + { name = "tqdm" }, + { name = "transformer-lens" }, + { name = "transformers" }, +] + +[package.metadata] +requires-dist = [ + { name = "einops", specifier = ">=0.8.0" }, + { name = "huggingface-hub", specifier = ">=0.26.0" }, + { name = "ipykernel", specifier = ">=6.29.5" }, + { name = "ipython", marker = "extra == 'dev'", specifier = ">=8.37.0" }, + { name = "ipywidgets", specifier = ">=8.1.7" }, + { name = "numpy", specifier = ">=1.24.0" }, + { name = "pydantic", specifier = ">=2.0.0" }, + { name = "pyright", marker = "extra == 'dev'", specifier = ">=1.1.403" }, + { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.0.0" }, + { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.12.7" }, + { name = "safetensors", specifier = ">=0.5.0" }, + { name = "tokenizers", specifier = ">=0.21.0" }, + { name = "torch", specifier = ">=2.0.0" }, + { name = "tqdm", specifier = ">=4.60.0" }, + { name = "transformer-lens", specifier = ">=2.16.0" }, + { name = "transformers", specifier = ">=4.50.0" }, +] +provides-extras = ["dev"] + [[package]] name = "click" version = "8.2.1" @@ -347,6 +405,7 @@ dependencies = [ [package.optional-dependencies] dev = [ + { name = "circuit-tracer" }, { name = "ipykernel" }, { name = "jupyterlab" }, { name = "pytest" }, @@ -361,6 +420,7 @@ dev = [ [package.metadata] requires-dist = [ + { name = "circuit-tracer", marker = "extra == 'dev'", editable = "../circuit-tracer" }, { name = "datasets", specifier = ">=3.6.0" }, { name = "einops", specifier = ">=0.8.1" }, { name = "h5py", specifier = ">=3.13.0" }, @@ -476,6 +536,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7b/8f/c4d9bafc34ad7ad5d8dc16dd1347ee0e507a52c3adb6bfa8887e1c6a26ba/executing-2.2.0-py2.py3-none-any.whl", hash = "sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa", size = 26702, upload-time = "2025-01-22T15:41:25.929Z" }, ] +[[package]] +name = "fancy-einsum" +version = "0.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b9/b1/f5a13cdc05b9a16502d760ead310a689a1538f3fee9618b92011200b9717/fancy_einsum-0.0.3.tar.gz", hash = "sha256:05ca6689999d0949bdaa5320c81117effa13644ec68a200121e93d7ebf3d3356", size = 4916, upload-time = "2022-02-04T01:53:46.028Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/14/26fc262ba70976eea9a42e67b05c67aa78a0ee38332d9d094cca5d2c5ec3/fancy_einsum-0.0.3-py3-none-any.whl", hash = "sha256:e0bf33587a61822b0668512ada237a0ffa5662adfb9acfcbb0356ee15a0396a1", size = 6239, upload-time = "2022-02-04T01:53:44.44Z" }, +] + [[package]] name = "fastjsonschema" version = "2.21.1" @@ -738,6 +807,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074, upload-time = "2025-01-17T11:24:33.271Z" }, ] +[[package]] +name = "ipywidgets" +version = "8.1.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "comm" }, + { name = "ipython" }, + { name = "jupyterlab-widgets" }, + { name = "traitlets" }, + { name = "widgetsnbextension" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3e/48/d3dbac45c2814cb73812f98dd6b38bbcc957a4e7bb31d6ea9c03bf94ed87/ipywidgets-8.1.7.tar.gz", hash = "sha256:15f1ac050b9ccbefd45dccfbb2ef6bed0029d8278682d569d71b8dd96bee0376", size = 116721, upload-time = "2025-05-05T12:42:03.489Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/58/6a/9166369a2f092bd286d24e6307de555d63616e8ddb373ebad2b5635ca4cd/ipywidgets-8.1.7-py3-none-any.whl", hash = "sha256:764f2602d25471c213919b8a1997df04bef869251db4ca8efba1b76b1bd9f7bb", size = 139806, upload-time = "2025-05-05T12:41:56.833Z" }, +] + [[package]] name = "isoduration" version = "20.11.0" @@ -1016,6 +1101,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/09/2032e7d15c544a0e3cd831c51d77a8ca57f7555b2e1b2922142eddb02a84/jupyterlab_server-2.27.3-py3-none-any.whl", hash = "sha256:e697488f66c3db49df675158a77b3b017520d772c6e1548c7d9bcc5df7944ee4", size = 59700, upload-time = "2024-07-16T17:02:01.115Z" }, ] +[[package]] +name = "jupyterlab-widgets" +version = "3.0.15" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b9/7d/160595ca88ee87ac6ba95d82177d29ec60aaa63821d3077babb22ce031a5/jupyterlab_widgets-3.0.15.tar.gz", hash = "sha256:2920888a0c2922351a9202817957a68c07d99673504d6cd37345299e971bb08b", size = 213149, upload-time = "2025-05-05T12:32:31.004Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/6a/ca128561b22b60bd5a0c4ea26649e68c8556b82bc70a0c396eebc977fe86/jupyterlab_widgets-3.0.15-py3-none-any.whl", hash = "sha256:d59023d7d7ef71400d51e6fee9a88867f6e65e10a4201605d2d7f3e8f012a31c", size = 216571, upload-time = "2025-05-05T12:32:29.534Z" }, +] + [[package]] name = "lightning" version = "2.5.1.post0" @@ -1050,6 +1144,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1a/c1/31b3184cba7b257a4a3b5ca5b88b9204ccb7aa02fe3c992280899293ed54/lightning_utilities-0.14.3-py3-none-any.whl", hash = "sha256:4ab9066aa36cd7b93a05713808901909e96cc3f187ea6fd3052b2fd91313b468", size = 28894, upload-time = "2025-04-03T15:59:55.658Z" }, ] +[[package]] +name = "markdown-it-py" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, +] + [[package]] name = "markupsafe" version = "3.0.2" @@ -1080,6 +1186,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca", size = 9899, upload-time = "2024-04-15T13:44:43.265Z" }, ] +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + [[package]] name = "mistune" version = "3.1.3" @@ -1247,21 +1362,18 @@ wheels = [ [[package]] name = "numpy" -version = "2.3.0" +version = "1.26.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f3/db/8e12381333aea300890829a0a36bfa738cac95475d88982d538725143fd9/numpy-2.3.0.tar.gz", hash = "sha256:581f87f9e9e9db2cba2141400e160e9dd644ee248788d6f90636eeb8fd9260a6", size = 20382813, upload-time = "2025-06-07T14:54:32.608Z" } +sdist = { url = "https://files.pythonhosted.org/packages/65/6e/09db70a523a96d25e115e71cc56a6f9031e7b8cd166c1ac8438307c14058/numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", size = 15786129, upload-time = "2024-02-06T00:26:44.495Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/89/59/9df493df81ac6f76e9f05cdbe013cdb0c9a37b434f6e594f5bd25e278908/numpy-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:389b85335838155a9076e9ad7f8fdba0827496ec2d2dc32ce69ce7898bde03ba", size = 20897025, upload-time = "2025-06-07T14:40:33.558Z" }, - { url = "https://files.pythonhosted.org/packages/2f/86/4ff04335901d6cf3a6bb9c748b0097546ae5af35e455ae9b962ebff4ecd7/numpy-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9498f60cd6bb8238d8eaf468a3d5bb031d34cd12556af53510f05fcf581c1b7e", size = 14129882, upload-time = "2025-06-07T14:40:55.034Z" }, - { url = "https://files.pythonhosted.org/packages/71/8d/a942cd4f959de7f08a79ab0c7e6cecb7431d5403dce78959a726f0f57aa1/numpy-2.3.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:622a65d40d8eb427d8e722fd410ac3ad4958002f109230bc714fa551044ebae2", size = 5110181, upload-time = "2025-06-07T14:41:04.4Z" }, - { url = "https://files.pythonhosted.org/packages/86/5d/45850982efc7b2c839c5626fb67fbbc520d5b0d7c1ba1ae3651f2f74c296/numpy-2.3.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:b9446d9d8505aadadb686d51d838f2b6688c9e85636a0c3abaeb55ed54756459", size = 6647581, upload-time = "2025-06-07T14:41:14.695Z" }, - { url = "https://files.pythonhosted.org/packages/1a/c0/c871d4a83f93b00373d3eebe4b01525eee8ef10b623a335ec262b58f4dc1/numpy-2.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:50080245365d75137a2bf46151e975de63146ae6d79f7e6bd5c0e85c9931d06a", size = 14262317, upload-time = "2025-06-07T14:41:35.862Z" }, - { url = "https://files.pythonhosted.org/packages/b7/f6/bc47f5fa666d5ff4145254f9e618d56e6a4ef9b874654ca74c19113bb538/numpy-2.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:c24bb4113c66936eeaa0dc1e47c74770453d34f46ee07ae4efd853a2ed1ad10a", size = 16633919, upload-time = "2025-06-07T14:42:00.622Z" }, - { url = "https://files.pythonhosted.org/packages/f5/b4/65f48009ca0c9b76df5f404fccdea5a985a1bb2e34e97f21a17d9ad1a4ba/numpy-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4d8d294287fdf685281e671886c6dcdf0291a7c19db3e5cb4178d07ccf6ecc67", size = 15567651, upload-time = "2025-06-07T14:42:24.429Z" }, - { url = "https://files.pythonhosted.org/packages/f1/62/5367855a2018578e9334ed08252ef67cc302e53edc869666f71641cad40b/numpy-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6295f81f093b7f5769d1728a6bd8bf7466de2adfa771ede944ce6711382b89dc", size = 18361723, upload-time = "2025-06-07T14:42:51.167Z" }, - { url = "https://files.pythonhosted.org/packages/d4/75/5baed8cd867eabee8aad1e74d7197d73971d6a3d40c821f1848b8fab8b84/numpy-2.3.0-cp312-cp312-win32.whl", hash = "sha256:e6648078bdd974ef5d15cecc31b0c410e2e24178a6e10bf511e0557eed0f2570", size = 6318285, upload-time = "2025-06-07T14:43:02.052Z" }, - { url = "https://files.pythonhosted.org/packages/bc/49/d5781eaa1a15acb3b3a3f49dc9e2ff18d92d0ce5c2976f4ab5c0a7360250/numpy-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:0898c67a58cdaaf29994bc0e2c65230fd4de0ac40afaf1584ed0b02cd74c6fdd", size = 12732594, upload-time = "2025-06-07T14:43:21.071Z" }, - { url = "https://files.pythonhosted.org/packages/c2/1c/6d343e030815c7c97a1f9fbad00211b47717c7fe446834c224bd5311e6f1/numpy-2.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:bd8df082b6c4695753ad6193018c05aac465d634834dca47a3ae06d4bb22d9ea", size = 9891498, upload-time = "2025-06-07T14:43:36.332Z" }, + { url = "https://files.pythonhosted.org/packages/95/12/8f2020a8e8b8383ac0177dc9570aad031a3beb12e38847f7129bacd96228/numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218", size = 20335901, upload-time = "2024-02-05T23:55:32.801Z" }, + { url = "https://files.pythonhosted.org/packages/75/5b/ca6c8bd14007e5ca171c7c03102d17b4f4e0ceb53957e8c44343a9546dcc/numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b", size = 13685868, upload-time = "2024-02-05T23:55:56.28Z" }, + { url = "https://files.pythonhosted.org/packages/79/f8/97f10e6755e2a7d027ca783f63044d5b1bc1ae7acb12afe6a9b4286eac17/numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b", size = 13925109, upload-time = "2024-02-05T23:56:20.368Z" }, + { url = "https://files.pythonhosted.org/packages/0f/50/de23fde84e45f5c4fda2488c759b69990fd4512387a8632860f3ac9cd225/numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed", size = 17950613, upload-time = "2024-02-05T23:56:56.054Z" }, + { url = "https://files.pythonhosted.org/packages/4c/0c/9c603826b6465e82591e05ca230dfc13376da512b25ccd0894709b054ed0/numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a", size = 13572172, upload-time = "2024-02-05T23:57:21.56Z" }, + { url = "https://files.pythonhosted.org/packages/76/8c/2ba3902e1a0fc1c74962ea9bb33a534bb05984ad7ff9515bf8d07527cadd/numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0", size = 17786643, upload-time = "2024-02-05T23:57:56.585Z" }, + { url = "https://files.pythonhosted.org/packages/28/4a/46d9e65106879492374999e76eb85f87b15328e06bd1550668f79f7b18c6/numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110", size = 5677803, upload-time = "2024-02-05T23:58:08.963Z" }, + { url = "https://files.pythonhosted.org/packages/16/2e/86f24451c2d530c88daf997cb8d6ac622c1d40d19f5a031ed68a4b73a374/numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818", size = 15517754, upload-time = "2024-02-05T23:58:36.364Z" }, ] [[package]] @@ -1872,6 +1984,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9", size = 4242, upload-time = "2019-10-28T16:00:13.976Z" }, ] +[[package]] +name = "rich" +version = "14.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fe/75/af448d8e52bf1d8fa6a9d089ca6c07ff4453d86c65c145d0a300bb073b9b/rich-14.1.0.tar.gz", hash = "sha256:e497a48b844b0320d45007cdebfeaeed8db2a4f4bcf49f15e455cfc4af11eaa8", size = 224441, upload-time = "2025-07-25T07:32:58.125Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e3/30/3c4d035596d3cf444529e0b2953ad0466f6049528a879d27534700580395/rich-14.1.0-py3-none-any.whl", hash = "sha256:536f5f1785986d6dbdea3c75205c473f970777b4a0d6c6dd1b696aa05a3fa04f", size = 243368, upload-time = "2025-07-25T07:32:56.73Z" }, +] + [[package]] name = "rpds-py" version = "0.25.1" @@ -1925,6 +2050,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/40/b0/4562db6223154aa4e22f939003cb92514c79f3d4dccca3444253fd17f902/Send2Trash-1.8.3-py3-none-any.whl", hash = "sha256:0c31227e0bd08961c7665474a3d1ef7193929fedda4233843689baa056be46c9", size = 18072, upload-time = "2024-04-07T00:01:07.438Z" }, ] +[[package]] +name = "sentencepiece" +version = "0.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/15/15/2e7a025fc62d764b151ae6d0f2a92f8081755ebe8d4a64099accc6f77ba6/sentencepiece-0.2.1.tar.gz", hash = "sha256:8138cec27c2f2282f4a34d9a016e3374cd40e5c6e9cb335063db66a0a3b71fad", size = 3228515, upload-time = "2025-08-12T07:00:51.718Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4a/be/32ce495aa1d0e0c323dcb1ba87096037358edee539cac5baf8755a6bd396/sentencepiece-0.2.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:57cae326c8727de58c85977b175af132a7138d84c764635d7e71bbee7e774133", size = 1943152, upload-time = "2025-08-12T06:59:40.048Z" }, + { url = "https://files.pythonhosted.org/packages/88/7e/ff23008899a58678e98c6ff592bf4d368eee5a71af96d0df6b38a039dd4f/sentencepiece-0.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:56dd39a3c4d6493db3cdca7e8cc68c6b633f0d4195495cbadfcf5af8a22d05a6", size = 1325651, upload-time = "2025-08-12T06:59:41.536Z" }, + { url = "https://files.pythonhosted.org/packages/19/84/42eb3ce4796777a1b5d3699dfd4dca85113e68b637f194a6c8d786f16a04/sentencepiece-0.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d9381351182ff9888cc80e41c632e7e274b106f450de33d67a9e8f6043da6f76", size = 1253645, upload-time = "2025-08-12T06:59:42.903Z" }, + { url = "https://files.pythonhosted.org/packages/89/fa/d3d5ebcba3cb9e6d3775a096251860c41a6bc53a1b9461151df83fe93255/sentencepiece-0.2.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:99f955df238021bf11f0fc37cdb54fd5e5b5f7fd30ecc3d93fb48b6815437167", size = 1316273, upload-time = "2025-08-12T06:59:44.476Z" }, + { url = "https://files.pythonhosted.org/packages/04/88/14f2f4a2b922d8b39be45bf63d79e6cd3a9b2f248b2fcb98a69b12af12f5/sentencepiece-0.2.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0cdfecef430d985f1c2bcbfff3defd1d95dae876fbd0173376012d2d7d24044b", size = 1387881, upload-time = "2025-08-12T06:59:46.09Z" }, + { url = "https://files.pythonhosted.org/packages/fd/b8/903e5ccb77b4ef140605d5d71b4f9e0ad95d456d6184688073ed11712809/sentencepiece-0.2.1-cp312-cp312-win32.whl", hash = "sha256:a483fd29a34c3e34c39ac5556b0a90942bec253d260235729e50976f5dba1068", size = 999540, upload-time = "2025-08-12T06:59:48.023Z" }, + { url = "https://files.pythonhosted.org/packages/2d/81/92df5673c067148c2545b1bfe49adfd775bcc3a169a047f5a0e6575ddaca/sentencepiece-0.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:4cdc7c36234fda305e85c32949c5211faaf8dd886096c7cea289ddc12a2d02de", size = 1054671, upload-time = "2025-08-12T06:59:49.895Z" }, + { url = "https://files.pythonhosted.org/packages/fe/02/c5e3bc518655d714622bec87d83db9cdba1cd0619a4a04e2109751c4f47f/sentencepiece-0.2.1-cp312-cp312-win_arm64.whl", hash = "sha256:daeb5e9e9fcad012324807856113708614d534f596d5008638eb9b40112cd9e4", size = 1033923, upload-time = "2025-08-12T06:59:51.952Z" }, +] + [[package]] name = "sentry-sdk" version = "2.29.1" @@ -2191,6 +2332,35 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359, upload-time = "2024-04-19T11:11:46.763Z" }, ] +[[package]] +name = "transformer-lens" +version = "2.16.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "accelerate" }, + { name = "beartype" }, + { name = "better-abc" }, + { name = "datasets" }, + { name = "einops" }, + { name = "fancy-einsum" }, + { name = "jaxtyping" }, + { name = "numpy" }, + { name = "pandas" }, + { name = "rich" }, + { name = "sentencepiece" }, + { name = "torch" }, + { name = "tqdm" }, + { name = "transformers" }, + { name = "transformers-stream-generator" }, + { name = "typeguard" }, + { name = "typing-extensions" }, + { name = "wandb" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/dd/91/96026f9de52e39e4385c503e2c79e355529ddf48eecade8c433fb9efa930/transformer_lens-2.16.1.tar.gz", hash = "sha256:62c92bb6b986af67cb5a1605da0f9b1a76a91cdf0cc05492c9faab716675b08e", size = 153889, upload-time = "2025-06-19T13:32:18.926Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/30/bf/fcf5e93e56d614025a5f732059ce924adac606cadf42b87c50e002ab7e5a/transformer_lens-2.16.1-py3-none-any.whl", hash = "sha256:fd59ab8c08d864d93a48f4e40ad20f437fc903e037e320cfd28c8d3f7a1817ce", size = 192023, upload-time = "2025-06-19T13:32:17.821Z" }, +] + [[package]] name = "transformers" version = "4.52.4" @@ -2212,6 +2382,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/96/f2/25b27b396af03d5b64e61976b14f7209e2939e9e806c10749b6d277c273e/transformers-4.52.4-py3-none-any.whl", hash = "sha256:203f5c19416d5877e36e88633943761719538a25d9775977a24fe77a1e5adfc7", size = 10460375, upload-time = "2025-05-30T09:17:14.477Z" }, ] +[[package]] +name = "transformers-stream-generator" +version = "0.0.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "transformers" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/c2/65f13aec253100e1916e9bd7965fe17bde796ebabeb1265f45191ab4ddc0/transformers-stream-generator-0.0.5.tar.gz", hash = "sha256:271deace0abf9c0f83b36db472c8ba61fdc7b04d1bf89d845644acac2795ed57", size = 13033, upload-time = "2024-03-11T14:18:02.079Z" } + [[package]] name = "triton" version = "3.4.0" @@ -2223,6 +2402,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d0/66/b1eb52839f563623d185f0927eb3530ee4d5ffe9d377cdaf5346b306689e/triton-3.4.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:31c1d84a5c0ec2c0f8e8a072d7fd150cab84a9c239eaddc6706c081bfae4eb04", size = 155560068, upload-time = "2025-07-30T19:58:37.081Z" }, ] +[[package]] +name = "typeguard" +version = "4.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c7/68/71c1a15b5f65f40e91b65da23b8224dad41349894535a97f63a52e462196/typeguard-4.4.4.tar.gz", hash = "sha256:3a7fd2dffb705d4d0efaed4306a704c89b9dee850b688f060a8b1615a79e5f74", size = 75203, upload-time = "2025-06-18T09:56:07.624Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1b/a9/e3aee762739c1d7528da1c3e06d518503f8b6c439c35549b53735ba52ead/typeguard-4.4.4-py3-none-any.whl", hash = "sha256:b5f562281b6bfa1f5492470464730ef001646128b180769880468bd84b68b09e", size = 34874, upload-time = "2025-06-18T09:56:05.999Z" }, +] + [[package]] name = "types-python-dateutil" version = "2.9.0.20250516" @@ -2370,6 +2561,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526", size = 58826, upload-time = "2024-04-23T22:16:14.422Z" }, ] +[[package]] +name = "widgetsnbextension" +version = "4.0.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/41/53/2e0253c5efd69c9656b1843892052a31c36d37ad42812b5da45c62191f7e/widgetsnbextension-4.0.14.tar.gz", hash = "sha256:a3629b04e3edb893212df862038c7232f62973373869db5084aed739b437b5af", size = 1097428, upload-time = "2025-04-10T13:01:25.628Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/51/5447876806d1088a0f8f71e16542bf350918128d0a69437df26047c8e46f/widgetsnbextension-4.0.14-py3-none-any.whl", hash = "sha256:4875a9eaf72fbf5079dc372a51a9f268fc38d46f767cbf85c43a36da5cb9b575", size = 2196503, upload-time = "2025-04-10T13:01:23.086Z" }, +] + [[package]] name = "wsproto" version = "1.2.0" From cee0d021c5cce965f547215597f79415785f85d5 Mon Sep 17 00:00:00 2001 From: jiito Date: Mon, 29 Sep 2025 20:37:38 -0700 Subject: [PATCH 03/99] rm imports --- crosslayer_transcoder/utils/convert_to_circuit_tracer.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/crosslayer_transcoder/utils/convert_to_circuit_tracer.py b/crosslayer_transcoder/utils/convert_to_circuit_tracer.py index f610ad1..9509f93 100644 --- a/crosslayer_transcoder/utils/convert_to_circuit_tracer.py +++ b/crosslayer_transcoder/utils/convert_to_circuit_tracer.py @@ -6,14 +6,11 @@ from huggingface_hub import upload_folder import torch import yaml -from einops import einops from safetensors.torch import save_file -from torch.export.graph_signature import OutputKind from crosslayer_transcoder.model.clt import ( CrosslayerDecoder, Encoder, - SimpleCrossLayerTranscoder, ) from crosslayer_transcoder.model.clt_lightning import ( CrossLayerTranscoderModule, From 211918ffc48358f23893b83ee06fa9d308743429 Mon Sep 17 00:00:00 2001 From: jiito Date: Mon, 29 Sep 2025 20:37:48 -0700 Subject: [PATCH 04/99] add CT callback --- crosslayer_transcoder/utils/callbacks.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/crosslayer_transcoder/utils/callbacks.py b/crosslayer_transcoder/utils/callbacks.py index b574ed5..bdfb6d0 100644 --- a/crosslayer_transcoder/utils/callbacks.py +++ b/crosslayer_transcoder/utils/callbacks.py @@ -13,6 +13,10 @@ tensorboard_trace_handler, ) +from crosslayer_transcoder.utils.convert_to_circuit_tracer import ( + convert_model_to_circuit_tracer, +) + logger = logging.getLogger(__name__) @@ -54,3 +58,14 @@ def on_train_end(self, trainer, pl_module): self.checkpoint_dir.mkdir(parents=True, exist_ok=True) checkpoint_path = self.checkpoint_dir / "clt.ckpt" trainer.save_checkpoint(checkpoint_path) + + +class CircuitTracerCallback(L.Callback): + """Callback to convert the model to a circuit-tracer model.""" + + def __init__(self, save_dir: str = "clt_module"): + super().__init__() + self.save_dir = Path(save_dir) + + def on_train_end(self, trainer, pl_module): + convert_model_to_circuit_tracer(pl_module, self.save_dir) From cd8ebdabcbadfcae133adbf88f01ae22ab4c6f3a Mon Sep 17 00:00:00 2001 From: jiito Date: Sat, 13 Sep 2025 16:32:46 -0700 Subject: [PATCH 05/99] initial working modal training setup --- crosslayer_transcoder/modal/train.py | 243 +++++ crosslayer_transcoder/model/clt.py | 61 +- pyproject.toml | 1 + uv.lock | 1461 ++++++++++++++------------ 4 files changed, 1102 insertions(+), 664 deletions(-) create mode 100644 crosslayer_transcoder/modal/train.py diff --git a/crosslayer_transcoder/modal/train.py b/crosslayer_transcoder/modal/train.py new file mode 100644 index 0000000..3243a87 --- /dev/null +++ b/crosslayer_transcoder/modal/train.py @@ -0,0 +1,243 @@ +from pathlib import Path +import logging +from typing import Optional + +from crosslayer_transcoder.model.jumprelu import JumpReLU +from crosslayer_transcoder.utils.buffer import DiscBuffer +import modal +import torch as t + +volume = modal.Volume.from_name("clt-checkpoints", create_if_missing=True) + +image = modal.Image.debian_slim(python_version="3.12").pip_install( + "torch>=2.8.0", + "nnsight==0.5.0.dev7", + "datasets==3.6.0", + "h5py>=3.13.0", + "einops>=0.8.1", + "jaxtyping>=0.3.2", + "lightning>=2.5.1", + "wandb>=0.19.11", + "transformers>=4.46.0", + "numpy>=1.24.0", + "jsonargparse[signatures]>=4.27.7", +) + +image = image.add_local_python_source("crosslayer_transcoder") + + +app = modal.App("clt-train", image=image) + +wandb_secret = modal.Secret.from_name("wandb-secret") + + +volume_path = Path("/experiments") +ACTIVATIONS_PATH = volume_path / "activations" +CHECKPOINTS_PATH = volume_path / "checkpoints" +WANDB_PATH = volume_path / "wandb" + +volumes = {volume_path: volume} + +retries = modal.Retries(initial_delay=0.0, max_retries=10) + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + + +def ensure_directories(): + ACTIVATIONS_PATH.mkdir(parents=True, exist_ok=True) + CHECKPOINTS_PATH.mkdir(parents=True, exist_ok=True) + WANDB_PATH.mkdir(parents=True, exist_ok=True) + + +@app.function( + volumes=volumes, + gpu="a10g", + retries=retries, + max_inputs=1, + timeout=60 * 60 * 24, + secrets=[wandb_secret], +) +def train_interruptible(*args, **kwargs): + train(*args, **kwargs) + + +def train(experiment): + ensure_directories() + experiment_dir = CHECKPOINTS_PATH / experiment + last_checkpoint = experiment_dir / "last.ckpt" + + if last_checkpoint.exists(): + print(f"⚡️ resuming training from the latest checkpoint: {last_checkpoint}") + train_model( + ACTIVATIONS_PATH, + experiment_dir, + resume_from_checkpoint=last_checkpoint, + ) + print("⚡️ training finished successfully") + else: + print("⚡️ starting training from scratch") + train_model(ACTIVATIONS_PATH, experiment_dir) + + +def volume_commit(volume): + def inner(func): + def wrapper(*args, **kwargs): + logger.info("Committing volume") + result = func(*args, **kwargs) + volume.commit() + logger.info("Volume committed") + return result + + return wrapper + + return inner + + +@volume_commit(volume) +def get_checkpoint(checkpoint_dir): + from lightning.pytorch.callbacks import ModelCheckpoint + + return ModelCheckpoint( + dirpath=checkpoint_dir, + save_last=True, + every_n_epochs=10, + filename="{epoch:02d}", + ) + + +def train_model(data_dir, checkpoint_dir, resume_from_checkpoint=None): + import lightning as L + from lightning.pytorch.loggers import WandbLogger + + model = get_model() + train_loader = get_train_loader( + data_dir=data_dir, file_name="openai-community_gpt2.h5", accessor="activations" + ) + checkpoint_callback = get_checkpoint(checkpoint_dir) + wandb_logger = WandbLogger(project="clt-train-modal") + + logger.info("Compiling model") + # model = t.compile(model) + logger.info("Model compiled") + + trainer = L.Trainer( + max_steps=100_000, + val_check_interval=1_000, + limit_val_batches=1, + check_val_every_n_epoch=None, + callbacks=[checkpoint_callback], + precision="16-true", + accelerator="gpu", + devices=[0], + logger=wandb_logger, + # strategy="ddp", + # callbacks=[TBProfilerCallback()], + accumulate_grad_batches=1, + ) + + if resume_from_checkpoint is not None: + trainer.fit( + model=model, + train_dataloaders=train_loader, + ckpt_path=resume_from_checkpoint, + ) + else: + logger.info("Training model from scratch") + trainer.fit(model, train_loader) + + +def get_model(checkpoint_path=None): + from crosslayer_transcoder.model.clt_lightning import ( + JumpReLUCrossLayerTranscoderModule, + ) + from crosslayer_transcoder.model.clt import CrossLayerTranscoder + from crosslayer_transcoder.model.clt import Encoder + from crosslayer_transcoder.model.clt import CrosslayerDecoder + from crosslayer_transcoder.model.standardize import DimensionwiseInputStandardizer + from crosslayer_transcoder.model.standardize import DimensionwiseOutputStandardizer + from crosslayer_transcoder.metrics.replacement_model_accuracy import ( + ReplacementModelAccuracy, + ) + from crosslayer_transcoder.metrics.dead_features import DeadFeatures + + encoder = Encoder( + d_acts=768, + d_features=10_000, + n_layers=12, + ) + decoder = CrosslayerDecoder( + d_acts=768, + d_features=10_000, + n_layers=12, + ) + replacement_model = ReplacementModelAccuracy( + model_name="openai-community/gpt2", + device_map="cuda:0", + loader_batch_size=2, + ) + + dead_features = DeadFeatures( + n_features=10_000, + n_layers=12, + return_per_layer=True, + return_log_freqs=True, + return_neuron_indices=True, + ) + + clt = CrossLayerTranscoder( + encoder=encoder, + decoder=decoder, + input_standardizer=DimensionwiseInputStandardizer( + n_layers=12, + activation_dim=768, + ), + output_standardizer=DimensionwiseOutputStandardizer( + n_layers=12, + activation_dim=768, + ), + nonlinearity=JumpReLU( + theta=0.03, bandwidth=0.01, n_layers=12, d_features=10_000 + ), + ) + + return JumpReLUCrossLayerTranscoderModule( + model=clt, + replacement_model=replacement_model, + dead_features=dead_features, + learning_rate=1e-4, + compile=True, + lr_decay_step=80_000, + lr_decay_factor=0.1, + lambda_sparsity=0.0007, + c_sparsity=1, + use_tanh=True, + pre_actv_loss=1e-6, + compute_dead_features=True, + compute_dead_features_every=500, + ) + + +def get_train_loader(data_dir, file_name="clt-activations-10M.h5", accessor="tensor"): + print("⚡ setting up data") + buffer = DiscBuffer(data_dir / file_name, accessor) + train_loader = t.utils.data.DataLoader( + buffer, + num_workers=20, + prefetch_factor=2, + batch_size=4000, + shuffle=True, + persistent_workers=True, + pin_memory=True, + ) + return train_loader + + +@app.local_entrypoint() +def main(experiment: Optional[str] = None): + if experiment is None: + from uuid import uuid4 + + experiment = uuid4().hex[:8] + print(f"⚡️ starting interruptible training experiment {experiment}") + train_interruptible.spawn(experiment).get() diff --git a/crosslayer_transcoder/model/clt.py b/crosslayer_transcoder/model/clt.py index cc58891..7090d57 100644 --- a/crosslayer_transcoder/model/clt.py +++ b/crosslayer_transcoder/model/clt.py @@ -51,7 +51,11 @@ def reset_parameters(self): dec_uniform_thresh = 1 / ((self.d_acts * self.n_layers) ** 0.5) self.W_dec.data.uniform_(-dec_uniform_thresh, dec_uniform_thresh) - mask = self.mask.unsqueeze(-1).unsqueeze(-1).repeat(1, 1, self.d_features, self.d_acts) + mask = ( + self.mask.unsqueeze(-1) + .unsqueeze(-1) + .repeat(1, 1, self.d_features, self.d_acts) + ) self.W_dec.data = torch.where(mask.bool(), self.W_dec.data, 0.0) if self.tied_init: @@ -63,7 +67,9 @@ def reset_parameters(self): # norm = self.W_dec.norm(p=2, dim=-1) # self.W_dec.data = self.W_dec.data / norm.unsqueeze(-1) - def initialize_standardizers(self, batch: Float[torch.Tensor, "batch_size io n_layers d_acts"]): + def initialize_standardizers( + self, batch: Float[torch.Tensor, "batch_size io n_layers d_acts"] + ): self.input_standardizer.initialize_from_batch(batch) self.output_standardizer.initialize_from_batch(batch) @@ -78,7 +84,9 @@ def decode( "from_layer to_layer -> batch_size to_layer d_acts", ) - def forward(self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"]) -> Tuple[ + def forward( + self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"] + ) -> Tuple[ Float[torch.Tensor, "batch_size n_layers d_features"], Float[torch.Tensor, "batch_size n_layers d_features"], Float[torch.Tensor, "batch_size n_layers d_acts"], @@ -132,7 +140,9 @@ def forward_layer( return pre_actvs def forward( - self, acts_norm: Float[torch.Tensor, "batch_size n_layers d_acts"], layer: str = "all" + self, + acts_norm: Float[torch.Tensor, "batch_size n_layers d_acts"], + layer: str = "all", ) -> Float[torch.Tensor, "batch_size n_layers d_features"]: # for inference if layer != "all": @@ -158,7 +168,9 @@ def __init__(self, d_acts: int, d_features: int, n_layers: int): self.d_acts = d_acts self.d_features = d_features self.n_layers = n_layers - self.register_parameter(f"W", nn.Parameter(torch.empty((n_layers, d_features, d_acts)))) + self.register_parameter( + f"W", nn.Parameter(torch.empty((n_layers, d_features, d_acts))) + ) self.reset_parameters() def reset_parameters(self): @@ -167,7 +179,9 @@ def reset_parameters(self): @torch.no_grad() def forward_layer( - self, features: Float[torch.Tensor, "batch_size seq from_layer d_features"], layer: int + self, + features: Float[torch.Tensor, "batch_size seq from_layer d_features"], + layer: int, ) -> Float[torch.Tensor, "batch_size seq d_acts"]: if features.ndim == 4: # (batch, seq, layer, d_features) features = features[:, :, layer, :] @@ -178,7 +192,9 @@ def forward_layer( ) def forward( - self, features: Float[torch.Tensor, "batch_size n_layers d_features"], layer: str = "all" + self, + features: Float[torch.Tensor, "batch_size n_layers d_features"], + layer: str = "all", ) -> Float[torch.Tensor, "batch_size n_layers d_acts"]: if layer != "all": return self.forward_layer(features, layer) @@ -198,14 +214,18 @@ def __init__(self, d_acts: int, d_features: int, n_layers: int): self.d_features = d_features self.n_layers = n_layers for i in range(n_layers): - self.register_parameter(f"W_{i}", nn.Parameter(torch.empty((i + 1, d_features, d_acts)))) + self.register_parameter( + f"W_{i}", nn.Parameter(torch.empty((i + 1, d_features, d_acts))) + ) self.register_parameter(f"b", nn.Parameter(torch.empty((n_layers, d_acts)))) self.reset_parameters() def reset_parameters(self): dec_uniform_thresh = 1 / ((self.d_acts * self.n_layers) ** 0.5) for i in range(self.n_layers): - self.get_parameter(f"W_{i}").data.uniform_(-dec_uniform_thresh, dec_uniform_thresh) + self.get_parameter(f"W_{i}").data.uniform_( + -dec_uniform_thresh, dec_uniform_thresh + ) # for l in range(i): # self.get_parameter(f"W_{i}").data[l, :, :] = self.get_parameter(f"W_{l}").data[l, :, :] * 0.0 @@ -213,7 +233,9 @@ def reset_parameters(self): @torch.no_grad() def forward_layer( - self, features: Float[torch.Tensor, "batch_size seq from_layer d_features"], layer: int + self, + features: Float[torch.Tensor, "batch_size seq from_layer d_features"], + layer: int, ) -> Float[torch.Tensor, "batch_size seq d_acts"]: return ( einsum( @@ -225,13 +247,19 @@ def forward_layer( ) def forward( - self, features: Float[torch.Tensor, "batch_size n_layers d_features"], layer: str = "all" + self, + features: Float[torch.Tensor, "batch_size n_layers d_features"], + layer: str = "all", ) -> Float[torch.Tensor, "batch_size n_layers d_acts"]: if layer != "all": return self.forward_layer(features, layer) recons = torch.empty( - features.shape[0], self.n_layers, self.d_acts, device=features.device, dtype=features.dtype + features.shape[0], + self.n_layers, + self.d_acts, + device=features.device, + dtype=features.dtype, ) for l in range(self.n_layers): W = self.get_parameter(f"W_{l}") @@ -269,11 +297,16 @@ def reset_parameters(self): self.encoder.reset_parameters() self.decoder.reset_parameters() - def initialize_standardizers(self, batch: Float[torch.Tensor, "batch_size io n_layers d_acts"]): + @torch._dynamo.disable() + def initialize_standardizers( + self, batch: Float[torch.Tensor, "batch_size io n_layers d_acts"] + ): self.input_standardizer.initialize_from_batch(batch) self.output_standardizer.initialize_from_batch(batch) - def forward(self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"]) -> Tuple[ + def forward( + self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"] + ) -> Tuple[ Float[torch.Tensor, "batch_size n_layers d_features"], # pre_actvs Float[torch.Tensor, "batch_size n_layers d_features"], # features Float[torch.Tensor, "batch_size n_layers d_acts"], # recons_norm diff --git a/pyproject.toml b/pyproject.toml index cbe532e..9100228 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,6 +23,7 @@ dependencies = [ "transformers>=4.46.0", "numpy>=1.24.0", "jsonargparse[signatures]>=4.27.7", + "modal>=1.1.4", ] [project.optional-dependencies] diff --git a/uv.lock b/uv.lock index f54c919..334ea17 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 2 +revision = 3 requires-python = "==3.12.*" resolution-markers = [ "sys_platform == 'linux'", @@ -8,7 +8,7 @@ resolution-markers = [ [[package]] name = "accelerate" -version = "1.7.0" +version = "1.11.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "huggingface-hub" }, @@ -19,9 +19,9 @@ dependencies = [ { name = "safetensors" }, { name = "torch" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/97/33/47bbd507e3a851d33d19ce7b2141c5ea3689bfae91ba168044d7db24b0e9/accelerate-1.7.0.tar.gz", hash = "sha256:e8a2a5503d6237b9eee73cc8d36cf543f9c2d8dd2c6713450b322f5e6d53a610", size = 376026, upload-time = "2025-05-15T10:00:52.117Z" } +sdist = { url = "https://files.pythonhosted.org/packages/23/60/2757c4f03a8705dbf80b1268b03881927878dca5ed07d74f733fb6c219e0/accelerate-1.11.0.tar.gz", hash = "sha256:bb1caf2597b4cd632b917b5000c591d10730bb024a79746f1ee205bba80bd229", size = 393715, upload-time = "2025-10-20T14:42:25.025Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f8/bb/be8146c196ad6e4dec78385d91e92591f8a433576c4e04c342a636fcd811/accelerate-1.7.0-py3-none-any.whl", hash = "sha256:cf57165cca28769c6cf2650812371c81b18e05743dfa3c748524b1bb4f2b272f", size = 362095, upload-time = "2025-05-15T10:00:49.914Z" }, + { url = "https://files.pythonhosted.org/packages/77/85/85951bc0f9843e2c10baaa1b6657227056095de08f4d1eea7d8b423a6832/accelerate-1.11.0-py3-none-any.whl", hash = "sha256:a628fa6beb069b8e549460fc449135d5bd8d73e7a11fd09f0bc9fc4ace7f06f1", size = 375777, upload-time = "2025-10-20T14:42:23.256Z" }, ] [[package]] @@ -35,7 +35,7 @@ wheels = [ [[package]] name = "aiohttp" -version = "3.12.11" +version = "3.13.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, @@ -46,37 +46,38 @@ dependencies = [ { name = "propcache" }, { name = "yarl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/93/6b/850a842871ab7be0d00686750d0ee9d8fb8e7be981e4e5700bb6c88f1b8f/aiohttp-3.12.11.tar.gz", hash = "sha256:a5149ae1b11ce4cf8b122846bfa3d7c5f29fe3bfe6745ab21b3eea9615bc5564", size = 7814403, upload-time = "2025-06-07T15:53:26.157Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/ce/3b83ebba6b3207a7135e5fcaba49706f8a4b6008153b4e30540c982fae26/aiohttp-3.13.2.tar.gz", hash = "sha256:40176a52c186aefef6eb3cad2cdd30cd06e3afbe88fe8ab2af9c0b90f228daca", size = 7837994, upload-time = "2025-10-28T20:59:39.937Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3f/6b/d5c7aa0e0b938ee1da791f781d51c5f08bddaa02b08f211999a62cc6abf2/aiohttp-3.12.11-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3d222c693342ccca64320410ada8f06a47c4762ff82de390f3357a0e51ca102c", size = 699756, upload-time = "2025-06-07T15:51:31.095Z" }, - { url = "https://files.pythonhosted.org/packages/47/c0/98d34a3ad793dc9884ae217ed5381e128d33d86b001da0687c9a457e415a/aiohttp-3.12.11-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f50c10bd5799d82a9effe90d5d5840e055a2c94e208b76f9ed9e6373ca2426fe", size = 474372, upload-time = "2025-06-07T15:51:32.872Z" }, - { url = "https://files.pythonhosted.org/packages/de/9a/f570309da9bbc84926683857893abaa3d77be1d77559fea10b1330feae70/aiohttp-3.12.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a01a21975b0fd5160886d9f2cd6ed13cdfc8d59f2a51051708ed729afcc2a2fb", size = 467208, upload-time = "2025-06-07T15:51:35.38Z" }, - { url = "https://files.pythonhosted.org/packages/76/67/349ad4ee103e2998b904c950f67cf8e854635714dd50f2dc7a7e9d66b68e/aiohttp-3.12.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39d29b6888ddd5a120dba1d52c78c0b45f5f34e227a23696cbece684872e62bd", size = 1714001, upload-time = "2025-06-07T15:51:37.625Z" }, - { url = "https://files.pythonhosted.org/packages/cf/cd/79538050dfbe9fcf745eb626bdc5429855615dd7ad3660f8082636b54664/aiohttp-3.12.11-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1df121c3ffcc5f7381cd4c84e8554ff121f558e92c318f48e049843b47ee9f1b", size = 1696652, upload-time = "2025-06-07T15:51:40.084Z" }, - { url = "https://files.pythonhosted.org/packages/41/26/844b6bc9b97e2cf76b6c1ee53ed2d65ed48d1647b90866d26f70dee7e679/aiohttp-3.12.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:644f74197757e26266a5f57af23424f8cd506c1ef70d9b288e21244af69d6fdc", size = 1751748, upload-time = "2025-06-07T15:51:42.513Z" }, - { url = "https://files.pythonhosted.org/packages/79/82/3c0b1dc8153d7158919e67f7eba5b52e4d8fb1708df1a562c0e3af7d949c/aiohttp-3.12.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:726d9a15a1fd1058b2d27d094b1fec627e9fd92882ca990d90ded9b7c550bd21", size = 1797903, upload-time = "2025-06-07T15:51:44.401Z" }, - { url = "https://files.pythonhosted.org/packages/f5/1b/1ba9cdb3d4dd676f8d335785562bf74eec98848c7516938522865f2c5ce5/aiohttp-3.12.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:405a60b979da942cec2c26381683bc230f3bcca346bf23a59c1dfc397e44b17b", size = 1717342, upload-time = "2025-06-07T15:51:46.607Z" }, - { url = "https://files.pythonhosted.org/packages/b1/e3/b2f42962f379307a1c3a5b5162115b8f244f47f1ef656ae3cf5f60c40116/aiohttp-3.12.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27e75e96a4a747756c2f59334e81cbb9a398e015bc9e08b28f91090e5f3a85ef", size = 1633146, upload-time = "2025-06-07T15:51:49.138Z" }, - { url = "https://files.pythonhosted.org/packages/12/fa/5f8f06bfeb8e9668d54082eb7428f47dc3a1dc74d7dfddaa16e237388b5f/aiohttp-3.12.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:15e1da30ac8bf92fb3f8c245ff53ace3f0ea1325750cc2f597fb707140dfd950", size = 1694205, upload-time = "2025-06-07T15:51:51.078Z" }, - { url = "https://files.pythonhosted.org/packages/e7/88/7af64b23ce041ec2693d763306fa670102a5b48c1012f342703e0a998f05/aiohttp-3.12.11-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:0329934d4df1500f13449c1db205d662123d9d0ee1c9d0c8c0cb997cdac75710", size = 1715659, upload-time = "2025-06-07T15:51:53.017Z" }, - { url = "https://files.pythonhosted.org/packages/ad/54/481761fcffe7264608272fc67877556e9ef00268af32a091950b909d06cf/aiohttp-3.12.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2a06b2a031d6c828828317ee951f07d8a0455edc9cd4fc0e0432fd6a4dfd612d", size = 1656310, upload-time = "2025-06-07T15:51:54.977Z" }, - { url = "https://files.pythonhosted.org/packages/fe/73/0ba372b3cb158334b1a23579a72f24c8ee99b7147d0671eefbe8a327cba4/aiohttp-3.12.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:87ece62697b8792e595627c4179f0eca4b038f39b0b354e67a149fa6f83d9493", size = 1735873, upload-time = "2025-06-07T15:51:57.441Z" }, - { url = "https://files.pythonhosted.org/packages/67/83/44057c78dc34f2c9d5f258da4aa6495aa20ca047044d50acfbab6630649f/aiohttp-3.12.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5c981b7659379b5cb3b149e480295adfcdf557b5892a792519a56badbe9f33ef", size = 1763846, upload-time = "2025-06-07T15:51:59.882Z" }, - { url = "https://files.pythonhosted.org/packages/45/39/f1fb8c2b3e3dd6e39ba9a5cf5dcb0cb70d163de4abceaab27d666f81e701/aiohttp-3.12.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e6fb2170cb0b9abbe0bee2767b08bb4a3dbf01583880ecea97bca9f3f918ea78", size = 1723455, upload-time = "2025-06-07T15:52:02.021Z" }, - { url = "https://files.pythonhosted.org/packages/5a/75/00b04567495f6ec2099b8a413408b65f058e78ce7325d3e6093f259da9b8/aiohttp-3.12.11-cp312-cp312-win32.whl", hash = "sha256:f20e4ec84a26f91adc8c54345a383095248d11851f257c816e8f1d853a6cef4c", size = 421027, upload-time = "2025-06-07T15:52:04.004Z" }, - { url = "https://files.pythonhosted.org/packages/cc/ef/4340f3e2bb7a00fd6ef9bbbba13ba8d56b47025c9323258da94b0d649117/aiohttp-3.12.11-cp312-cp312-win_amd64.whl", hash = "sha256:b54d4c3cd77cf394e71a7ad5c3b8143a5bfe105a40fc693bcdfe472a286f1d95", size = 447132, upload-time = "2025-06-07T15:52:05.891Z" }, + { url = "https://files.pythonhosted.org/packages/29/9b/01f00e9856d0a73260e86dd8ed0c2234a466c5c1712ce1c281548df39777/aiohttp-3.13.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b1e56bab2e12b2b9ed300218c351ee2a3d8c8fdab5b1ec6193e11a817767e47b", size = 737623, upload-time = "2025-10-28T20:56:30.797Z" }, + { url = "https://files.pythonhosted.org/packages/5a/1b/4be39c445e2b2bd0aab4ba736deb649fabf14f6757f405f0c9685019b9e9/aiohttp-3.13.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:364e25edaabd3d37b1db1f0cbcee8c73c9a3727bfa262b83e5e4cf3489a2a9dc", size = 492664, upload-time = "2025-10-28T20:56:32.708Z" }, + { url = "https://files.pythonhosted.org/packages/28/66/d35dcfea8050e131cdd731dff36434390479b4045a8d0b9d7111b0a968f1/aiohttp-3.13.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c5c94825f744694c4b8db20b71dba9a257cd2ba8e010a803042123f3a25d50d7", size = 491808, upload-time = "2025-10-28T20:56:34.57Z" }, + { url = "https://files.pythonhosted.org/packages/00/29/8e4609b93e10a853b65f8291e64985de66d4f5848c5637cddc70e98f01f8/aiohttp-3.13.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba2715d842ffa787be87cbfce150d5e88c87a98e0b62e0f5aa489169a393dbbb", size = 1738863, upload-time = "2025-10-28T20:56:36.377Z" }, + { url = "https://files.pythonhosted.org/packages/9d/fa/4ebdf4adcc0def75ced1a0d2d227577cd7b1b85beb7edad85fcc87693c75/aiohttp-3.13.2-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:585542825c4bc662221fb257889e011a5aa00f1ae4d75d1d246a5225289183e3", size = 1700586, upload-time = "2025-10-28T20:56:38.034Z" }, + { url = "https://files.pythonhosted.org/packages/da/04/73f5f02ff348a3558763ff6abe99c223381b0bace05cd4530a0258e52597/aiohttp-3.13.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:39d02cb6025fe1aabca329c5632f48c9532a3dabccd859e7e2f110668972331f", size = 1768625, upload-time = "2025-10-28T20:56:39.75Z" }, + { url = "https://files.pythonhosted.org/packages/f8/49/a825b79ffec124317265ca7d2344a86bcffeb960743487cb11988ffb3494/aiohttp-3.13.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e67446b19e014d37342f7195f592a2a948141d15a312fe0e700c2fd2f03124f6", size = 1867281, upload-time = "2025-10-28T20:56:41.471Z" }, + { url = "https://files.pythonhosted.org/packages/b9/48/adf56e05f81eac31edcfae45c90928f4ad50ef2e3ea72cb8376162a368f8/aiohttp-3.13.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4356474ad6333e41ccefd39eae869ba15a6c5299c9c01dfdcfdd5c107be4363e", size = 1752431, upload-time = "2025-10-28T20:56:43.162Z" }, + { url = "https://files.pythonhosted.org/packages/30/ab/593855356eead019a74e862f21523db09c27f12fd24af72dbc3555b9bfd9/aiohttp-3.13.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:eeacf451c99b4525f700f078becff32c32ec327b10dcf31306a8a52d78166de7", size = 1562846, upload-time = "2025-10-28T20:56:44.85Z" }, + { url = "https://files.pythonhosted.org/packages/39/0f/9f3d32271aa8dc35036e9668e31870a9d3b9542dd6b3e2c8a30931cb27ae/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d8a9b889aeabd7a4e9af0b7f4ab5ad94d42e7ff679aaec6d0db21e3b639ad58d", size = 1699606, upload-time = "2025-10-28T20:56:46.519Z" }, + { url = "https://files.pythonhosted.org/packages/2c/3c/52d2658c5699b6ef7692a3f7128b2d2d4d9775f2a68093f74bca06cf01e1/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:fa89cb11bc71a63b69568d5b8a25c3ca25b6d54c15f907ca1c130d72f320b76b", size = 1720663, upload-time = "2025-10-28T20:56:48.528Z" }, + { url = "https://files.pythonhosted.org/packages/9b/d4/8f8f3ff1fb7fb9e3f04fcad4e89d8a1cd8fc7d05de67e3de5b15b33008ff/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8aa7c807df234f693fed0ecd507192fc97692e61fee5702cdc11155d2e5cadc8", size = 1737939, upload-time = "2025-10-28T20:56:50.77Z" }, + { url = "https://files.pythonhosted.org/packages/03/d3/ddd348f8a27a634daae39a1b8e291ff19c77867af438af844bf8b7e3231b/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:9eb3e33fdbe43f88c3c75fa608c25e7c47bbd80f48d012763cb67c47f39a7e16", size = 1555132, upload-time = "2025-10-28T20:56:52.568Z" }, + { url = "https://files.pythonhosted.org/packages/39/b8/46790692dc46218406f94374903ba47552f2f9f90dad554eed61bfb7b64c/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9434bc0d80076138ea986833156c5a48c9c7a8abb0c96039ddbb4afc93184169", size = 1764802, upload-time = "2025-10-28T20:56:54.292Z" }, + { url = "https://files.pythonhosted.org/packages/ba/e4/19ce547b58ab2a385e5f0b8aa3db38674785085abcf79b6e0edd1632b12f/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ff15c147b2ad66da1f2cbb0622313f2242d8e6e8f9b79b5206c84523a4473248", size = 1719512, upload-time = "2025-10-28T20:56:56.428Z" }, + { url = "https://files.pythonhosted.org/packages/70/30/6355a737fed29dcb6dfdd48682d5790cb5eab050f7b4e01f49b121d3acad/aiohttp-3.13.2-cp312-cp312-win32.whl", hash = "sha256:27e569eb9d9e95dbd55c0fc3ec3a9335defbf1d8bc1d20171a49f3c4c607b93e", size = 426690, upload-time = "2025-10-28T20:56:58.736Z" }, + { url = "https://files.pythonhosted.org/packages/0a/0d/b10ac09069973d112de6ef980c1f6bb31cb7dcd0bc363acbdad58f927873/aiohttp-3.13.2-cp312-cp312-win_amd64.whl", hash = "sha256:8709a0f05d59a71f33fd05c17fc11fcb8c30140506e13c2f5e8ee1b8964e1b45", size = 453465, upload-time = "2025-10-28T20:57:00.795Z" }, ] [[package]] name = "aiosignal" -version = "1.3.2" +version = "1.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "frozenlist" }, + { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ba/b5/6d55e80f6d8a08ce22b982eafa278d823b541c925f11ee774b0b9c43473d/aiosignal-1.3.2.tar.gz", hash = "sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54", size = 19424, upload-time = "2024-12-13T17:10:40.86Z" } +sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/6a/bc7e17a3e87a2985d3e8f4da4cd0f481060eb78fb08596c42be62c90a4d9/aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5", size = 7597, upload-time = "2024-12-13T17:10:38.469Z" }, + { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, ] [[package]] @@ -90,16 +91,16 @@ wheels = [ [[package]] name = "anyio" -version = "4.9.0" +version = "4.11.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "sniffio" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/95/7d/4c1bd541d4dffa1b52bd83fb8527089e097a106fc90b467a7313b105f840/anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028", size = 190949, upload-time = "2025-03-17T00:02:54.77Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c6/78/7d432127c41b50bccba979505f272c16cbcadcc33645d5fa3a738110ae75/anyio-4.11.0.tar.gz", hash = "sha256:82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4", size = 219094, upload-time = "2025-09-23T09:19:12.58Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916, upload-time = "2025-03-17T00:02:52.713Z" }, + { url = "https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl", hash = "sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc", size = 109097, upload-time = "2025-09-23T09:19:10.601Z" }, ] [[package]] @@ -125,36 +126,36 @@ wheels = [ [[package]] name = "argon2-cffi-bindings" -version = "21.2.0" +version = "25.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b9/e9/184b8ccce6683b0aa2fbb7ba5683ea4b9c5763f1356347f1312c32e3c66e/argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3", size = 1779911, upload-time = "2021-12-01T08:52:55.68Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5c/2d/db8af0df73c1cf454f71b2bbe5e356b8c1f8041c979f505b3d3186e520a9/argon2_cffi_bindings-25.1.0.tar.gz", hash = "sha256:b957f3e6ea4d55d820e40ff76f450952807013d361a65d7f28acc0acbf29229d", size = 1783441, upload-time = "2025-07-30T10:02:05.147Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d4/13/838ce2620025e9666aa8f686431f67a29052241692a3dd1ae9d3692a89d3/argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367", size = 29658, upload-time = "2021-12-01T09:09:17.016Z" }, - { url = "https://files.pythonhosted.org/packages/b3/02/f7f7bb6b6af6031edb11037639c697b912e1dea2db94d436e681aea2f495/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d", size = 80583, upload-time = "2021-12-01T09:09:19.546Z" }, - { url = "https://files.pythonhosted.org/packages/ec/f7/378254e6dd7ae6f31fe40c8649eea7d4832a42243acaf0f1fff9083b2bed/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae", size = 86168, upload-time = "2021-12-01T09:09:21.445Z" }, - { url = "https://files.pythonhosted.org/packages/74/f6/4a34a37a98311ed73bb80efe422fed95f2ac25a4cacc5ae1d7ae6a144505/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c", size = 82709, upload-time = "2021-12-01T09:09:18.182Z" }, - { url = "https://files.pythonhosted.org/packages/74/2b/73d767bfdaab25484f7e7901379d5f8793cccbb86c6e0cbc4c1b96f63896/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86", size = 83613, upload-time = "2021-12-01T09:09:22.741Z" }, - { url = "https://files.pythonhosted.org/packages/4f/fd/37f86deef67ff57c76f137a67181949c2d408077e2e3dd70c6c42912c9bf/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_i686.whl", hash = "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f", size = 84583, upload-time = "2021-12-01T09:09:24.177Z" }, - { url = "https://files.pythonhosted.org/packages/6f/52/5a60085a3dae8fded8327a4f564223029f5f54b0cb0455a31131b5363a01/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e", size = 88475, upload-time = "2021-12-01T09:09:26.673Z" }, - { url = "https://files.pythonhosted.org/packages/8b/95/143cd64feb24a15fa4b189a3e1e7efbaeeb00f39a51e99b26fc62fbacabd/argon2_cffi_bindings-21.2.0-cp36-abi3-win32.whl", hash = "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082", size = 27698, upload-time = "2021-12-01T09:09:27.87Z" }, - { url = "https://files.pythonhosted.org/packages/37/2c/e34e47c7dee97ba6f01a6203e0383e15b60fb85d78ac9a15cd066f6fe28b/argon2_cffi_bindings-21.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f", size = 30817, upload-time = "2021-12-01T09:09:30.267Z" }, - { url = "https://files.pythonhosted.org/packages/5a/e4/bf8034d25edaa495da3c8a3405627d2e35758e44ff6eaa7948092646fdcc/argon2_cffi_bindings-21.2.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93", size = 53104, upload-time = "2021-12-01T09:09:31.335Z" }, + { url = "https://files.pythonhosted.org/packages/1d/57/96b8b9f93166147826da5f90376e784a10582dd39a393c99bb62cfcf52f0/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:aecba1723ae35330a008418a91ea6cfcedf6d31e5fbaa056a166462ff066d500", size = 54121, upload-time = "2025-07-30T10:01:50.815Z" }, + { url = "https://files.pythonhosted.org/packages/0a/08/a9bebdb2e0e602dde230bdde8021b29f71f7841bd54801bcfd514acb5dcf/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2630b6240b495dfab90aebe159ff784d08ea999aa4b0d17efa734055a07d2f44", size = 29177, upload-time = "2025-07-30T10:01:51.681Z" }, + { url = "https://files.pythonhosted.org/packages/b6/02/d297943bcacf05e4f2a94ab6f462831dc20158614e5d067c35d4e63b9acb/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:7aef0c91e2c0fbca6fc68e7555aa60ef7008a739cbe045541e438373bc54d2b0", size = 31090, upload-time = "2025-07-30T10:01:53.184Z" }, + { url = "https://files.pythonhosted.org/packages/c1/93/44365f3d75053e53893ec6d733e4a5e3147502663554b4d864587c7828a7/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e021e87faa76ae0d413b619fe2b65ab9a037f24c60a1e6cc43457ae20de6dc6", size = 81246, upload-time = "2025-07-30T10:01:54.145Z" }, + { url = "https://files.pythonhosted.org/packages/09/52/94108adfdd6e2ddf58be64f959a0b9c7d4ef2fa71086c38356d22dc501ea/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d3e924cfc503018a714f94a49a149fdc0b644eaead5d1f089330399134fa028a", size = 87126, upload-time = "2025-07-30T10:01:55.074Z" }, + { url = "https://files.pythonhosted.org/packages/72/70/7a2993a12b0ffa2a9271259b79cc616e2389ed1a4d93842fac5a1f923ffd/argon2_cffi_bindings-25.1.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c87b72589133f0346a1cb8d5ecca4b933e3c9b64656c9d175270a000e73b288d", size = 80343, upload-time = "2025-07-30T10:01:56.007Z" }, + { url = "https://files.pythonhosted.org/packages/78/9a/4e5157d893ffc712b74dbd868c7f62365618266982b64accab26bab01edc/argon2_cffi_bindings-25.1.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1db89609c06afa1a214a69a462ea741cf735b29a57530478c06eb81dd403de99", size = 86777, upload-time = "2025-07-30T10:01:56.943Z" }, + { url = "https://files.pythonhosted.org/packages/74/cd/15777dfde1c29d96de7f18edf4cc94c385646852e7c7b0320aa91ccca583/argon2_cffi_bindings-25.1.0-cp39-abi3-win32.whl", hash = "sha256:473bcb5f82924b1becbb637b63303ec8d10e84c8d241119419897a26116515d2", size = 27180, upload-time = "2025-07-30T10:01:57.759Z" }, + { url = "https://files.pythonhosted.org/packages/e2/c6/a759ece8f1829d1f162261226fbfd2c6832b3ff7657384045286d2afa384/argon2_cffi_bindings-25.1.0-cp39-abi3-win_amd64.whl", hash = "sha256:a98cd7d17e9f7ce244c0803cad3c23a7d379c301ba618a5fa76a67d116618b98", size = 31715, upload-time = "2025-07-30T10:01:58.56Z" }, + { url = "https://files.pythonhosted.org/packages/42/b9/f8d6fa329ab25128b7e98fd83a3cb34d9db5b059a9847eddb840a0af45dd/argon2_cffi_bindings-25.1.0-cp39-abi3-win_arm64.whl", hash = "sha256:b0fdbcf513833809c882823f98dc2f931cf659d9a1429616ac3adebb49f5db94", size = 27149, upload-time = "2025-07-30T10:01:59.329Z" }, ] [[package]] name = "arrow" -version = "1.3.0" +version = "1.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "python-dateutil" }, - { name = "types-python-dateutil" }, + { name = "tzdata" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2e/00/0f6e8fcdb23ea632c866620cc872729ff43ed91d284c866b515c6342b173/arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85", size = 131960, upload-time = "2023-09-30T22:11:18.25Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b9/33/032cdc44182491aa708d06a68b62434140d8c50820a087fac7af37703357/arrow-1.4.0.tar.gz", hash = "sha256:ed0cc050e98001b8779e84d461b0098c4ac597e88704a655582b21d116e526d7", size = 152931, upload-time = "2025-10-18T17:46:46.761Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f8/ed/e97229a566617f2ae958a6b13e7cc0f585470eac730a73e9e82c32a3cdd2/arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80", size = 66419, upload-time = "2023-09-30T22:11:16.072Z" }, + { url = "https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl", hash = "sha256:749f0769958ebdc79c173ff0b0670d59051a535fa26e8eba02953dc19eb43205", size = 68797, upload-time = "2025-10-18T17:46:45.663Z" }, ] [[package]] @@ -186,11 +187,11 @@ wheels = [ [[package]] name = "attrs" -version = "25.3.0" +version = "25.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload-time = "2025-03-13T11:10:22.779Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251, upload-time = "2025-10-06T13:54:44.725Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" }, + { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, ] [[package]] @@ -213,15 +214,15 @@ wheels = [ [[package]] name = "beautifulsoup4" -version = "4.13.4" +version = "4.14.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "soupsieve" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d8/e4/0c4c39e18fd76d6a628d4dd8da40543d136ce2d1752bd6eeeab0791f4d6b/beautifulsoup4-4.13.4.tar.gz", hash = "sha256:dbb3c4e1ceae6aefebdaf2423247260cd062430a410e38c66f2baa50a8437195", size = 621067, upload-time = "2025-04-15T17:05:13.836Z" } +sdist = { url = "https://files.pythonhosted.org/packages/77/e9/df2358efd7659577435e2177bfa69cba6c33216681af51a707193dec162a/beautifulsoup4-4.14.2.tar.gz", hash = "sha256:2a98ab9f944a11acee9cc848508ec28d9228abfd522ef0fad6a02a72e0ded69e", size = 625822, upload-time = "2025-09-29T10:05:42.613Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/50/cd/30110dc0ffcf3b131156077b90e9f60ed75711223f306da4db08eff8403b/beautifulsoup4-4.13.4-py3-none-any.whl", hash = "sha256:9bbbb14bfde9d79f38b8cd5f8c7c85f4b8f2523190ebed90e950a8dea4cb1c4b", size = 187285, upload-time = "2025-04-15T17:05:12.221Z" }, + { url = "https://files.pythonhosted.org/packages/94/fe/3aed5d0be4d404d12d36ab97e2f1791424d9ca39c2f754a6285d59a3b01d/beautifulsoup4-4.14.2-py3-none-any.whl", hash = "sha256:5ef6fa3a8cbece8488d66985560f97ed091e22bbc4e9c2338508a9d5de6d4515", size = 106392, upload-time = "2025-09-29T10:05:43.771Z" }, ] [[package]] @@ -244,14 +245,14 @@ wheels = [ [[package]] name = "bleach" -version = "6.2.0" +version = "6.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "webencodings" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/76/9a/0e33f5054c54d349ea62c277191c020c2d6ef1d65ab2cb1993f91ec846d1/bleach-6.2.0.tar.gz", hash = "sha256:123e894118b8a599fd80d3ec1a6d4cc7ce4e5882b1317a7e1ba69b56e95f991f", size = 203083, upload-time = "2024-10-29T18:30:40.477Z" } +sdist = { url = "https://files.pythonhosted.org/packages/07/18/3c8523962314be6bf4c8989c79ad9531c825210dd13a8669f6b84336e8bd/bleach-6.3.0.tar.gz", hash = "sha256:6f3b91b1c0a02bb9a78b5a454c92506aa0fdf197e1d5e114d2e00c6f64306d22", size = 203533, upload-time = "2025-10-27T17:57:39.211Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fc/55/96142937f66150805c25c4d0f31ee4132fd33497753400734f9dfdcbdc66/bleach-6.2.0-py3-none-any.whl", hash = "sha256:117d9c6097a7c3d22fd578fcd8d35ff1e125df6736f554da4e432fdd63f31e5e", size = 163406, upload-time = "2024-10-29T18:30:38.186Z" }, + { url = "https://files.pythonhosted.org/packages/cd/3a/577b549de0cc09d95f11087ee63c739bba856cd3952697eec4c4bb91350a/bleach-6.3.0-py3-none-any.whl", hash = "sha256:fe10ec77c93ddf3d13a73b035abaac7a9f5e436513864ccdad516693213c65d6", size = 164437, upload-time = "2025-10-27T17:57:37.538Z" }, ] [package.optional-dependencies] @@ -259,57 +260,78 @@ css = [ { name = "tinycss2" }, ] +[[package]] +name = "cbor2" +version = "5.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/b8/c0f6a7d46f816cb18b1fda61a2fe648abe16039f1ff93ea720a6e9fb3cee/cbor2-5.7.1.tar.gz", hash = "sha256:7a405a1d7c8230ee9acf240aad48ae947ef584e8af05f169f3c1bde8f01f8b71", size = 102467, upload-time = "2025-10-24T09:23:06.569Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/56/54/48426472f0c051982c647331441aed09b271a0500356ae0b7054c813d174/cbor2-5.7.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bd5ca44891c06f6b85d440836c967187dc1d30b15f86f315d55c675d3a841078", size = 69031, upload-time = "2025-10-24T09:22:25.438Z" }, + { url = "https://files.pythonhosted.org/packages/d3/68/1dd58c7706e9752188358223db58c83f3c48e07f728aa84221ffd244652f/cbor2-5.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:537d73ef930ccc1a7b6a2e8d2cbf81407d270deb18e40cda5eb511bd70f71078", size = 68825, upload-time = "2025-10-24T09:22:26.497Z" }, + { url = "https://files.pythonhosted.org/packages/09/4e/380562fe9f9995a1875fb5ec26fd041e19d61f4630cb690a98c5195945fc/cbor2-5.7.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:edbf814dd7763b6eda27a5770199f6ccd55bd78be8f4367092460261bfbf19d0", size = 286222, upload-time = "2025-10-24T09:22:27.546Z" }, + { url = "https://files.pythonhosted.org/packages/7c/bb/9eccdc1ea3c4d5c7cdb2e49b9de49534039616be5455ce69bd64c0b2efe2/cbor2-5.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9fc81da8c0e09beb42923e455e477b36ff14a03b9ca18a8a2e9b462de9a953e8", size = 285688, upload-time = "2025-10-24T09:22:28.651Z" }, + { url = "https://files.pythonhosted.org/packages/59/8c/4696d82f5bd04b3d45d9a64ec037fa242630c134e3218d6c252b4f59b909/cbor2-5.7.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e4a7d660d428911a3aadb7105e94438d7671ab977356fdf647a91aab751033bd", size = 277063, upload-time = "2025-10-24T09:22:29.775Z" }, + { url = "https://files.pythonhosted.org/packages/95/50/6538e44ca970caaad2fa376b81701d073d84bf597aac07a59d0a253b1a7f/cbor2-5.7.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:228e0af9c0a9ddf6375b6ae010eaa1942a1901d403f134ac9ee6a76a322483f9", size = 278334, upload-time = "2025-10-24T09:22:30.904Z" }, + { url = "https://files.pythonhosted.org/packages/64/a9/156ccd2207fb26b5b61d23728b4dbdc595d1600125aa79683a4a8ddc9313/cbor2-5.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:2d08a6c0d9ed778448e185508d870f4160ba74f59bb17a966abd0d14d0ff4dd3", size = 68404, upload-time = "2025-10-24T09:22:32.108Z" }, + { url = "https://files.pythonhosted.org/packages/4f/49/adc53615e9dd32c4421f6935dfa2235013532c6e6b28ee515bbdd92618be/cbor2-5.7.1-cp312-cp312-win_arm64.whl", hash = "sha256:752506cfe72da0f4014b468b30191470ee8919a64a0772bd3b36a4fccf5fcefc", size = 64047, upload-time = "2025-10-24T09:22:33.147Z" }, + { url = "https://files.pythonhosted.org/packages/d5/7d/383bafeabb54c17fe5b6d5aca4e863e6b7df10bcc833b34aa169e9dfce1a/cbor2-5.7.1-py3-none-any.whl", hash = "sha256:68834e4eff2f56629ce6422b0634bc3f74c5a4269de5363f5265fe452c706ba7", size = 23829, upload-time = "2025-10-24T09:23:05.54Z" }, +] + [[package]] name = "certifi" -version = "2025.4.26" +version = "2025.10.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705, upload-time = "2025-04-26T02:12:29.51Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/5b/b6ce21586237c77ce67d01dc5507039d444b630dd76611bbca2d8e5dcd91/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43", size = 164519, upload-time = "2025-10-05T04:12:15.808Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618, upload-time = "2025-04-26T02:12:27.662Z" }, + { url = "https://files.pythonhosted.org/packages/e4/37/af0d2ef3967ac0d6113837b44a4f0bfe1328c2b9763bd5b1744520e5cfed/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", size = 163286, upload-time = "2025-10-05T04:12:14.03Z" }, ] [[package]] name = "cffi" -version = "1.17.1" +version = "2.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pycparser" }, + { name = "pycparser", marker = "implementation_name != 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621, upload-time = "2024-09-04T20:45:21.852Z" } +sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178, upload-time = "2024-09-04T20:44:12.232Z" }, - { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840, upload-time = "2024-09-04T20:44:13.739Z" }, - { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803, upload-time = "2024-09-04T20:44:15.231Z" }, - { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850, upload-time = "2024-09-04T20:44:17.188Z" }, - { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729, upload-time = "2024-09-04T20:44:18.688Z" }, - { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256, upload-time = "2024-09-04T20:44:20.248Z" }, - { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424, upload-time = "2024-09-04T20:44:21.673Z" }, - { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568, upload-time = "2024-09-04T20:44:23.245Z" }, - { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736, upload-time = "2024-09-04T20:44:24.757Z" }, - { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448, upload-time = "2024-09-04T20:44:26.208Z" }, - { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976, upload-time = "2024-09-04T20:44:27.578Z" }, + { url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271, upload-time = "2025-09-08T23:22:44.795Z" }, + { url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048, upload-time = "2025-09-08T23:22:45.938Z" }, + { url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529, upload-time = "2025-09-08T23:22:47.349Z" }, + { url = "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", size = 220097, upload-time = "2025-09-08T23:22:48.677Z" }, + { url = "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", size = 207983, upload-time = "2025-09-08T23:22:50.06Z" }, + { url = "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", size = 206519, upload-time = "2025-09-08T23:22:51.364Z" }, + { url = "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", size = 219572, upload-time = "2025-09-08T23:22:52.902Z" }, + { url = "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", size = 222963, upload-time = "2025-09-08T23:22:54.518Z" }, + { url = "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", size = 221361, upload-time = "2025-09-08T23:22:55.867Z" }, + { url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932, upload-time = "2025-09-08T23:22:57.188Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557, upload-time = "2025-09-08T23:22:58.351Z" }, + { url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762, upload-time = "2025-09-08T23:22:59.668Z" }, ] [[package]] name = "charset-normalizer" -version = "3.4.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e4/33/89c2ced2b67d1c2a61c19c6751aa8902d46ce3dacb23600a283619f5a12d/charset_normalizer-3.4.2.tar.gz", hash = "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63", size = 126367, upload-time = "2025-05-02T08:34:42.01Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/a4/37f4d6035c89cac7930395a35cc0f1b872e652eaafb76a6075943754f095/charset_normalizer-3.4.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0c29de6a1a95f24b9a1aa7aefd27d2487263f00dfd55a77719b530788f75cff7", size = 199936, upload-time = "2025-05-02T08:32:33.712Z" }, - { url = "https://files.pythonhosted.org/packages/ee/8a/1a5e33b73e0d9287274f899d967907cd0bf9c343e651755d9307e0dbf2b3/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cddf7bd982eaa998934a91f69d182aec997c6c468898efe6679af88283b498d3", size = 143790, upload-time = "2025-05-02T08:32:35.768Z" }, - { url = "https://files.pythonhosted.org/packages/66/52/59521f1d8e6ab1482164fa21409c5ef44da3e9f653c13ba71becdd98dec3/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcbe676a55d7445b22c10967bceaaf0ee69407fbe0ece4d032b6eb8d4565982a", size = 153924, upload-time = "2025-05-02T08:32:37.284Z" }, - { url = "https://files.pythonhosted.org/packages/86/2d/fb55fdf41964ec782febbf33cb64be480a6b8f16ded2dbe8db27a405c09f/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d41c4d287cfc69060fa91cae9683eacffad989f1a10811995fa309df656ec214", size = 146626, upload-time = "2025-05-02T08:32:38.803Z" }, - { url = "https://files.pythonhosted.org/packages/8c/73/6ede2ec59bce19b3edf4209d70004253ec5f4e319f9a2e3f2f15601ed5f7/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e594135de17ab3866138f496755f302b72157d115086d100c3f19370839dd3a", size = 148567, upload-time = "2025-05-02T08:32:40.251Z" }, - { url = "https://files.pythonhosted.org/packages/09/14/957d03c6dc343c04904530b6bef4e5efae5ec7d7990a7cbb868e4595ee30/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf713fe9a71ef6fd5adf7a79670135081cd4431c2943864757f0fa3a65b1fafd", size = 150957, upload-time = "2025-05-02T08:32:41.705Z" }, - { url = "https://files.pythonhosted.org/packages/0d/c8/8174d0e5c10ccebdcb1b53cc959591c4c722a3ad92461a273e86b9f5a302/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a370b3e078e418187da8c3674eddb9d983ec09445c99a3a263c2011993522981", size = 145408, upload-time = "2025-05-02T08:32:43.709Z" }, - { url = "https://files.pythonhosted.org/packages/58/aa/8904b84bc8084ac19dc52feb4f5952c6df03ffb460a887b42615ee1382e8/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a955b438e62efdf7e0b7b52a64dc5c3396e2634baa62471768a64bc2adb73d5c", size = 153399, upload-time = "2025-05-02T08:32:46.197Z" }, - { url = "https://files.pythonhosted.org/packages/c2/26/89ee1f0e264d201cb65cf054aca6038c03b1a0c6b4ae998070392a3ce605/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7222ffd5e4de8e57e03ce2cef95a4c43c98fcb72ad86909abdfc2c17d227fc1b", size = 156815, upload-time = "2025-05-02T08:32:48.105Z" }, - { url = "https://files.pythonhosted.org/packages/fd/07/68e95b4b345bad3dbbd3a8681737b4338ff2c9df29856a6d6d23ac4c73cb/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:bee093bf902e1d8fc0ac143c88902c3dfc8941f7ea1d6a8dd2bcb786d33db03d", size = 154537, upload-time = "2025-05-02T08:32:49.719Z" }, - { url = "https://files.pythonhosted.org/packages/77/1a/5eefc0ce04affb98af07bc05f3bac9094513c0e23b0562d64af46a06aae4/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb8adb91d11846ee08bec4c8236c8549ac721c245678282dcb06b221aab59f", size = 149565, upload-time = "2025-05-02T08:32:51.404Z" }, - { url = "https://files.pythonhosted.org/packages/37/a0/2410e5e6032a174c95e0806b1a6585eb21e12f445ebe239fac441995226a/charset_normalizer-3.4.2-cp312-cp312-win32.whl", hash = "sha256:db4c7bf0e07fc3b7d89ac2a5880a6a8062056801b83ff56d8464b70f65482b6c", size = 98357, upload-time = "2025-05-02T08:32:53.079Z" }, - { url = "https://files.pythonhosted.org/packages/6c/4f/c02d5c493967af3eda9c771ad4d2bbc8df6f99ddbeb37ceea6e8716a32bc/charset_normalizer-3.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:5a9979887252a82fefd3d3ed2a8e3b937a7a809f65dcb1e068b090e165bbe99e", size = 105776, upload-time = "2025-05-02T08:32:54.573Z" }, - { url = "https://files.pythonhosted.org/packages/20/94/c5790835a017658cbfabd07f3bfb549140c3ac458cfc196323996b10095a/charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0", size = 52626, upload-time = "2025-05-02T08:34:40.053Z" }, +version = "3.4.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload-time = "2025-10-14T04:40:53.353Z" }, + { url = "https://files.pythonhosted.org/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload-time = "2025-10-14T04:40:54.558Z" }, + { url = "https://files.pythonhosted.org/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload-time = "2025-10-14T04:40:55.677Z" }, + { url = "https://files.pythonhosted.org/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", size = 161497, upload-time = "2025-10-14T04:40:57.217Z" }, + { url = "https://files.pythonhosted.org/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", size = 159240, upload-time = "2025-10-14T04:40:58.358Z" }, + { url = "https://files.pythonhosted.org/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", size = 153471, upload-time = "2025-10-14T04:40:59.468Z" }, + { url = "https://files.pythonhosted.org/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", size = 150864, upload-time = "2025-10-14T04:41:00.623Z" }, + { url = "https://files.pythonhosted.org/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", size = 150647, upload-time = "2025-10-14T04:41:01.754Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", size = 145110, upload-time = "2025-10-14T04:41:03.231Z" }, + { url = "https://files.pythonhosted.org/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", size = 162839, upload-time = "2025-10-14T04:41:04.715Z" }, + { url = "https://files.pythonhosted.org/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", size = 150667, upload-time = "2025-10-14T04:41:05.827Z" }, + { url = "https://files.pythonhosted.org/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", size = 160535, upload-time = "2025-10-14T04:41:06.938Z" }, + { url = "https://files.pythonhosted.org/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", size = 154816, upload-time = "2025-10-14T04:41:08.101Z" }, + { url = "https://files.pythonhosted.org/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", size = 99694, upload-time = "2025-10-14T04:41:09.23Z" }, + { url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" }, + { url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, ] [[package]] @@ -354,14 +376,14 @@ provides-extras = ["dev"] [[package]] name = "click" -version = "8.2.1" +version = "8.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342, upload-time = "2025-05-20T23:19:49.832Z" } +sdist = { url = "https://files.pythonhosted.org/packages/46/61/de6cd827efad202d7057d93e0fed9294b96952e188f7384832791c7b2254/click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4", size = 276943, upload-time = "2025-09-18T17:32:23.696Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b", size = 102215, upload-time = "2025-05-20T23:19:47.796Z" }, + { url = "https://files.pythonhosted.org/packages/db/d3/9dcc0f5797f070ec8edf30fbadfb200e71d9db6b84d211e3b2085a7589a0/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", size = 107295, upload-time = "2025-09-18T17:32:22.42Z" }, ] [[package]] @@ -375,14 +397,11 @@ wheels = [ [[package]] name = "comm" -version = "0.2.2" +version = "0.2.3" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "traitlets" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e9/a8/fb783cb0abe2b5fded9f55e5703015cdf1c9c85b3669087c538dd15a6a86/comm-0.2.2.tar.gz", hash = "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e", size = 6210, upload-time = "2024-03-12T16:53:41.133Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/13/7d740c5849255756bc17888787313b61fd38a0a8304fc4f073dfc46122aa/comm-0.2.3.tar.gz", hash = "sha256:2dc8048c10962d55d7ad693be1e7045d891b7ce8d999c97963a5e3e99c055971", size = 6319, upload-time = "2025-07-25T14:02:04.452Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e6/75/49e5bfe642f71f272236b5b2d2691cf915a7283cc0ceda56357b61daa538/comm-0.2.2-py3-none-any.whl", hash = "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3", size = 7180, upload-time = "2024-03-12T16:53:39.226Z" }, + { url = "https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl", hash = "sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417", size = 7294, upload-time = "2025-07-25T14:02:02.896Z" }, ] [[package]] @@ -396,6 +415,7 @@ dependencies = [ { name = "jaxtyping" }, { name = "jsonargparse", extra = ["signatures"] }, { name = "lightning" }, + { name = "modal" }, { name = "nnsight" }, { name = "numpy" }, { name = "torch" }, @@ -429,6 +449,7 @@ requires-dist = [ { name = "jsonargparse", extras = ["signatures"], specifier = ">=4.27.7" }, { name = "jupyterlab", marker = "extra == 'dev'", specifier = ">=4.4.2" }, { name = "lightning", specifier = ">=2.5.1" }, + { name = "modal", specifier = ">=1.1.4" }, { name = "nnsight", specifier = "==0.5.0.dev7" }, { name = "numpy", specifier = ">=1.24.0" }, { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.4.1" }, @@ -447,12 +468,13 @@ dev = [ [[package]] name = "datasets" -version = "3.6.0" +version = "4.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "dill" }, { name = "filelock" }, { name = "fsspec", extra = ["http"] }, + { name = "httpx" }, { name = "huggingface-hub" }, { name = "multiprocess" }, { name = "numpy" }, @@ -464,22 +486,22 @@ dependencies = [ { name = "tqdm" }, { name = "xxhash" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1a/89/d3d6fef58a488f8569c82fd293ab7cbd4250244d67f425dcae64c63800ea/datasets-3.6.0.tar.gz", hash = "sha256:1b2bf43b19776e2787e181cfd329cb0ca1a358ea014780c3581e0f276375e041", size = 569336, upload-time = "2025-05-07T15:15:02.659Z" } +sdist = { url = "https://files.pythonhosted.org/packages/93/bf/0dae295d6d1ba0b1a200a9dd216838464b5bbd05da01407cb1330b377445/datasets-4.4.1.tar.gz", hash = "sha256:80322699aa8c0bbbdb7caa87906da689c3c2e29523cff698775c67f28fdab1fc", size = 585341, upload-time = "2025-11-05T16:00:38.162Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/34/a08b0ee99715eaba118cbe19a71f7b5e2425c2718ef96007c325944a1152/datasets-3.6.0-py3-none-any.whl", hash = "sha256:25000c4a2c0873a710df127d08a202a06eab7bf42441a6bc278b499c2f72cd1b", size = 491546, upload-time = "2025-05-07T15:14:59.742Z" }, + { url = "https://files.pythonhosted.org/packages/3b/5e/6f8d874366788ad5d549e9ba258037d974dda6e004843be1bda794571701/datasets-4.4.1-py3-none-any.whl", hash = "sha256:c1163de5211e42546079ab355cc0250c7e6db16eb209ac5ac6252f801f596c44", size = 511591, upload-time = "2025-11-05T16:00:36.365Z" }, ] [[package]] name = "debugpy" -version = "1.8.14" +version = "1.8.17" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bd/75/087fe07d40f490a78782ff3b0a30e3968936854105487decdb33446d4b0e/debugpy-1.8.14.tar.gz", hash = "sha256:7cd287184318416850aa8b60ac90105837bb1e59531898c07569d197d2ed5322", size = 1641444, upload-time = "2025-04-10T19:46:10.981Z" } +sdist = { url = "https://files.pythonhosted.org/packages/15/ad/71e708ff4ca377c4230530d6a7aa7992592648c122a2cd2b321cf8b35a76/debugpy-1.8.17.tar.gz", hash = "sha256:fd723b47a8c08892b1a16b2c6239a8b96637c62a59b94bb5dab4bac592a58a8e", size = 1644129, upload-time = "2025-09-17T16:33:20.633Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/2a/ac2df0eda4898f29c46eb6713a5148e6f8b2b389c8ec9e425a4a1d67bf07/debugpy-1.8.14-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:8899c17920d089cfa23e6005ad9f22582fd86f144b23acb9feeda59e84405b84", size = 2501268, upload-time = "2025-04-10T19:46:26.044Z" }, - { url = "https://files.pythonhosted.org/packages/10/53/0a0cb5d79dd9f7039169f8bf94a144ad3efa52cc519940b3b7dde23bcb89/debugpy-1.8.14-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6bb5c0dcf80ad5dbc7b7d6eac484e2af34bdacdf81df09b6a3e62792b722826", size = 4221077, upload-time = "2025-04-10T19:46:27.464Z" }, - { url = "https://files.pythonhosted.org/packages/f8/d5/84e01821f362327bf4828728aa31e907a2eca7c78cd7c6ec062780d249f8/debugpy-1.8.14-cp312-cp312-win32.whl", hash = "sha256:281d44d248a0e1791ad0eafdbbd2912ff0de9eec48022a5bfbc332957487ed3f", size = 5255127, upload-time = "2025-04-10T19:46:29.467Z" }, - { url = "https://files.pythonhosted.org/packages/33/16/1ed929d812c758295cac7f9cf3dab5c73439c83d9091f2d91871e648093e/debugpy-1.8.14-cp312-cp312-win_amd64.whl", hash = "sha256:5aa56ef8538893e4502a7d79047fe39b1dae08d9ae257074c6464a7b290b806f", size = 5297249, upload-time = "2025-04-10T19:46:31.538Z" }, - { url = "https://files.pythonhosted.org/packages/97/1a/481f33c37ee3ac8040d3d51fc4c4e4e7e61cb08b8bc8971d6032acc2279f/debugpy-1.8.14-py2.py3-none-any.whl", hash = "sha256:5cd9a579d553b6cb9759a7908a41988ee6280b961f24f63336835d9418216a20", size = 5256230, upload-time = "2025-04-10T19:46:54.077Z" }, + { url = "https://files.pythonhosted.org/packages/08/2b/9d8e65beb2751876c82e1aceb32f328c43ec872711fa80257c7674f45650/debugpy-1.8.17-cp312-cp312-macosx_15_0_universal2.whl", hash = "sha256:f14467edef672195c6f6b8e27ce5005313cb5d03c9239059bc7182b60c176e2d", size = 2549522, upload-time = "2025-09-17T16:33:38.466Z" }, + { url = "https://files.pythonhosted.org/packages/b4/78/eb0d77f02971c05fca0eb7465b18058ba84bd957062f5eec82f941ac792a/debugpy-1.8.17-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:24693179ef9dfa20dca8605905a42b392be56d410c333af82f1c5dff807a64cc", size = 4309417, upload-time = "2025-09-17T16:33:41.299Z" }, + { url = "https://files.pythonhosted.org/packages/37/42/c40f1d8cc1fed1e75ea54298a382395b8b937d923fcf41ab0797a554f555/debugpy-1.8.17-cp312-cp312-win32.whl", hash = "sha256:6a4e9dacf2cbb60d2514ff7b04b4534b0139facbf2abdffe0639ddb6088e59cf", size = 5277130, upload-time = "2025-09-17T16:33:43.554Z" }, + { url = "https://files.pythonhosted.org/packages/72/22/84263b205baad32b81b36eac076de0cdbe09fe2d0637f5b32243dc7c925b/debugpy-1.8.17-cp312-cp312-win_amd64.whl", hash = "sha256:e8f8f61c518952fb15f74a302e068b48d9c4691768ade433e4adeea961993464", size = 5319053, upload-time = "2025-09-17T16:33:53.033Z" }, + { url = "https://files.pythonhosted.org/packages/b0/d0/89247ec250369fc76db477720a26b2fce7ba079ff1380e4ab4529d2fe233/debugpy-1.8.17-py2.py3-none-any.whl", hash = "sha256:60c7dca6571efe660ccb7a9508d73ca14b8796c4ed484c2002abba714226cfef", size = 5283210, upload-time = "2025-09-17T16:34:25.835Z" }, ] [[package]] @@ -502,20 +524,20 @@ wheels = [ [[package]] name = "dill" -version = "0.3.8" +version = "0.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/17/4d/ac7ffa80c69ea1df30a8aa11b3578692a5118e7cd1aa157e3ef73b092d15/dill-0.3.8.tar.gz", hash = "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca", size = 184847, upload-time = "2024-01-27T23:42:16.145Z" } +sdist = { url = "https://files.pythonhosted.org/packages/12/80/630b4b88364e9a8c8c5797f4602d0f76ef820909ee32f0bacb9f90654042/dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0", size = 186976, upload-time = "2025-04-16T00:41:48.867Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c9/7a/cef76fd8438a42f96db64ddaa85280485a9c395e7df3db8158cfec1eee34/dill-0.3.8-py3-none-any.whl", hash = "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7", size = 116252, upload-time = "2024-01-27T23:42:14.239Z" }, + { url = "https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049", size = 119668, upload-time = "2025-04-16T00:41:47.671Z" }, ] [[package]] name = "docstring-parser" -version = "0.16" +version = "0.17.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/08/12/9c22a58c0b1e29271051222d8906257616da84135af9ed167c9e28f85cb3/docstring_parser-0.16.tar.gz", hash = "sha256:538beabd0af1e2db0146b6bd3caa526c35a34d61af9fd2887f3a8a27a739aa6e", size = 26565, upload-time = "2024-03-15T10:39:44.419Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/9d/c3b43da9515bd270df0f80548d9944e389870713cc1fe2b8fb35fe2bcefd/docstring_parser-0.17.0.tar.gz", hash = "sha256:583de4a309722b3315439bb31d64ba3eebada841f2e2cee23b99df001434c912", size = 27442, upload-time = "2025-07-21T07:35:01.868Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/7c/e9fcff7623954d86bdc17782036cbf715ecab1bec4847c008557affe1ca8/docstring_parser-0.16-py3-none-any.whl", hash = "sha256:bf0a1387354d3691d102edef7ec124f219ef639982d096e26e3b60aeffa90637", size = 36533, upload-time = "2024-03-15T10:39:41.527Z" }, + { url = "https://files.pythonhosted.org/packages/55/e2/2537ebcff11c1ee1ff17d8d0b6f4db75873e3b0fb32c2d4a2ee31ecb310a/docstring_parser-0.17.0-py3-none-any.whl", hash = "sha256:cf2569abd23dce8099b300f9b4fa8191e9582dda731fd533daf54c4551658708", size = 36896, upload-time = "2025-07-21T07:35:00.684Z" }, ] [[package]] @@ -529,11 +551,11 @@ wheels = [ [[package]] name = "executing" -version = "2.2.0" +version = "2.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/91/50/a9d80c47ff289c611ff12e63f7c5d13942c65d68125160cefd768c73e6e4/executing-2.2.0.tar.gz", hash = "sha256:5d108c028108fe2551d1a7b2e8b713341e2cb4fc0aa7dcf966fa4327a5226755", size = 978693, upload-time = "2025-01-22T15:41:29.403Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/28/c14e053b6762b1044f34a13aab6859bbf40456d37d23aa286ac24cfd9a5d/executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4", size = 1129488, upload-time = "2025-09-01T09:48:10.866Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7b/8f/c4d9bafc34ad7ad5d8dc16dd1347ee0e507a52c3adb6bfa8887e1c6a26ba/executing-2.2.0-py2.py3-none-any.whl", hash = "sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa", size = 26702, upload-time = "2025-01-22T15:41:25.929Z" }, + { url = "https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017", size = 28317, upload-time = "2025-09-01T09:48:08.5Z" }, ] [[package]] @@ -547,20 +569,20 @@ wheels = [ [[package]] name = "fastjsonschema" -version = "2.21.1" +version = "2.21.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8b/50/4b769ce1ac4071a1ef6d86b1a3fb56cdc3a37615e8c5519e1af96cdac366/fastjsonschema-2.21.1.tar.gz", hash = "sha256:794d4f0a58f848961ba16af7b9c85a3e88cd360df008c59aac6fc5ae9323b5d4", size = 373939, upload-time = "2024-12-02T10:55:15.133Z" } +sdist = { url = "https://files.pythonhosted.org/packages/20/b5/23b216d9d985a956623b6bd12d4086b60f0059b27799f23016af04a74ea1/fastjsonschema-2.21.2.tar.gz", hash = "sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de", size = 374130, upload-time = "2025-08-14T18:49:36.666Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/90/2b/0817a2b257fe88725c25589d89aec060581aabf668707a8d03b2e9e0cb2a/fastjsonschema-2.21.1-py3-none-any.whl", hash = "sha256:c9e5b7e908310918cf494a434eeb31384dd84a98b57a30bcb1f535015b554667", size = 23924, upload-time = "2024-12-02T10:55:07.599Z" }, + { url = "https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl", hash = "sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463", size = 24024, upload-time = "2025-08-14T18:49:34.776Z" }, ] [[package]] name = "filelock" -version = "3.18.0" +version = "3.20.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0a/10/c23352565a6544bdc5353e0b15fc1c563352101f30e24bf500207a54df9a/filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2", size = 18075, upload-time = "2025-03-14T07:11:40.47Z" } +sdist = { url = "https://files.pythonhosted.org/packages/58/46/0028a82567109b5ef6e4d2a1f04a583fb513e6cf9527fcdd09afd817deeb/filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4", size = 18922, upload-time = "2025-10-08T18:03:50.056Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4d/36/2a115987e2d8c300a974597416d9de88f2444426de9571f4b59b2cca3acc/filelock-3.18.0-py3-none-any.whl", hash = "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de", size = 16215, upload-time = "2025-03-14T07:11:39.145Z" }, + { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" }, ] [[package]] @@ -574,37 +596,36 @@ wheels = [ [[package]] name = "frozenlist" -version = "1.6.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5b/bf/a812e2fe6cb3f6c6cfc8d0303bf1742f2286004e5ec41ac8c89cf68cdb54/frozenlist-1.6.2.tar.gz", hash = "sha256:effc641518696471cf4962e8e32050133bc1f7b2851ae8fd0cb8797dd70dc202", size = 43108, upload-time = "2025-06-03T21:48:04.467Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c3/50/4632c944c57945cc1960e10ab8d6120cefb97bf923fd89052a3bcf8dc605/frozenlist-1.6.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:48544d07404d7fcfccb6cc091922ae10de4d9e512c537c710c063ae8f5662b85", size = 85258, upload-time = "2025-06-03T21:46:08.919Z" }, - { url = "https://files.pythonhosted.org/packages/3a/f4/5be5dbb219f341a4e996588e8841806c1df0c880c440c1171d143c83ce39/frozenlist-1.6.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6ee0cf89e7638de515c0bb2e8be30e8e2e48f3be9b6c2f7127bca4a1f35dff45", size = 49620, upload-time = "2025-06-03T21:46:10.658Z" }, - { url = "https://files.pythonhosted.org/packages/2a/fe/6697c1242126dc344840a43bffd5d5013cf5d61b272567f68025274622e1/frozenlist-1.6.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e084d838693d73c0fe87d212b91af80c18068c95c3d877e294f165056cedfa58", size = 48129, upload-time = "2025-06-03T21:46:11.93Z" }, - { url = "https://files.pythonhosted.org/packages/b1/cb/aa09a825abeabb8165282f3f79cb3f130847486ee6427d72d742efa604d6/frozenlist-1.6.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84d918b01781c6ebb5b776c18a87dd3016ff979eb78626aaca928bae69a640c3", size = 241513, upload-time = "2025-06-03T21:46:13.26Z" }, - { url = "https://files.pythonhosted.org/packages/2c/a3/9c22011770ea8b423adf0e12ec34200cf68ff444348d6c7c3466acc6be53/frozenlist-1.6.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e2892d9ab060a847f20fab83fdb886404d0f213f648bdeaebbe76a6134f0973d", size = 234019, upload-time = "2025-06-03T21:46:14.727Z" }, - { url = "https://files.pythonhosted.org/packages/88/39/83c077661ba708d28859dc01d299c9272c9adeb4b9e58dba85da2271cb08/frozenlist-1.6.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbd2225d7218e7d386f4953d11484b0e38e5d134e85c91f0a6b0f30fb6ae25c4", size = 247035, upload-time = "2025-06-03T21:46:16.706Z" }, - { url = "https://files.pythonhosted.org/packages/78/9f/7153e16e51ee8d660e907ef43c5a73882e3dc96582f70b00ece7d8a69b43/frozenlist-1.6.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b679187cba0a99f1162c7ec1b525e34bdc5ca246857544d16c1ed234562df80", size = 244126, upload-time = "2025-06-03T21:46:18.253Z" }, - { url = "https://files.pythonhosted.org/packages/71/1f/e8e6b72f3b285f8a6cfe4c01d14c4bbbf477c40868c8386bd9617298c696/frozenlist-1.6.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bceb7bd48849d4b76eac070a6d508aa3a529963f5d9b0a6840fd41fb381d5a09", size = 224463, upload-time = "2025-06-03T21:46:20.177Z" }, - { url = "https://files.pythonhosted.org/packages/69/b5/20ab79daba2e787c3426f6fa7bb2114edfcdffa4cfb2dd1c8e84f6964519/frozenlist-1.6.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b1b79ae86fdacc4bf842a4e0456540947abba64a84e61b5ae24c87adb089db", size = 240225, upload-time = "2025-06-03T21:46:21.615Z" }, - { url = "https://files.pythonhosted.org/packages/02/46/5d2e14cec6f577426f53e8726f824028da55703a5a6b41c6eb7a3cdf1372/frozenlist-1.6.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6c5c3c575148aa7308a38709906842039d7056bf225da6284b7a11cf9275ac5d", size = 237668, upload-time = "2025-06-03T21:46:23.143Z" }, - { url = "https://files.pythonhosted.org/packages/5d/35/d29a3297954c34b69842f63541833eaca71e50fb6ebbafd9eb95babc1508/frozenlist-1.6.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:16263bd677a31fe1a5dc2b803b564e349c96f804a81706a62b8698dd14dbba50", size = 248603, upload-time = "2025-06-03T21:46:28.592Z" }, - { url = "https://files.pythonhosted.org/packages/1e/30/bcb572840d112b22b89d2178168741674ab3766ad507c33e2549fdfee7f0/frozenlist-1.6.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2e51b2054886ff7db71caf68285c2cd936eb7a145a509965165a2aae715c92a7", size = 225855, upload-time = "2025-06-03T21:46:30.151Z" }, - { url = "https://files.pythonhosted.org/packages/ac/33/a0d3f75b126a18deb151f1cfb42ff64bbce22d8651fdda061e4fb56cd9b5/frozenlist-1.6.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ae1785b76f641cce4efd7e6f49ca4ae456aa230383af5ab0d4d3922a7e37e763", size = 246094, upload-time = "2025-06-03T21:46:32.709Z" }, - { url = "https://files.pythonhosted.org/packages/4d/7c/c5140e62f1b878a2982246505ed9461c4238f17fd53237ae25ddc9dbeb8d/frozenlist-1.6.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:30155cc481f73f92f47ab1e858a7998f7b1207f9b5cf3b3cba90ec65a7f224f5", size = 247984, upload-time = "2025-06-03T21:46:35.095Z" }, - { url = "https://files.pythonhosted.org/packages/77/da/32ac9c843ee126f8b2c3b164cf39a1bbf05e7a46e57659fef1db4f35e5dc/frozenlist-1.6.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1a1d82f2eb3d2875a8d139ae3f5026f7797f9de5dce44f53811ab0a883e85e7", size = 239770, upload-time = "2025-06-03T21:46:36.55Z" }, - { url = "https://files.pythonhosted.org/packages/e0/2f/4c512f0f9db149609c7f7e7be108ddce93131bf56e81adddb64510919573/frozenlist-1.6.2-cp312-cp312-win32.whl", hash = "sha256:84105cb0f3479dfa20b85f459fb2db3b0ee52e2f84e86d447ea8b0de1fb7acdd", size = 40918, upload-time = "2025-06-03T21:46:39.547Z" }, - { url = "https://files.pythonhosted.org/packages/54/c9/abb008594e5474132398aa417522776bee64d1753f98634c97b541938566/frozenlist-1.6.2-cp312-cp312-win_amd64.whl", hash = "sha256:eecc861bd30bc5ee3b04a1e6ebf74ed0451f596d91606843f3edbd2f273e2fe3", size = 45148, upload-time = "2025-06-03T21:46:40.787Z" }, - { url = "https://files.pythonhosted.org/packages/13/be/0ebbb283f2d91b72beaee2d07760b2c47dab875c49c286f5591d3d157198/frozenlist-1.6.2-py3-none-any.whl", hash = "sha256:947abfcc8c42a329bbda6df97a4b9c9cdb4e12c85153b3b57b9d2f02aa5877dc", size = 12582, upload-time = "2025-06-03T21:48:03.201Z" }, +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875, upload-time = "2025-10-06T05:38:17.865Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/29/948b9aa87e75820a38650af445d2ef2b6b8a6fab1a23b6bb9e4ef0be2d59/frozenlist-1.8.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1", size = 87782, upload-time = "2025-10-06T05:36:06.649Z" }, + { url = "https://files.pythonhosted.org/packages/64/80/4f6e318ee2a7c0750ed724fa33a4bdf1eacdc5a39a7a24e818a773cd91af/frozenlist-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b", size = 50594, upload-time = "2025-10-06T05:36:07.69Z" }, + { url = "https://files.pythonhosted.org/packages/2b/94/5c8a2b50a496b11dd519f4a24cb5496cf125681dd99e94c604ccdea9419a/frozenlist-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4", size = 50448, upload-time = "2025-10-06T05:36:08.78Z" }, + { url = "https://files.pythonhosted.org/packages/6a/bd/d91c5e39f490a49df14320f4e8c80161cfcce09f1e2cde1edd16a551abb3/frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383", size = 242411, upload-time = "2025-10-06T05:36:09.801Z" }, + { url = "https://files.pythonhosted.org/packages/8f/83/f61505a05109ef3293dfb1ff594d13d64a2324ac3482be2cedc2be818256/frozenlist-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4", size = 243014, upload-time = "2025-10-06T05:36:11.394Z" }, + { url = "https://files.pythonhosted.org/packages/d8/cb/cb6c7b0f7d4023ddda30cf56b8b17494eb3a79e3fda666bf735f63118b35/frozenlist-1.8.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8", size = 234909, upload-time = "2025-10-06T05:36:12.598Z" }, + { url = "https://files.pythonhosted.org/packages/31/c5/cd7a1f3b8b34af009fb17d4123c5a778b44ae2804e3ad6b86204255f9ec5/frozenlist-1.8.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b", size = 250049, upload-time = "2025-10-06T05:36:14.065Z" }, + { url = "https://files.pythonhosted.org/packages/c0/01/2f95d3b416c584a1e7f0e1d6d31998c4a795f7544069ee2e0962a4b60740/frozenlist-1.8.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52", size = 256485, upload-time = "2025-10-06T05:36:15.39Z" }, + { url = "https://files.pythonhosted.org/packages/ce/03/024bf7720b3abaebcff6d0793d73c154237b85bdf67b7ed55e5e9596dc9a/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29", size = 237619, upload-time = "2025-10-06T05:36:16.558Z" }, + { url = "https://files.pythonhosted.org/packages/69/fa/f8abdfe7d76b731f5d8bd217827cf6764d4f1d9763407e42717b4bed50a0/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3", size = 250320, upload-time = "2025-10-06T05:36:17.821Z" }, + { url = "https://files.pythonhosted.org/packages/f5/3c/b051329f718b463b22613e269ad72138cc256c540f78a6de89452803a47d/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143", size = 246820, upload-time = "2025-10-06T05:36:19.046Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ae/58282e8f98e444b3f4dd42448ff36fa38bef29e40d40f330b22e7108f565/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608", size = 250518, upload-time = "2025-10-06T05:36:20.763Z" }, + { url = "https://files.pythonhosted.org/packages/8f/96/007e5944694d66123183845a106547a15944fbbb7154788cbf7272789536/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa", size = 239096, upload-time = "2025-10-06T05:36:22.129Z" }, + { url = "https://files.pythonhosted.org/packages/66/bb/852b9d6db2fa40be96f29c0d1205c306288f0684df8fd26ca1951d461a56/frozenlist-1.8.0-cp312-cp312-win32.whl", hash = "sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf", size = 39985, upload-time = "2025-10-06T05:36:23.661Z" }, + { url = "https://files.pythonhosted.org/packages/b8/af/38e51a553dd66eb064cdf193841f16f077585d4d28394c2fa6235cb41765/frozenlist-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746", size = 44591, upload-time = "2025-10-06T05:36:24.958Z" }, + { url = "https://files.pythonhosted.org/packages/a7/06/1dc65480ab147339fecc70797e9c2f69d9cea9cf38934ce08df070fdb9cb/frozenlist-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd", size = 40102, upload-time = "2025-10-06T05:36:26.333Z" }, + { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, ] [[package]] name = "fsspec" -version = "2025.3.0" +version = "2025.10.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/34/f4/5721faf47b8c499e776bc34c6a8fc17efdf7fdef0b00f398128bc5dcb4ac/fsspec-2025.3.0.tar.gz", hash = "sha256:a935fd1ea872591f2b5148907d103488fc523295e6c64b835cfad8c3eca44972", size = 298491, upload-time = "2025-03-07T21:47:56.461Z" } +sdist = { url = "https://files.pythonhosted.org/packages/24/7f/2747c0d332b9acfa75dc84447a066fdf812b5a6b8d30472b74d309bfe8cb/fsspec-2025.10.0.tar.gz", hash = "sha256:b6789427626f068f9a83ca4e8a3cc050850b6c0f71f99ddb4f542b8266a26a59", size = 309285, upload-time = "2025-10-30T14:58:44.036Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/56/53/eb690efa8513166adef3e0669afd31e95ffde69fb3c52ec2ac7223ed6018/fsspec-2025.3.0-py3-none-any.whl", hash = "sha256:efb87af3efa9103f94ca91a7f8cb7a4df91af9f74fc106c9c7ea0efd7277c1b3", size = 193615, upload-time = "2025-03-07T21:47:54.809Z" }, + { url = "https://files.pythonhosted.org/packages/eb/02/a6b21098b1d5d6249b7c5ab69dde30108a71e4e819d4a9778f1de1d5b70d/fsspec-2025.10.0-py3-none-any.whl", hash = "sha256:7c7712353ae7d875407f97715f0e1ffcc21e33d5b24556cb1e090ae9409ec61d", size = 200966, upload-time = "2025-10-30T14:58:42.53Z" }, ] [package.optional-dependencies] @@ -626,14 +647,27 @@ wheels = [ [[package]] name = "gitpython" -version = "3.1.44" +version = "3.1.45" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "gitdb" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c0/89/37df0b71473153574a5cdef8f242de422a0f5d26d7a9e231e6f169b4ad14/gitpython-3.1.44.tar.gz", hash = "sha256:c87e30b26253bf5418b01b0660f818967f3c503193838337fe5e573331249269", size = 214196, upload-time = "2025-01-02T07:32:43.59Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/c8/dd58967d119baab745caec2f9d853297cec1989ec1d63f677d3880632b88/gitpython-3.1.45.tar.gz", hash = "sha256:85b0ee964ceddf211c41b9f27a49086010a190fd8132a24e21f362a4b36a791c", size = 215076, upload-time = "2025-07-24T03:45:54.871Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1d/9a/4114a9057db2f1462d5c8f8390ab7383925fe1ac012eaa42402ad65c2963/GitPython-3.1.44-py3-none-any.whl", hash = "sha256:9e0e10cda9bed1ee64bc9a6de50e7e38a9c9943241cd7f585f6df3ed28011110", size = 207599, upload-time = "2025-01-02T07:32:40.731Z" }, + { url = "https://files.pythonhosted.org/packages/01/61/d4b89fec821f72385526e1b9d9a3a0385dda4a72b206d28049e2c7cd39b8/gitpython-3.1.45-py3-none-any.whl", hash = "sha256:8908cb2e02fb3b93b7eb0f2827125cb699869470432cc885f019b8fd0fccff77", size = 208168, upload-time = "2025-07-24T03:45:52.517Z" }, +] + +[[package]] +name = "grpclib" +version = "0.4.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "h2" }, + { name = "multidict" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/75/0f0d3524b38b35e5cd07334b754aa9bd0570140ad982131b04ebfa3b0374/grpclib-0.4.8.tar.gz", hash = "sha256:d8823763780ef94fed8b2c562f7485cf0bbee15fc7d065a640673667f7719c9a", size = 62793, upload-time = "2025-05-04T16:27:30.051Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/03/8b/ad381ec1b8195fa4a9a693cb8087e031b99530c0d6b8ad036dcb99e144c4/grpclib-0.4.8-py3-none-any.whl", hash = "sha256:a5047733a7acc1c1cee6abf3c841c7c6fab67d2844a45a853b113fa2e6cd2654", size = 76311, upload-time = "2025-05-04T16:27:22.818Z" }, ] [[package]] @@ -645,35 +679,60 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, ] +[[package]] +name = "h2" +version = "4.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "hpack" }, + { name = "hyperframe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1d/17/afa56379f94ad0fe8defd37d6eb3f89a25404ffc71d4d848893d270325fc/h2-4.3.0.tar.gz", hash = "sha256:6c59efe4323fa18b47a632221a1888bd7fde6249819beda254aeca909f221bf1", size = 2152026, upload-time = "2025-08-23T18:12:19.778Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/b2/119f6e6dcbd96f9069ce9a2665e0146588dc9f88f29549711853645e736a/h2-4.3.0-py3-none-any.whl", hash = "sha256:c438f029a25f7945c69e0ccf0fb951dc3f73a5f6412981daee861431b70e2bdd", size = 61779, upload-time = "2025-08-23T18:12:17.779Z" }, +] + [[package]] name = "h5py" -version = "3.14.0" +version = "3.15.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5d/57/dfb3c5c3f1bf5f5ef2e59a22dec4ff1f3d7408b55bfcefcfb0ea69ef21c6/h5py-3.14.0.tar.gz", hash = "sha256:2372116b2e0d5d3e5e705b7f663f7c8d96fa79a4052d250484ef91d24d6a08f4", size = 424323, upload-time = "2025-06-06T14:06:15.01Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4d/6a/0d79de0b025aa85dc8864de8e97659c94cf3d23148394a954dc5ca52f8c8/h5py-3.15.1.tar.gz", hash = "sha256:c86e3ed45c4473564de55aa83b6fc9e5ead86578773dfbd93047380042e26b69", size = 426236, upload-time = "2025-10-16T10:35:27.404Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3e/77/8f651053c1843391e38a189ccf50df7e261ef8cd8bfd8baba0cbe694f7c3/h5py-3.14.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e0045115d83272090b0717c555a31398c2c089b87d212ceba800d3dc5d952e23", size = 3312740, upload-time = "2025-06-06T14:05:01.193Z" }, - { url = "https://files.pythonhosted.org/packages/ff/10/20436a6cf419b31124e59fefc78d74cb061ccb22213226a583928a65d715/h5py-3.14.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6da62509b7e1d71a7d110478aa25d245dd32c8d9a1daee9d2a42dba8717b047a", size = 2829207, upload-time = "2025-06-06T14:05:05.061Z" }, - { url = "https://files.pythonhosted.org/packages/3f/19/c8bfe8543bfdd7ccfafd46d8cfd96fce53d6c33e9c7921f375530ee1d39a/h5py-3.14.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:554ef0ced3571366d4d383427c00c966c360e178b5fb5ee5bb31a435c424db0c", size = 4708455, upload-time = "2025-06-06T14:05:11.528Z" }, - { url = "https://files.pythonhosted.org/packages/86/f9/f00de11c82c88bfc1ef22633557bfba9e271e0cb3189ad704183fc4a2644/h5py-3.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0cbd41f4e3761f150aa5b662df991868ca533872c95467216f2bec5fcad84882", size = 4929422, upload-time = "2025-06-06T14:05:18.399Z" }, - { url = "https://files.pythonhosted.org/packages/7a/6d/6426d5d456f593c94b96fa942a9b3988ce4d65ebaf57d7273e452a7222e8/h5py-3.14.0-cp312-cp312-win_amd64.whl", hash = "sha256:bf4897d67e613ecf5bdfbdab39a1158a64df105827da70ea1d90243d796d367f", size = 2862845, upload-time = "2025-06-06T14:05:23.699Z" }, + { url = "https://files.pythonhosted.org/packages/62/b8/c0d9aa013ecfa8b7057946c080c0c07f6fa41e231d2e9bd306a2f8110bdc/h5py-3.15.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:316dd0f119734f324ca7ed10b5627a2de4ea42cc4dfbcedbee026aaa361c238c", size = 3399089, upload-time = "2025-10-16T10:34:12.135Z" }, + { url = "https://files.pythonhosted.org/packages/a4/5e/3c6f6e0430813c7aefe784d00c6711166f46225f5d229546eb53032c3707/h5py-3.15.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b51469890e58e85d5242e43aab29f5e9c7e526b951caab354f3ded4ac88e7b76", size = 2847803, upload-time = "2025-10-16T10:34:14.564Z" }, + { url = "https://files.pythonhosted.org/packages/00/69/ba36273b888a4a48d78f9268d2aee05787e4438557450a8442946ab8f3ec/h5py-3.15.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a33bfd5dfcea037196f7778534b1ff7e36a7f40a89e648c8f2967292eb6898e", size = 4914884, upload-time = "2025-10-16T10:34:18.452Z" }, + { url = "https://files.pythonhosted.org/packages/3a/30/d1c94066343a98bb2cea40120873193a4fed68c4ad7f8935c11caf74c681/h5py-3.15.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:25c8843fec43b2cc368aa15afa1cdf83fc5e17b1c4e10cd3771ef6c39b72e5ce", size = 5109965, upload-time = "2025-10-16T10:34:21.853Z" }, + { url = "https://files.pythonhosted.org/packages/81/3d/d28172116eafc3bc9f5991b3cb3fd2c8a95f5984f50880adfdf991de9087/h5py-3.15.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a308fd8681a864c04423c0324527237a0484e2611e3441f8089fd00ed56a8171", size = 4561870, upload-time = "2025-10-16T10:34:26.69Z" }, + { url = "https://files.pythonhosted.org/packages/a5/83/393a7226024238b0f51965a7156004eaae1fcf84aa4bfecf7e582676271b/h5py-3.15.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f4a016df3f4a8a14d573b496e4d1964deb380e26031fc85fb40e417e9131888a", size = 5037161, upload-time = "2025-10-16T10:34:30.383Z" }, + { url = "https://files.pythonhosted.org/packages/cf/51/329e7436bf87ca6b0fe06dd0a3795c34bebe4ed8d6c44450a20565d57832/h5py-3.15.1-cp312-cp312-win_amd64.whl", hash = "sha256:59b25cf02411bf12e14f803fef0b80886444c7fe21a5ad17c6a28d3f08098a1e", size = 2874165, upload-time = "2025-10-16T10:34:33.461Z" }, + { url = "https://files.pythonhosted.org/packages/09/a8/2d02b10a66747c54446e932171dd89b8b4126c0111b440e6bc05a7c852ec/h5py-3.15.1-cp312-cp312-win_arm64.whl", hash = "sha256:61d5a58a9851e01ee61c932bbbb1c98fe20aba0a5674776600fb9a361c0aa652", size = 2458214, upload-time = "2025-10-16T10:34:35.733Z" }, ] [[package]] name = "hf-xet" -version = "1.1.3" +version = "1.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/75/dc/dc091aeeb671e71cbec30e84963f9c0202c17337b24b0a800e7d205543e8/hf_xet-1.1.3.tar.gz", hash = "sha256:a5f09b1dd24e6ff6bcedb4b0ddab2d81824098bb002cf8b4ffa780545fa348c3", size = 488127, upload-time = "2025-06-04T00:47:27.456Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/6e/0f11bacf08a67f7fb5ee09740f2ca54163863b07b70d579356e9222ce5d8/hf_xet-1.2.0.tar.gz", hash = "sha256:a8c27070ca547293b6890c4bf389f713f80e8c478631432962bb7f4bc0bd7d7f", size = 506020, upload-time = "2025-10-24T19:04:32.129Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9b/1f/bc01a4c0894973adebbcd4aa338a06815c76333ebb3921d94dcbd40dae6a/hf_xet-1.1.3-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:c3b508b5f583a75641aebf732853deb058953370ce8184f5dabc49f803b0819b", size = 2256929, upload-time = "2025-06-04T00:47:21.206Z" }, - { url = "https://files.pythonhosted.org/packages/78/07/6ef50851b5c6b45b77a6e018fa299c69a2db3b8bbd0d5af594c0238b1ceb/hf_xet-1.1.3-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:b788a61977fbe6b5186e66239e2a329a3f0b7e7ff50dad38984c0c74f44aeca1", size = 2153719, upload-time = "2025-06-04T00:47:19.302Z" }, - { url = "https://files.pythonhosted.org/packages/52/48/e929e6e3db6e4758c2adf0f2ca2c59287f1b76229d8bdc1a4c9cfc05212e/hf_xet-1.1.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd2da210856444a34aad8ada2fc12f70dabed7cc20f37e90754d1d9b43bc0534", size = 4820519, upload-time = "2025-06-04T00:47:17.244Z" }, - { url = "https://files.pythonhosted.org/packages/28/2e/03f89c5014a5aafaa9b150655f811798a317036646623bdaace25f485ae8/hf_xet-1.1.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:8203f52827e3df65981984936654a5b390566336956f65765a8aa58c362bb841", size = 4964121, upload-time = "2025-06-04T00:47:15.17Z" }, - { url = "https://files.pythonhosted.org/packages/47/8b/5cd399a92b47d98086f55fc72d69bc9ea5e5c6f27a9ed3e0cdd6be4e58a3/hf_xet-1.1.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:30c575a5306f8e6fda37edb866762140a435037365eba7a17ce7bd0bc0216a8b", size = 5283017, upload-time = "2025-06-04T00:47:23.239Z" }, - { url = "https://files.pythonhosted.org/packages/53/e3/2fcec58d2fcfd25ff07feb876f466cfa11f8dcf9d3b742c07fe9dd51ee0a/hf_xet-1.1.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:7c1a6aa6abed1f696f8099aa9796ca04c9ee778a58728a115607de9cc4638ff1", size = 4970349, upload-time = "2025-06-04T00:47:25.383Z" }, - { url = "https://files.pythonhosted.org/packages/53/bf/10ca917e335861101017ff46044c90e517b574fbb37219347b83be1952f6/hf_xet-1.1.3-cp37-abi3-win_amd64.whl", hash = "sha256:b578ae5ac9c056296bb0df9d018e597c8dc6390c5266f35b5c44696003cde9f3", size = 2310934, upload-time = "2025-06-04T00:47:29.632Z" }, + { url = "https://files.pythonhosted.org/packages/96/2d/22338486473df5923a9ab7107d375dbef9173c338ebef5098ef593d2b560/hf_xet-1.2.0-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:46740d4ac024a7ca9b22bebf77460ff43332868b661186a8e46c227fdae01848", size = 2866099, upload-time = "2025-10-24T19:04:15.366Z" }, + { url = "https://files.pythonhosted.org/packages/7f/8c/c5becfa53234299bc2210ba314eaaae36c2875e0045809b82e40a9544f0c/hf_xet-1.2.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:27df617a076420d8845bea087f59303da8be17ed7ec0cd7ee3b9b9f579dff0e4", size = 2722178, upload-time = "2025-10-24T19:04:13.695Z" }, + { url = "https://files.pythonhosted.org/packages/9a/92/cf3ab0b652b082e66876d08da57fcc6fa2f0e6c70dfbbafbd470bb73eb47/hf_xet-1.2.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3651fd5bfe0281951b988c0facbe726aa5e347b103a675f49a3fa8144c7968fd", size = 3320214, upload-time = "2025-10-24T19:04:03.596Z" }, + { url = "https://files.pythonhosted.org/packages/46/92/3f7ec4a1b6a65bf45b059b6d4a5d38988f63e193056de2f420137e3c3244/hf_xet-1.2.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d06fa97c8562fb3ee7a378dd9b51e343bc5bc8190254202c9771029152f5e08c", size = 3229054, upload-time = "2025-10-24T19:04:01.949Z" }, + { url = "https://files.pythonhosted.org/packages/0b/dd/7ac658d54b9fb7999a0ccb07ad863b413cbaf5cf172f48ebcd9497ec7263/hf_xet-1.2.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:4c1428c9ae73ec0939410ec73023c4f842927f39db09b063b9482dac5a3bb737", size = 3413812, upload-time = "2025-10-24T19:04:24.585Z" }, + { url = "https://files.pythonhosted.org/packages/92/68/89ac4e5b12a9ff6286a12174c8538a5930e2ed662091dd2572bbe0a18c8a/hf_xet-1.2.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a55558084c16b09b5ed32ab9ed38421e2d87cf3f1f89815764d1177081b99865", size = 3508920, upload-time = "2025-10-24T19:04:26.927Z" }, + { url = "https://files.pythonhosted.org/packages/cb/44/870d44b30e1dcfb6a65932e3e1506c103a8a5aea9103c337e7a53180322c/hf_xet-1.2.0-cp37-abi3-win_amd64.whl", hash = "sha256:e6584a52253f72c9f52f9e549d5895ca7a471608495c4ecaa6cc73dba2b24d69", size = 2905735, upload-time = "2025-10-24T19:04:35.928Z" }, +] + +[[package]] +name = "hpack" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2c/48/71de9ed269fdae9c8057e5a4c0aa7402e8bb16f2c6e90b3aa53327b113f8/hpack-4.1.0.tar.gz", hash = "sha256:ec5eca154f7056aa06f196a557655c5b009b382873ac8d1e66e79e87535f1dca", size = 51276, upload-time = "2025-01-22T21:44:58.347Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/c6/80c95b1b2b94682a72cbdbfb85b81ae2daffa4291fbfa1b1464502ede10d/hpack-4.1.0-py3-none-any.whl", hash = "sha256:157ac792668d995c657d93111f46b4535ed114f0c9c8d672271bbec7eae1b496", size = 34357, upload-time = "2025-01-22T21:44:56.92Z" }, ] [[package]] @@ -706,7 +765,7 @@ wheels = [ [[package]] name = "huggingface-hub" -version = "0.32.4" +version = "0.36.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "filelock" }, @@ -718,18 +777,27 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/60/c8/4f7d270285c46324fd66f62159eb16739aa5696f422dba57678a8c6b78e9/huggingface_hub-0.32.4.tar.gz", hash = "sha256:f61d45cd338736f59fb0e97550b74c24ee771bcc92c05ae0766b9116abe720be", size = 424494, upload-time = "2025-06-03T09:59:46.105Z" } +sdist = { url = "https://files.pythonhosted.org/packages/98/63/4910c5fa9128fdadf6a9c5ac138e8b1b6cee4ca44bf7915bbfbce4e355ee/huggingface_hub-0.36.0.tar.gz", hash = "sha256:47b3f0e2539c39bf5cde015d63b72ec49baff67b6931c3d97f3f84532e2b8d25", size = 463358, upload-time = "2025-10-23T12:12:01.413Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/67/8b/222140f3cfb6f17b0dd8c4b9a0b36bd4ebefe9fb0098ba35d6960abcda0f/huggingface_hub-0.32.4-py3-none-any.whl", hash = "sha256:37abf8826b38d971f60d3625229221c36e53fe58060286db9baf619cfbf39767", size = 512101, upload-time = "2025-06-03T09:59:44.099Z" }, + { url = "https://files.pythonhosted.org/packages/cb/bd/1a875e0d592d447cbc02805fd3fe0f497714d6a2583f59d14fa9ebad96eb/huggingface_hub-0.36.0-py3-none-any.whl", hash = "sha256:7bcc9ad17d5b3f07b57c78e79d527102d08313caa278a641993acddcb894548d", size = 566094, upload-time = "2025-10-23T12:11:59.557Z" }, +] + +[[package]] +name = "hyperframe" +version = "6.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/02/e7/94f8232d4a74cc99514c13a9f995811485a6903d48e5d952771ef6322e30/hyperframe-6.1.0.tar.gz", hash = "sha256:f630908a00854a7adeabd6382b43923a4c4cd4b821fcb527e6ab9e15382a3b08", size = 26566, upload-time = "2025-01-22T21:41:49.302Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/30/47d0bf6072f7252e6521f3447ccfa40b421b6824517f82854703d0f5a98b/hyperframe-6.1.0-py3-none-any.whl", hash = "sha256:b03380493a519fce58ea5af42e4a42317bf9bd425596f7a0835ffce80f1a42e5", size = 13007, upload-time = "2025-01-22T21:41:47.295Z" }, ] [[package]] name = "idna" -version = "3.10" +version = "3.11" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, ] [[package]] @@ -743,16 +811,16 @@ wheels = [ [[package]] name = "iniconfig" -version = "2.1.0" +version = "2.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, ] [[package]] name = "ipykernel" -version = "6.29.5" +version = "7.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "appnope", marker = "sys_platform == 'darwin'" }, @@ -769,14 +837,14 @@ dependencies = [ { name = "tornado" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e9/5c/67594cb0c7055dc50814b21731c22a601101ea3b1b50a9a1b090e11f5d0f/ipykernel-6.29.5.tar.gz", hash = "sha256:f093a22c4a40f8828f8e330a9c297cb93dcab13bd9678ded6de8e5cf81c56215", size = 163367, upload-time = "2024-07-01T14:07:22.543Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b9/a4/4948be6eb88628505b83a1f2f40d90254cab66abf2043b3c40fa07dfce0f/ipykernel-7.1.0.tar.gz", hash = "sha256:58a3fc88533d5930c3546dc7eac66c6d288acde4f801e2001e65edc5dc9cf0db", size = 174579, upload-time = "2025-10-27T09:46:39.471Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/94/5c/368ae6c01c7628438358e6d337c19b05425727fbb221d2a3c4303c372f42/ipykernel-6.29.5-py3-none-any.whl", hash = "sha256:afdb66ba5aa354b09b91379bac28ae4afebbb30e8b39510c9690afb7a10421b5", size = 117173, upload-time = "2024-07-01T14:07:19.603Z" }, + { url = "https://files.pythonhosted.org/packages/a3/17/20c2552266728ceba271967b87919664ecc0e33efca29c3efc6baf88c5f9/ipykernel-7.1.0-py3-none-any.whl", hash = "sha256:763b5ec6c5b7776f6a8d7ce09b267693b4e5ce75cb50ae696aaefb3c85e1ea4c", size = 117968, upload-time = "2025-10-27T09:46:37.805Z" }, ] [[package]] name = "ipython" -version = "9.3.0" +version = "9.7.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -790,9 +858,9 @@ dependencies = [ { name = "stack-data" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/dc/09/4c7e06b96fbd203e06567b60fb41b06db606b6a82db6db7b2c85bb72a15c/ipython-9.3.0.tar.gz", hash = "sha256:79eb896f9f23f50ad16c3bc205f686f6e030ad246cc309c6279a242b14afe9d8", size = 4426460, upload-time = "2025-05-31T16:34:55.678Z" } +sdist = { url = "https://files.pythonhosted.org/packages/29/e6/48c74d54039241a456add616464ea28c6ebf782e4110d419411b83dae06f/ipython-9.7.0.tar.gz", hash = "sha256:5f6de88c905a566c6a9d6c400a8fed54a638e1f7543d17aae2551133216b1e4e", size = 4422115, upload-time = "2025-11-05T12:18:54.646Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/99/9ed3d52d00f1846679e3aa12e2326ac7044b5e7f90dc822b60115fa533ca/ipython-9.3.0-py3-none-any.whl", hash = "sha256:1a0b6dd9221a1f5dddf725b57ac0cb6fddc7b5f470576231ae9162b9b3455a04", size = 605320, upload-time = "2025-05-31T16:34:52.154Z" }, + { url = "https://files.pythonhosted.org/packages/05/aa/62893d6a591d337aa59dcc4c6f6c842f1fe20cd72c8c5c1f980255243252/ipython-9.7.0-py3-none-any.whl", hash = "sha256:bce8ac85eb9521adc94e1845b4c03d88365fd6ac2f4908ec4ed1eb1b0a065f9f", size = 618911, upload-time = "2025-11-05T12:18:52.484Z" }, ] [[package]] @@ -809,7 +877,7 @@ wheels = [ [[package]] name = "ipywidgets" -version = "8.1.7" +version = "8.1.8" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "comm" }, @@ -818,9 +886,9 @@ dependencies = [ { name = "traitlets" }, { name = "widgetsnbextension" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3e/48/d3dbac45c2814cb73812f98dd6b38bbcc957a4e7bb31d6ea9c03bf94ed87/ipywidgets-8.1.7.tar.gz", hash = "sha256:15f1ac050b9ccbefd45dccfbb2ef6bed0029d8278682d569d71b8dd96bee0376", size = 116721, upload-time = "2025-05-05T12:42:03.489Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/ae/c5ce1edc1afe042eadb445e95b0671b03cee61895264357956e61c0d2ac0/ipywidgets-8.1.8.tar.gz", hash = "sha256:61f969306b95f85fba6b6986b7fe45d73124d1d9e3023a8068710d47a22ea668", size = 116739, upload-time = "2025-11-01T21:18:12.393Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/58/6a/9166369a2f092bd286d24e6307de555d63616e8ddb373ebad2b5635ca4cd/ipywidgets-8.1.7-py3-none-any.whl", hash = "sha256:764f2602d25471c213919b8a1997df04bef869251db4ca8efba1b76b1bd9f7bb", size = 139806, upload-time = "2025-05-05T12:41:56.833Z" }, + { url = "https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl", hash = "sha256:ecaca67aed704a338f88f67b1181b58f821ab5dc89c1f0f5ef99db43c1c2921e", size = 139808, upload-time = "2025-11-01T21:18:10.956Z" }, ] [[package]] @@ -837,14 +905,14 @@ wheels = [ [[package]] name = "jaxtyping" -version = "0.3.2" +version = "0.3.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "wadler-lindig" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/88/a8/416bd7ea110ec6b68e8868b0f99c985c735adcf7badc491d3c343937260a/jaxtyping-0.3.2.tar.gz", hash = "sha256:f30483fac4b42e915db8ad2414a85c3b63284aa7d3c100b96b59f755cf4a86ad", size = 44989, upload-time = "2025-04-23T09:48:16.907Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e4/1e/827f9e17b26e21c7d4d934fd1a214284ad05663afedd37c21ed105db366b/jaxtyping-0.3.3.tar.gz", hash = "sha256:8003cfd16ba2ad9b47fdda1d982a575299a81ddfc7997ad0e917c87a0897ea86", size = 45484, upload-time = "2025-10-01T13:46:51.933Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c9/b9/281e10e2d967ea5e481683eaec99f55ac5a61085ee60551c36942ef32bef/jaxtyping-0.3.2-py3-none-any.whl", hash = "sha256:6a020fd276226ddb5ac4f5725323843dd65e3c7e85c64fd62431e5f738c74e04", size = 55409, upload-time = "2025-04-23T09:48:15.924Z" }, + { url = "https://files.pythonhosted.org/packages/b8/97/88264b1af140f66ba7ca6eb2f3a108be233ee278bb3f1d5c750243e7458a/jaxtyping-0.3.3-py3-none-any.whl", hash = "sha256:a1c2f0f4351a8deda84b0e3b5c5a50894a1cdae2b82d841279fce4393aff4a7c", size = 55926, upload-time = "2025-10-01T13:46:50.621Z" }, ] [[package]] @@ -873,23 +941,23 @@ wheels = [ [[package]] name = "json5" -version = "0.12.0" +version = "0.12.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/12/be/c6c745ec4c4539b25a278b70e29793f10382947df0d9efba2fa09120895d/json5-0.12.0.tar.gz", hash = "sha256:0b4b6ff56801a1c7dc817b0241bca4ce474a0e6a163bfef3fc594d3fd263ff3a", size = 51907, upload-time = "2025-04-03T16:33:13.201Z" } +sdist = { url = "https://files.pythonhosted.org/packages/12/ae/929aee9619e9eba9015207a9d2c1c54db18311da7eb4dcf6d41ad6f0eb67/json5-0.12.1.tar.gz", hash = "sha256:b2743e77b3242f8d03c143dd975a6ec7c52e2f2afe76ed934e53503dd4ad4990", size = 52191, upload-time = "2025-08-12T19:47:42.583Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/41/9f/3500910d5a98549e3098807493851eeef2b89cdd3032227558a104dfe926/json5-0.12.0-py3-none-any.whl", hash = "sha256:6d37aa6c08b0609f16e1ec5ff94697e2cbbfbad5ac112afa05794da9ab7810db", size = 36079, upload-time = "2025-04-03T16:33:11.927Z" }, + { url = "https://files.pythonhosted.org/packages/85/e2/05328bd2621be49a6fed9e3030b1e51a2d04537d3f816d211b9cc53c5262/json5-0.12.1-py3-none-any.whl", hash = "sha256:d9c9b3bc34a5f54d43c35e11ef7cb87d8bdd098c6ace87117a7b7e83e705c1d5", size = 36119, upload-time = "2025-08-12T19:47:41.131Z" }, ] [[package]] name = "jsonargparse" -version = "4.40.0" +version = "4.42.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyyaml" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ec/e6/6a296858db86228a7484753fb7d79d92ba29820acfc7d8bff05ab13e8f1b/jsonargparse-4.40.0.tar.gz", hash = "sha256:fa6d748b48e36c0dadadc744c9d7bab3812785e7f4cee27fb0239b8301c808a1", size = 203052, upload-time = "2025-05-16T04:55:26.626Z" } +sdist = { url = "https://files.pythonhosted.org/packages/32/ef/6bcc6d88e401af6d1c05c6a3f3955ebeae538711f1199e25c53326c921e5/jsonargparse-4.42.0.tar.gz", hash = "sha256:170551344f06500091ca6732bf93726c5aa79f4f2632a7f2a18d7a897ae2c5c1", size = 212273, upload-time = "2025-10-14T05:23:43.15Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cc/b7/1cd333988594bf4b2cf6aa92073ebb57e7db15bcd6ef8ef45b6e68caeb9c/jsonargparse-4.40.0-py3-none-any.whl", hash = "sha256:5822a84efa7d10d2a5aacc3fc6c6414ea2919419a398c06d9e8ac79a420365af", size = 224276, upload-time = "2025-05-16T04:55:24.901Z" }, + { url = "https://files.pythonhosted.org/packages/0b/a1/3f06c00dc217baaa273b08022c00bc6c71d619c4d03325179b8fec80d90f/jsonargparse-4.42.0-py3-none-any.whl", hash = "sha256:d112bdaab22918ff5a8fb2d6036596f8527961922fd972b6e50afc6340514a28", size = 235760, upload-time = "2025-10-14T05:23:40.849Z" }, ] [package.optional-dependencies] @@ -909,7 +977,7 @@ wheels = [ [[package]] name = "jsonschema" -version = "4.24.0" +version = "4.25.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "attrs" }, @@ -917,9 +985,9 @@ dependencies = [ { name = "referencing" }, { name = "rpds-py" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bf/d3/1cf5326b923a53515d8f3a2cd442e6d7e94fcc444716e879ea70a0ce3177/jsonschema-4.24.0.tar.gz", hash = "sha256:0b4e8069eb12aedfa881333004bccaec24ecef5a8a6a4b6df142b2cc9599d196", size = 353480, upload-time = "2025-05-26T18:48:10.459Z" } +sdist = { url = "https://files.pythonhosted.org/packages/74/69/f7185de793a29082a9f3c7728268ffb31cb5095131a9c139a74078e27336/jsonschema-4.25.1.tar.gz", hash = "sha256:e4a9655ce0da0c0b67a085847e00a3a51449e1157f4f75e9fb5aa545e122eb85", size = 357342, upload-time = "2025-08-18T17:03:50.038Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a2/3d/023389198f69c722d039351050738d6755376c8fd343e91dc493ea485905/jsonschema-4.24.0-py3-none-any.whl", hash = "sha256:a462455f19f5faf404a7902952b6f0e3ce868f3ee09a359b05eca6673bd8412d", size = 88709, upload-time = "2025-05-26T18:48:08.417Z" }, + { url = "https://files.pythonhosted.org/packages/bf/9c/8c95d856233c1f82500c2450b8c68576b4cf1c871db3afac5c34ff84e6fd/jsonschema-4.25.1-py3-none-any.whl", hash = "sha256:3fba0169e345c7175110351d456342c364814cfcf3b964ba4587f22915230a63", size = 90040, upload-time = "2025-08-18T17:03:48.373Z" }, ] [package.optional-dependencies] @@ -930,20 +998,21 @@ format-nongpl = [ { name = "jsonpointer" }, { name = "rfc3339-validator" }, { name = "rfc3986-validator" }, + { name = "rfc3987-syntax" }, { name = "uri-template" }, { name = "webcolors" }, ] [[package]] name = "jsonschema-specifications" -version = "2025.4.1" +version = "2025.9.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "referencing" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bf/ce/46fbd9c8119cfc3581ee5643ea49464d168028cfb5caff5fc0596d0cf914/jsonschema_specifications-2025.4.1.tar.gz", hash = "sha256:630159c9f4dbea161a6a2205c3011cc4f18ff381b189fff48bb39b9bf26ae608", size = 15513, upload-time = "2025-04-23T12:34:07.418Z" } +sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/01/0e/b27cdbaccf30b890c40ed1da9fd4a3593a5cf94dae54fb34f8a4b74fcd3f/jsonschema_specifications-2025.4.1-py3-none-any.whl", hash = "sha256:4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af", size = 18437, upload-time = "2025-04-23T12:34:05.422Z" }, + { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, ] [[package]] @@ -964,16 +1033,15 @@ wheels = [ [[package]] name = "jupyter-core" -version = "5.8.1" +version = "5.9.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "platformdirs" }, - { name = "pywin32", marker = "platform_python_implementation != 'PyPy' and sys_platform == 'win32'" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/99/1b/72906d554acfeb588332eaaa6f61577705e9ec752ddb486f302dafa292d9/jupyter_core-5.8.1.tar.gz", hash = "sha256:0a5f9706f70e64786b75acba995988915ebd4601c8a52e534a40b51c95f59941", size = 88923, upload-time = "2025-05-27T07:38:16.655Z" } +sdist = { url = "https://files.pythonhosted.org/packages/02/49/9d1284d0dc65e2c757b74c6687b6d319b02f822ad039e5c512df9194d9dd/jupyter_core-5.9.1.tar.gz", hash = "sha256:4d09aaff303b9566c3ce657f580bd089ff5c91f5f89cf7d8846c3cdf465b5508", size = 89814, upload-time = "2025-10-16T19:19:18.444Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2f/57/6bffd4b20b88da3800c5d691e0337761576ee688eb01299eae865689d2df/jupyter_core-5.8.1-py3-none-any.whl", hash = "sha256:c28d268fc90fb53f1338ded2eb410704c5449a358406e8a948b75706e24863d0", size = 28880, upload-time = "2025-05-27T07:38:15.137Z" }, + { url = "https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl", hash = "sha256:ebf87fdc6073d142e114c72c9e29a9d7ca03fad818c5d300ce2adc1fb0743407", size = 29032, upload-time = "2025-10-16T19:19:16.783Z" }, ] [[package]] @@ -997,19 +1065,19 @@ wheels = [ [[package]] name = "jupyter-lsp" -version = "2.2.5" +version = "2.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jupyter-server" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/85/b4/3200b0b09c12bc3b72d943d923323c398eff382d1dcc7c0dbc8b74630e40/jupyter-lsp-2.2.5.tar.gz", hash = "sha256:793147a05ad446f809fd53ef1cd19a9f5256fd0a2d6b7ce943a982cb4f545001", size = 48741, upload-time = "2024-04-09T17:59:44.918Z" } +sdist = { url = "https://files.pythonhosted.org/packages/eb/5a/9066c9f8e94ee517133cd98dba393459a16cd48bba71a82f16a65415206c/jupyter_lsp-2.3.0.tar.gz", hash = "sha256:458aa59339dc868fb784d73364f17dbce8836e906cd75fd471a325cba02e0245", size = 54823, upload-time = "2025-08-27T17:47:34.671Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/07/e0/7bd7cff65594fd9936e2f9385701e44574fc7d721331ff676ce440b14100/jupyter_lsp-2.2.5-py3-none-any.whl", hash = "sha256:45fbddbd505f3fbfb0b6cb2f1bc5e15e83ab7c79cd6e89416b248cb3c00c11da", size = 69146, upload-time = "2024-04-09T17:59:43.388Z" }, + { url = "https://files.pythonhosted.org/packages/1a/60/1f6cee0c46263de1173894f0fafcb3475ded276c472c14d25e0280c18d6d/jupyter_lsp-2.3.0-py3-none-any.whl", hash = "sha256:e914a3cb2addf48b1c7710914771aaf1819d46b2e5a79b0f917b5478ec93f34f", size = 76687, upload-time = "2025-08-27T17:47:33.15Z" }, ] [[package]] name = "jupyter-server" -version = "2.16.0" +version = "2.17.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -1021,7 +1089,6 @@ dependencies = [ { name = "jupyter-server-terminals" }, { name = "nbconvert" }, { name = "nbformat" }, - { name = "overrides" }, { name = "packaging" }, { name = "prometheus-client" }, { name = "pywinpty", marker = "os_name == 'nt' and sys_platform != 'linux'" }, @@ -1032,9 +1099,9 @@ dependencies = [ { name = "traitlets" }, { name = "websocket-client" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/41/c8/ba2bbcd758c47f1124c4ca14061e8ce60d9c6fd537faee9534a95f83521a/jupyter_server-2.16.0.tar.gz", hash = "sha256:65d4b44fdf2dcbbdfe0aa1ace4a842d4aaf746a2b7b168134d5aaed35621b7f6", size = 728177, upload-time = "2025-05-12T16:44:46.245Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5b/ac/e040ec363d7b6b1f11304cc9f209dac4517ece5d5e01821366b924a64a50/jupyter_server-2.17.0.tar.gz", hash = "sha256:c38ea898566964c888b4772ae1ed58eca84592e88251d2cfc4d171f81f7e99d5", size = 731949, upload-time = "2025-08-21T14:42:54.042Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/46/1f/5ebbced977171d09a7b0c08a285ff9a20aafb9c51bde07e52349ff1ddd71/jupyter_server-2.16.0-py3-none-any.whl", hash = "sha256:3d8db5be3bc64403b1c65b400a1d7f4647a5ce743f3b20dbdefe8ddb7b55af9e", size = 386904, upload-time = "2025-05-12T16:44:43.335Z" }, + { url = "https://files.pythonhosted.org/packages/92/80/a24767e6ca280f5a49525d987bf3e4d7552bf67c8be07e8ccf20271f8568/jupyter_server-2.17.0-py3-none-any.whl", hash = "sha256:e8cb9c7db4251f51ed307e329b81b72ccf2056ff82d50524debde1ee1870e13f", size = 388221, upload-time = "2025-08-21T14:42:52.034Z" }, ] [[package]] @@ -1052,7 +1119,7 @@ wheels = [ [[package]] name = "jupyterlab" -version = "4.4.3" +version = "4.4.10" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "async-lru" }, @@ -1069,9 +1136,9 @@ dependencies = [ { name = "tornado" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d3/2d/d1678dcf2db66cb4a38a80d9e5fcf48c349f3ac12f2d38882993353ae768/jupyterlab-4.4.3.tar.gz", hash = "sha256:a94c32fd7f8b93e82a49dc70a6ec45a5c18281ca2a7228d12765e4e210e5bca2", size = 23032376, upload-time = "2025-05-26T11:18:00.996Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/5d/75c42a48ff5fc826a7dff3fe4004cda47c54f9d981c351efacfbc9139d3c/jupyterlab-4.4.10.tar.gz", hash = "sha256:521c017508af4e1d6d9d8a9d90f47a11c61197ad63b2178342489de42540a615", size = 22969303, upload-time = "2025-10-22T14:50:58.768Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c6/4d/7dd5c2ffbb960930452a031dc8410746183c924580f2ab4e68ceb5b3043f/jupyterlab-4.4.3-py3-none-any.whl", hash = "sha256:164302f6d4b6c44773dfc38d585665a4db401a16e5296c37df5cba63904fbdea", size = 12295480, upload-time = "2025-05-26T11:17:56.607Z" }, + { url = "https://files.pythonhosted.org/packages/f7/46/1eaa5db8d54a594bdade67afbcae42e9a2da676628be3eb39f36dcff6390/jupyterlab-4.4.10-py3-none-any.whl", hash = "sha256:65939ab4c8dcd0c42185c2d0d1a9d60b254dc8c46fc4fdb286b63c51e9358e07", size = 12293385, upload-time = "2025-10-22T14:50:54.075Z" }, ] [[package]] @@ -1085,7 +1152,7 @@ wheels = [ [[package]] name = "jupyterlab-server" -version = "2.27.3" +version = "2.28.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "babel" }, @@ -1096,23 +1163,32 @@ dependencies = [ { name = "packaging" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0a/c9/a883ce65eb27905ce77ace410d83587c82ea64dc85a48d1f7ed52bcfa68d/jupyterlab_server-2.27.3.tar.gz", hash = "sha256:eb36caca59e74471988f0ae25c77945610b887f777255aa21f8065def9e51ed4", size = 76173, upload-time = "2024-07-16T17:02:04.149Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/2c/90153f189e421e93c4bb4f9e3f59802a1f01abd2ac5cf40b152d7f735232/jupyterlab_server-2.28.0.tar.gz", hash = "sha256:35baa81898b15f93573e2deca50d11ac0ae407ebb688299d3a5213265033712c", size = 76996, upload-time = "2025-10-22T13:59:18.37Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/54/09/2032e7d15c544a0e3cd831c51d77a8ca57f7555b2e1b2922142eddb02a84/jupyterlab_server-2.27.3-py3-none-any.whl", hash = "sha256:e697488f66c3db49df675158a77b3b017520d772c6e1548c7d9bcc5df7944ee4", size = 59700, upload-time = "2024-07-16T17:02:01.115Z" }, + { url = "https://files.pythonhosted.org/packages/e0/07/a000fe835f76b7e1143242ab1122e6362ef1c03f23f83a045c38859c2ae0/jupyterlab_server-2.28.0-py3-none-any.whl", hash = "sha256:e4355b148fdcf34d312bbbc80f22467d6d20460e8b8736bf235577dd18506968", size = 59830, upload-time = "2025-10-22T13:59:16.767Z" }, ] [[package]] name = "jupyterlab-widgets" -version = "3.0.15" +version = "3.0.16" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b9/7d/160595ca88ee87ac6ba95d82177d29ec60aaa63821d3077babb22ce031a5/jupyterlab_widgets-3.0.15.tar.gz", hash = "sha256:2920888a0c2922351a9202817957a68c07d99673504d6cd37345299e971bb08b", size = 213149, upload-time = "2025-05-05T12:32:31.004Z" } +sdist = { url = "https://files.pythonhosted.org/packages/26/2d/ef58fed122b268c69c0aa099da20bc67657cdfb2e222688d5731bd5b971d/jupyterlab_widgets-3.0.16.tar.gz", hash = "sha256:423da05071d55cf27a9e602216d35a3a65a3e41cdf9c5d3b643b814ce38c19e0", size = 897423, upload-time = "2025-11-01T21:11:29.724Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/43/6a/ca128561b22b60bd5a0c4ea26649e68c8556b82bc70a0c396eebc977fe86/jupyterlab_widgets-3.0.15-py3-none-any.whl", hash = "sha256:d59023d7d7ef71400d51e6fee9a88867f6e65e10a4201605d2d7f3e8f012a31c", size = 216571, upload-time = "2025-05-05T12:32:29.534Z" }, + { url = "https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl", hash = "sha256:45fa36d9c6422cf2559198e4db481aa243c7a32d9926b500781c830c80f7ecf8", size = 914926, upload-time = "2025-11-01T21:11:28.008Z" }, +] + +[[package]] +name = "lark" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/34/28fff3ab31ccff1fd4f6c7c7b0ceb2b6968d8ea4950663eadcb5720591a0/lark-1.3.1.tar.gz", hash = "sha256:b426a7a6d6d53189d318f2b6236ab5d6429eaf09259f1ca33eb716eed10d2905", size = 382732, upload-time = "2025-10-27T18:25:56.653Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl", hash = "sha256:c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12", size = 113151, upload-time = "2025-10-27T18:25:54.882Z" }, ] [[package]] name = "lightning" -version = "2.5.1.post0" +version = "2.5.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "fsspec", extra = ["http"] }, @@ -1125,23 +1201,23 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/97/d0/fb3c5077efdd74c28ea3a277fd80bbf03738d866013a8637691138bfebca/lightning-2.5.1.post0.tar.gz", hash = "sha256:fda1ac63c283b3b08a54be8d905dd88469cf09e9845d36dd28b699e78911cbc8", size = 631113, upload-time = "2025-04-25T20:24:25.054Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e9/da/289e17b2d4631b885771ce10ab7fe19c6c0ab2b1208d1dda418818ffbbfd/lightning-2.5.6.tar.gz", hash = "sha256:57b6abe87080895bc237fb7f36b7b4abaa2793760cbca00e3907e56607e0ed27", size = 640106, upload-time = "2025-11-05T20:53:06.823Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9e/1b/67201d693a575e8a086831710f33e697fab66166223f792e459ef2b84934/lightning-2.5.1.post0-py3-none-any.whl", hash = "sha256:a228a52ca52f0c5006ff327c92b8942f09e1aea3f2d9b0d7c8a209edd5b9e71d", size = 819001, upload-time = "2025-04-25T20:24:21.212Z" }, + { url = "https://files.pythonhosted.org/packages/23/dc/d7804f13928b6a81a0e948cfecbf0071e8cc74e3f341c704e23e75e504ad/lightning-2.5.6-py3-none-any.whl", hash = "sha256:25bb2053078c2efc57c082fda89dfbd975dfa76beb08def191947c2b571a8c8a", size = 827915, upload-time = "2025-11-05T20:53:03.169Z" }, ] [[package]] name = "lightning-utilities" -version = "0.14.3" +version = "0.15.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "packaging" }, { name = "setuptools" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0f/bb/63a6a8c9e7a96b6ba92647fa5b1595c2dbee29f8178705adb4704d82ecba/lightning_utilities-0.14.3.tar.gz", hash = "sha256:37e2f83f273890052955a44054382c211a303012ee577619efbaa5df9e65e9f5", size = 30346, upload-time = "2025-04-03T15:59:56.928Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b8/39/6fc58ca81492db047149b4b8fd385aa1bfb8c28cd7cacb0c7eb0c44d842f/lightning_utilities-0.15.2.tar.gz", hash = "sha256:cdf12f530214a63dacefd713f180d1ecf5d165338101617b4742e8f22c032e24", size = 31090, upload-time = "2025-08-06T13:57:39.242Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1a/c1/31b3184cba7b257a4a3b5ca5b88b9204ccb7aa02fe3c992280899293ed54/lightning_utilities-0.14.3-py3-none-any.whl", hash = "sha256:4ab9066aa36cd7b93a05713808901909e96cc3f187ea6fd3052b2fd91313b468", size = 28894, upload-time = "2025-04-03T15:59:55.658Z" }, + { url = "https://files.pythonhosted.org/packages/de/73/3d757cb3fc16f0f9794dd289bcd0c4a031d9cf54d8137d6b984b2d02edf3/lightning_utilities-0.15.2-py3-none-any.whl", hash = "sha256:ad3ab1703775044bbf880dbf7ddaaac899396c96315f3aa1779cec9d618a9841", size = 29431, upload-time = "2025-08-06T13:57:38.046Z" }, ] [[package]] @@ -1158,32 +1234,33 @@ wheels = [ [[package]] name = "markupsafe" -version = "3.0.2" +version = "3.0.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274, upload-time = "2024-10-18T15:21:13.777Z" }, - { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348, upload-time = "2024-10-18T15:21:14.822Z" }, - { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149, upload-time = "2024-10-18T15:21:15.642Z" }, - { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118, upload-time = "2024-10-18T15:21:17.133Z" }, - { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993, upload-time = "2024-10-18T15:21:18.064Z" }, - { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178, upload-time = "2024-10-18T15:21:18.859Z" }, - { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319, upload-time = "2024-10-18T15:21:19.671Z" }, - { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352, upload-time = "2024-10-18T15:21:20.971Z" }, - { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097, upload-time = "2024-10-18T15:21:22.646Z" }, - { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601, upload-time = "2024-10-18T15:21:23.499Z" }, + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, ] [[package]] name = "matplotlib-inline" -version = "0.1.7" +version = "0.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/99/5b/a36a337438a14116b16480db471ad061c36c3694df7c2084a0da7ba538b7/matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90", size = 8159, upload-time = "2024-04-15T13:44:44.803Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/74/97e72a36efd4ae2bccb3463284300f8953f199b5ffbc04cbbb0ec78f74b1/matplotlib_inline-0.2.1.tar.gz", hash = "sha256:e1ee949c340d771fc39e241ea75683deb94762c8fa5f2927ec57c83c4dffa9fe", size = 8110, upload-time = "2025-10-23T09:00:22.126Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca", size = 9899, upload-time = "2024-04-15T13:44:43.265Z" }, + { url = "https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl", hash = "sha256:d56ce5156ba6085e00a9d54fead6ed29a9c47e215cd1bba2e976ef39f5710a76", size = 9516, upload-time = "2025-10-23T09:00:20.675Z" }, ] [[package]] @@ -1197,11 +1274,36 @@ wheels = [ [[package]] name = "mistune" -version = "3.1.3" +version = "3.1.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c4/79/bda47f7dd7c3c55770478d6d02c9960c430b0cf1773b72366ff89126ea31/mistune-3.1.3.tar.gz", hash = "sha256:a7035c21782b2becb6be62f8f25d3df81ccb4d6fa477a6525b15af06539f02a0", size = 94347, upload-time = "2025-03-19T14:27:24.955Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/02/a7fb8b21d4d55ac93cdcde9d3638da5dd0ebdd3a4fed76c7725e10b81cbe/mistune-3.1.4.tar.gz", hash = "sha256:b5a7f801d389f724ec702840c11d8fc48f2b33519102fc7ee739e8177b672164", size = 94588, upload-time = "2025-08-29T07:20:43.594Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/01/4d/23c4e4f09da849e127e9f123241946c23c1e30f45a88366879e064211815/mistune-3.1.3-py3-none-any.whl", hash = "sha256:1a32314113cff28aa6432e99e522677c8587fd83e3d51c29b82a52409c842bd9", size = 53410, upload-time = "2025-03-19T14:27:23.451Z" }, + { url = "https://files.pythonhosted.org/packages/7a/f0/8282d9641415e9e33df173516226b404d367a0fc55e1a60424a152913abc/mistune-3.1.4-py3-none-any.whl", hash = "sha256:93691da911e5d9d2e23bc54472892aff676df27a75274962ff9edc210364266d", size = 53481, upload-time = "2025-08-29T07:20:42.218Z" }, +] + +[[package]] +name = "modal" +version = "1.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "cbor2" }, + { name = "certifi" }, + { name = "click" }, + { name = "grpclib" }, + { name = "protobuf" }, + { name = "rich" }, + { name = "synchronicity" }, + { name = "toml" }, + { name = "typer" }, + { name = "types-certifi" }, + { name = "types-toml" }, + { name = "typing-extensions" }, + { name = "watchfiles" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/05/67/a3581c4ca0a4aaf025d4bfc844943fe8d4629ab56e5ee03b4c363099f2d4/modal-1.2.1.tar.gz", hash = "sha256:c1d0de8bbaf41fa382b837bd79193b6eb0fa67560ad1bb882a55409fc51607fb", size = 636887, upload-time = "2025-10-22T20:07:57.792Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/30/2b/9e7d6ce150e37e8566d03b986cebc0a3a4f8a8f74f0004f775c5f9b23a6c/modal-1.2.1-py3-none-any.whl", hash = "sha256:151b4942bad86f8b13a21226328cca8be005a0e780736fa6561226fedbade431", size = 733792, upload-time = "2025-10-22T20:07:54.243Z" }, ] [[package]] @@ -1215,44 +1317,45 @@ wheels = [ [[package]] name = "multidict" -version = "6.4.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/91/2f/a3470242707058fe856fe59241eee5635d79087100b7042a867368863a27/multidict-6.4.4.tar.gz", hash = "sha256:69ee9e6ba214b5245031b76233dd95408a0fd57fdb019ddcc1ead4790932a8e8", size = 90183, upload-time = "2025-05-19T14:16:37.381Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/b5/5675377da23d60875fe7dae6be841787755878e315e2f517235f22f59e18/multidict-6.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:dc388f75a1c00000824bf28b7633e40854f4127ede80512b44c3cfeeea1839a2", size = 64293, upload-time = "2025-05-19T14:14:44.724Z" }, - { url = "https://files.pythonhosted.org/packages/34/a7/be384a482754bb8c95d2bbe91717bf7ccce6dc38c18569997a11f95aa554/multidict-6.4.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:98af87593a666f739d9dba5d0ae86e01b0e1a9cfcd2e30d2d361fbbbd1a9162d", size = 38096, upload-time = "2025-05-19T14:14:45.95Z" }, - { url = "https://files.pythonhosted.org/packages/66/6d/d59854bb4352306145bdfd1704d210731c1bb2c890bfee31fb7bbc1c4c7f/multidict-6.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aff4cafea2d120327d55eadd6b7f1136a8e5a0ecf6fb3b6863e8aca32cd8e50a", size = 37214, upload-time = "2025-05-19T14:14:47.158Z" }, - { url = "https://files.pythonhosted.org/packages/99/e0/c29d9d462d7cfc5fc8f9bf24f9c6843b40e953c0b55e04eba2ad2cf54fba/multidict-6.4.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:169c4ba7858176b797fe551d6e99040c531c775d2d57b31bcf4de6d7a669847f", size = 224686, upload-time = "2025-05-19T14:14:48.366Z" }, - { url = "https://files.pythonhosted.org/packages/dc/4a/da99398d7fd8210d9de068f9a1b5f96dfaf67d51e3f2521f17cba4ee1012/multidict-6.4.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b9eb4c59c54421a32b3273d4239865cb14ead53a606db066d7130ac80cc8ec93", size = 231061, upload-time = "2025-05-19T14:14:49.952Z" }, - { url = "https://files.pythonhosted.org/packages/21/f5/ac11add39a0f447ac89353e6ca46666847051103649831c08a2800a14455/multidict-6.4.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7cf3bd54c56aa16fdb40028d545eaa8d051402b61533c21e84046e05513d5780", size = 232412, upload-time = "2025-05-19T14:14:51.812Z" }, - { url = "https://files.pythonhosted.org/packages/d9/11/4b551e2110cded705a3c13a1d4b6a11f73891eb5a1c449f1b2b6259e58a6/multidict-6.4.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f682c42003c7264134bfe886376299db4cc0c6cd06a3295b41b347044bcb5482", size = 231563, upload-time = "2025-05-19T14:14:53.262Z" }, - { url = "https://files.pythonhosted.org/packages/4c/02/751530c19e78fe73b24c3da66618eda0aa0d7f6e7aa512e46483de6be210/multidict-6.4.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920f9cf2abdf6e493c519492d892c362007f113c94da4c239ae88429835bad1", size = 223811, upload-time = "2025-05-19T14:14:55.232Z" }, - { url = "https://files.pythonhosted.org/packages/c7/cb/2be8a214643056289e51ca356026c7b2ce7225373e7a1f8c8715efee8988/multidict-6.4.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:530d86827a2df6504526106b4c104ba19044594f8722d3e87714e847c74a0275", size = 216524, upload-time = "2025-05-19T14:14:57.226Z" }, - { url = "https://files.pythonhosted.org/packages/19/f3/6d5011ec375c09081f5250af58de85f172bfcaafebff286d8089243c4bd4/multidict-6.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ecde56ea2439b96ed8a8d826b50c57364612ddac0438c39e473fafad7ae1c23b", size = 229012, upload-time = "2025-05-19T14:14:58.597Z" }, - { url = "https://files.pythonhosted.org/packages/67/9c/ca510785df5cf0eaf5b2a8132d7d04c1ce058dcf2c16233e596ce37a7f8e/multidict-6.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:dc8c9736d8574b560634775ac0def6bdc1661fc63fa27ffdfc7264c565bcb4f2", size = 226765, upload-time = "2025-05-19T14:15:00.048Z" }, - { url = "https://files.pythonhosted.org/packages/36/c8/ca86019994e92a0f11e642bda31265854e6ea7b235642f0477e8c2e25c1f/multidict-6.4.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7f3d3b3c34867579ea47cbd6c1f2ce23fbfd20a273b6f9e3177e256584f1eacc", size = 222888, upload-time = "2025-05-19T14:15:01.568Z" }, - { url = "https://files.pythonhosted.org/packages/c6/67/bc25a8e8bd522935379066950ec4e2277f9b236162a73548a2576d4b9587/multidict-6.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:87a728af265e08f96b6318ebe3c0f68b9335131f461efab2fc64cc84a44aa6ed", size = 234041, upload-time = "2025-05-19T14:15:03.759Z" }, - { url = "https://files.pythonhosted.org/packages/f1/a0/70c4c2d12857fccbe607b334b7ee28b6b5326c322ca8f73ee54e70d76484/multidict-6.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9f193eeda1857f8e8d3079a4abd258f42ef4a4bc87388452ed1e1c4d2b0c8740", size = 231046, upload-time = "2025-05-19T14:15:05.698Z" }, - { url = "https://files.pythonhosted.org/packages/c1/0f/52954601d02d39742aab01d6b92f53c1dd38b2392248154c50797b4df7f1/multidict-6.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:be06e73c06415199200e9a2324a11252a3d62030319919cde5e6950ffeccf72e", size = 227106, upload-time = "2025-05-19T14:15:07.124Z" }, - { url = "https://files.pythonhosted.org/packages/af/24/679d83ec4379402d28721790dce818e5d6b9f94ce1323a556fb17fa9996c/multidict-6.4.4-cp312-cp312-win32.whl", hash = "sha256:622f26ea6a7e19b7c48dd9228071f571b2fbbd57a8cd71c061e848f281550e6b", size = 35351, upload-time = "2025-05-19T14:15:08.556Z" }, - { url = "https://files.pythonhosted.org/packages/52/ef/40d98bc5f986f61565f9b345f102409534e29da86a6454eb6b7c00225a13/multidict-6.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:5e2bcda30d5009996ff439e02a9f2b5c3d64a20151d34898c000a6281faa3781", size = 38791, upload-time = "2025-05-19T14:15:09.825Z" }, - { url = "https://files.pythonhosted.org/packages/84/5d/e17845bb0fa76334477d5de38654d27946d5b5d3695443987a094a71b440/multidict-6.4.4-py3-none-any.whl", hash = "sha256:bd4557071b561a8b3b6075c3ce93cf9bfb6182cb241805c3d66ced3b75eff4ac", size = 10481, upload-time = "2025-05-19T14:16:36.024Z" }, +version = "6.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/80/1e/5492c365f222f907de1039b91f922b93fa4f764c713ee858d235495d8f50/multidict-6.7.0.tar.gz", hash = "sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5", size = 101834, upload-time = "2025-10-06T14:52:30.657Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/9e/9f61ac18d9c8b475889f32ccfa91c9f59363480613fc807b6e3023d6f60b/multidict-6.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8a3862568a36d26e650a19bb5cbbba14b71789032aebc0423f8cc5f150730184", size = 76877, upload-time = "2025-10-06T14:49:20.884Z" }, + { url = "https://files.pythonhosted.org/packages/38/6f/614f09a04e6184f8824268fce4bc925e9849edfa654ddd59f0b64508c595/multidict-6.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:960c60b5849b9b4f9dcc9bea6e3626143c252c74113df2c1540aebce70209b45", size = 45467, upload-time = "2025-10-06T14:49:22.054Z" }, + { url = "https://files.pythonhosted.org/packages/b3/93/c4f67a436dd026f2e780c433277fff72be79152894d9fc36f44569cab1a6/multidict-6.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2049be98fb57a31b4ccf870bf377af2504d4ae35646a19037ec271e4c07998aa", size = 43834, upload-time = "2025-10-06T14:49:23.566Z" }, + { url = "https://files.pythonhosted.org/packages/7f/f5/013798161ca665e4a422afbc5e2d9e4070142a9ff8905e482139cd09e4d0/multidict-6.7.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0934f3843a1860dd465d38895c17fce1f1cb37295149ab05cd1b9a03afacb2a7", size = 250545, upload-time = "2025-10-06T14:49:24.882Z" }, + { url = "https://files.pythonhosted.org/packages/71/2f/91dbac13e0ba94669ea5119ba267c9a832f0cb65419aca75549fcf09a3dc/multidict-6.7.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3e34f3a1b8131ba06f1a73adab24f30934d148afcd5f5de9a73565a4404384e", size = 258305, upload-time = "2025-10-06T14:49:26.778Z" }, + { url = "https://files.pythonhosted.org/packages/ef/b0/754038b26f6e04488b48ac621f779c341338d78503fb45403755af2df477/multidict-6.7.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:efbb54e98446892590dc2458c19c10344ee9a883a79b5cec4bc34d6656e8d546", size = 242363, upload-time = "2025-10-06T14:49:28.562Z" }, + { url = "https://files.pythonhosted.org/packages/87/15/9da40b9336a7c9fa606c4cf2ed80a649dffeb42b905d4f63a1d7eb17d746/multidict-6.7.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a35c5fc61d4f51eb045061e7967cfe3123d622cd500e8868e7c0c592a09fedc4", size = 268375, upload-time = "2025-10-06T14:49:29.96Z" }, + { url = "https://files.pythonhosted.org/packages/82/72/c53fcade0cc94dfaad583105fd92b3a783af2091eddcb41a6d5a52474000/multidict-6.7.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29fe6740ebccba4175af1b9b87bf553e9c15cd5868ee967e010efcf94e4fd0f1", size = 269346, upload-time = "2025-10-06T14:49:31.404Z" }, + { url = "https://files.pythonhosted.org/packages/0d/e2/9baffdae21a76f77ef8447f1a05a96ec4bc0a24dae08767abc0a2fe680b8/multidict-6.7.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:123e2a72e20537add2f33a79e605f6191fba2afda4cbb876e35c1a7074298a7d", size = 256107, upload-time = "2025-10-06T14:49:32.974Z" }, + { url = "https://files.pythonhosted.org/packages/3c/06/3f06f611087dc60d65ef775f1fb5aca7c6d61c6db4990e7cda0cef9b1651/multidict-6.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b284e319754366c1aee2267a2036248b24eeb17ecd5dc16022095e747f2f4304", size = 253592, upload-time = "2025-10-06T14:49:34.52Z" }, + { url = "https://files.pythonhosted.org/packages/20/24/54e804ec7945b6023b340c412ce9c3f81e91b3bf5fa5ce65558740141bee/multidict-6.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:803d685de7be4303b5a657b76e2f6d1240e7e0a8aa2968ad5811fa2285553a12", size = 251024, upload-time = "2025-10-06T14:49:35.956Z" }, + { url = "https://files.pythonhosted.org/packages/14/48/011cba467ea0b17ceb938315d219391d3e421dfd35928e5dbdc3f4ae76ef/multidict-6.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c04a328260dfd5db8c39538f999f02779012268f54614902d0afc775d44e0a62", size = 251484, upload-time = "2025-10-06T14:49:37.631Z" }, + { url = "https://files.pythonhosted.org/packages/0d/2f/919258b43bb35b99fa127435cfb2d91798eb3a943396631ef43e3720dcf4/multidict-6.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8a19cdb57cd3df4cd865849d93ee14920fb97224300c88501f16ecfa2604b4e0", size = 263579, upload-time = "2025-10-06T14:49:39.502Z" }, + { url = "https://files.pythonhosted.org/packages/31/22/a0e884d86b5242b5a74cf08e876bdf299e413016b66e55511f7a804a366e/multidict-6.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b2fd74c52accced7e75de26023b7dccee62511a600e62311b918ec5c168fc2a", size = 259654, upload-time = "2025-10-06T14:49:41.32Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e5/17e10e1b5c5f5a40f2fcbb45953c9b215f8a4098003915e46a93f5fcaa8f/multidict-6.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3e8bfdd0e487acf992407a140d2589fe598238eaeffa3da8448d63a63cd363f8", size = 251511, upload-time = "2025-10-06T14:49:46.021Z" }, + { url = "https://files.pythonhosted.org/packages/e3/9a/201bb1e17e7af53139597069c375e7b0dcbd47594604f65c2d5359508566/multidict-6.7.0-cp312-cp312-win32.whl", hash = "sha256:dd32a49400a2c3d52088e120ee00c1e3576cbff7e10b98467962c74fdb762ed4", size = 41895, upload-time = "2025-10-06T14:49:48.718Z" }, + { url = "https://files.pythonhosted.org/packages/46/e2/348cd32faad84eaf1d20cce80e2bb0ef8d312c55bca1f7fa9865e7770aaf/multidict-6.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:92abb658ef2d7ef22ac9f8bb88e8b6c3e571671534e029359b6d9e845923eb1b", size = 46073, upload-time = "2025-10-06T14:49:50.28Z" }, + { url = "https://files.pythonhosted.org/packages/25/ec/aad2613c1910dce907480e0c3aa306905830f25df2e54ccc9dea450cb5aa/multidict-6.7.0-cp312-cp312-win_arm64.whl", hash = "sha256:490dab541a6a642ce1a9d61a4781656b346a55c13038f0b1244653828e3a83ec", size = 43226, upload-time = "2025-10-06T14:49:52.304Z" }, + { url = "https://files.pythonhosted.org/packages/b7/da/7d22601b625e241d4f23ef1ebff8acfc60da633c9e7e7922e24d10f592b3/multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3", size = 12317, upload-time = "2025-10-06T14:52:29.272Z" }, ] [[package]] name = "multiprocess" -version = "0.70.16" +version = "0.70.18" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "dill" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b5/ae/04f39c5d0d0def03247c2893d6f2b83c136bf3320a2154d7b8858f2ba72d/multiprocess-0.70.16.tar.gz", hash = "sha256:161af703d4652a0e1410be6abccecde4a7ddffd19341be0a7011b94aeb171ac1", size = 1772603, upload-time = "2024-01-28T18:52:34.85Z" } +sdist = { url = "https://files.pythonhosted.org/packages/72/fd/2ae3826f5be24c6ed87266bc4e59c46ea5b059a103f3d7e7eb76a52aeecb/multiprocess-0.70.18.tar.gz", hash = "sha256:f9597128e6b3e67b23956da07cf3d2e5cba79e2f4e0fba8d7903636663ec6d0d", size = 1798503, upload-time = "2025-04-17T03:11:27.742Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/f7/7ec7fddc92e50714ea3745631f79bd9c96424cb2702632521028e57d3a36/multiprocess-0.70.16-py310-none-any.whl", hash = "sha256:c4a9944c67bd49f823687463660a2d6daae94c289adff97e0f9d696ba6371d02", size = 134824, upload-time = "2024-01-28T18:52:26.062Z" }, - { url = "https://files.pythonhosted.org/packages/50/15/b56e50e8debaf439f44befec5b2af11db85f6e0f344c3113ae0be0593a91/multiprocess-0.70.16-py311-none-any.whl", hash = "sha256:af4cabb0dac72abfb1e794fa7855c325fd2b55a10a44628a3c1ad3311c04127a", size = 143519, upload-time = "2024-01-28T18:52:28.115Z" }, - { url = "https://files.pythonhosted.org/packages/0a/7d/a988f258104dcd2ccf1ed40fdc97e26c4ac351eeaf81d76e266c52d84e2f/multiprocess-0.70.16-py312-none-any.whl", hash = "sha256:fc0544c531920dde3b00c29863377f87e1632601092ea2daca74e4beb40faa2e", size = 146741, upload-time = "2024-01-28T18:52:29.395Z" }, - { url = "https://files.pythonhosted.org/packages/ea/89/38df130f2c799090c978b366cfdf5b96d08de5b29a4a293df7f7429fa50b/multiprocess-0.70.16-py38-none-any.whl", hash = "sha256:a71d82033454891091a226dfc319d0cfa8019a4e888ef9ca910372a446de4435", size = 132628, upload-time = "2024-01-28T18:52:30.853Z" }, - { url = "https://files.pythonhosted.org/packages/da/d9/f7f9379981e39b8c2511c9e0326d212accacb82f12fbfdc1aa2ce2a7b2b6/multiprocess-0.70.16-py39-none-any.whl", hash = "sha256:a0bafd3ae1b732eac64be2e72038231c1ba97724b60b09400d68f229fcc2fbf3", size = 133351, upload-time = "2024-01-28T18:52:31.981Z" }, + { url = "https://files.pythonhosted.org/packages/ba/d8/0cba6cf51a1a31f20471fbc823a716170c73012ddc4fb85d706630ed6e8f/multiprocess-0.70.18-py310-none-any.whl", hash = "sha256:60c194974c31784019c1f459d984e8f33ee48f10fcf42c309ba97b30d9bd53ea", size = 134948, upload-time = "2025-04-17T03:11:20.223Z" }, + { url = "https://files.pythonhosted.org/packages/4b/88/9039f2fed1012ef584751d4ceff9ab4a51e5ae264898f0b7cbf44340a859/multiprocess-0.70.18-py311-none-any.whl", hash = "sha256:5aa6eef98e691281b3ad923be2832bf1c55dd2c859acd73e5ec53a66aae06a1d", size = 144462, upload-time = "2025-04-17T03:11:21.657Z" }, + { url = "https://files.pythonhosted.org/packages/bf/b6/5f922792be93b82ec6b5f270bbb1ef031fd0622847070bbcf9da816502cc/multiprocess-0.70.18-py312-none-any.whl", hash = "sha256:9b78f8e5024b573730bfb654783a13800c2c0f2dfc0c25e70b40d184d64adaa2", size = 150287, upload-time = "2025-04-17T03:11:22.69Z" }, + { url = "https://files.pythonhosted.org/packages/3b/c3/ca84c19bd14cdfc21c388fdcebf08b86a7a470ebc9f5c3c084fc2dbc50f7/multiprocess-0.70.18-py38-none-any.whl", hash = "sha256:dbf705e52a154fe5e90fb17b38f02556169557c2dd8bb084f2e06c2784d8279b", size = 132636, upload-time = "2025-04-17T03:11:24.936Z" }, + { url = "https://files.pythonhosted.org/packages/6c/28/dd72947e59a6a8c856448a5e74da6201cb5502ddff644fbc790e4bd40b9a/multiprocess-0.70.18-py39-none-any.whl", hash = "sha256:e78ca805a72b1b810c690b6b4cc32579eba34f403094bbbae962b7b5bf9dfcb8", size = 133478, upload-time = "2025-04-17T03:11:26.253Z" }, ] [[package]] @@ -1413,7 +1516,7 @@ name = "nvidia-cudnn-cu12" version = "9.10.2.21" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas-cu12", marker = "sys_platform == 'linux'" }, + { name = "nvidia-cublas-cu12" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/ba/51/e123d997aa098c61d029f76663dedbfb9bc8dcf8c60cbd6adbe42f76d049/nvidia_cudnn_cu12-9.10.2.21-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:949452be657fa16687d0930933f032835951ef0892b37d2d53824d1a84dc97a8", size = 706758467, upload-time = "2025-06-06T21:54:08.597Z" }, @@ -1424,7 +1527,7 @@ name = "nvidia-cufft-cu12" version = "11.3.3.83" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" }, + { name = "nvidia-nvjitlink-cu12" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/1f/13/ee4e00f30e676b66ae65b4f08cb5bcbb8392c03f54f2d5413ea99a5d1c80/nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d2dd21ec0b88cf61b62e6b43564355e5222e4a3fb394cac0db101f2dd0d4f74", size = 193118695, upload-time = "2025-03-07T01:45:27.821Z" }, @@ -1451,9 +1554,9 @@ name = "nvidia-cusolver-cu12" version = "11.7.3.90" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas-cu12", marker = "sys_platform == 'linux'" }, - { name = "nvidia-cusparse-cu12", marker = "sys_platform == 'linux'" }, - { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" }, + { name = "nvidia-cublas-cu12" }, + { name = "nvidia-cusparse-cu12" }, + { name = "nvidia-nvjitlink-cu12" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/85/48/9a13d2975803e8cf2777d5ed57b87a0b6ca2cc795f9a4f59796a910bfb80/nvidia_cusolver_cu12-11.7.3.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:4376c11ad263152bd50ea295c05370360776f8c3427b30991df774f9fb26c450", size = 267506905, upload-time = "2025-03-07T01:47:16.273Z" }, @@ -1464,7 +1567,7 @@ name = "nvidia-cusparse-cu12" version = "12.5.8.93" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" }, + { name = "nvidia-nvjitlink-cu12" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/c2/f5/e1854cb2f2bcd4280c44736c93550cc300ff4b8c95ebe370d0aa7d2b473d/nvidia_cusparse_cu12-12.5.8.93-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ec05d76bbbd8b61b06a80e1eaf8cf4959c3d4ce8e711b65ebd0443bb0ebb13b", size = 288216466, upload-time = "2025-03-07T01:48:13.779Z" }, @@ -1480,10 +1583,10 @@ wheels = [ [[package]] name = "nvidia-nccl-cu12" -version = "2.27.3" +version = "2.27.5" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/5b/4e4fff7bad39adf89f735f2bc87248c81db71205b62bcc0d5ca5b606b3c3/nvidia_nccl_cu12-2.27.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:adf27ccf4238253e0b826bce3ff5fa532d65fc42322c8bfdfaf28024c0fbe039", size = 322364134, upload-time = "2025-06-03T21:58:04.013Z" }, + { url = "https://files.pythonhosted.org/packages/6e/89/f7a07dc961b60645dbbf42e80f2bc85ade7feb9a491b11a1e973aa00071f/nvidia_nccl_cu12-2.27.5-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ad730cf15cb5d25fe849c6e6ca9eb5b76db16a80f13f425ac68d8e2e55624457", size = 322348229, upload-time = "2025-06-26T04:11:28.385Z" }, ] [[package]] @@ -1495,34 +1598,33 @@ wheels = [ ] [[package]] -name = "nvidia-nvtx-cu12" -version = "12.8.90" +name = "nvidia-nvshmem-cu12" +version = "3.3.20" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a2/eb/86626c1bbc2edb86323022371c39aa48df6fd8b0a1647bc274577f72e90b/nvidia_nvtx_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b17e2001cc0d751a5bc2c6ec6d26ad95913324a4adb86788c944f8ce9ba441f", size = 89954, upload-time = "2025-03-07T01:42:44.131Z" }, + { url = "https://files.pythonhosted.org/packages/3b/6c/99acb2f9eb85c29fc6f3a7ac4dccfd992e22666dd08a642b303311326a97/nvidia_nvshmem_cu12-3.3.20-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d00f26d3f9b2e3c3065be895e3059d6479ea5c638a3f38c9fec49b1b9dd7c1e5", size = 124657145, upload-time = "2025-08-04T20:25:19.995Z" }, ] [[package]] -name = "overrides" -version = "7.7.0" +name = "nvidia-nvtx-cu12" +version = "12.8.90" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/36/86/b585f53236dec60aba864e050778b25045f857e17f6e5ea0ae95fe80edd2/overrides-7.7.0.tar.gz", hash = "sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a", size = 22812, upload-time = "2024-01-27T21:01:33.423Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl", hash = "sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49", size = 17832, upload-time = "2024-01-27T21:01:31.393Z" }, + { url = "https://files.pythonhosted.org/packages/a2/eb/86626c1bbc2edb86323022371c39aa48df6fd8b0a1647bc274577f72e90b/nvidia_nvtx_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b17e2001cc0d751a5bc2c6ec6d26ad95913324a4adb86788c944f8ce9ba441f", size = 89954, upload-time = "2025-03-07T01:42:44.131Z" }, ] [[package]] name = "packaging" -version = "24.2" +version = "25.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950, upload-time = "2024-11-08T09:47:47.202Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451, upload-time = "2024-11-08T09:47:44.722Z" }, + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, ] [[package]] name = "pandas" -version = "2.3.0" +version = "2.3.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, @@ -1530,15 +1632,15 @@ dependencies = [ { name = "pytz" }, { name = "tzdata" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/72/51/48f713c4c728d7c55ef7444ba5ea027c26998d96d1a40953b346438602fc/pandas-2.3.0.tar.gz", hash = "sha256:34600ab34ebf1131a7613a260a61dbe8b62c188ec0ea4c296da7c9a06b004133", size = 4484490, upload-time = "2025-06-05T03:27:54.133Z" } +sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/94/46/24192607058dd607dbfacdd060a2370f6afb19c2ccb617406469b9aeb8e7/pandas-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2eb4728a18dcd2908c7fccf74a982e241b467d178724545a48d0caf534b38ebf", size = 11573865, upload-time = "2025-06-05T03:26:46.774Z" }, - { url = "https://files.pythonhosted.org/packages/9f/cc/ae8ea3b800757a70c9fdccc68b67dc0280a6e814efcf74e4211fd5dea1ca/pandas-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b9d8c3187be7479ea5c3d30c32a5d73d62a621166675063b2edd21bc47614027", size = 10702154, upload-time = "2025-06-05T16:50:14.439Z" }, - { url = "https://files.pythonhosted.org/packages/d8/ba/a7883d7aab3d24c6540a2768f679e7414582cc389876d469b40ec749d78b/pandas-2.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ff730713d4c4f2f1c860e36c005c7cefc1c7c80c21c0688fd605aa43c9fcf09", size = 11262180, upload-time = "2025-06-05T16:50:17.453Z" }, - { url = "https://files.pythonhosted.org/packages/01/a5/931fc3ad333d9d87b10107d948d757d67ebcfc33b1988d5faccc39c6845c/pandas-2.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba24af48643b12ffe49b27065d3babd52702d95ab70f50e1b34f71ca703e2c0d", size = 11991493, upload-time = "2025-06-05T03:26:51.813Z" }, - { url = "https://files.pythonhosted.org/packages/d7/bf/0213986830a92d44d55153c1d69b509431a972eb73f204242988c4e66e86/pandas-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:404d681c698e3c8a40a61d0cd9412cc7364ab9a9cc6e144ae2992e11a2e77a20", size = 12470733, upload-time = "2025-06-06T00:00:18.651Z" }, - { url = "https://files.pythonhosted.org/packages/a4/0e/21eb48a3a34a7d4bac982afc2c4eb5ab09f2d988bdf29d92ba9ae8e90a79/pandas-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6021910b086b3ca756755e86ddc64e0ddafd5e58e076c72cb1585162e5ad259b", size = 13212406, upload-time = "2025-06-05T03:26:55.992Z" }, - { url = "https://files.pythonhosted.org/packages/1f/d9/74017c4eec7a28892d8d6e31ae9de3baef71f5a5286e74e6b7aad7f8c837/pandas-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:094e271a15b579650ebf4c5155c05dcd2a14fd4fdd72cf4854b2f7ad31ea30be", size = 10976199, upload-time = "2025-06-05T03:26:59.594Z" }, + { url = "https://files.pythonhosted.org/packages/9c/fb/231d89e8637c808b997d172b18e9d4a4bc7bf31296196c260526055d1ea0/pandas-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53", size = 11597846, upload-time = "2025-09-29T23:19:48.856Z" }, + { url = "https://files.pythonhosted.org/packages/5c/bd/bf8064d9cfa214294356c2d6702b716d3cf3bb24be59287a6a21e24cae6b/pandas-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35", size = 10729618, upload-time = "2025-09-29T23:39:08.659Z" }, + { url = "https://files.pythonhosted.org/packages/57/56/cf2dbe1a3f5271370669475ead12ce77c61726ffd19a35546e31aa8edf4e/pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908", size = 11737212, upload-time = "2025-09-29T23:19:59.765Z" }, + { url = "https://files.pythonhosted.org/packages/e5/63/cd7d615331b328e287d8233ba9fdf191a9c2d11b6af0c7a59cfcec23de68/pandas-2.3.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89", size = 12362693, upload-time = "2025-09-29T23:20:14.098Z" }, + { url = "https://files.pythonhosted.org/packages/a6/de/8b1895b107277d52f2b42d3a6806e69cfef0d5cf1d0ba343470b9d8e0a04/pandas-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98", size = 12771002, upload-time = "2025-09-29T23:20:26.76Z" }, + { url = "https://files.pythonhosted.org/packages/87/21/84072af3187a677c5893b170ba2c8fbe450a6ff911234916da889b698220/pandas-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084", size = 13450971, upload-time = "2025-09-29T23:20:41.344Z" }, + { url = "https://files.pythonhosted.org/packages/86/41/585a168330ff063014880a80d744219dbf1dd7a1c706e75ab3425a987384/pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b", size = 10992722, upload-time = "2025-09-29T23:20:54.139Z" }, ] [[package]] @@ -1552,11 +1654,11 @@ wheels = [ [[package]] name = "parso" -version = "0.8.4" +version = "0.8.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/66/94/68e2e17afaa9169cf6412ab0f28623903be73d1b32e208d9e8e541bb086d/parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d", size = 400609, upload-time = "2024-04-05T09:43:55.897Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d4/de/53e0bcf53d13e005bd8c92e7855142494f41171b34c2536b86187474184d/parso-0.8.5.tar.gz", hash = "sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a", size = 401205, upload-time = "2025-08-23T15:15:28.028Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c6/ac/dac4a63f978e4dcb3c6d3a78c4d8e0192a113d288502a1216950c41b1027/parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18", size = 103650, upload-time = "2024-04-05T09:43:53.299Z" }, + { url = "https://files.pythonhosted.org/packages/16/32/f8e3c85d1d5250232a5d3477a2a28cc291968ff175caeadaf3cc19ce0e4a/parso-0.8.5-py2.py3-none-any.whl", hash = "sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887", size = 106668, upload-time = "2025-08-23T15:15:25.663Z" }, ] [[package]] @@ -1573,11 +1675,11 @@ wheels = [ [[package]] name = "platformdirs" -version = "4.3.8" +version = "4.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fe/8b/3c73abc9c759ecd3f1f7ceff6685840859e8070c4d947c93fae71f6a0bf2/platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc", size = 21362, upload-time = "2025-05-07T22:47:42.121Z" } +sdist = { url = "https://files.pythonhosted.org/packages/61/33/9611380c2bdb1225fdef633e2a9610622310fed35ab11dac9620972ee088/platformdirs-4.5.0.tar.gz", hash = "sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312", size = 21632, upload-time = "2025-10-08T17:44:48.791Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4", size = 18567, upload-time = "2025-05-07T22:47:40.376Z" }, + { url = "https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl", hash = "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3", size = 18651, upload-time = "2025-10-08T17:44:47.223Z" }, ] [[package]] @@ -1591,77 +1693,76 @@ wheels = [ [[package]] name = "prometheus-client" -version = "0.22.1" +version = "0.23.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5e/cf/40dde0a2be27cc1eb41e333d1a674a74ce8b8b0457269cc640fd42b07cf7/prometheus_client-0.22.1.tar.gz", hash = "sha256:190f1331e783cf21eb60bca559354e0a4d4378facecf78f5428c39b675d20d28", size = 69746, upload-time = "2025-06-02T14:29:01.152Z" } +sdist = { url = "https://files.pythonhosted.org/packages/23/53/3edb5d68ecf6b38fcbcc1ad28391117d2a322d9a1a3eff04bfdb184d8c3b/prometheus_client-0.23.1.tar.gz", hash = "sha256:6ae8f9081eaaaf153a2e959d2e6c4f4fb57b12ef76c8c7980202f1e57b48b2ce", size = 80481, upload-time = "2025-09-18T20:47:25.043Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/32/ae/ec06af4fe3ee72d16973474f122541746196aaa16cea6f66d18b963c6177/prometheus_client-0.22.1-py3-none-any.whl", hash = "sha256:cca895342e308174341b2cbf99a56bef291fbc0ef7b9e5412a0f26d653ba7094", size = 58694, upload-time = "2025-06-02T14:29:00.068Z" }, + { url = "https://files.pythonhosted.org/packages/b8/db/14bafcb4af2139e046d03fd00dea7873e48eafe18b7d2797e73d6681f210/prometheus_client-0.23.1-py3-none-any.whl", hash = "sha256:dd1913e6e76b59cfe44e7a4b83e01afc9873c1bdfd2ed8739f1e76aeca115f99", size = 61145, upload-time = "2025-09-18T20:47:23.875Z" }, ] [[package]] name = "prompt-toolkit" -version = "3.0.51" +version = "3.0.52" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "wcwidth" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bb/6e/9d084c929dfe9e3bfe0c6a47e31f78a25c54627d64a66e884a8bf5474f1c/prompt_toolkit-3.0.51.tar.gz", hash = "sha256:931a162e3b27fc90c86f1b48bb1fb2c528c2761475e57c9c06de13311c7b54ed", size = 428940, upload-time = "2025-04-15T09:18:47.731Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/96/06e01a7b38dce6fe1db213e061a4602dd6032a8a97ef6c1a862537732421/prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855", size = 434198, upload-time = "2025-08-27T15:24:02.057Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ce/4f/5249960887b1fbe561d9ff265496d170b55a735b76724f10ef19f9e40716/prompt_toolkit-3.0.51-py3-none-any.whl", hash = "sha256:52742911fde84e2d423e2f9a4cf1de7d7ac4e51958f648d9540e0fb8db077b07", size = 387810, upload-time = "2025-04-15T09:18:44.753Z" }, + { url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431, upload-time = "2025-08-27T15:23:59.498Z" }, ] [[package]] name = "propcache" -version = "0.3.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/07/c8/fdc6686a986feae3541ea23dcaa661bd93972d3940460646c6bb96e21c40/propcache-0.3.1.tar.gz", hash = "sha256:40d980c33765359098837527e18eddefc9a24cea5b45e078a7f3bb5b032c6ecf", size = 43651, upload-time = "2025-03-26T03:06:12.05Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/41/aa/ca78d9be314d1e15ff517b992bebbed3bdfef5b8919e85bf4940e57b6137/propcache-0.3.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f78eb8422acc93d7b69964012ad7048764bb45a54ba7a39bb9e146c72ea29723", size = 80430, upload-time = "2025-03-26T03:04:26.436Z" }, - { url = "https://files.pythonhosted.org/packages/1a/d8/f0c17c44d1cda0ad1979af2e593ea290defdde9eaeb89b08abbe02a5e8e1/propcache-0.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:89498dd49c2f9a026ee057965cdf8192e5ae070ce7d7a7bd4b66a8e257d0c976", size = 46637, upload-time = "2025-03-26T03:04:27.932Z" }, - { url = "https://files.pythonhosted.org/packages/ae/bd/c1e37265910752e6e5e8a4c1605d0129e5b7933c3dc3cf1b9b48ed83b364/propcache-0.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:09400e98545c998d57d10035ff623266927cb784d13dd2b31fd33b8a5316b85b", size = 46123, upload-time = "2025-03-26T03:04:30.659Z" }, - { url = "https://files.pythonhosted.org/packages/d4/b0/911eda0865f90c0c7e9f0415d40a5bf681204da5fd7ca089361a64c16b28/propcache-0.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa8efd8c5adc5a2c9d3b952815ff8f7710cefdcaf5f2c36d26aff51aeca2f12f", size = 243031, upload-time = "2025-03-26T03:04:31.977Z" }, - { url = "https://files.pythonhosted.org/packages/0a/06/0da53397c76a74271621807265b6eb61fb011451b1ddebf43213df763669/propcache-0.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2fe5c910f6007e716a06d269608d307b4f36e7babee5f36533722660e8c4a70", size = 249100, upload-time = "2025-03-26T03:04:33.45Z" }, - { url = "https://files.pythonhosted.org/packages/f1/eb/13090e05bf6b963fc1653cdc922133ced467cb4b8dab53158db5a37aa21e/propcache-0.3.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a0ab8cf8cdd2194f8ff979a43ab43049b1df0b37aa64ab7eca04ac14429baeb7", size = 250170, upload-time = "2025-03-26T03:04:35.542Z" }, - { url = "https://files.pythonhosted.org/packages/3b/4c/f72c9e1022b3b043ec7dc475a0f405d4c3e10b9b1d378a7330fecf0652da/propcache-0.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:563f9d8c03ad645597b8d010ef4e9eab359faeb11a0a2ac9f7b4bc8c28ebef25", size = 245000, upload-time = "2025-03-26T03:04:37.501Z" }, - { url = "https://files.pythonhosted.org/packages/e8/fd/970ca0e22acc829f1adf5de3724085e778c1ad8a75bec010049502cb3a86/propcache-0.3.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb6e0faf8cb6b4beea5d6ed7b5a578254c6d7df54c36ccd3d8b3eb00d6770277", size = 230262, upload-time = "2025-03-26T03:04:39.532Z" }, - { url = "https://files.pythonhosted.org/packages/c4/42/817289120c6b9194a44f6c3e6b2c3277c5b70bbad39e7df648f177cc3634/propcache-0.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1c5c7ab7f2bb3f573d1cb921993006ba2d39e8621019dffb1c5bc94cdbae81e8", size = 236772, upload-time = "2025-03-26T03:04:41.109Z" }, - { url = "https://files.pythonhosted.org/packages/7c/9c/3b3942b302badd589ad6b672da3ca7b660a6c2f505cafd058133ddc73918/propcache-0.3.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:050b571b2e96ec942898f8eb46ea4bfbb19bd5502424747e83badc2d4a99a44e", size = 231133, upload-time = "2025-03-26T03:04:42.544Z" }, - { url = "https://files.pythonhosted.org/packages/98/a1/75f6355f9ad039108ff000dfc2e19962c8dea0430da9a1428e7975cf24b2/propcache-0.3.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e1c4d24b804b3a87e9350f79e2371a705a188d292fd310e663483af6ee6718ee", size = 230741, upload-time = "2025-03-26T03:04:44.06Z" }, - { url = "https://files.pythonhosted.org/packages/67/0c/3e82563af77d1f8731132166da69fdfd95e71210e31f18edce08a1eb11ea/propcache-0.3.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e4fe2a6d5ce975c117a6bb1e8ccda772d1e7029c1cca1acd209f91d30fa72815", size = 244047, upload-time = "2025-03-26T03:04:45.983Z" }, - { url = "https://files.pythonhosted.org/packages/f7/50/9fb7cca01532a08c4d5186d7bb2da6c4c587825c0ae134b89b47c7d62628/propcache-0.3.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:feccd282de1f6322f56f6845bf1207a537227812f0a9bf5571df52bb418d79d5", size = 246467, upload-time = "2025-03-26T03:04:47.699Z" }, - { url = "https://files.pythonhosted.org/packages/a9/02/ccbcf3e1c604c16cc525309161d57412c23cf2351523aedbb280eb7c9094/propcache-0.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ec314cde7314d2dd0510c6787326bbffcbdc317ecee6b7401ce218b3099075a7", size = 241022, upload-time = "2025-03-26T03:04:49.195Z" }, - { url = "https://files.pythonhosted.org/packages/db/19/e777227545e09ca1e77a6e21274ae9ec45de0f589f0ce3eca2a41f366220/propcache-0.3.1-cp312-cp312-win32.whl", hash = "sha256:7d2d5a0028d920738372630870e7d9644ce437142197f8c827194fca404bf03b", size = 40647, upload-time = "2025-03-26T03:04:50.595Z" }, - { url = "https://files.pythonhosted.org/packages/24/bb/3b1b01da5dd04c77a204c84e538ff11f624e31431cfde7201d9110b092b1/propcache-0.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:88c423efef9d7a59dae0614eaed718449c09a5ac79a5f224a8b9664d603f04a3", size = 44784, upload-time = "2025-03-26T03:04:51.791Z" }, - { url = "https://files.pythonhosted.org/packages/b8/d3/c3cb8f1d6ae3b37f83e1de806713a9b3642c5895f0215a62e1a4bd6e5e34/propcache-0.3.1-py3-none-any.whl", hash = "sha256:9a8ecf38de50a7f518c21568c80f985e776397b902f1ce0b01f799aba1608b40", size = 12376, upload-time = "2025-03-26T03:06:10.5Z" }, +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9e/da/e9fc233cf63743258bff22b3dfa7ea5baef7b5bc324af47a0ad89b8ffc6f/propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", size = 46442, upload-time = "2025-10-08T19:49:02.291Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/0f/f17b1b2b221d5ca28b4b876e8bb046ac40466513960646bda8e1853cdfa2/propcache-0.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2", size = 80061, upload-time = "2025-10-08T19:46:46.075Z" }, + { url = "https://files.pythonhosted.org/packages/76/47/8ccf75935f51448ba9a16a71b783eb7ef6b9ee60f5d14c7f8a8a79fbeed7/propcache-0.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403", size = 46037, upload-time = "2025-10-08T19:46:47.23Z" }, + { url = "https://files.pythonhosted.org/packages/0a/b6/5c9a0e42df4d00bfb4a3cbbe5cf9f54260300c88a0e9af1f47ca5ce17ac0/propcache-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207", size = 47324, upload-time = "2025-10-08T19:46:48.384Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d3/6c7ee328b39a81ee877c962469f1e795f9db87f925251efeb0545e0020d0/propcache-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72", size = 225505, upload-time = "2025-10-08T19:46:50.055Z" }, + { url = "https://files.pythonhosted.org/packages/01/5d/1c53f4563490b1d06a684742cc6076ef944bc6457df6051b7d1a877c057b/propcache-0.4.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367", size = 230242, upload-time = "2025-10-08T19:46:51.815Z" }, + { url = "https://files.pythonhosted.org/packages/20/e1/ce4620633b0e2422207c3cb774a0ee61cac13abc6217763a7b9e2e3f4a12/propcache-0.4.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4", size = 238474, upload-time = "2025-10-08T19:46:53.208Z" }, + { url = "https://files.pythonhosted.org/packages/46/4b/3aae6835b8e5f44ea6a68348ad90f78134047b503765087be2f9912140ea/propcache-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf", size = 221575, upload-time = "2025-10-08T19:46:54.511Z" }, + { url = "https://files.pythonhosted.org/packages/6e/a5/8a5e8678bcc9d3a1a15b9a29165640d64762d424a16af543f00629c87338/propcache-0.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3", size = 216736, upload-time = "2025-10-08T19:46:56.212Z" }, + { url = "https://files.pythonhosted.org/packages/f1/63/b7b215eddeac83ca1c6b934f89d09a625aa9ee4ba158338854c87210cc36/propcache-0.4.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778", size = 213019, upload-time = "2025-10-08T19:46:57.595Z" }, + { url = "https://files.pythonhosted.org/packages/57/74/f580099a58c8af587cac7ba19ee7cb418506342fbbe2d4a4401661cca886/propcache-0.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6", size = 220376, upload-time = "2025-10-08T19:46:59.067Z" }, + { url = "https://files.pythonhosted.org/packages/c4/ee/542f1313aff7eaf19c2bb758c5d0560d2683dac001a1c96d0774af799843/propcache-0.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9", size = 226988, upload-time = "2025-10-08T19:47:00.544Z" }, + { url = "https://files.pythonhosted.org/packages/8f/18/9c6b015dd9c6930f6ce2229e1f02fb35298b847f2087ea2b436a5bfa7287/propcache-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75", size = 215615, upload-time = "2025-10-08T19:47:01.968Z" }, + { url = "https://files.pythonhosted.org/packages/80/9e/e7b85720b98c45a45e1fca6a177024934dc9bc5f4d5dd04207f216fc33ed/propcache-0.4.1-cp312-cp312-win32.whl", hash = "sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8", size = 38066, upload-time = "2025-10-08T19:47:03.503Z" }, + { url = "https://files.pythonhosted.org/packages/54/09/d19cff2a5aaac632ec8fc03737b223597b1e347416934c1b3a7df079784c/propcache-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db", size = 41655, upload-time = "2025-10-08T19:47:04.973Z" }, + { url = "https://files.pythonhosted.org/packages/68/ab/6b5c191bb5de08036a8c697b265d4ca76148efb10fa162f14af14fb5f076/propcache-0.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1", size = 37789, upload-time = "2025-10-08T19:47:06.077Z" }, + { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" }, ] [[package]] name = "protobuf" -version = "6.31.1" +version = "6.33.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/52/f3/b9655a711b32c19720253f6f06326faf90580834e2e83f840472d752bc8b/protobuf-6.31.1.tar.gz", hash = "sha256:d8cac4c982f0b957a4dc73a80e2ea24fab08e679c0de9deb835f4a12d69aca9a", size = 441797, upload-time = "2025-05-28T19:25:54.947Z" } +sdist = { url = "https://files.pythonhosted.org/packages/19/ff/64a6c8f420818bb873713988ca5492cba3a7946be57e027ac63495157d97/protobuf-6.33.0.tar.gz", hash = "sha256:140303d5c8d2037730c548f8c7b93b20bb1dc301be280c378b82b8894589c954", size = 443463, upload-time = "2025-10-15T20:39:52.159Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f3/6f/6ab8e4bf962fd5570d3deaa2d5c38f0a363f57b4501047b5ebeb83ab1125/protobuf-6.31.1-cp310-abi3-win32.whl", hash = "sha256:7fa17d5a29c2e04b7d90e5e32388b8bfd0e7107cd8e616feef7ed3fa6bdab5c9", size = 423603, upload-time = "2025-05-28T19:25:41.198Z" }, - { url = "https://files.pythonhosted.org/packages/44/3a/b15c4347dd4bf3a1b0ee882f384623e2063bb5cf9fa9d57990a4f7df2fb6/protobuf-6.31.1-cp310-abi3-win_amd64.whl", hash = "sha256:426f59d2964864a1a366254fa703b8632dcec0790d8862d30034d8245e1cd447", size = 435283, upload-time = "2025-05-28T19:25:44.275Z" }, - { url = "https://files.pythonhosted.org/packages/6a/c9/b9689a2a250264a84e66c46d8862ba788ee7a641cdca39bccf64f59284b7/protobuf-6.31.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:6f1227473dc43d44ed644425268eb7c2e488ae245d51c6866d19fe158e207402", size = 425604, upload-time = "2025-05-28T19:25:45.702Z" }, - { url = "https://files.pythonhosted.org/packages/76/a1/7a5a94032c83375e4fe7e7f56e3976ea6ac90c5e85fac8576409e25c39c3/protobuf-6.31.1-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:a40fc12b84c154884d7d4c4ebd675d5b3b5283e155f324049ae396b95ddebc39", size = 322115, upload-time = "2025-05-28T19:25:47.128Z" }, - { url = "https://files.pythonhosted.org/packages/fa/b1/b59d405d64d31999244643d88c45c8241c58f17cc887e73bcb90602327f8/protobuf-6.31.1-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:4ee898bf66f7a8b0bd21bce523814e6fbd8c6add948045ce958b73af7e8878c6", size = 321070, upload-time = "2025-05-28T19:25:50.036Z" }, - { url = "https://files.pythonhosted.org/packages/f7/af/ab3c51ab7507a7325e98ffe691d9495ee3d3aa5f589afad65ec920d39821/protobuf-6.31.1-py3-none-any.whl", hash = "sha256:720a6c7e6b77288b85063569baae8536671b39f15cc22037ec7045658d80489e", size = 168724, upload-time = "2025-05-28T19:25:53.926Z" }, + { url = "https://files.pythonhosted.org/packages/7e/ee/52b3fa8feb6db4a833dfea4943e175ce645144532e8a90f72571ad85df4e/protobuf-6.33.0-cp310-abi3-win32.whl", hash = "sha256:d6101ded078042a8f17959eccd9236fb7a9ca20d3b0098bbcb91533a5680d035", size = 425593, upload-time = "2025-10-15T20:39:40.29Z" }, + { url = "https://files.pythonhosted.org/packages/7b/c6/7a465f1825872c55e0341ff4a80198743f73b69ce5d43ab18043699d1d81/protobuf-6.33.0-cp310-abi3-win_amd64.whl", hash = "sha256:9a031d10f703f03768f2743a1c403af050b6ae1f3480e9c140f39c45f81b13ee", size = 436882, upload-time = "2025-10-15T20:39:42.841Z" }, + { url = "https://files.pythonhosted.org/packages/e1/a9/b6eee662a6951b9c3640e8e452ab3e09f117d99fc10baa32d1581a0d4099/protobuf-6.33.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:905b07a65f1a4b72412314082c7dbfae91a9e8b68a0cc1577515f8df58ecf455", size = 427521, upload-time = "2025-10-15T20:39:43.803Z" }, + { url = "https://files.pythonhosted.org/packages/10/35/16d31e0f92c6d2f0e77c2a3ba93185130ea13053dd16200a57434c882f2b/protobuf-6.33.0-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:e0697ece353e6239b90ee43a9231318302ad8353c70e6e45499fa52396debf90", size = 324445, upload-time = "2025-10-15T20:39:44.932Z" }, + { url = "https://files.pythonhosted.org/packages/e6/eb/2a981a13e35cda8b75b5585aaffae2eb904f8f351bdd3870769692acbd8a/protobuf-6.33.0-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:e0a1715e4f27355afd9570f3ea369735afc853a6c3951a6afe1f80d8569ad298", size = 339159, upload-time = "2025-10-15T20:39:46.186Z" }, + { url = "https://files.pythonhosted.org/packages/21/51/0b1cbad62074439b867b4e04cc09b93f6699d78fd191bed2bbb44562e077/protobuf-6.33.0-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:35be49fd3f4fefa4e6e2aacc35e8b837d6703c37a2168a55ac21e9b1bc7559ef", size = 323172, upload-time = "2025-10-15T20:39:47.465Z" }, + { url = "https://files.pythonhosted.org/packages/07/d1/0a28c21707807c6aacd5dc9c3704b2aa1effbf37adebd8caeaf68b17a636/protobuf-6.33.0-py3-none-any.whl", hash = "sha256:25c9e1963c6734448ea2d308cfa610e692b801304ba0908d7bfa564ac5132995", size = 170477, upload-time = "2025-10-15T20:39:51.311Z" }, ] [[package]] name = "psutil" -version = "7.0.0" +version = "7.1.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2a/80/336820c1ad9286a4ded7e845b2eccfcb27851ab8ac6abece774a6ff4d3de/psutil-7.0.0.tar.gz", hash = "sha256:7be9c3eba38beccb6495ea33afd982a44074b78f28c434a1f51cc07fd315c456", size = 497003, upload-time = "2025-02-13T21:54:07.946Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e1/88/bdd0a41e5857d5d703287598cbf08dad90aed56774ea52ae071bae9071b6/psutil-7.1.3.tar.gz", hash = "sha256:6c86281738d77335af7aec228328e944b30930899ea760ecf33a4dba66be5e74", size = 489059, upload-time = "2025-11-02T12:25:54.619Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ed/e6/2d26234410f8b8abdbf891c9da62bee396583f713fb9f3325a4760875d22/psutil-7.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:101d71dc322e3cffd7cea0650b09b3d08b8e7c4109dd6809fe452dfd00e58b25", size = 238051, upload-time = "2025-02-13T21:54:12.36Z" }, - { url = "https://files.pythonhosted.org/packages/04/8b/30f930733afe425e3cbfc0e1468a30a18942350c1a8816acfade80c005c4/psutil-7.0.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:39db632f6bb862eeccf56660871433e111b6ea58f2caea825571951d4b6aa3da", size = 239535, upload-time = "2025-02-13T21:54:16.07Z" }, - { url = "https://files.pythonhosted.org/packages/2a/ed/d362e84620dd22876b55389248e522338ed1bf134a5edd3b8231d7207f6d/psutil-7.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fcee592b4c6f146991ca55919ea3d1f8926497a713ed7faaf8225e174581e91", size = 275004, upload-time = "2025-02-13T21:54:18.662Z" }, - { url = "https://files.pythonhosted.org/packages/bf/b9/b0eb3f3cbcb734d930fdf839431606844a825b23eaf9a6ab371edac8162c/psutil-7.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b1388a4f6875d7e2aff5c4ca1cc16c545ed41dd8bb596cefea80111db353a34", size = 277986, upload-time = "2025-02-13T21:54:21.811Z" }, - { url = "https://files.pythonhosted.org/packages/eb/a2/709e0fe2f093556c17fbafda93ac032257242cabcc7ff3369e2cb76a97aa/psutil-7.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5f098451abc2828f7dc6b58d44b532b22f2088f4999a937557b603ce72b1993", size = 279544, upload-time = "2025-02-13T21:54:24.68Z" }, - { url = "https://files.pythonhosted.org/packages/50/e6/eecf58810b9d12e6427369784efe814a1eec0f492084ce8eb8f4d89d6d61/psutil-7.0.0-cp37-abi3-win32.whl", hash = "sha256:ba3fcef7523064a6c9da440fc4d6bd07da93ac726b5733c29027d7dc95b39d99", size = 241053, upload-time = "2025-02-13T21:54:34.31Z" }, - { url = "https://files.pythonhosted.org/packages/50/1b/6921afe68c74868b4c9fa424dad3be35b095e16687989ebbb50ce4fceb7c/psutil-7.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:4cf3d4eb1aa9b348dec30105c55cd9b7d4629285735a102beb4441e38db90553", size = 244885, upload-time = "2025-02-13T21:54:37.486Z" }, + { url = "https://files.pythonhosted.org/packages/ef/94/46b9154a800253e7ecff5aaacdf8ebf43db99de4a2dfa18575b02548654e/psutil-7.1.3-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2bdbcd0e58ca14996a42adf3621a6244f1bb2e2e528886959c72cf1e326677ab", size = 238359, upload-time = "2025-11-02T12:26:25.284Z" }, + { url = "https://files.pythonhosted.org/packages/68/3a/9f93cff5c025029a36d9a92fef47220ab4692ee7f2be0fba9f92813d0cb8/psutil-7.1.3-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:bc31fa00f1fbc3c3802141eede66f3a2d51d89716a194bf2cd6fc68310a19880", size = 239171, upload-time = "2025-11-02T12:26:27.23Z" }, + { url = "https://files.pythonhosted.org/packages/ce/b1/5f49af514f76431ba4eea935b8ad3725cdeb397e9245ab919dbc1d1dc20f/psutil-7.1.3-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3bb428f9f05c1225a558f53e30ccbad9930b11c3fc206836242de1091d3e7dd3", size = 263261, upload-time = "2025-11-02T12:26:29.48Z" }, + { url = "https://files.pythonhosted.org/packages/e0/95/992c8816a74016eb095e73585d747e0a8ea21a061ed3689474fabb29a395/psutil-7.1.3-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:56d974e02ca2c8eb4812c3f76c30e28836fffc311d55d979f1465c1feeb2b68b", size = 264635, upload-time = "2025-11-02T12:26:31.74Z" }, + { url = "https://files.pythonhosted.org/packages/55/4c/c3ed1a622b6ae2fd3c945a366e64eb35247a31e4db16cf5095e269e8eb3c/psutil-7.1.3-cp37-abi3-win_amd64.whl", hash = "sha256:f39c2c19fe824b47484b96f9692932248a54c43799a84282cfe58d05a6449efd", size = 247633, upload-time = "2025-11-02T12:26:33.887Z" }, + { url = "https://files.pythonhosted.org/packages/c9/ad/33b2ccec09bf96c2b2ef3f9a6f66baac8253d7565d8839e024a6b905d45d/psutil-7.1.3-cp37-abi3-win_arm64.whl", hash = "sha256:bd0d69cee829226a761e92f28140bec9a5ee9d5b4fb4b0cc589068dbfff559b1", size = 244608, upload-time = "2025-11-02T12:26:36.136Z" }, ] [[package]] @@ -1684,33 +1785,31 @@ wheels = [ [[package]] name = "pyarrow" -version = "20.0.0" +version = "22.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/ee/a7810cb9f3d6e9238e61d312076a9859bf3668fd21c69744de9532383912/pyarrow-20.0.0.tar.gz", hash = "sha256:febc4a913592573c8d5805091a6c2b5064c8bd6e002131f01061797d91c783c1", size = 1125187, upload-time = "2025-04-27T12:34:23.264Z" } +sdist = { url = "https://files.pythonhosted.org/packages/30/53/04a7fdc63e6056116c9ddc8b43bc28c12cdd181b85cbeadb79278475f3ae/pyarrow-22.0.0.tar.gz", hash = "sha256:3d600dc583260d845c7d8a6db540339dd883081925da2bd1c5cb808f720b3cd9", size = 1151151, upload-time = "2025-10-24T12:30:00.762Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a1/d6/0c10e0d54f6c13eb464ee9b67a68b8c71bcf2f67760ef5b6fbcddd2ab05f/pyarrow-20.0.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:75a51a5b0eef32727a247707d4755322cb970be7e935172b6a3a9f9ae98404ba", size = 30815067, upload-time = "2025-04-27T12:29:44.384Z" }, - { url = "https://files.pythonhosted.org/packages/7e/e2/04e9874abe4094a06fd8b0cbb0f1312d8dd7d707f144c2ec1e5e8f452ffa/pyarrow-20.0.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:211d5e84cecc640c7a3ab900f930aaff5cd2702177e0d562d426fb7c4f737781", size = 32297128, upload-time = "2025-04-27T12:29:52.038Z" }, - { url = "https://files.pythonhosted.org/packages/31/fd/c565e5dcc906a3b471a83273039cb75cb79aad4a2d4a12f76cc5ae90a4b8/pyarrow-20.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ba3cf4182828be7a896cbd232aa8dd6a31bd1f9e32776cc3796c012855e1199", size = 41334890, upload-time = "2025-04-27T12:29:59.452Z" }, - { url = "https://files.pythonhosted.org/packages/af/a9/3bdd799e2c9b20c1ea6dc6fa8e83f29480a97711cf806e823f808c2316ac/pyarrow-20.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c3a01f313ffe27ac4126f4c2e5ea0f36a5fc6ab51f8726cf41fee4b256680bd", size = 42421775, upload-time = "2025-04-27T12:30:06.875Z" }, - { url = "https://files.pythonhosted.org/packages/10/f7/da98ccd86354c332f593218101ae56568d5dcedb460e342000bd89c49cc1/pyarrow-20.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:a2791f69ad72addd33510fec7bb14ee06c2a448e06b649e264c094c5b5f7ce28", size = 40687231, upload-time = "2025-04-27T12:30:13.954Z" }, - { url = "https://files.pythonhosted.org/packages/bb/1b/2168d6050e52ff1e6cefc61d600723870bf569cbf41d13db939c8cf97a16/pyarrow-20.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:4250e28a22302ce8692d3a0e8ec9d9dde54ec00d237cff4dfa9c1fbf79e472a8", size = 42295639, upload-time = "2025-04-27T12:30:21.949Z" }, - { url = "https://files.pythonhosted.org/packages/b2/66/2d976c0c7158fd25591c8ca55aee026e6d5745a021915a1835578707feb3/pyarrow-20.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:89e030dc58fc760e4010148e6ff164d2f44441490280ef1e97a542375e41058e", size = 42908549, upload-time = "2025-04-27T12:30:29.551Z" }, - { url = "https://files.pythonhosted.org/packages/31/a9/dfb999c2fc6911201dcbf348247f9cc382a8990f9ab45c12eabfd7243a38/pyarrow-20.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6102b4864d77102dbbb72965618e204e550135a940c2534711d5ffa787df2a5a", size = 44557216, upload-time = "2025-04-27T12:30:36.977Z" }, - { url = "https://files.pythonhosted.org/packages/a0/8e/9adee63dfa3911be2382fb4d92e4b2e7d82610f9d9f668493bebaa2af50f/pyarrow-20.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:96d6a0a37d9c98be08f5ed6a10831d88d52cac7b13f5287f1e0f625a0de8062b", size = 25660496, upload-time = "2025-04-27T12:30:42.809Z" }, + { url = "https://files.pythonhosted.org/packages/af/63/ba23862d69652f85b615ca14ad14f3bcfc5bf1b99ef3f0cd04ff93fdad5a/pyarrow-22.0.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:bea79263d55c24a32b0d79c00a1c58bb2ee5f0757ed95656b01c0fb310c5af3d", size = 34211578, upload-time = "2025-10-24T10:05:21.583Z" }, + { url = "https://files.pythonhosted.org/packages/b1/d0/f9ad86fe809efd2bcc8be32032fa72e8b0d112b01ae56a053006376c5930/pyarrow-22.0.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:12fe549c9b10ac98c91cf791d2945e878875d95508e1a5d14091a7aaa66d9cf8", size = 35989906, upload-time = "2025-10-24T10:05:29.485Z" }, + { url = "https://files.pythonhosted.org/packages/b4/a8/f910afcb14630e64d673f15904ec27dd31f1e009b77033c365c84e8c1e1d/pyarrow-22.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:334f900ff08ce0423407af97e6c26ad5d4e3b0763645559ece6fbf3747d6a8f5", size = 45021677, upload-time = "2025-10-24T10:05:38.274Z" }, + { url = "https://files.pythonhosted.org/packages/13/95/aec81f781c75cd10554dc17a25849c720d54feafb6f7847690478dcf5ef8/pyarrow-22.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:c6c791b09c57ed76a18b03f2631753a4960eefbbca80f846da8baefc6491fcfe", size = 47726315, upload-time = "2025-10-24T10:05:47.314Z" }, + { url = "https://files.pythonhosted.org/packages/bb/d4/74ac9f7a54cfde12ee42734ea25d5a3c9a45db78f9def949307a92720d37/pyarrow-22.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c3200cb41cdbc65156e5f8c908d739b0dfed57e890329413da2748d1a2cd1a4e", size = 47990906, upload-time = "2025-10-24T10:05:58.254Z" }, + { url = "https://files.pythonhosted.org/packages/2e/71/fedf2499bf7a95062eafc989ace56572f3343432570e1c54e6599d5b88da/pyarrow-22.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ac93252226cf288753d8b46280f4edf3433bf9508b6977f8dd8526b521a1bbb9", size = 50306783, upload-time = "2025-10-24T10:06:08.08Z" }, + { url = "https://files.pythonhosted.org/packages/68/ed/b202abd5a5b78f519722f3d29063dda03c114711093c1995a33b8e2e0f4b/pyarrow-22.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:44729980b6c50a5f2bfcc2668d36c569ce17f8b17bccaf470c4313dcbbf13c9d", size = 27972883, upload-time = "2025-10-24T10:06:14.204Z" }, ] [[package]] name = "pycparser" -version = "2.22" +version = "2.23" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736, upload-time = "2024-03-30T13:22:22.564Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size = 173734, upload-time = "2025-09-09T13:23:47.91Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552, upload-time = "2024-03-30T13:22:20.476Z" }, + { url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140, upload-time = "2025-09-09T13:23:46.651Z" }, ] [[package]] name = "pydantic" -version = "2.11.5" +version = "2.12.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -1718,48 +1817,52 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f0/86/8ce9040065e8f924d642c58e4a344e33163a07f6b57f836d0d734e0ad3fb/pydantic-2.11.5.tar.gz", hash = "sha256:7f853db3d0ce78ce8bbb148c401c2cdd6431b3473c0cdff2755c7690952a7b7a", size = 787102, upload-time = "2025-05-22T21:18:08.761Z" } +sdist = { url = "https://files.pythonhosted.org/packages/96/ad/a17bc283d7d81837c061c49e3eaa27a45991759a1b7eae1031921c6bd924/pydantic-2.12.4.tar.gz", hash = "sha256:0f8cb9555000a4b5b617f66bfd2566264c4984b27589d3b845685983e8ea85ac", size = 821038, upload-time = "2025-11-05T10:50:08.59Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b5/69/831ed22b38ff9b4b64b66569f0e5b7b97cf3638346eb95a2147fdb49ad5f/pydantic-2.11.5-py3-none-any.whl", hash = "sha256:f9c26ba06f9747749ca1e5c94d6a85cb84254577553c8785576fd38fa64dc0f7", size = 444229, upload-time = "2025-05-22T21:18:06.329Z" }, + { url = "https://files.pythonhosted.org/packages/82/2f/e68750da9b04856e2a7ec56fc6f034a5a79775e9b9a81882252789873798/pydantic-2.12.4-py3-none-any.whl", hash = "sha256:92d3d202a745d46f9be6df459ac5a064fdaa3c1c4cd8adcfa332ccf3c05f871e", size = 463400, upload-time = "2025-11-05T10:50:06.732Z" }, ] [[package]] name = "pydantic-core" -version = "2.33.2" +version = "2.41.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195, upload-time = "2025-04-23T18:33:52.104Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/18/8a/2b41c97f554ec8c71f2a8a5f85cb56a8b0956addfe8b0efb5b3d77e8bdc3/pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc", size = 2009000, upload-time = "2025-04-23T18:31:25.863Z" }, - { url = "https://files.pythonhosted.org/packages/a1/02/6224312aacb3c8ecbaa959897af57181fb6cf3a3d7917fd44d0f2917e6f2/pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7", size = 1847996, upload-time = "2025-04-23T18:31:27.341Z" }, - { url = "https://files.pythonhosted.org/packages/d6/46/6dcdf084a523dbe0a0be59d054734b86a981726f221f4562aed313dbcb49/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025", size = 1880957, upload-time = "2025-04-23T18:31:28.956Z" }, - { url = "https://files.pythonhosted.org/packages/ec/6b/1ec2c03837ac00886ba8160ce041ce4e325b41d06a034adbef11339ae422/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011", size = 1964199, upload-time = "2025-04-23T18:31:31.025Z" }, - { url = "https://files.pythonhosted.org/packages/2d/1d/6bf34d6adb9debd9136bd197ca72642203ce9aaaa85cfcbfcf20f9696e83/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f", size = 2120296, upload-time = "2025-04-23T18:31:32.514Z" }, - { url = "https://files.pythonhosted.org/packages/e0/94/2bd0aaf5a591e974b32a9f7123f16637776c304471a0ab33cf263cf5591a/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88", size = 2676109, upload-time = "2025-04-23T18:31:33.958Z" }, - { url = "https://files.pythonhosted.org/packages/f9/41/4b043778cf9c4285d59742281a769eac371b9e47e35f98ad321349cc5d61/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1", size = 2002028, upload-time = "2025-04-23T18:31:39.095Z" }, - { url = "https://files.pythonhosted.org/packages/cb/d5/7bb781bf2748ce3d03af04d5c969fa1308880e1dca35a9bd94e1a96a922e/pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b", size = 2100044, upload-time = "2025-04-23T18:31:41.034Z" }, - { url = "https://files.pythonhosted.org/packages/fe/36/def5e53e1eb0ad896785702a5bbfd25eed546cdcf4087ad285021a90ed53/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1", size = 2058881, upload-time = "2025-04-23T18:31:42.757Z" }, - { url = "https://files.pythonhosted.org/packages/01/6c/57f8d70b2ee57fc3dc8b9610315949837fa8c11d86927b9bb044f8705419/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6", size = 2227034, upload-time = "2025-04-23T18:31:44.304Z" }, - { url = "https://files.pythonhosted.org/packages/27/b9/9c17f0396a82b3d5cbea4c24d742083422639e7bb1d5bf600e12cb176a13/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea", size = 2234187, upload-time = "2025-04-23T18:31:45.891Z" }, - { url = "https://files.pythonhosted.org/packages/b0/6a/adf5734ffd52bf86d865093ad70b2ce543415e0e356f6cacabbc0d9ad910/pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290", size = 1892628, upload-time = "2025-04-23T18:31:47.819Z" }, - { url = "https://files.pythonhosted.org/packages/43/e4/5479fecb3606c1368d496a825d8411e126133c41224c1e7238be58b87d7e/pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2", size = 1955866, upload-time = "2025-04-23T18:31:49.635Z" }, - { url = "https://files.pythonhosted.org/packages/0d/24/8b11e8b3e2be9dd82df4b11408a67c61bb4dc4f8e11b5b0fc888b38118b5/pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab", size = 1888894, upload-time = "2025-04-23T18:31:51.609Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952, upload-time = "2025-11-04T13:43:49.098Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/5d/5f6c63eebb5afee93bcaae4ce9a898f3373ca23df3ccaef086d0233a35a7/pydantic_core-2.41.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7", size = 2110990, upload-time = "2025-11-04T13:39:58.079Z" }, + { url = "https://files.pythonhosted.org/packages/aa/32/9c2e8ccb57c01111e0fd091f236c7b371c1bccea0fa85247ac55b1e2b6b6/pydantic_core-2.41.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0", size = 1896003, upload-time = "2025-11-04T13:39:59.956Z" }, + { url = "https://files.pythonhosted.org/packages/68/b8/a01b53cb0e59139fbc9e4fda3e9724ede8de279097179be4ff31f1abb65a/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69", size = 1919200, upload-time = "2025-11-04T13:40:02.241Z" }, + { url = "https://files.pythonhosted.org/packages/38/de/8c36b5198a29bdaade07b5985e80a233a5ac27137846f3bc2d3b40a47360/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75", size = 2052578, upload-time = "2025-11-04T13:40:04.401Z" }, + { url = "https://files.pythonhosted.org/packages/00/b5/0e8e4b5b081eac6cb3dbb7e60a65907549a1ce035a724368c330112adfdd/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05", size = 2208504, upload-time = "2025-11-04T13:40:06.072Z" }, + { url = "https://files.pythonhosted.org/packages/77/56/87a61aad59c7c5b9dc8caad5a41a5545cba3810c3e828708b3d7404f6cef/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc", size = 2335816, upload-time = "2025-11-04T13:40:07.835Z" }, + { url = "https://files.pythonhosted.org/packages/0d/76/941cc9f73529988688a665a5c0ecff1112b3d95ab48f81db5f7606f522d3/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c", size = 2075366, upload-time = "2025-11-04T13:40:09.804Z" }, + { url = "https://files.pythonhosted.org/packages/d3/43/ebef01f69baa07a482844faaa0a591bad1ef129253ffd0cdaa9d8a7f72d3/pydantic_core-2.41.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5", size = 2171698, upload-time = "2025-11-04T13:40:12.004Z" }, + { url = "https://files.pythonhosted.org/packages/b1/87/41f3202e4193e3bacfc2c065fab7706ebe81af46a83d3e27605029c1f5a6/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c", size = 2132603, upload-time = "2025-11-04T13:40:13.868Z" }, + { url = "https://files.pythonhosted.org/packages/49/7d/4c00df99cb12070b6bccdef4a195255e6020a550d572768d92cc54dba91a/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294", size = 2329591, upload-time = "2025-11-04T13:40:15.672Z" }, + { url = "https://files.pythonhosted.org/packages/cc/6a/ebf4b1d65d458f3cda6a7335d141305dfa19bdc61140a884d165a8a1bbc7/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1", size = 2319068, upload-time = "2025-11-04T13:40:17.532Z" }, + { url = "https://files.pythonhosted.org/packages/49/3b/774f2b5cd4192d5ab75870ce4381fd89cf218af999515baf07e7206753f0/pydantic_core-2.41.5-cp312-cp312-win32.whl", hash = "sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d", size = 1985908, upload-time = "2025-11-04T13:40:19.309Z" }, + { url = "https://files.pythonhosted.org/packages/86/45/00173a033c801cacf67c190fef088789394feaf88a98a7035b0e40d53dc9/pydantic_core-2.41.5-cp312-cp312-win_amd64.whl", hash = "sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815", size = 2020145, upload-time = "2025-11-04T13:40:21.548Z" }, + { url = "https://files.pythonhosted.org/packages/f9/22/91fbc821fa6d261b376a3f73809f907cec5ca6025642c463d3488aad22fb/pydantic_core-2.41.5-cp312-cp312-win_arm64.whl", hash = "sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3", size = 1976179, upload-time = "2025-11-04T13:40:23.393Z" }, + { url = "https://files.pythonhosted.org/packages/09/32/59b0c7e63e277fa7911c2fc70ccfb45ce4b98991e7ef37110663437005af/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd", size = 2110495, upload-time = "2025-11-04T13:42:49.689Z" }, + { url = "https://files.pythonhosted.org/packages/aa/81/05e400037eaf55ad400bcd318c05bb345b57e708887f07ddb2d20e3f0e98/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc", size = 1915388, upload-time = "2025-11-04T13:42:52.215Z" }, + { url = "https://files.pythonhosted.org/packages/6e/0d/e3549b2399f71d56476b77dbf3cf8937cec5cd70536bdc0e374a421d0599/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56", size = 1942879, upload-time = "2025-11-04T13:42:56.483Z" }, + { url = "https://files.pythonhosted.org/packages/f7/07/34573da085946b6a313d7c42f82f16e8920bfd730665de2d11c0c37a74b5/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b", size = 2139017, upload-time = "2025-11-04T13:42:59.471Z" }, ] [[package]] name = "pygments" -version = "2.19.1" +version = "2.19.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581, upload-time = "2025-01-06T17:26:30.443Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293, upload-time = "2025-01-06T17:26:25.553Z" }, + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, ] [[package]] name = "pytest" -version = "8.4.1" +version = "8.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -1768,9 +1871,9 @@ dependencies = [ { name = "pluggy" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, + { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" }, ] [[package]] @@ -1787,36 +1890,36 @@ wheels = [ [[package]] name = "python-engineio" -version = "4.12.2" +version = "4.12.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "simple-websocket" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ba/0b/67295279b66835f9fa7a491650efcd78b20321c127036eef62c11a31e028/python_engineio-4.12.2.tar.gz", hash = "sha256:e7e712ffe1be1f6a05ee5f951e72d434854a32fcfc7f6e4d9d3cae24ec70defa", size = 91677, upload-time = "2025-06-04T19:22:18.789Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/d8/63e5535ab21dc4998ba1cfe13690ccf122883a38f025dca24d6e56c05eba/python_engineio-4.12.3.tar.gz", hash = "sha256:35633e55ec30915e7fc8f7e34ca8d73ee0c080cec8a8cd04faf2d7396f0a7a7a", size = 91910, upload-time = "2025-09-28T06:31:36.765Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0c/fa/df59acedf7bbb937f69174d00f921a7b93aa5a5f5c17d05296c814fff6fc/python_engineio-4.12.2-py3-none-any.whl", hash = "sha256:8218ab66950e179dfec4b4bbb30aecf3f5d86f5e58e6fc1aa7fde2c698b2804f", size = 59536, upload-time = "2025-06-04T19:22:16.916Z" }, + { url = "https://files.pythonhosted.org/packages/d8/f0/c5aa0a69fd9326f013110653543f36ece4913c17921f3e1dbd78e1b423ee/python_engineio-4.12.3-py3-none-any.whl", hash = "sha256:7c099abb2a27ea7ab429c04da86ab2d82698cdd6c52406cb73766fe454feb7e1", size = 59637, upload-time = "2025-09-28T06:31:35.354Z" }, ] [[package]] name = "python-json-logger" -version = "3.3.0" +version = "4.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9e/de/d3144a0bceede957f961e975f3752760fbe390d57fbe194baf709d8f1f7b/python_json_logger-3.3.0.tar.gz", hash = "sha256:12b7e74b17775e7d565129296105bbe3910842d9d0eb083fc83a6a617aa8df84", size = 16642, upload-time = "2025-03-07T07:08:27.301Z" } +sdist = { url = "https://files.pythonhosted.org/packages/29/bf/eca6a3d43db1dae7070f70e160ab20b807627ba953663ba07928cdd3dc58/python_json_logger-4.0.0.tar.gz", hash = "sha256:f58e68eb46e1faed27e0f574a55a0455eecd7b8a5b88b85a784519ba3cff047f", size = 17683, upload-time = "2025-10-06T04:15:18.984Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/08/20/0f2523b9e50a8052bc6a8b732dfc8568abbdc42010aef03a2d750bdab3b2/python_json_logger-3.3.0-py3-none-any.whl", hash = "sha256:dd980fae8cffb24c13caf6e158d3d61c0d6d22342f932cb6e9deedab3d35eec7", size = 15163, upload-time = "2025-03-07T07:08:25.627Z" }, + { url = "https://files.pythonhosted.org/packages/51/e5/fecf13f06e5e5f67e8837d777d1bc43fac0ed2b77a676804df5c34744727/python_json_logger-4.0.0-py3-none-any.whl", hash = "sha256:af09c9daf6a813aa4cc7180395f50f2a9e5fa056034c9953aec92e381c5ba1e2", size = 15548, upload-time = "2025-10-06T04:15:17.553Z" }, ] [[package]] name = "python-socketio" -version = "5.13.0" +version = "5.14.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "bidict" }, { name = "python-engineio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/21/1a/396d50ccf06ee539fa758ce5623b59a9cb27637fc4b2dc07ed08bf495e77/python_socketio-5.13.0.tar.gz", hash = "sha256:ac4e19a0302ae812e23b712ec8b6427ca0521f7c582d6abb096e36e24a263029", size = 121125, upload-time = "2025-04-12T15:46:59.933Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c0/3f/02f5970c82285bd015ec433078bfc3275580b03715ed6024607dbe0f1966/python_socketio-5.14.3.tar.gz", hash = "sha256:cd8da5e0666e741b4be19e07882e880f57a4751d1645f92c2bc746c95f23b1eb", size = 124266, upload-time = "2025-10-29T09:42:53.749Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/32/b4fb8585d1be0f68bde7e110dffbcf354915f77ad8c778563f0ad9655c02/python_socketio-5.13.0-py3-none-any.whl", hash = "sha256:51f68d6499f2df8524668c24bcec13ba1414117cfb3a90115c559b601ab10caf", size = 77800, upload-time = "2025-04-12T15:46:58.412Z" }, + { url = "https://files.pythonhosted.org/packages/c0/1a/b393a06aa6f2f6ab4a9c5c160a62d488b17d6da5cf93a67bc13a6e3239cd/python_socketio-5.14.3-py3-none-any.whl", hash = "sha256:a5208c1bbf45a8d6328d01ed67e3fa52ec8b186fd3ea44cfcfcbd120f0c71fbe", size = 79010, upload-time = "2025-10-29T09:42:52.098Z" }, ] [package.optional-dependencies] @@ -1827,7 +1930,7 @@ client = [ [[package]] name = "pytorch-lightning" -version = "2.5.1.post0" +version = "2.5.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "fsspec", extra = ["http"] }, @@ -1839,9 +1942,9 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fe/0c/cfa6223c525f67ea3a7a2907e36e9e9a9653300f82cfd9af88f8136514ab/pytorch_lightning-2.5.1.post0.tar.gz", hash = "sha256:abc3d5a804d41f941b14e3fd7db5572a1270cd1e9889b50e962984c87d498d94", size = 634368, upload-time = "2025-04-25T20:24:29.272Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0a/1f/94a441d30779e1ffa5f7dc2ac5fa374c142d8b96c347a49a30226264124e/pytorch_lightning-2.5.6.tar.gz", hash = "sha256:c428faaceef74be50b870814d0d7e9f9c6ee748b8769a2afd3366bc69daf3a0f", size = 642830, upload-time = "2025-11-05T20:53:04.871Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/de/a9/e14821cfaf08e8d78185cca0477c9d3a62bafe1b4b530100f7b66bb1f7bb/pytorch_lightning-2.5.1.post0-py3-none-any.whl", hash = "sha256:873fb21392c8b79908218f5ca8f65bd835439216e52550c36ff55d849e99c93e", size = 823084, upload-time = "2025-04-25T20:24:27.421Z" }, + { url = "https://files.pythonhosted.org/packages/17/e4/32ed2f33c1b634f7c2895369222f4f8cb345044f4642bbff718e7dd1e0b7/pytorch_lightning-2.5.6-py3-none-any.whl", hash = "sha256:037bad1e2fd94d5eb6c5144f045fd4c1070c3d38fc9c14d9f3774a3a9be54dff", size = 831555, upload-time = "2025-11-05T20:53:03.316Z" }, ] [[package]] @@ -1853,104 +1956,93 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" }, ] -[[package]] -name = "pywin32" -version = "310" -source = { registry = "https://pypi.org/simple" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/ec/4fdbe47932f671d6e348474ea35ed94227fb5df56a7c30cbbb42cd396ed0/pywin32-310-cp312-cp312-win32.whl", hash = "sha256:8a75a5cc3893e83a108c05d82198880704c44bbaee4d06e442e471d3c9ea4f3d", size = 8796239, upload-time = "2025-03-17T00:55:58.807Z" }, - { url = "https://files.pythonhosted.org/packages/e3/e5/b0627f8bb84e06991bea89ad8153a9e50ace40b2e1195d68e9dff6b03d0f/pywin32-310-cp312-cp312-win_amd64.whl", hash = "sha256:bf5c397c9a9a19a6f62f3fb821fbf36cac08f03770056711f765ec1503972060", size = 9503839, upload-time = "2025-03-17T00:56:00.8Z" }, - { url = "https://files.pythonhosted.org/packages/1f/32/9ccf53748df72301a89713936645a664ec001abd35ecc8578beda593d37d/pywin32-310-cp312-cp312-win_arm64.whl", hash = "sha256:2349cc906eae872d0663d4d6290d13b90621eaf78964bb1578632ff20e152966", size = 8459470, upload-time = "2025-03-17T00:56:02.601Z" }, -] - [[package]] name = "pywinpty" -version = "2.0.15" +version = "3.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2d/7c/917f9c4681bb8d34bfbe0b79d36bbcd902651aeab48790df3d30ba0202fb/pywinpty-2.0.15.tar.gz", hash = "sha256:312cf39153a8736c617d45ce8b6ad6cd2107de121df91c455b10ce6bba7a39b2", size = 29017, upload-time = "2025-02-03T21:53:23.265Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/bb/a7cc2967c5c4eceb6cc49cfe39447d4bfc56e6c865e7c2249b6eb978935f/pywinpty-3.0.2.tar.gz", hash = "sha256:1505cc4cb248af42cb6285a65c9c2086ee9e7e574078ee60933d5d7fa86fb004", size = 30669, upload-time = "2025-10-03T21:16:29.205Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/e5/9714def18c3a411809771a3fbcec70bffa764b9675afb00048a620fca604/pywinpty-2.0.15-cp312-cp312-win_amd64.whl", hash = "sha256:83a8f20b430bbc5d8957249f875341a60219a4e971580f2ba694fbfb54a45ebc", size = 1405243, upload-time = "2025-02-03T21:56:52.476Z" }, + { url = "https://files.pythonhosted.org/packages/02/4e/1098484e042c9485f56f16eb2b69b43b874bd526044ee401512234cf9e04/pywinpty-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:99fdd9b455f0ad6419aba6731a7a0d2f88ced83c3c94a80ff9533d95fa8d8a9e", size = 2050391, upload-time = "2025-10-03T21:19:01.642Z" }, ] [[package]] name = "pyyaml" -version = "6.0.2" +version = "6.0.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873, upload-time = "2024-08-06T20:32:25.131Z" }, - { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302, upload-time = "2024-08-06T20:32:26.511Z" }, - { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154, upload-time = "2024-08-06T20:32:28.363Z" }, - { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223, upload-time = "2024-08-06T20:32:30.058Z" }, - { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542, upload-time = "2024-08-06T20:32:31.881Z" }, - { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164, upload-time = "2024-08-06T20:32:37.083Z" }, - { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611, upload-time = "2024-08-06T20:32:38.898Z" }, - { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591, upload-time = "2024-08-06T20:32:40.241Z" }, - { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338, upload-time = "2024-08-06T20:32:41.93Z" }, + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, ] [[package]] name = "pyzmq" -version = "26.4.0" +version = "27.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "implementation_name == 'pypy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b1/11/b9213d25230ac18a71b39b3723494e57adebe36e066397b961657b3b41c1/pyzmq-26.4.0.tar.gz", hash = "sha256:4bd13f85f80962f91a651a7356fe0472791a5f7a92f227822b5acf44795c626d", size = 278293, upload-time = "2025-04-04T12:05:44.049Z" } +sdist = { url = "https://files.pythonhosted.org/packages/04/0b/3c9baedbdf613ecaa7aa07027780b8867f57b6293b6ee50de316c9f3222b/pyzmq-27.1.0.tar.gz", hash = "sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540", size = 281750, upload-time = "2025-09-08T23:10:18.157Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/10/44/a778555ebfdf6c7fc00816aad12d185d10a74d975800341b1bc36bad1187/pyzmq-26.4.0-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:5227cb8da4b6f68acfd48d20c588197fd67745c278827d5238c707daf579227b", size = 1341586, upload-time = "2025-04-04T12:03:41.954Z" }, - { url = "https://files.pythonhosted.org/packages/9c/4f/f3a58dc69ac757e5103be3bd41fb78721a5e17da7cc617ddb56d973a365c/pyzmq-26.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1c07a7fa7f7ba86554a2b1bef198c9fed570c08ee062fd2fd6a4dcacd45f905", size = 665880, upload-time = "2025-04-04T12:03:43.45Z" }, - { url = "https://files.pythonhosted.org/packages/fe/45/50230bcfb3ae5cb98bee683b6edeba1919f2565d7cc1851d3c38e2260795/pyzmq-26.4.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae775fa83f52f52de73183f7ef5395186f7105d5ed65b1ae65ba27cb1260de2b", size = 902216, upload-time = "2025-04-04T12:03:45.572Z" }, - { url = "https://files.pythonhosted.org/packages/41/59/56bbdc5689be5e13727491ad2ba5efd7cd564365750514f9bc8f212eef82/pyzmq-26.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66c760d0226ebd52f1e6b644a9e839b5db1e107a23f2fcd46ec0569a4fdd4e63", size = 859814, upload-time = "2025-04-04T12:03:47.188Z" }, - { url = "https://files.pythonhosted.org/packages/81/b1/57db58cfc8af592ce94f40649bd1804369c05b2190e4cbc0a2dad572baeb/pyzmq-26.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ef8c6ecc1d520debc147173eaa3765d53f06cd8dbe7bd377064cdbc53ab456f5", size = 855889, upload-time = "2025-04-04T12:03:49.223Z" }, - { url = "https://files.pythonhosted.org/packages/e8/92/47542e629cbac8f221c230a6d0f38dd3d9cff9f6f589ed45fdf572ffd726/pyzmq-26.4.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3150ef4084e163dec29ae667b10d96aad309b668fac6810c9e8c27cf543d6e0b", size = 1197153, upload-time = "2025-04-04T12:03:50.591Z" }, - { url = "https://files.pythonhosted.org/packages/07/e5/b10a979d1d565d54410afc87499b16c96b4a181af46e7645ab4831b1088c/pyzmq-26.4.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4448c9e55bf8329fa1dcedd32f661bf611214fa70c8e02fee4347bc589d39a84", size = 1507352, upload-time = "2025-04-04T12:03:52.473Z" }, - { url = "https://files.pythonhosted.org/packages/ab/58/5a23db84507ab9c01c04b1232a7a763be66e992aa2e66498521bbbc72a71/pyzmq-26.4.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e07dde3647afb084d985310d067a3efa6efad0621ee10826f2cb2f9a31b89d2f", size = 1406834, upload-time = "2025-04-04T12:03:54Z" }, - { url = "https://files.pythonhosted.org/packages/22/74/aaa837b331580c13b79ac39396601fb361454ee184ca85e8861914769b99/pyzmq-26.4.0-cp312-cp312-win32.whl", hash = "sha256:ba034a32ecf9af72adfa5ee383ad0fd4f4e38cdb62b13624278ef768fe5b5b44", size = 577992, upload-time = "2025-04-04T12:03:55.815Z" }, - { url = "https://files.pythonhosted.org/packages/30/0f/55f8c02c182856743b82dde46b2dc3e314edda7f1098c12a8227eeda0833/pyzmq-26.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:056a97aab4064f526ecb32f4343917a4022a5d9efb6b9df990ff72e1879e40be", size = 640466, upload-time = "2025-04-04T12:03:57.231Z" }, - { url = "https://files.pythonhosted.org/packages/e4/29/073779afc3ef6f830b8de95026ef20b2d1ec22d0324d767748d806e57379/pyzmq-26.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:2f23c750e485ce1eb639dbd576d27d168595908aa2d60b149e2d9e34c9df40e0", size = 556342, upload-time = "2025-04-04T12:03:59.218Z" }, + { url = "https://files.pythonhosted.org/packages/92/e7/038aab64a946d535901103da16b953c8c9cc9c961dadcbf3609ed6428d23/pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:452631b640340c928fa343801b0d07eb0c3789a5ffa843f6e1a9cee0ba4eb4fc", size = 1306279, upload-time = "2025-09-08T23:08:03.807Z" }, + { url = "https://files.pythonhosted.org/packages/e8/5e/c3c49fdd0f535ef45eefcc16934648e9e59dace4a37ee88fc53f6cd8e641/pyzmq-27.1.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113", size = 895645, upload-time = "2025-09-08T23:08:05.301Z" }, + { url = "https://files.pythonhosted.org/packages/f8/e5/b0b2504cb4e903a74dcf1ebae157f9e20ebb6ea76095f6cfffea28c42ecd/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233", size = 652574, upload-time = "2025-09-08T23:08:06.828Z" }, + { url = "https://files.pythonhosted.org/packages/f8/9b/c108cdb55560eaf253f0cbdb61b29971e9fb34d9c3499b0e96e4e60ed8a5/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43ad9a73e3da1fab5b0e7e13402f0b2fb934ae1c876c51d0afff0e7c052eca31", size = 840995, upload-time = "2025-09-08T23:08:08.396Z" }, + { url = "https://files.pythonhosted.org/packages/c2/bb/b79798ca177b9eb0825b4c9998c6af8cd2a7f15a6a1a4272c1d1a21d382f/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0de3028d69d4cdc475bfe47a6128eb38d8bc0e8f4d69646adfbcd840facbac28", size = 1642070, upload-time = "2025-09-08T23:08:09.989Z" }, + { url = "https://files.pythonhosted.org/packages/9c/80/2df2e7977c4ede24c79ae39dcef3899bfc5f34d1ca7a5b24f182c9b7a9ca/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:cf44a7763aea9298c0aa7dbf859f87ed7012de8bda0f3977b6fb1d96745df856", size = 2021121, upload-time = "2025-09-08T23:08:11.907Z" }, + { url = "https://files.pythonhosted.org/packages/46/bd/2d45ad24f5f5ae7e8d01525eb76786fa7557136555cac7d929880519e33a/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f30f395a9e6fbca195400ce833c731e7b64c3919aa481af4d88c3759e0cb7496", size = 1878550, upload-time = "2025-09-08T23:08:13.513Z" }, + { url = "https://files.pythonhosted.org/packages/e6/2f/104c0a3c778d7c2ab8190e9db4f62f0b6957b53c9d87db77c284b69f33ea/pyzmq-27.1.0-cp312-abi3-win32.whl", hash = "sha256:250e5436a4ba13885494412b3da5d518cd0d3a278a1ae640e113c073a5f88edd", size = 559184, upload-time = "2025-09-08T23:08:15.163Z" }, + { url = "https://files.pythonhosted.org/packages/fc/7f/a21b20d577e4100c6a41795842028235998a643b1ad406a6d4163ea8f53e/pyzmq-27.1.0-cp312-abi3-win_amd64.whl", hash = "sha256:9ce490cf1d2ca2ad84733aa1d69ce6855372cb5ce9223802450c9b2a7cba0ccf", size = 619480, upload-time = "2025-09-08T23:08:17.192Z" }, + { url = "https://files.pythonhosted.org/packages/78/c2/c012beae5f76b72f007a9e91ee9401cb88c51d0f83c6257a03e785c81cc2/pyzmq-27.1.0-cp312-abi3-win_arm64.whl", hash = "sha256:75a2f36223f0d535a0c919e23615fc85a1e23b71f40c7eb43d7b1dedb4d8f15f", size = 552993, upload-time = "2025-09-08T23:08:18.926Z" }, ] [[package]] name = "referencing" -version = "0.36.2" +version = "0.37.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "attrs" }, { name = "rpds-py" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744, upload-time = "2025-01-25T08:48:16.138Z" } +sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036, upload-time = "2025-10-13T15:30:48.871Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0", size = 26775, upload-time = "2025-01-25T08:48:14.241Z" }, + { url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231", size = 26766, upload-time = "2025-10-13T15:30:47.625Z" }, ] [[package]] name = "regex" -version = "2024.11.6" +version = "2025.11.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8e/5f/bd69653fbfb76cf8604468d3b4ec4c403197144c7bfe0e6a5fc9e02a07cb/regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519", size = 399494, upload-time = "2024-11-06T20:12:31.635Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/a9/546676f25e573a4cf00fe8e119b78a37b6a8fe2dc95cda877b30889c9c45/regex-2025.11.3.tar.gz", hash = "sha256:1fedc720f9bb2494ce31a58a1631f9c82df6a09b49c19517ea5cc280b4541e01", size = 414669, upload-time = "2025-11-03T21:34:22.089Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ba/30/9a87ce8336b172cc232a0db89a3af97929d06c11ceaa19d97d84fa90a8f8/regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a", size = 483781, upload-time = "2024-11-06T20:10:07.07Z" }, - { url = "https://files.pythonhosted.org/packages/01/e8/00008ad4ff4be8b1844786ba6636035f7ef926db5686e4c0f98093612add/regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9", size = 288455, upload-time = "2024-11-06T20:10:09.117Z" }, - { url = "https://files.pythonhosted.org/packages/60/85/cebcc0aff603ea0a201667b203f13ba75d9fc8668fab917ac5b2de3967bc/regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2", size = 284759, upload-time = "2024-11-06T20:10:11.155Z" }, - { url = "https://files.pythonhosted.org/packages/94/2b/701a4b0585cb05472a4da28ee28fdfe155f3638f5e1ec92306d924e5faf0/regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4", size = 794976, upload-time = "2024-11-06T20:10:13.24Z" }, - { url = "https://files.pythonhosted.org/packages/4b/bf/fa87e563bf5fee75db8915f7352e1887b1249126a1be4813837f5dbec965/regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577", size = 833077, upload-time = "2024-11-06T20:10:15.37Z" }, - { url = "https://files.pythonhosted.org/packages/a1/56/7295e6bad94b047f4d0834e4779491b81216583c00c288252ef625c01d23/regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3", size = 823160, upload-time = "2024-11-06T20:10:19.027Z" }, - { url = "https://files.pythonhosted.org/packages/fb/13/e3b075031a738c9598c51cfbc4c7879e26729c53aa9cca59211c44235314/regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e", size = 796896, upload-time = "2024-11-06T20:10:21.85Z" }, - { url = "https://files.pythonhosted.org/packages/24/56/0b3f1b66d592be6efec23a795b37732682520b47c53da5a32c33ed7d84e3/regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe", size = 783997, upload-time = "2024-11-06T20:10:24.329Z" }, - { url = "https://files.pythonhosted.org/packages/f9/a1/eb378dada8b91c0e4c5f08ffb56f25fcae47bf52ad18f9b2f33b83e6d498/regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e", size = 781725, upload-time = "2024-11-06T20:10:28.067Z" }, - { url = "https://files.pythonhosted.org/packages/83/f2/033e7dec0cfd6dda93390089864732a3409246ffe8b042e9554afa9bff4e/regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29", size = 789481, upload-time = "2024-11-06T20:10:31.612Z" }, - { url = "https://files.pythonhosted.org/packages/83/23/15d4552ea28990a74e7696780c438aadd73a20318c47e527b47a4a5a596d/regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39", size = 852896, upload-time = "2024-11-06T20:10:34.054Z" }, - { url = "https://files.pythonhosted.org/packages/e3/39/ed4416bc90deedbfdada2568b2cb0bc1fdb98efe11f5378d9892b2a88f8f/regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51", size = 860138, upload-time = "2024-11-06T20:10:36.142Z" }, - { url = "https://files.pythonhosted.org/packages/93/2d/dd56bb76bd8e95bbce684326302f287455b56242a4f9c61f1bc76e28360e/regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad", size = 787692, upload-time = "2024-11-06T20:10:38.394Z" }, - { url = "https://files.pythonhosted.org/packages/0b/55/31877a249ab7a5156758246b9c59539abbeba22461b7d8adc9e8475ff73e/regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54", size = 262135, upload-time = "2024-11-06T20:10:40.367Z" }, - { url = "https://files.pythonhosted.org/packages/38/ec/ad2d7de49a600cdb8dd78434a1aeffe28b9d6fc42eb36afab4a27ad23384/regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b", size = 273567, upload-time = "2024-11-06T20:10:43.467Z" }, + { url = "https://files.pythonhosted.org/packages/e8/74/18f04cb53e58e3fb107439699bd8375cf5a835eec81084e0bddbd122e4c2/regex-2025.11.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bc8ab71e2e31b16e40868a40a69007bc305e1109bd4658eb6cad007e0bf67c41", size = 489312, upload-time = "2025-11-03T21:31:34.343Z" }, + { url = "https://files.pythonhosted.org/packages/78/3f/37fcdd0d2b1e78909108a876580485ea37c91e1acf66d3bb8e736348f441/regex-2025.11.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:22b29dda7e1f7062a52359fca6e58e548e28c6686f205e780b02ad8ef710de36", size = 291256, upload-time = "2025-11-03T21:31:35.675Z" }, + { url = "https://files.pythonhosted.org/packages/bf/26/0a575f58eb23b7ebd67a45fccbc02ac030b737b896b7e7a909ffe43ffd6a/regex-2025.11.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3a91e4a29938bc1a082cc28fdea44be420bf2bebe2665343029723892eb073e1", size = 288921, upload-time = "2025-11-03T21:31:37.07Z" }, + { url = "https://files.pythonhosted.org/packages/ea/98/6a8dff667d1af907150432cf5abc05a17ccd32c72a3615410d5365ac167a/regex-2025.11.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08b884f4226602ad40c5d55f52bf91a9df30f513864e0054bad40c0e9cf1afb7", size = 798568, upload-time = "2025-11-03T21:31:38.784Z" }, + { url = "https://files.pythonhosted.org/packages/64/15/92c1db4fa4e12733dd5a526c2dd2b6edcbfe13257e135fc0f6c57f34c173/regex-2025.11.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3e0b11b2b2433d1c39c7c7a30e3f3d0aeeea44c2a8d0bae28f6b95f639927a69", size = 864165, upload-time = "2025-11-03T21:31:40.559Z" }, + { url = "https://files.pythonhosted.org/packages/f9/e7/3ad7da8cdee1ce66c7cd37ab5ab05c463a86ffeb52b1a25fe7bd9293b36c/regex-2025.11.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:87eb52a81ef58c7ba4d45c3ca74e12aa4b4e77816f72ca25258a85b3ea96cb48", size = 912182, upload-time = "2025-11-03T21:31:42.002Z" }, + { url = "https://files.pythonhosted.org/packages/84/bd/9ce9f629fcb714ffc2c3faf62b6766ecb7a585e1e885eb699bcf130a5209/regex-2025.11.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a12ab1f5c29b4e93db518f5e3872116b7e9b1646c9f9f426f777b50d44a09e8c", size = 803501, upload-time = "2025-11-03T21:31:43.815Z" }, + { url = "https://files.pythonhosted.org/packages/7c/0f/8dc2e4349d8e877283e6edd6c12bdcebc20f03744e86f197ab6e4492bf08/regex-2025.11.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7521684c8c7c4f6e88e35ec89680ee1aa8358d3f09d27dfbdf62c446f5d4c695", size = 787842, upload-time = "2025-11-03T21:31:45.353Z" }, + { url = "https://files.pythonhosted.org/packages/f9/73/cff02702960bc185164d5619c0c62a2f598a6abff6695d391b096237d4ab/regex-2025.11.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7fe6e5440584e94cc4b3f5f4d98a25e29ca12dccf8873679a635638349831b98", size = 858519, upload-time = "2025-11-03T21:31:46.814Z" }, + { url = "https://files.pythonhosted.org/packages/61/83/0e8d1ae71e15bc1dc36231c90b46ee35f9d52fab2e226b0e039e7ea9c10a/regex-2025.11.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:8e026094aa12b43f4fd74576714e987803a315c76edb6b098b9809db5de58f74", size = 850611, upload-time = "2025-11-03T21:31:48.289Z" }, + { url = "https://files.pythonhosted.org/packages/c8/f5/70a5cdd781dcfaa12556f2955bf170cd603cb1c96a1827479f8faea2df97/regex-2025.11.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:435bbad13e57eb5606a68443af62bed3556de2f46deb9f7d4237bc2f1c9fb3a0", size = 789759, upload-time = "2025-11-03T21:31:49.759Z" }, + { url = "https://files.pythonhosted.org/packages/59/9b/7c29be7903c318488983e7d97abcf8ebd3830e4c956c4c540005fcfb0462/regex-2025.11.3-cp312-cp312-win32.whl", hash = "sha256:3839967cf4dc4b985e1570fd8d91078f0c519f30491c60f9ac42a8db039be204", size = 266194, upload-time = "2025-11-03T21:31:51.53Z" }, + { url = "https://files.pythonhosted.org/packages/1a/67/3b92df89f179d7c367be654ab5626ae311cb28f7d5c237b6bb976cd5fbbb/regex-2025.11.3-cp312-cp312-win_amd64.whl", hash = "sha256:e721d1b46e25c481dc5ded6f4b3f66c897c58d2e8cfdf77bbced84339108b0b9", size = 277069, upload-time = "2025-11-03T21:31:53.151Z" }, + { url = "https://files.pythonhosted.org/packages/d7/55/85ba4c066fe5094d35b249c3ce8df0ba623cfd35afb22d6764f23a52a1c5/regex-2025.11.3-cp312-cp312-win_arm64.whl", hash = "sha256:64350685ff08b1d3a6fff33f45a9ca183dc1d58bbfe4981604e70ec9801bbc26", size = 270330, upload-time = "2025-11-03T21:31:54.514Z" }, ] [[package]] name = "requests" -version = "2.32.3" +version = "2.32.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, @@ -1958,9 +2050,9 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218, upload-time = "2024-05-29T15:37:49.536Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928, upload-time = "2024-05-29T15:37:47.027Z" }, + { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, ] [[package]] @@ -1984,61 +2076,74 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9", size = 4242, upload-time = "2019-10-28T16:00:13.976Z" }, ] +[[package]] +name = "rfc3987-syntax" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "lark" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2c/06/37c1a5557acf449e8e406a830a05bf885ac47d33270aec454ef78675008d/rfc3987_syntax-1.1.0.tar.gz", hash = "sha256:717a62cbf33cffdd16dfa3a497d81ce48a660ea691b1ddd7be710c22f00b4a0d", size = 14239, upload-time = "2025-07-18T01:05:05.015Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl", hash = "sha256:6c3d97604e4c5ce9f714898e05401a0445a641cfa276432b0a648c80856f6a3f", size = 8046, upload-time = "2025-07-18T01:05:03.843Z" }, +] + [[package]] name = "rich" -version = "14.1.0" +version = "14.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown-it-py" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fe/75/af448d8e52bf1d8fa6a9d089ca6c07ff4453d86c65c145d0a300bb073b9b/rich-14.1.0.tar.gz", hash = "sha256:e497a48b844b0320d45007cdebfeaeed8db2a4f4bcf49f15e455cfc4af11eaa8", size = 224441, upload-time = "2025-07-25T07:32:58.125Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fb/d2/8920e102050a0de7bfabeb4c4614a49248cf8d5d7a8d01885fbb24dc767a/rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4", size = 219990, upload-time = "2025-10-09T14:16:53.064Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e3/30/3c4d035596d3cf444529e0b2953ad0466f6049528a879d27534700580395/rich-14.1.0-py3-none-any.whl", hash = "sha256:536f5f1785986d6dbdea3c75205c473f970777b4a0d6c6dd1b696aa05a3fa04f", size = 243368, upload-time = "2025-07-25T07:32:56.73Z" }, + { url = "https://files.pythonhosted.org/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", size = 243393, upload-time = "2025-10-09T14:16:51.245Z" }, ] [[package]] name = "rpds-py" -version = "0.25.1" +version = "0.28.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8c/a6/60184b7fc00dd3ca80ac635dd5b8577d444c57e8e8742cecabfacb829921/rpds_py-0.25.1.tar.gz", hash = "sha256:8960b6dac09b62dac26e75d7e2c4a22efb835d827a7278c34f72b2b84fa160e3", size = 27304, upload-time = "2025-05-21T12:46:12.502Z" } +sdist = { url = "https://files.pythonhosted.org/packages/48/dc/95f074d43452b3ef5d06276696ece4b3b5d696e7c9ad7173c54b1390cd70/rpds_py-0.28.0.tar.gz", hash = "sha256:abd4df20485a0983e2ca334a216249b6186d6e3c1627e106651943dbdb791aea", size = 27419, upload-time = "2025-10-22T22:24:29.327Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/81/28ab0408391b1dc57393653b6a0cf2014cc282cc2909e4615e63e58262be/rpds_py-0.25.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b5ffe453cde61f73fea9430223c81d29e2fbf412a6073951102146c84e19e34c", size = 364647, upload-time = "2025-05-21T12:43:28.559Z" }, - { url = "https://files.pythonhosted.org/packages/2c/9a/7797f04cad0d5e56310e1238434f71fc6939d0bc517192a18bb99a72a95f/rpds_py-0.25.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:115874ae5e2fdcfc16b2aedc95b5eef4aebe91b28e7e21951eda8a5dc0d3461b", size = 350454, upload-time = "2025-05-21T12:43:30.615Z" }, - { url = "https://files.pythonhosted.org/packages/69/3c/93d2ef941b04898011e5d6eaa56a1acf46a3b4c9f4b3ad1bbcbafa0bee1f/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a714bf6e5e81b0e570d01f56e0c89c6375101b8463999ead3a93a5d2a4af91fa", size = 389665, upload-time = "2025-05-21T12:43:32.629Z" }, - { url = "https://files.pythonhosted.org/packages/c1/57/ad0e31e928751dde8903a11102559628d24173428a0f85e25e187defb2c1/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:35634369325906bcd01577da4c19e3b9541a15e99f31e91a02d010816b49bfda", size = 403873, upload-time = "2025-05-21T12:43:34.576Z" }, - { url = "https://files.pythonhosted.org/packages/16/ad/c0c652fa9bba778b4f54980a02962748479dc09632e1fd34e5282cf2556c/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d4cb2b3ddc16710548801c6fcc0cfcdeeff9dafbc983f77265877793f2660309", size = 525866, upload-time = "2025-05-21T12:43:36.123Z" }, - { url = "https://files.pythonhosted.org/packages/2a/39/3e1839bc527e6fcf48d5fec4770070f872cdee6c6fbc9b259932f4e88a38/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9ceca1cf097ed77e1a51f1dbc8d174d10cb5931c188a4505ff9f3e119dfe519b", size = 416886, upload-time = "2025-05-21T12:43:38.034Z" }, - { url = "https://files.pythonhosted.org/packages/7a/95/dd6b91cd4560da41df9d7030a038298a67d24f8ca38e150562644c829c48/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c2cd1a4b0c2b8c5e31ffff50d09f39906fe351389ba143c195566056c13a7ea", size = 390666, upload-time = "2025-05-21T12:43:40.065Z" }, - { url = "https://files.pythonhosted.org/packages/64/48/1be88a820e7494ce0a15c2d390ccb7c52212370badabf128e6a7bb4cb802/rpds_py-0.25.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1de336a4b164c9188cb23f3703adb74a7623ab32d20090d0e9bf499a2203ad65", size = 425109, upload-time = "2025-05-21T12:43:42.263Z" }, - { url = "https://files.pythonhosted.org/packages/cf/07/3e2a17927ef6d7720b9949ec1b37d1e963b829ad0387f7af18d923d5cfa5/rpds_py-0.25.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9fca84a15333e925dd59ce01da0ffe2ffe0d6e5d29a9eeba2148916d1824948c", size = 567244, upload-time = "2025-05-21T12:43:43.846Z" }, - { url = "https://files.pythonhosted.org/packages/d2/e5/76cf010998deccc4f95305d827847e2eae9c568099c06b405cf96384762b/rpds_py-0.25.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:88ec04afe0c59fa64e2f6ea0dd9657e04fc83e38de90f6de201954b4d4eb59bd", size = 596023, upload-time = "2025-05-21T12:43:45.932Z" }, - { url = "https://files.pythonhosted.org/packages/52/9a/df55efd84403736ba37a5a6377b70aad0fd1cb469a9109ee8a1e21299a1c/rpds_py-0.25.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a8bd2f19e312ce3e1d2c635618e8a8d8132892bb746a7cf74780a489f0f6cdcb", size = 561634, upload-time = "2025-05-21T12:43:48.263Z" }, - { url = "https://files.pythonhosted.org/packages/ab/aa/dc3620dd8db84454aaf9374bd318f1aa02578bba5e567f5bf6b79492aca4/rpds_py-0.25.1-cp312-cp312-win32.whl", hash = "sha256:e5e2f7280d8d0d3ef06f3ec1b4fd598d386cc6f0721e54f09109a8132182fbfe", size = 222713, upload-time = "2025-05-21T12:43:49.897Z" }, - { url = "https://files.pythonhosted.org/packages/a3/7f/7cef485269a50ed5b4e9bae145f512d2a111ca638ae70cc101f661b4defd/rpds_py-0.25.1-cp312-cp312-win_amd64.whl", hash = "sha256:db58483f71c5db67d643857404da360dce3573031586034b7d59f245144cc192", size = 235280, upload-time = "2025-05-21T12:43:51.893Z" }, - { url = "https://files.pythonhosted.org/packages/99/f2/c2d64f6564f32af913bf5f3f7ae41c7c263c5ae4c4e8f1a17af8af66cd46/rpds_py-0.25.1-cp312-cp312-win_arm64.whl", hash = "sha256:6d50841c425d16faf3206ddbba44c21aa3310a0cebc3c1cdfc3e3f4f9f6f5728", size = 225399, upload-time = "2025-05-21T12:43:53.351Z" }, + { url = "https://files.pythonhosted.org/packages/b8/5c/6c3936495003875fe7b14f90ea812841a08fca50ab26bd840e924097d9c8/rpds_py-0.28.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:6b4f28583a4f247ff60cd7bdda83db8c3f5b05a7a82ff20dd4b078571747708f", size = 366439, upload-time = "2025-10-22T22:22:04.525Z" }, + { url = "https://files.pythonhosted.org/packages/56/f9/a0f1ca194c50aa29895b442771f036a25b6c41a35e4f35b1a0ea713bedae/rpds_py-0.28.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d678e91b610c29c4b3d52a2c148b641df2b4676ffe47c59f6388d58b99cdc424", size = 348170, upload-time = "2025-10-22T22:22:06.397Z" }, + { url = "https://files.pythonhosted.org/packages/18/ea/42d243d3a586beb72c77fa5def0487daf827210069a95f36328e869599ea/rpds_py-0.28.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e819e0e37a44a78e1383bf1970076e2ccc4dc8c2bbaa2f9bd1dc987e9afff628", size = 378838, upload-time = "2025-10-22T22:22:07.932Z" }, + { url = "https://files.pythonhosted.org/packages/e7/78/3de32e18a94791af8f33601402d9d4f39613136398658412a4e0b3047327/rpds_py-0.28.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5ee514e0f0523db5d3fb171f397c54875dbbd69760a414dccf9d4d7ad628b5bd", size = 393299, upload-time = "2025-10-22T22:22:09.435Z" }, + { url = "https://files.pythonhosted.org/packages/13/7e/4bdb435afb18acea2eb8a25ad56b956f28de7c59f8a1d32827effa0d4514/rpds_py-0.28.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5f3fa06d27fdcee47f07a39e02862da0100cb4982508f5ead53ec533cd5fe55e", size = 518000, upload-time = "2025-10-22T22:22:11.326Z" }, + { url = "https://files.pythonhosted.org/packages/31/d0/5f52a656875cdc60498ab035a7a0ac8f399890cc1ee73ebd567bac4e39ae/rpds_py-0.28.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:46959ef2e64f9e4a41fc89aa20dbca2b85531f9a72c21099a3360f35d10b0d5a", size = 408746, upload-time = "2025-10-22T22:22:13.143Z" }, + { url = "https://files.pythonhosted.org/packages/3e/cd/49ce51767b879cde77e7ad9fae164ea15dce3616fe591d9ea1df51152706/rpds_py-0.28.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8455933b4bcd6e83fde3fefc987a023389c4b13f9a58c8d23e4b3f6d13f78c84", size = 386379, upload-time = "2025-10-22T22:22:14.602Z" }, + { url = "https://files.pythonhosted.org/packages/6a/99/e4e1e1ee93a98f72fc450e36c0e4d99c35370220e815288e3ecd2ec36a2a/rpds_py-0.28.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:ad50614a02c8c2962feebe6012b52f9802deec4263946cddea37aaf28dd25a66", size = 401280, upload-time = "2025-10-22T22:22:16.063Z" }, + { url = "https://files.pythonhosted.org/packages/61/35/e0c6a57488392a8b319d2200d03dad2b29c0db9996f5662c3b02d0b86c02/rpds_py-0.28.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e5deca01b271492553fdb6c7fd974659dce736a15bae5dad7ab8b93555bceb28", size = 412365, upload-time = "2025-10-22T22:22:17.504Z" }, + { url = "https://files.pythonhosted.org/packages/ff/6a/841337980ea253ec797eb084665436007a1aad0faac1ba097fb906c5f69c/rpds_py-0.28.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:735f8495a13159ce6a0d533f01e8674cec0c57038c920495f87dcb20b3ddb48a", size = 559573, upload-time = "2025-10-22T22:22:19.108Z" }, + { url = "https://files.pythonhosted.org/packages/e7/5e/64826ec58afd4c489731f8b00729c5f6afdb86f1df1df60bfede55d650bb/rpds_py-0.28.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:961ca621ff10d198bbe6ba4957decca61aa2a0c56695384c1d6b79bf61436df5", size = 583973, upload-time = "2025-10-22T22:22:20.768Z" }, + { url = "https://files.pythonhosted.org/packages/b6/ee/44d024b4843f8386a4eeaa4c171b3d31d55f7177c415545fd1a24c249b5d/rpds_py-0.28.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2374e16cc9131022e7d9a8f8d65d261d9ba55048c78f3b6e017971a4f5e6353c", size = 553800, upload-time = "2025-10-22T22:22:22.25Z" }, + { url = "https://files.pythonhosted.org/packages/7d/89/33e675dccff11a06d4d85dbb4d1865f878d5020cbb69b2c1e7b2d3f82562/rpds_py-0.28.0-cp312-cp312-win32.whl", hash = "sha256:d15431e334fba488b081d47f30f091e5d03c18527c325386091f31718952fe08", size = 216954, upload-time = "2025-10-22T22:22:24.105Z" }, + { url = "https://files.pythonhosted.org/packages/af/36/45f6ebb3210887e8ee6dbf1bc710ae8400bb417ce165aaf3024b8360d999/rpds_py-0.28.0-cp312-cp312-win_amd64.whl", hash = "sha256:a410542d61fc54710f750d3764380b53bf09e8c4edbf2f9141a82aa774a04f7c", size = 227844, upload-time = "2025-10-22T22:22:25.551Z" }, + { url = "https://files.pythonhosted.org/packages/57/91/f3fb250d7e73de71080f9a221d19bd6a1c1eb0d12a1ea26513f6c1052ad6/rpds_py-0.28.0-cp312-cp312-win_arm64.whl", hash = "sha256:1f0cfd1c69e2d14f8c892b893997fa9a60d890a0c8a603e88dca4955f26d1edd", size = 217624, upload-time = "2025-10-22T22:22:26.914Z" }, ] [[package]] name = "safetensors" -version = "0.5.3" +version = "0.6.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/71/7e/2d5d6ee7b40c0682315367ec7475693d110f512922d582fef1bd4a63adc3/safetensors-0.5.3.tar.gz", hash = "sha256:b6b0d6ecacec39a4fdd99cc19f4576f5219ce858e6fd8dbe7609df0b8dc56965", size = 67210, upload-time = "2025-02-26T09:15:13.155Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ac/cc/738f3011628920e027a11754d9cae9abec1aed00f7ae860abbf843755233/safetensors-0.6.2.tar.gz", hash = "sha256:43ff2aa0e6fa2dc3ea5524ac7ad93a9839256b8703761e76e2d0b2a3fa4f15d9", size = 197968, upload-time = "2025-08-08T13:13:58.654Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/18/ae/88f6c49dbd0cc4da0e08610019a3c78a7d390879a919411a410a1876d03a/safetensors-0.5.3-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:bd20eb133db8ed15b40110b7c00c6df51655a2998132193de2f75f72d99c7073", size = 436917, upload-time = "2025-02-26T09:15:03.702Z" }, - { url = "https://files.pythonhosted.org/packages/b8/3b/11f1b4a2f5d2ab7da34ecc062b0bc301f2be024d110a6466726bec8c055c/safetensors-0.5.3-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:21d01c14ff6c415c485616b8b0bf961c46b3b343ca59110d38d744e577f9cce7", size = 418419, upload-time = "2025-02-26T09:15:01.765Z" }, - { url = "https://files.pythonhosted.org/packages/5d/9a/add3e6fef267658075c5a41573c26d42d80c935cdc992384dfae435feaef/safetensors-0.5.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11bce6164887cd491ca75c2326a113ba934be596e22b28b1742ce27b1d076467", size = 459493, upload-time = "2025-02-26T09:14:51.812Z" }, - { url = "https://files.pythonhosted.org/packages/df/5c/bf2cae92222513cc23b3ff85c4a1bb2811a2c3583ac0f8e8d502751de934/safetensors-0.5.3-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4a243be3590bc3301c821da7a18d87224ef35cbd3e5f5727e4e0728b8172411e", size = 472400, upload-time = "2025-02-26T09:14:53.549Z" }, - { url = "https://files.pythonhosted.org/packages/58/11/7456afb740bd45782d0f4c8e8e1bb9e572f1bf82899fb6ace58af47b4282/safetensors-0.5.3-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8bd84b12b1670a6f8e50f01e28156422a2bc07fb16fc4e98bded13039d688a0d", size = 522891, upload-time = "2025-02-26T09:14:55.717Z" }, - { url = "https://files.pythonhosted.org/packages/57/3d/fe73a9d2ace487e7285f6e157afee2383bd1ddb911b7cb44a55cf812eae3/safetensors-0.5.3-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:391ac8cab7c829452175f871fcaf414aa1e292b5448bd02620f675a7f3e7abb9", size = 537694, upload-time = "2025-02-26T09:14:57.036Z" }, - { url = "https://files.pythonhosted.org/packages/a6/f8/dae3421624fcc87a89d42e1898a798bc7ff72c61f38973a65d60df8f124c/safetensors-0.5.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cead1fa41fc54b1e61089fa57452e8834f798cb1dc7a09ba3524f1eb08e0317a", size = 471642, upload-time = "2025-02-26T09:15:00.544Z" }, - { url = "https://files.pythonhosted.org/packages/ce/20/1fbe16f9b815f6c5a672f5b760951e20e17e43f67f231428f871909a37f6/safetensors-0.5.3-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1077f3e94182d72618357b04b5ced540ceb71c8a813d3319f1aba448e68a770d", size = 502241, upload-time = "2025-02-26T09:14:58.303Z" }, - { url = "https://files.pythonhosted.org/packages/5f/18/8e108846b506487aa4629fe4116b27db65c3dde922de2c8e0cc1133f3f29/safetensors-0.5.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:799021e78287bac619c7b3f3606730a22da4cda27759ddf55d37c8db7511c74b", size = 638001, upload-time = "2025-02-26T09:15:05.79Z" }, - { url = "https://files.pythonhosted.org/packages/82/5a/c116111d8291af6c8c8a8b40628fe833b9db97d8141c2a82359d14d9e078/safetensors-0.5.3-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:df26da01aaac504334644e1b7642fa000bfec820e7cef83aeac4e355e03195ff", size = 734013, upload-time = "2025-02-26T09:15:07.892Z" }, - { url = "https://files.pythonhosted.org/packages/7d/ff/41fcc4d3b7de837963622e8610d998710705bbde9a8a17221d85e5d0baad/safetensors-0.5.3-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:32c3ef2d7af8b9f52ff685ed0bc43913cdcde135089ae322ee576de93eae5135", size = 670687, upload-time = "2025-02-26T09:15:09.979Z" }, - { url = "https://files.pythonhosted.org/packages/40/ad/2b113098e69c985a3d8fbda4b902778eae4a35b7d5188859b4a63d30c161/safetensors-0.5.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:37f1521be045e56fc2b54c606d4455573e717b2d887c579ee1dbba5f868ece04", size = 643147, upload-time = "2025-02-26T09:15:11.185Z" }, - { url = "https://files.pythonhosted.org/packages/0a/0c/95aeb51d4246bd9a3242d3d8349c1112b4ee7611a4b40f0c5c93b05f001d/safetensors-0.5.3-cp38-abi3-win32.whl", hash = "sha256:cfc0ec0846dcf6763b0ed3d1846ff36008c6e7290683b61616c4b040f6a54ace", size = 296677, upload-time = "2025-02-26T09:15:16.554Z" }, - { url = "https://files.pythonhosted.org/packages/69/e2/b011c38e5394c4c18fb5500778a55ec43ad6106126e74723ffaee246f56e/safetensors-0.5.3-cp38-abi3-win_amd64.whl", hash = "sha256:836cbbc320b47e80acd40e44c8682db0e8ad7123209f69b093def21ec7cafd11", size = 308878, upload-time = "2025-02-26T09:15:14.99Z" }, + { url = "https://files.pythonhosted.org/packages/4d/b1/3f5fd73c039fc87dba3ff8b5d528bfc5a32b597fea8e7a6a4800343a17c7/safetensors-0.6.2-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:9c85ede8ec58f120bad982ec47746981e210492a6db876882aa021446af8ffba", size = 454797, upload-time = "2025-08-08T13:13:52.066Z" }, + { url = "https://files.pythonhosted.org/packages/8c/c9/bb114c158540ee17907ec470d01980957fdaf87b4aa07914c24eba87b9c6/safetensors-0.6.2-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:d6675cf4b39c98dbd7d940598028f3742e0375a6b4d4277e76beb0c35f4b843b", size = 432206, upload-time = "2025-08-08T13:13:50.931Z" }, + { url = "https://files.pythonhosted.org/packages/d3/8e/f70c34e47df3110e8e0bb268d90db8d4be8958a54ab0336c9be4fe86dac8/safetensors-0.6.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d2d2b3ce1e2509c68932ca03ab8f20570920cd9754b05063d4368ee52833ecd", size = 473261, upload-time = "2025-08-08T13:13:41.259Z" }, + { url = "https://files.pythonhosted.org/packages/2a/f5/be9c6a7c7ef773e1996dc214e73485286df1836dbd063e8085ee1976f9cb/safetensors-0.6.2-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:93de35a18f46b0f5a6a1f9e26d91b442094f2df02e9fd7acf224cfec4238821a", size = 485117, upload-time = "2025-08-08T13:13:43.506Z" }, + { url = "https://files.pythonhosted.org/packages/c9/55/23f2d0a2c96ed8665bf17a30ab4ce5270413f4d74b6d87dd663258b9af31/safetensors-0.6.2-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:89a89b505f335640f9120fac65ddeb83e40f1fd081cb8ed88b505bdccec8d0a1", size = 616154, upload-time = "2025-08-08T13:13:45.096Z" }, + { url = "https://files.pythonhosted.org/packages/98/c6/affb0bd9ce02aa46e7acddbe087912a04d953d7a4d74b708c91b5806ef3f/safetensors-0.6.2-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fc4d0d0b937e04bdf2ae6f70cd3ad51328635fe0e6214aa1fc811f3b576b3bda", size = 520713, upload-time = "2025-08-08T13:13:46.25Z" }, + { url = "https://files.pythonhosted.org/packages/fe/5d/5a514d7b88e310c8b146e2404e0dc161282e78634d9358975fd56dfd14be/safetensors-0.6.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8045db2c872db8f4cbe3faa0495932d89c38c899c603f21e9b6486951a5ecb8f", size = 485835, upload-time = "2025-08-08T13:13:49.373Z" }, + { url = "https://files.pythonhosted.org/packages/7a/7b/4fc3b2ba62c352b2071bea9cfbad330fadda70579f617506ae1a2f129cab/safetensors-0.6.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:81e67e8bab9878bb568cffbc5f5e655adb38d2418351dc0859ccac158f753e19", size = 521503, upload-time = "2025-08-08T13:13:47.651Z" }, + { url = "https://files.pythonhosted.org/packages/5a/50/0057e11fe1f3cead9254315a6c106a16dd4b1a19cd247f7cc6414f6b7866/safetensors-0.6.2-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b0e4d029ab0a0e0e4fdf142b194514695b1d7d3735503ba700cf36d0fc7136ce", size = 652256, upload-time = "2025-08-08T13:13:53.167Z" }, + { url = "https://files.pythonhosted.org/packages/e9/29/473f789e4ac242593ac1656fbece6e1ecd860bb289e635e963667807afe3/safetensors-0.6.2-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:fa48268185c52bfe8771e46325a1e21d317207bcabcb72e65c6e28e9ffeb29c7", size = 747281, upload-time = "2025-08-08T13:13:54.656Z" }, + { url = "https://files.pythonhosted.org/packages/68/52/f7324aad7f2df99e05525c84d352dc217e0fa637a4f603e9f2eedfbe2c67/safetensors-0.6.2-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:d83c20c12c2d2f465997c51b7ecb00e407e5f94d7dec3ea0cc11d86f60d3fde5", size = 692286, upload-time = "2025-08-08T13:13:55.884Z" }, + { url = "https://files.pythonhosted.org/packages/ad/fe/cad1d9762868c7c5dc70c8620074df28ebb1a8e4c17d4c0cb031889c457e/safetensors-0.6.2-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d944cea65fad0ead848b6ec2c37cc0b197194bec228f8020054742190e9312ac", size = 655957, upload-time = "2025-08-08T13:13:57.029Z" }, + { url = "https://files.pythonhosted.org/packages/59/a7/e2158e17bbe57d104f0abbd95dff60dda916cf277c9f9663b4bf9bad8b6e/safetensors-0.6.2-cp38-abi3-win32.whl", hash = "sha256:cab75ca7c064d3911411461151cb69380c9225798a20e712b102edda2542ddb1", size = 308926, upload-time = "2025-08-08T13:14:01.095Z" }, + { url = "https://files.pythonhosted.org/packages/2c/c3/c0be1135726618dc1e28d181b8c442403d8dbb9e273fd791de2d4384bcdd/safetensors-0.6.2-cp38-abi3-win_amd64.whl", hash = "sha256:c7b214870df923cbc1593c3faee16bec59ea462758699bd3fee399d00aac072c", size = 320192, upload-time = "2025-08-08T13:13:59.467Z" }, ] [[package]] @@ -2068,44 +2173,45 @@ wheels = [ [[package]] name = "sentry-sdk" -version = "2.29.1" +version = "2.43.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/22/67/d552a5f8e5a6a56b2feea6529e2d8ccd54349084c84176d5a1f7295044bc/sentry_sdk-2.29.1.tar.gz", hash = "sha256:8d4a0206b95fa5fe85e5e7517ed662e3888374bdc342c00e435e10e6d831aa6d", size = 325518, upload-time = "2025-05-19T14:27:38.512Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b3/18/09875b4323b03ca9025bae7e6539797b27e4fc032998a466b4b9c3d24653/sentry_sdk-2.43.0.tar.gz", hash = "sha256:52ed6e251c5d2c084224d73efee56b007ef5c2d408a4a071270e82131d336e20", size = 368953, upload-time = "2025-10-29T11:26:08.156Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f0/e5/da07b0bd832cefd52d16f2b9bbbe31624d57552602c06631686b93ccb1bd/sentry_sdk-2.29.1-py2.py3-none-any.whl", hash = "sha256:90862fe0616ded4572da6c9dadb363121a1ae49a49e21c418f0634e9d10b4c19", size = 341553, upload-time = "2025-05-19T14:27:36.882Z" }, + { url = "https://files.pythonhosted.org/packages/69/31/8228fa962f7fd8814d634e4ebece8780e2cdcfbdf0cd2e14d4a6861a7cd5/sentry_sdk-2.43.0-py2.py3-none-any.whl", hash = "sha256:4aacafcf1756ef066d359ae35030881917160ba7f6fc3ae11e0e58b09edc2d5d", size = 400997, upload-time = "2025-10-29T11:26:05.77Z" }, ] [[package]] -name = "setproctitle" -version = "1.3.6" +name = "setuptools" +version = "80.9.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9e/af/56efe21c53ac81ac87e000b15e60b3d8104224b4313b6eacac3597bd183d/setproctitle-1.3.6.tar.gz", hash = "sha256:c9f32b96c700bb384f33f7cf07954bb609d35dd82752cef57fb2ee0968409169", size = 26889, upload-time = "2025-04-29T13:35:00.184Z" } +sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8f/fb/99456fd94d4207c5f6c40746a048a33a52b4239cd7d9c8d4889e2210ec82/setproctitle-1.3.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:af44bb7a1af163806bbb679eb8432fa7b4fb6d83a5d403b541b675dcd3798638", size = 17399, upload-time = "2025-04-29T13:33:13.406Z" }, - { url = "https://files.pythonhosted.org/packages/d5/48/9699191fe6062827683c43bfa9caac33a2c89f8781dd8c7253fa3dba85fd/setproctitle-1.3.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3cca16fd055316a48f0debfcbfb6af7cea715429fc31515ab3fcac05abd527d8", size = 11966, upload-time = "2025-04-29T13:33:14.976Z" }, - { url = "https://files.pythonhosted.org/packages/33/03/b085d192b9ecb9c7ce6ad6ef30ecf4110b7f39430b58a56245569827fcf4/setproctitle-1.3.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea002088d5554fd75e619742cefc78b84a212ba21632e59931b3501f0cfc8f67", size = 32017, upload-time = "2025-04-29T13:33:16.163Z" }, - { url = "https://files.pythonhosted.org/packages/ae/68/c53162e645816f97212002111420d1b2f75bf6d02632e37e961dc2cd6d8b/setproctitle-1.3.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb465dd5825356c1191a038a86ee1b8166e3562d6e8add95eec04ab484cfb8a2", size = 33419, upload-time = "2025-04-29T13:33:18.239Z" }, - { url = "https://files.pythonhosted.org/packages/ac/0d/119a45d15a816a6cf5ccc61b19729f82620095b27a47e0a6838216a95fae/setproctitle-1.3.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d2c8e20487b3b73c1fa72c56f5c89430617296cd380373e7af3a538a82d4cd6d", size = 30711, upload-time = "2025-04-29T13:33:19.571Z" }, - { url = "https://files.pythonhosted.org/packages/e3/fb/5e9b5068df9e9f31a722a775a5e8322a29a638eaaa3eac5ea7f0b35e6314/setproctitle-1.3.6-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0d6252098e98129a1decb59b46920d4eca17b0395f3d71b0d327d086fefe77d", size = 31742, upload-time = "2025-04-29T13:33:21.172Z" }, - { url = "https://files.pythonhosted.org/packages/35/88/54de1e73e8fce87d587889c7eedb48fc4ee2bbe4e4ca6331690d03024f86/setproctitle-1.3.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:cf355fbf0d4275d86f9f57be705d8e5eaa7f8ddb12b24ced2ea6cbd68fdb14dc", size = 31925, upload-time = "2025-04-29T13:33:22.427Z" }, - { url = "https://files.pythonhosted.org/packages/f3/01/65948d7badd66e63e3db247b923143da142790fa293830fdecf832712c2d/setproctitle-1.3.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e288f8a162d663916060beb5e8165a8551312b08efee9cf68302687471a6545d", size = 30981, upload-time = "2025-04-29T13:33:23.739Z" }, - { url = "https://files.pythonhosted.org/packages/22/20/c495e61786f1d38d5dc340b9d9077fee9be3dfc7e89f515afe12e1526dbc/setproctitle-1.3.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b2e54f4a2dc6edf0f5ea5b1d0a608d2af3dcb5aa8c8eeab9c8841b23e1b054fe", size = 33209, upload-time = "2025-04-29T13:33:24.915Z" }, - { url = "https://files.pythonhosted.org/packages/98/3f/a457b8550fbd34d5b482fe20b8376b529e76bf1fbf9a474a6d9a641ab4ad/setproctitle-1.3.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b6f4abde9a2946f57e8daaf1160b2351bcf64274ef539e6675c1d945dbd75e2a", size = 31587, upload-time = "2025-04-29T13:33:26.123Z" }, - { url = "https://files.pythonhosted.org/packages/44/fe/743517340e5a635e3f1c4310baea20c16c66202f96a6f4cead222ffd6d84/setproctitle-1.3.6-cp312-cp312-win32.whl", hash = "sha256:db608db98ccc21248370d30044a60843b3f0f3d34781ceeea67067c508cd5a28", size = 11487, upload-time = "2025-04-29T13:33:27.403Z" }, - { url = "https://files.pythonhosted.org/packages/60/9a/d88f1c1f0f4efff1bd29d9233583ee341114dda7d9613941453984849674/setproctitle-1.3.6-cp312-cp312-win_amd64.whl", hash = "sha256:082413db8a96b1f021088e8ec23f0a61fec352e649aba20881895815388b66d3", size = 12208, upload-time = "2025-04-29T13:33:28.852Z" }, + { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" }, ] [[package]] -name = "setuptools" -version = "80.9.0" +name = "shellingham" +version = "1.5.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" }, + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[package]] +name = "sigtools" +version = "4.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5f/db/669ca14166814da187b3087b908ca924cf83f5b504fe23b3859a3ef67d4f/sigtools-4.0.1.tar.gz", hash = "sha256:4b8e135a9cd4d2ea00da670c093372d74e672ba3abb87f4c98d8e73dea54445c", size = 71910, upload-time = "2022-10-13T07:03:54.149Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1f/91/853dbf6ec096197dba9cd5fd0c836c5fc19142038b7db60ebe6332b1bab1/sigtools-4.0.1-py2.py3-none-any.whl", hash = "sha256:d216b4cf920bbab0fce636ddc429ed8463a5b533d9e1492acb45a2a1bc36ac6c", size = 76419, upload-time = "2022-10-13T07:03:52.658Z" }, ] [[package]] @@ -2149,11 +2255,11 @@ wheels = [ [[package]] name = "soupsieve" -version = "2.7" +version = "2.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3f/f4/4a80cd6ef364b2e8b65b15816a843c0980f7a5a2b4dc701fc574952aa19f/soupsieve-2.7.tar.gz", hash = "sha256:ad282f9b6926286d2ead4750552c8a6142bc4c783fd66b0293547c8fe6ae126a", size = 103418, upload-time = "2025-04-20T18:50:08.518Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6d/e6/21ccce3262dd4889aa3332e5a119a3491a95e8f60939870a3a035aabac0d/soupsieve-2.8.tar.gz", hash = "sha256:e2dd4a40a628cb5f28f6d4b0db8800b8f581b65bb380b97de22ba5ca8d72572f", size = 103472, upload-time = "2025-08-27T15:39:51.78Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/9c/0e6afc12c269578be5c0c1c9f4b49a8d32770a080260c333ac04cc1c832d/soupsieve-2.7-py3-none-any.whl", hash = "sha256:6e60cc5c1ffaf1cebcc12e8188320b72071e922c2e897f737cadce79ad5d30c4", size = 36677, upload-time = "2025-04-20T18:50:07.196Z" }, + { url = "https://files.pythonhosted.org/packages/14/a0/bb38d3b76b8cae341dad93a2dd83ab7462e6dbcdd84d43f54ee60a8dc167/soupsieve-2.8-py3-none-any.whl", hash = "sha256:0cc76456a30e20f5d7f2e14a98a4ae2ee4e5abdc7c5ea0aafe795f344bc7984c", size = 36679, upload-time = "2025-08-27T15:39:50.179Z" }, ] [[package]] @@ -2182,6 +2288,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" }, ] +[[package]] +name = "synchronicity" +version = "0.10.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sigtools" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/77/b6/e977f03915cc02406bb52ac15398ea44dbde47805e5955b6bac9268acc12/synchronicity-0.10.2.tar.gz", hash = "sha256:e0dfd8a2ba4fb89c60ee53365c5fa2d2d69aabce60709055d38f736f6a592c86", size = 53891, upload-time = "2025-07-30T20:23:19.122Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/f9/ce041b9531022a0b5999a47e6da14485239f7bce9c595d1bfb387fe60e89/synchronicity-0.10.2-py3-none-any.whl", hash = "sha256:4ba1f8c02ca582ef068033300201e3c403e08d81e42553554f4e67b27f0d9bb1", size = 38766, upload-time = "2025-07-30T20:23:18.04Z" }, +] + [[package]] name = "terminado" version = "0.18.1" @@ -2210,27 +2329,27 @@ wheels = [ [[package]] name = "tokenizers" -version = "0.21.1" +version = "0.22.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "huggingface-hub" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/92/76/5ac0c97f1117b91b7eb7323dcd61af80d72f790b4df71249a7850c195f30/tokenizers-0.21.1.tar.gz", hash = "sha256:a1bb04dc5b448985f86ecd4b05407f5a8d97cb2c0532199b2a302a604a0165ab", size = 343256, upload-time = "2025-03-13T10:51:18.189Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/46/fb6854cec3278fbfa4a75b50232c77622bc517ac886156e6afbfa4d8fc6e/tokenizers-0.22.1.tar.gz", hash = "sha256:61de6522785310a309b3407bac22d99c4db5dba349935e99e4d15ea2226af2d9", size = 363123, upload-time = "2025-09-19T09:49:23.424Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/1f/328aee25f9115bf04262e8b4e5a2050b7b7cf44b59c74e982db7270c7f30/tokenizers-0.21.1-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:e78e413e9e668ad790a29456e677d9d3aa50a9ad311a40905d6861ba7692cf41", size = 2780767, upload-time = "2025-03-13T10:51:09.459Z" }, - { url = "https://files.pythonhosted.org/packages/ae/1a/4526797f3719b0287853f12c5ad563a9be09d446c44ac784cdd7c50f76ab/tokenizers-0.21.1-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:cd51cd0a91ecc801633829fcd1fda9cf8682ed3477c6243b9a095539de4aecf3", size = 2650555, upload-time = "2025-03-13T10:51:07.692Z" }, - { url = "https://files.pythonhosted.org/packages/4d/7a/a209b29f971a9fdc1da86f917fe4524564924db50d13f0724feed37b2a4d/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28da6b72d4fb14ee200a1bd386ff74ade8992d7f725f2bde2c495a9a98cf4d9f", size = 2937541, upload-time = "2025-03-13T10:50:56.679Z" }, - { url = "https://files.pythonhosted.org/packages/3c/1e/b788b50ffc6191e0b1fc2b0d49df8cff16fe415302e5ceb89f619d12c5bc/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:34d8cfde551c9916cb92014e040806122295a6800914bab5865deb85623931cf", size = 2819058, upload-time = "2025-03-13T10:50:59.525Z" }, - { url = "https://files.pythonhosted.org/packages/36/aa/3626dfa09a0ecc5b57a8c58eeaeb7dd7ca9a37ad9dd681edab5acd55764c/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aaa852d23e125b73d283c98f007e06d4595732104b65402f46e8ef24b588d9f8", size = 3133278, upload-time = "2025-03-13T10:51:04.678Z" }, - { url = "https://files.pythonhosted.org/packages/a4/4d/8fbc203838b3d26269f944a89459d94c858f5b3f9a9b6ee9728cdcf69161/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a21a15d5c8e603331b8a59548bbe113564136dc0f5ad8306dd5033459a226da0", size = 3144253, upload-time = "2025-03-13T10:51:01.261Z" }, - { url = "https://files.pythonhosted.org/packages/d8/1b/2bd062adeb7c7511b847b32e356024980c0ffcf35f28947792c2d8ad2288/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2fdbd4c067c60a0ac7eca14b6bd18a5bebace54eb757c706b47ea93204f7a37c", size = 3398225, upload-time = "2025-03-13T10:51:03.243Z" }, - { url = "https://files.pythonhosted.org/packages/8a/63/38be071b0c8e06840bc6046991636bcb30c27f6bb1e670f4f4bc87cf49cc/tokenizers-0.21.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dd9a0061e403546f7377df940e866c3e678d7d4e9643d0461ea442b4f89e61a", size = 3038874, upload-time = "2025-03-13T10:51:06.235Z" }, - { url = "https://files.pythonhosted.org/packages/ec/83/afa94193c09246417c23a3c75a8a0a96bf44ab5630a3015538d0c316dd4b/tokenizers-0.21.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:db9484aeb2e200c43b915a1a0150ea885e35f357a5a8fabf7373af333dcc8dbf", size = 9014448, upload-time = "2025-03-13T10:51:10.927Z" }, - { url = "https://files.pythonhosted.org/packages/ae/b3/0e1a37d4f84c0f014d43701c11eb8072704f6efe8d8fc2dcdb79c47d76de/tokenizers-0.21.1-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:ed248ab5279e601a30a4d67bdb897ecbe955a50f1e7bb62bd99f07dd11c2f5b6", size = 8937877, upload-time = "2025-03-13T10:51:12.688Z" }, - { url = "https://files.pythonhosted.org/packages/ac/33/ff08f50e6d615eb180a4a328c65907feb6ded0b8f990ec923969759dc379/tokenizers-0.21.1-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:9ac78b12e541d4ce67b4dfd970e44c060a2147b9b2a21f509566d556a509c67d", size = 9186645, upload-time = "2025-03-13T10:51:14.723Z" }, - { url = "https://files.pythonhosted.org/packages/5f/aa/8ae85f69a9f6012c6f8011c6f4aa1c96154c816e9eea2e1b758601157833/tokenizers-0.21.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e5a69c1a4496b81a5ee5d2c1f3f7fbdf95e90a0196101b0ee89ed9956b8a168f", size = 9384380, upload-time = "2025-03-13T10:51:16.526Z" }, - { url = "https://files.pythonhosted.org/packages/e8/5b/a5d98c89f747455e8b7a9504910c865d5e51da55e825a7ae641fb5ff0a58/tokenizers-0.21.1-cp39-abi3-win32.whl", hash = "sha256:1039a3a5734944e09de1d48761ade94e00d0fa760c0e0551151d4dd851ba63e3", size = 2239506, upload-time = "2025-03-13T10:51:20.643Z" }, - { url = "https://files.pythonhosted.org/packages/e6/b6/072a8e053ae600dcc2ac0da81a23548e3b523301a442a6ca900e92ac35be/tokenizers-0.21.1-cp39-abi3-win_amd64.whl", hash = "sha256:0f0dcbcc9f6e13e675a66d7a5f2f225a736745ce484c1a4e07476a89ccdad382", size = 2435481, upload-time = "2025-03-13T10:51:19.243Z" }, + { url = "https://files.pythonhosted.org/packages/bf/33/f4b2d94ada7ab297328fc671fed209368ddb82f965ec2224eb1892674c3a/tokenizers-0.22.1-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:59fdb013df17455e5f950b4b834a7b3ee2e0271e6378ccb33aa74d178b513c73", size = 3069318, upload-time = "2025-09-19T09:49:11.848Z" }, + { url = "https://files.pythonhosted.org/packages/1c/58/2aa8c874d02b974990e89ff95826a4852a8b2a273c7d1b4411cdd45a4565/tokenizers-0.22.1-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:8d4e484f7b0827021ac5f9f71d4794aaef62b979ab7608593da22b1d2e3c4edc", size = 2926478, upload-time = "2025-09-19T09:49:09.759Z" }, + { url = "https://files.pythonhosted.org/packages/1e/3b/55e64befa1e7bfea963cf4b787b2cea1011362c4193f5477047532ce127e/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19d2962dd28bc67c1f205ab180578a78eef89ac60ca7ef7cbe9635a46a56422a", size = 3256994, upload-time = "2025-09-19T09:48:56.701Z" }, + { url = "https://files.pythonhosted.org/packages/71/0b/fbfecf42f67d9b7b80fde4aabb2b3110a97fac6585c9470b5bff103a80cb/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:38201f15cdb1f8a6843e6563e6e79f4abd053394992b9bbdf5213ea3469b4ae7", size = 3153141, upload-time = "2025-09-19T09:48:59.749Z" }, + { url = "https://files.pythonhosted.org/packages/17/a9/b38f4e74e0817af8f8ef925507c63c6ae8171e3c4cb2d5d4624bf58fca69/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1cbe5454c9a15df1b3443c726063d930c16f047a3cc724b9e6e1a91140e5a21", size = 3508049, upload-time = "2025-09-19T09:49:05.868Z" }, + { url = "https://files.pythonhosted.org/packages/d2/48/dd2b3dac46bb9134a88e35d72e1aa4869579eacc1a27238f1577270773ff/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e7d094ae6312d69cc2a872b54b91b309f4f6fbce871ef28eb27b52a98e4d0214", size = 3710730, upload-time = "2025-09-19T09:49:01.832Z" }, + { url = "https://files.pythonhosted.org/packages/93/0e/ccabc8d16ae4ba84a55d41345207c1e2ea88784651a5a487547d80851398/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:afd7594a56656ace95cdd6df4cca2e4059d294c5cfb1679c57824b605556cb2f", size = 3412560, upload-time = "2025-09-19T09:49:03.867Z" }, + { url = "https://files.pythonhosted.org/packages/d0/c6/dc3a0db5a6766416c32c034286d7c2d406da1f498e4de04ab1b8959edd00/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2ef6063d7a84994129732b47e7915e8710f27f99f3a3260b8a38fc7ccd083f4", size = 3250221, upload-time = "2025-09-19T09:49:07.664Z" }, + { url = "https://files.pythonhosted.org/packages/d7/a6/2c8486eef79671601ff57b093889a345dd3d576713ef047776015dc66de7/tokenizers-0.22.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ba0a64f450b9ef412c98f6bcd2a50c6df6e2443b560024a09fa6a03189726879", size = 9345569, upload-time = "2025-09-19T09:49:14.214Z" }, + { url = "https://files.pythonhosted.org/packages/6b/16/32ce667f14c35537f5f605fe9bea3e415ea1b0a646389d2295ec348d5657/tokenizers-0.22.1-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:331d6d149fa9c7d632cde4490fb8bbb12337fa3a0232e77892be656464f4b446", size = 9271599, upload-time = "2025-09-19T09:49:16.639Z" }, + { url = "https://files.pythonhosted.org/packages/51/7c/a5f7898a3f6baa3fc2685c705e04c98c1094c523051c805cdd9306b8f87e/tokenizers-0.22.1-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:607989f2ea68a46cb1dfbaf3e3aabdf3f21d8748312dbeb6263d1b3b66c5010a", size = 9533862, upload-time = "2025-09-19T09:49:19.146Z" }, + { url = "https://files.pythonhosted.org/packages/36/65/7e75caea90bc73c1dd8d40438adf1a7bc26af3b8d0a6705ea190462506e1/tokenizers-0.22.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a0f307d490295717726598ef6fa4f24af9d484809223bbc253b201c740a06390", size = 9681250, upload-time = "2025-09-19T09:49:21.501Z" }, + { url = "https://files.pythonhosted.org/packages/30/2c/959dddef581b46e6209da82df3b78471e96260e2bc463f89d23b1bf0e52a/tokenizers-0.22.1-cp39-abi3-win32.whl", hash = "sha256:b5120eed1442765cd90b903bb6cfef781fd8fe64e34ccaecbae4c619b7b12a82", size = 2472003, upload-time = "2025-09-19T09:49:27.089Z" }, + { url = "https://files.pythonhosted.org/packages/b3/46/e33a8c93907b631a99377ef4c5f817ab453d0b34f93529421f42ff559671/tokenizers-0.22.1-cp39-abi3-win_amd64.whl", hash = "sha256:65fd6e3fb11ca1e78a6a93602490f134d1fdeb13bcef99389d5102ea318ed138", size = 2674684, upload-time = "2025-09-19T09:49:24.953Z" }, ] [[package]] @@ -2244,7 +2363,7 @@ wheels = [ [[package]] name = "torch" -version = "2.8.0" +version = "2.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "filelock" }, @@ -2264,6 +2383,7 @@ dependencies = [ { name = "nvidia-cusparselt-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "nvidia-nccl-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvshmem-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "setuptools" }, { name = "sympy" }, @@ -2271,15 +2391,15 @@ dependencies = [ { name = "typing-extensions" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/49/0c/2fd4df0d83a495bb5e54dca4474c4ec5f9c62db185421563deeb5dabf609/torch-2.8.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:e2fab4153768d433f8ed9279c8133a114a034a61e77a3a104dcdf54388838705", size = 101906089, upload-time = "2025-08-06T14:53:52.631Z" }, - { url = "https://files.pythonhosted.org/packages/99/a8/6acf48d48838fb8fe480597d98a0668c2beb02ee4755cc136de92a0a956f/torch-2.8.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b2aca0939fb7e4d842561febbd4ffda67a8e958ff725c1c27e244e85e982173c", size = 887913624, upload-time = "2025-08-06T14:56:44.33Z" }, - { url = "https://files.pythonhosted.org/packages/af/8a/5c87f08e3abd825c7dfecef5a0f1d9aa5df5dd0e3fd1fa2f490a8e512402/torch-2.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:2f4ac52f0130275d7517b03a33d2493bab3693c83dcfadf4f81688ea82147d2e", size = 241326087, upload-time = "2025-08-06T14:53:46.503Z" }, - { url = "https://files.pythonhosted.org/packages/be/66/5c9a321b325aaecb92d4d1855421e3a055abd77903b7dab6575ca07796db/torch-2.8.0-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:619c2869db3ada2c0105487ba21b5008defcc472d23f8b80ed91ac4a380283b0", size = 73630478, upload-time = "2025-08-06T14:53:57.144Z" }, + { url = "https://files.pythonhosted.org/packages/d1/d3/3985739f3b8e88675127bf70f82b3a48ae083e39cda56305dbd90398fec0/torch-2.9.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:e5f7af1dc4c0a7c4a260c2534f41ddaf209714f7c89145e644c44712fbd6b642", size = 104107898, upload-time = "2025-10-15T15:46:20.883Z" }, + { url = "https://files.pythonhosted.org/packages/a5/4b/f4bb2e6c25d0272f798cd6d7a04ed315da76cec68c602d87040c7847287f/torch-2.9.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:01cff95ecd9a212ea2f141db28acccdceb6a4c54f64e6c51091146f5e2a772c6", size = 899738273, upload-time = "2025-10-15T15:50:04.188Z" }, + { url = "https://files.pythonhosted.org/packages/66/11/c1c5ba6691cda6279087c35bd626536e4fd29521fe740abf5008377a9a02/torch-2.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:4582b162f541651f0cb184d3e291c05c2f556c7117c64a9873e2ee158d40062b", size = 109280887, upload-time = "2025-10-15T15:46:26.228Z" }, + { url = "https://files.pythonhosted.org/packages/dd/5f/b85bd8c05312d71de9402bf5868d217c38827cfd09d8f8514e5be128a52b/torch-2.9.0-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:33f58e9a102a91259af289d50525c30323b5c9ae1d31322b6447c0814da68695", size = 74478983, upload-time = "2025-10-15T15:46:39.406Z" }, ] [[package]] name = "torchmetrics" -version = "1.7.2" +version = "1.8.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "lightning-utilities" }, @@ -2287,28 +2407,28 @@ dependencies = [ { name = "packaging" }, { name = "torch" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b7/ec/f5a4f94c77a1b4c0a37e5c5c8b666a33bc074130258a6b655346bec560c2/torchmetrics-1.7.2.tar.gz", hash = "sha256:ba401cd01aeaa268e809c0e4f42ef8f95669bf9b485e1d93d54dc765e012338a", size = 566185, upload-time = "2025-05-28T20:26:29.543Z" } +sdist = { url = "https://files.pythonhosted.org/packages/85/2e/48a887a59ecc4a10ce9e8b35b3e3c5cef29d902c4eac143378526e7485cb/torchmetrics-1.8.2.tar.gz", hash = "sha256:cf64a901036bf107f17a524009eea7781c9c5315d130713aeca5747a686fe7a5", size = 580679, upload-time = "2025-09-03T14:00:54.077Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/56/89/b5fd7eb99b27457d71d3b7d9eca0b884fa5992abca7672aab1177c5f22d8/torchmetrics-1.7.2-py3-none-any.whl", hash = "sha256:9cc3bff07a715fcb37fb04d2a1a5ae36267c36066c097578020056653a94f2a8", size = 962510, upload-time = "2025-05-28T20:26:27.385Z" }, + { url = "https://files.pythonhosted.org/packages/02/21/aa0f434434c48490f91b65962b1ce863fdcce63febc166ca9fe9d706c2b6/torchmetrics-1.8.2-py3-none-any.whl", hash = "sha256:08382fd96b923e39e904c4d570f3d49e2cc71ccabd2a94e0f895d1f0dac86242", size = 983161, upload-time = "2025-09-03T14:00:51.921Z" }, ] [[package]] name = "tornado" -version = "6.5.1" +version = "6.5.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/51/89/c72771c81d25d53fe33e3dca61c233b665b2780f21820ba6fd2c6793c12b/tornado-6.5.1.tar.gz", hash = "sha256:84ceece391e8eb9b2b95578db65e920d2a61070260594819589609ba9bc6308c", size = 509934, upload-time = "2025-05-22T18:15:38.788Z" } +sdist = { url = "https://files.pythonhosted.org/packages/09/ce/1eb500eae19f4648281bb2186927bb062d2438c2e5093d1360391afd2f90/tornado-6.5.2.tar.gz", hash = "sha256:ab53c8f9a0fa351e2c0741284e06c7a45da86afb544133201c5cc8578eb076a0", size = 510821, upload-time = "2025-08-08T18:27:00.78Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/77/89/f4532dee6843c9e0ebc4e28d4be04c67f54f60813e4bf73d595fe7567452/tornado-6.5.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d50065ba7fd11d3bd41bcad0825227cc9a95154bad83239357094c36708001f7", size = 441948, upload-time = "2025-05-22T18:15:20.862Z" }, - { url = "https://files.pythonhosted.org/packages/15/9a/557406b62cffa395d18772e0cdcf03bed2fff03b374677348eef9f6a3792/tornado-6.5.1-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9e9ca370f717997cb85606d074b0e5b247282cf5e2e1611568b8821afe0342d6", size = 440112, upload-time = "2025-05-22T18:15:22.591Z" }, - { url = "https://files.pythonhosted.org/packages/55/82/7721b7319013a3cf881f4dffa4f60ceff07b31b394e459984e7a36dc99ec/tornado-6.5.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b77e9dfa7ed69754a54c89d82ef746398be82f749df69c4d3abe75c4d1ff4888", size = 443672, upload-time = "2025-05-22T18:15:24.027Z" }, - { url = "https://files.pythonhosted.org/packages/7d/42/d11c4376e7d101171b94e03cef0cbce43e823ed6567ceda571f54cf6e3ce/tornado-6.5.1-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:253b76040ee3bab8bcf7ba9feb136436a3787208717a1fb9f2c16b744fba7331", size = 443019, upload-time = "2025-05-22T18:15:25.735Z" }, - { url = "https://files.pythonhosted.org/packages/7d/f7/0c48ba992d875521ac761e6e04b0a1750f8150ae42ea26df1852d6a98942/tornado-6.5.1-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:308473f4cc5a76227157cdf904de33ac268af770b2c5f05ca6c1161d82fdd95e", size = 443252, upload-time = "2025-05-22T18:15:27.499Z" }, - { url = "https://files.pythonhosted.org/packages/89/46/d8d7413d11987e316df4ad42e16023cd62666a3c0dfa1518ffa30b8df06c/tornado-6.5.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:caec6314ce8a81cf69bd89909f4b633b9f523834dc1a352021775d45e51d9401", size = 443930, upload-time = "2025-05-22T18:15:29.299Z" }, - { url = "https://files.pythonhosted.org/packages/78/b2/f8049221c96a06df89bed68260e8ca94beca5ea532ffc63b1175ad31f9cc/tornado-6.5.1-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:13ce6e3396c24e2808774741331638ee6c2f50b114b97a55c5b442df65fd9692", size = 443351, upload-time = "2025-05-22T18:15:31.038Z" }, - { url = "https://files.pythonhosted.org/packages/76/ff/6a0079e65b326cc222a54720a748e04a4db246870c4da54ece4577bfa702/tornado-6.5.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5cae6145f4cdf5ab24744526cc0f55a17d76f02c98f4cff9daa08ae9a217448a", size = 443328, upload-time = "2025-05-22T18:15:32.426Z" }, - { url = "https://files.pythonhosted.org/packages/49/18/e3f902a1d21f14035b5bc6246a8c0f51e0eef562ace3a2cea403c1fb7021/tornado-6.5.1-cp39-abi3-win32.whl", hash = "sha256:e0a36e1bc684dca10b1aa75a31df8bdfed656831489bc1e6a6ebed05dc1ec365", size = 444396, upload-time = "2025-05-22T18:15:34.205Z" }, - { url = "https://files.pythonhosted.org/packages/7b/09/6526e32bf1049ee7de3bebba81572673b19a2a8541f795d887e92af1a8bc/tornado-6.5.1-cp39-abi3-win_amd64.whl", hash = "sha256:908e7d64567cecd4c2b458075589a775063453aeb1d2a1853eedb806922f568b", size = 444840, upload-time = "2025-05-22T18:15:36.1Z" }, - { url = "https://files.pythonhosted.org/packages/55/a7/535c44c7bea4578e48281d83c615219f3ab19e6abc67625ef637c73987be/tornado-6.5.1-cp39-abi3-win_arm64.whl", hash = "sha256:02420a0eb7bf617257b9935e2b754d1b63897525d8a289c9d65690d580b4dcf7", size = 443596, upload-time = "2025-05-22T18:15:37.433Z" }, + { url = "https://files.pythonhosted.org/packages/f6/48/6a7529df2c9cc12efd2e8f5dd219516184d703b34c06786809670df5b3bd/tornado-6.5.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:2436822940d37cde62771cff8774f4f00b3c8024fe482e16ca8387b8a2724db6", size = 442563, upload-time = "2025-08-08T18:26:42.945Z" }, + { url = "https://files.pythonhosted.org/packages/f2/b5/9b575a0ed3e50b00c40b08cbce82eb618229091d09f6d14bce80fc01cb0b/tornado-6.5.2-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:583a52c7aa94ee046854ba81d9ebb6c81ec0fd30386d96f7640c96dad45a03ef", size = 440729, upload-time = "2025-08-08T18:26:44.473Z" }, + { url = "https://files.pythonhosted.org/packages/1b/4e/619174f52b120efcf23633c817fd3fed867c30bff785e2cd5a53a70e483c/tornado-6.5.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0fe179f28d597deab2842b86ed4060deec7388f1fd9c1b4a41adf8af058907e", size = 444295, upload-time = "2025-08-08T18:26:46.021Z" }, + { url = "https://files.pythonhosted.org/packages/95/fa/87b41709552bbd393c85dd18e4e3499dcd8983f66e7972926db8d96aa065/tornado-6.5.2-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b186e85d1e3536d69583d2298423744740986018e393d0321df7340e71898882", size = 443644, upload-time = "2025-08-08T18:26:47.625Z" }, + { url = "https://files.pythonhosted.org/packages/f9/41/fb15f06e33d7430ca89420283a8762a4e6b8025b800ea51796ab5e6d9559/tornado-6.5.2-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e792706668c87709709c18b353da1f7662317b563ff69f00bab83595940c7108", size = 443878, upload-time = "2025-08-08T18:26:50.599Z" }, + { url = "https://files.pythonhosted.org/packages/11/92/fe6d57da897776ad2e01e279170ea8ae726755b045fe5ac73b75357a5a3f/tornado-6.5.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:06ceb1300fd70cb20e43b1ad8aaee0266e69e7ced38fa910ad2e03285009ce7c", size = 444549, upload-time = "2025-08-08T18:26:51.864Z" }, + { url = "https://files.pythonhosted.org/packages/9b/02/c8f4f6c9204526daf3d760f4aa555a7a33ad0e60843eac025ccfd6ff4a93/tornado-6.5.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:74db443e0f5251be86cbf37929f84d8c20c27a355dd452a5cfa2aada0d001ec4", size = 443973, upload-time = "2025-08-08T18:26:53.625Z" }, + { url = "https://files.pythonhosted.org/packages/ae/2d/f5f5707b655ce2317190183868cd0f6822a1121b4baeae509ceb9590d0bd/tornado-6.5.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b5e735ab2889d7ed33b32a459cac490eda71a1ba6857b0118de476ab6c366c04", size = 443954, upload-time = "2025-08-08T18:26:55.072Z" }, + { url = "https://files.pythonhosted.org/packages/e8/59/593bd0f40f7355806bf6573b47b8c22f8e1374c9b6fd03114bd6b7a3dcfd/tornado-6.5.2-cp39-abi3-win32.whl", hash = "sha256:c6f29e94d9b37a95013bb669616352ddb82e3bfe8326fccee50583caebc8a5f0", size = 445023, upload-time = "2025-08-08T18:26:56.677Z" }, + { url = "https://files.pythonhosted.org/packages/c7/2a/f609b420c2f564a748a2d80ebfb2ee02a73ca80223af712fca591386cafb/tornado-6.5.2-cp39-abi3-win_amd64.whl", hash = "sha256:e56a5af51cc30dd2cae649429af65ca2f6571da29504a07995175df14c18f35f", size = 445427, upload-time = "2025-08-08T18:26:57.91Z" }, + { url = "https://files.pythonhosted.org/packages/5e/4f/e1f65e8f8c76d73658b33d33b81eed4322fb5085350e4328d5c956f0c8f9/tornado-6.5.2-cp39-abi3-win_arm64.whl", hash = "sha256:d6c33dc3672e3a1f3618eb63b7ef4683a7688e7b9e6e8f0d9aa5726360a004af", size = 444456, upload-time = "2025-08-08T18:26:59.207Z" }, ] [[package]] @@ -2363,7 +2483,7 @@ wheels = [ [[package]] name = "transformers" -version = "4.52.4" +version = "4.57.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "filelock" }, @@ -2377,9 +2497,9 @@ dependencies = [ { name = "tokenizers" }, { name = "tqdm" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/da/a9/275037087f9d846580b02f2d7cae0e0a6955d46f84583d0151d6227bd416/transformers-4.52.4.tar.gz", hash = "sha256:aff3764441c1adc192a08dba49740d3cbbcb72d850586075aed6bd89b98203e6", size = 8945376, upload-time = "2025-05-30T09:17:17.947Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/68/a39307bcc4116a30b2106f2e689130a48de8bd8a1e635b5e1030e46fcd9e/transformers-4.57.1.tar.gz", hash = "sha256:f06c837959196c75039809636cd964b959f6604b75b8eeec6fdfc0440b89cc55", size = 10142511, upload-time = "2025-10-14T15:39:26.18Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/96/f2/25b27b396af03d5b64e61976b14f7209e2939e9e806c10749b6d277c273e/transformers-4.52.4-py3-none-any.whl", hash = "sha256:203f5c19416d5877e36e88633943761719538a25d9775977a24fe77a1e5adfc7", size = 10460375, upload-time = "2025-05-30T09:17:14.477Z" }, + { url = "https://files.pythonhosted.org/packages/71/d3/c16c3b3cf7655a67db1144da94b021c200ac1303f82428f2beef6c2e72bb/transformers-4.57.1-py3-none-any.whl", hash = "sha256:b10d05da8fa67dc41644dbbf9bc45a44cb86ae33da6f9295f5fbf5b7890bd267", size = 11990925, upload-time = "2025-10-14T15:39:23.085Z" }, ] [[package]] @@ -2393,13 +2513,10 @@ sdist = { url = "https://files.pythonhosted.org/packages/42/c2/65f13aec253100e19 [[package]] name = "triton" -version = "3.4.0" +version = "3.5.0" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "setuptools", marker = "sys_platform == 'linux'" }, -] wheels = [ - { url = "https://files.pythonhosted.org/packages/d0/66/b1eb52839f563623d185f0927eb3530ee4d5ffe9d377cdaf5346b306689e/triton-3.4.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:31c1d84a5c0ec2c0f8e8a072d7fd150cab84a9c239eaddc6706c081bfae4eb04", size = 155560068, upload-time = "2025-07-30T19:58:37.081Z" }, + { url = "https://files.pythonhosted.org/packages/f5/3a/e991574f3102147b642e49637e0281e9bb7c4ba254edb2bab78247c85e01/triton-3.5.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9e71db82261c4ffa3921cd050cd5faa18322d2d405c30eb56084afaff3b0833", size = 170476535, upload-time = "2025-10-13T16:38:05.18Z" }, ] [[package]] @@ -2415,46 +2532,70 @@ wheels = [ ] [[package]] -name = "types-python-dateutil" -version = "2.9.0.20250516" +name = "typer" +version = "0.20.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "rich" }, + { name = "shellingham" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8f/28/7c85c8032b91dbe79725b6f17d2fffc595dff06a35c7a30a37bef73a1ab4/typer-0.20.0.tar.gz", hash = "sha256:1aaf6494031793e4876fb0bacfa6a912b551cf43c1e63c800df8b1a866720c37", size = 106492, upload-time = "2025-10-20T17:03:49.445Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/64/7713ffe4b5983314e9d436a90d5bd4f63b6054e2aca783a3cfc44cb95bbf/typer-0.20.0-py3-none-any.whl", hash = "sha256:5b463df6793ec1dca6213a3cf4c0f03bc6e322ac5e16e13ddd622a889489784a", size = 47028, upload-time = "2025-10-20T17:03:47.617Z" }, +] + +[[package]] +name = "types-certifi" +version = "2021.10.8.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ef/88/d65ed807393285204ab6e2801e5d11fbbea811adcaa979a2ed3b67a5ef41/types_python_dateutil-2.9.0.20250516.tar.gz", hash = "sha256:13e80d6c9c47df23ad773d54b2826bd52dbbb41be87c3f339381c1700ad21ee5", size = 13943, upload-time = "2025-05-16T03:06:58.385Z" } +sdist = { url = "https://files.pythonhosted.org/packages/52/68/943c3aeaf14624712a0357c4a67814dba5cea36d194f5c764dad7959a00c/types-certifi-2021.10.8.3.tar.gz", hash = "sha256:72cf7798d165bc0b76e1c10dd1ea3097c7063c42c21d664523b928e88b554a4f", size = 2095, upload-time = "2022-06-09T15:19:05.244Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c5/3f/b0e8db149896005adc938a1e7f371d6d7e9eca4053a29b108978ed15e0c2/types_python_dateutil-2.9.0.20250516-py3-none-any.whl", hash = "sha256:2b2b3f57f9c6a61fba26a9c0ffb9ea5681c9b83e69cd897c6b5f668d9c0cab93", size = 14356, upload-time = "2025-05-16T03:06:57.249Z" }, + { url = "https://files.pythonhosted.org/packages/b5/63/2463d89481e811f007b0e1cd0a91e52e141b47f9de724d20db7b861dcfec/types_certifi-2021.10.8.3-py3-none-any.whl", hash = "sha256:b2d1e325e69f71f7c78e5943d410e650b4707bb0ef32e4ddf3da37f54176e88a", size = 2136, upload-time = "2022-06-09T15:19:03.127Z" }, +] + +[[package]] +name = "types-toml" +version = "0.10.8.20240310" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/86/47/3e4c75042792bff8e90d7991aa5c51812cc668828cc6cce711e97f63a607/types-toml-0.10.8.20240310.tar.gz", hash = "sha256:3d41501302972436a6b8b239c850b26689657e25281b48ff0ec06345b8830331", size = 4392, upload-time = "2024-03-10T02:18:37.518Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/a2/d32ab58c0b216912638b140ab2170ee4b8644067c293b170e19fba340ccc/types_toml-0.10.8.20240310-py3-none-any.whl", hash = "sha256:627b47775d25fa29977d9c70dc0cbab3f314f32c8d8d0c012f2ef5de7aaec05d", size = 4777, upload-time = "2024-03-10T02:18:36.568Z" }, ] [[package]] name = "typeshed-client" -version = "2.7.0" +version = "2.8.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "importlib-resources" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/65/1e/f20e33447be772486acf028295cdd21437454a051adb602d52ddb5334f9e/typeshed_client-2.7.0.tar.gz", hash = "sha256:e63df1e738588ad39f1226de042f4407ab6a99c456f0837063afd83b1415447c", size = 433569, upload-time = "2024-07-16T17:01:17.181Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/3e/4074d3505b4700a6bf13cb1bb2d1848bb8c78e902e3f9fe5916274c5d284/typeshed_client-2.8.2.tar.gz", hash = "sha256:9d8e29fb74574d87bf9a719f77131dc40f2aeea20e97d25d4a3dc2cc30debd31", size = 501617, upload-time = "2025-07-16T01:49:49.299Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fd/39/4702c2901899c018189b9aa7eb75aa8eb54527aed71c3f285895190dc664/typeshed_client-2.7.0-py3-none-any.whl", hash = "sha256:97084e5abc58a76ace2c4618ecaebd625f2d19bbd85aa1b3fb86216bf174bbea", size = 624417, upload-time = "2024-07-16T17:01:15.246Z" }, + { url = "https://files.pythonhosted.org/packages/11/db/e7474719e90062df673057e865f94f67da2d0b4f671d8051020c74962c77/typeshed_client-2.8.2-py3-none-any.whl", hash = "sha256:4cf886d976c777689cd31889f13abf5bfb7797c82519b07e5969e541380c75ee", size = 760467, upload-time = "2025-07-16T01:49:47.758Z" }, ] [[package]] name = "typing-extensions" -version = "4.14.0" +version = "4.15.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d1/bc/51647cd02527e87d05cb083ccc402f93e441606ff1f01739a62c8ad09ba5/typing_extensions-4.14.0.tar.gz", hash = "sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4", size = 107423, upload-time = "2025-06-02T14:52:11.399Z" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/69/e0/552843e0d356fbb5256d21449fa957fa4eff3bbc135a74a691ee70c7c5da/typing_extensions-4.14.0-py3-none-any.whl", hash = "sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af", size = 43839, upload-time = "2025-06-02T14:52:10.026Z" }, + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, ] [[package]] name = "typing-inspection" -version = "0.4.1" +version = "0.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726, upload-time = "2025-05-21T18:55:23.885Z" } +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552, upload-time = "2025-05-21T18:55:22.152Z" }, + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, ] [[package]] @@ -2477,25 +2618,25 @@ wheels = [ [[package]] name = "urllib3" -version = "2.4.0" +version = "2.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672, upload-time = "2025-04-10T15:23:39.232Z" } +sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680, upload-time = "2025-04-10T15:23:37.377Z" }, + { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, ] [[package]] name = "wadler-lindig" -version = "0.1.6" +version = "0.1.7" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4d/c8/e2112ecb627e01c9e2911f9b388167231c23a114946946d046f4e9535118/wadler_lindig-0.1.6.tar.gz", hash = "sha256:8b6adad9718291a7d82fb088a596b93659ce2346321ca76819810affbc66102b", size = 15812, upload-time = "2025-05-14T22:26:16.012Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1e/67/cbae4bf7683a64755c2c1778c418fea96d00e34395bb91743f08bd951571/wadler_lindig-0.1.7.tar.gz", hash = "sha256:81d14d3fe77d441acf3ebd7f4aefac20c74128bf460e84b512806dccf7b2cd55", size = 15842, upload-time = "2025-06-18T07:00:42.843Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/9a/937038f3efc70871fb26b0ee6148efcfcfb96643c517c2aaddd7ed07ad76/wadler_lindig-0.1.6-py3-none-any.whl", hash = "sha256:d707f63994c7d3e1e125e7fb7e196f4adb6f80f4a11beb955c6da937754026a3", size = 20483, upload-time = "2025-05-14T22:26:14.574Z" }, + { url = "https://files.pythonhosted.org/packages/8d/96/04e7b441807b26b794da5b11e59ed7f83b2cf8af202bd7eba8ad2fa6046e/wadler_lindig-0.1.7-py3-none-any.whl", hash = "sha256:e3ec83835570fd0a9509f969162aeb9c65618f998b1f42918cfc8d45122fe953", size = 20516, upload-time = "2025-06-18T07:00:41.684Z" }, ] [[package]] name = "wandb" -version = "0.20.1" +version = "0.22.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -2503,44 +2644,65 @@ dependencies = [ { name = "packaging" }, { name = "platformdirs" }, { name = "protobuf" }, - { name = "psutil" }, { name = "pydantic" }, { name = "pyyaml" }, { name = "requests" }, { name = "sentry-sdk" }, - { name = "setproctitle" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/62/1f/92be0ca87fb49eb48c16dcf0845a3579a57c4734fec2b95862cf5a0494a0/wandb-0.20.1.tar.gz", hash = "sha256:dbd3fc60dfe7bf83c4de24b206b99b44949fef323f817a783883db72fc5f3bfe", size = 40320062, upload-time = "2025-06-05T00:00:24.483Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c1/d1/6b70f365ed86bd69debba8ad55dec8606fc21006e7ca703a5a091bd3b719/wandb-0.22.3.tar.gz", hash = "sha256:04468a8ab2769a46f5e384c9c4ada5da0dced005ca689a8424e4b8b5cb2a0291", size = 44337368, upload-time = "2025-10-28T23:59:10.275Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/02/87fb60f587ec249f784a40bd91c30de1b2b24d691ee72675d5b66c3d0728/wandb-0.22.3-py3-none-macosx_12_0_arm64.whl", hash = "sha256:81b3b6e405f38342b0a080898b7d00c5b9375432f5ba358942a09e65cdcfe781", size = 18758047, upload-time = "2025-10-28T23:58:46.56Z" }, + { url = "https://files.pythonhosted.org/packages/26/88/64081740ef2b2efc7fbcb2139a07a849e42bcb09ae0c56ae50c41bd0ad63/wandb-0.22.3-py3-none-macosx_12_0_x86_64.whl", hash = "sha256:d29c16817cca6401b4919069ec7570c781eacb67dc0b1ff2e0096a9a59581720", size = 19798011, upload-time = "2025-10-28T23:58:49.718Z" }, + { url = "https://files.pythonhosted.org/packages/19/72/c4f922b33dbb84d1c81ee045ff8791dd14e26d79e1e9bbafff964b7043e2/wandb-0.22.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb955d73a4ba55df9adc61fafbabef5556784d33fc39c7b5c8165d2694ddeb3b", size = 18542713, upload-time = "2025-10-28T23:58:51.927Z" }, + { url = "https://files.pythonhosted.org/packages/ad/98/3ce5f6e2086d91b0c51b38ae7ff591109e7da2bb25fe1a12eec0cdbaa494/wandb-0.22.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23f3ebe41a26506117a098fdfd2706ed0e50b37899bfbefe3a0628fcbd70c69d", size = 19984910, upload-time = "2025-10-28T23:58:54.641Z" }, + { url = "https://files.pythonhosted.org/packages/5e/57/e68cb38427b60490d6ddf1b992e6c7f36be83be1079d291ce87a8d347f48/wandb-0.22.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:2973462bed5d4a653b1a97cf9fc350673bb200fb356a2f4eba34beae9b87e0aa", size = 18581776, upload-time = "2025-10-28T23:58:56.975Z" }, + { url = "https://files.pythonhosted.org/packages/66/6d/543f907ce0c6b6da13628b23d19ca7282c559fd73eb47b04977b9a61d0c6/wandb-0.22.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:c5c2bd18f95c1639863c527da0a5818ac6b0e5194f9c691426b265908ddd8b2c", size = 20078800, upload-time = "2025-10-28T23:58:59.217Z" }, + { url = "https://files.pythonhosted.org/packages/da/91/1decaf1a6ac2017481c782e0fad7f90bc9ae4057f3d76d478cb6527f3dd3/wandb-0.22.3-py3-none-win32.whl", hash = "sha256:09ca1edfe0fd6dc30447d368acddb825668e60ee705c98594a6bbfd30d34d47e", size = 19160297, upload-time = "2025-10-28T23:59:01.536Z" }, + { url = "https://files.pythonhosted.org/packages/4c/ba/3b092634279994b0c79fe05220532822be09f3a353ae95c54e7142769db8/wandb-0.22.3-py3-none-win_amd64.whl", hash = "sha256:55403bf93872c9978433d101324f51e43e78c70c809bf6d06ca7b2760e39f497", size = 19160300, upload-time = "2025-10-28T23:59:04.06Z" }, + { url = "https://files.pythonhosted.org/packages/7f/80/4662fce9eebcc8c71f5083e9152ccaf7d43d4ca9c446e1422f9aa784a51c/wandb-0.22.3-py3-none-win_arm64.whl", hash = "sha256:49f66b05882abfa53816cc8d01b3c2435a89c5a090176802fa6928b5979d34d9", size = 17461959, upload-time = "2025-10-28T23:59:07.059Z" }, +] + +[[package]] +name = "watchfiles" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c2/c9/8869df9b2a2d6c59d79220a4db37679e74f807c559ffe5265e08b227a210/watchfiles-1.1.1.tar.gz", hash = "sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2", size = 94440, upload-time = "2025-10-14T15:06:21.08Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c9/18/afcc37d0b93dd6f6d0f0c5683b9cfff9416ae1539931f58932a2938c0070/wandb-0.20.1-py3-none-any.whl", hash = "sha256:e6395cabf074247042be1cf0dc6ab0b06aa4c9538c2e1fdc5b507a690ce0cf17", size = 6458872, upload-time = "2025-06-04T23:59:55.441Z" }, - { url = "https://files.pythonhosted.org/packages/e6/b5/70f9e2a3d1380b729ae5853763d938edc50072df357f79bbd19b9aae8e3f/wandb-0.20.1-py3-none-macosx_10_14_x86_64.whl", hash = "sha256:2475a48c693adf677d40da9e1c8ceeaf86d745ffc3b7e3535731279d02f9e845", size = 22517483, upload-time = "2025-06-04T23:59:58.687Z" }, - { url = "https://files.pythonhosted.org/packages/cc/7e/4eb9aeb2fd974d410a8f2eb11b0219536503913a050d46a03206151705c8/wandb-0.20.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:99cce804c31ec1e0d1e691650a7d51773ed7329c41745d56384fa3655a0e9b2c", size = 22034511, upload-time = "2025-06-05T00:00:01.301Z" }, - { url = "https://files.pythonhosted.org/packages/34/38/1df22c2273e6f7ab0aae4fd032085d6d92ab112f5b261646e7dc5e675cfe/wandb-0.20.1-py3-none-macosx_11_0_x86_64.whl", hash = "sha256:ce3ee412677a1679e04b21e03a91e1e02eb90faf658d682bee86c33cf5f32e09", size = 22720771, upload-time = "2025-06-05T00:00:04.122Z" }, - { url = "https://files.pythonhosted.org/packages/38/96/78fc7a7ea7158d136c84f481423f8736c9346a2387287ec8a6d92019975c/wandb-0.20.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e58ca32c7147161158f09b0fb5f5896876f8569d0d10ae7b64d0510c868ce33", size = 21537453, upload-time = "2025-06-05T00:00:09.474Z" }, - { url = "https://files.pythonhosted.org/packages/88/c9/41b8bdb493e5eda32b502bc1cc49d539335a92cacaf0ef304d7dae0240aa/wandb-0.20.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:591506ecbdd396648cc323ba270f3ab4aed3158e1dbfa7636c09f9f7f0253e1c", size = 23161349, upload-time = "2025-06-05T00:00:11.903Z" }, - { url = "https://files.pythonhosted.org/packages/7d/f2/79e783cc50a47d373dfbda862eb5396de8139167e8c6443a16ef0166106f/wandb-0.20.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:382508532db09893f81cc926b1d333caa4c8a7db057878899fadf929bbdb3b56", size = 21550624, upload-time = "2025-06-05T00:00:14.28Z" }, - { url = "https://files.pythonhosted.org/packages/26/32/23890a726302e7be28bda9fff47ce9b491af64e339aba4d32b3b8d1a7aaf/wandb-0.20.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:29ea495e49393db860f17437fe37e48018da90436ce10949b471780f09293bd7", size = 23237996, upload-time = "2025-06-05T00:00:16.647Z" }, - { url = "https://files.pythonhosted.org/packages/af/94/296e520b086b2a4f10e99bcea3cd5856421b9c004824663501e3789a713b/wandb-0.20.1-py3-none-win32.whl", hash = "sha256:455ee0a652e59ab1e4b546fa1dc833dd3063aa7e64eb8abf95d22f0e9f08c574", size = 22518456, upload-time = "2025-06-05T00:00:19.006Z" }, - { url = "https://files.pythonhosted.org/packages/52/5f/c44ad7b2a062ca5f4da99ae475cea274c38f6ec37bdaca1b1c653ee87274/wandb-0.20.1-py3-none-win_amd64.whl", hash = "sha256:6d2431652f096b7e394c29a99135a6441c02ed3198b963f0b351a5b5e56aeca0", size = 22518459, upload-time = "2025-06-05T00:00:21.374Z" }, + { url = "https://files.pythonhosted.org/packages/74/d5/f039e7e3c639d9b1d09b07ea412a6806d38123f0508e5f9b48a87b0a76cc/watchfiles-1.1.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:8c89f9f2f740a6b7dcc753140dd5e1ab9215966f7a3530d0c0705c83b401bd7d", size = 404745, upload-time = "2025-10-14T15:04:46.731Z" }, + { url = "https://files.pythonhosted.org/packages/a5/96/a881a13aa1349827490dab2d363c8039527060cfcc2c92cc6d13d1b1049e/watchfiles-1.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bd404be08018c37350f0d6e34676bd1e2889990117a2b90070b3007f172d0610", size = 391769, upload-time = "2025-10-14T15:04:48.003Z" }, + { url = "https://files.pythonhosted.org/packages/4b/5b/d3b460364aeb8da471c1989238ea0e56bec24b6042a68046adf3d9ddb01c/watchfiles-1.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8526e8f916bb5b9a0a777c8317c23ce65de259422bba5b31325a6fa6029d33af", size = 449374, upload-time = "2025-10-14T15:04:49.179Z" }, + { url = "https://files.pythonhosted.org/packages/b9/44/5769cb62d4ed055cb17417c0a109a92f007114a4e07f30812a73a4efdb11/watchfiles-1.1.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2edc3553362b1c38d9f06242416a5d8e9fe235c204a4072e988ce2e5bb1f69f6", size = 459485, upload-time = "2025-10-14T15:04:50.155Z" }, + { url = "https://files.pythonhosted.org/packages/19/0c/286b6301ded2eccd4ffd0041a1b726afda999926cf720aab63adb68a1e36/watchfiles-1.1.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30f7da3fb3f2844259cba4720c3fc7138eb0f7b659c38f3bfa65084c7fc7abce", size = 488813, upload-time = "2025-10-14T15:04:51.059Z" }, + { url = "https://files.pythonhosted.org/packages/c7/2b/8530ed41112dd4a22f4dcfdb5ccf6a1baad1ff6eed8dc5a5f09e7e8c41c7/watchfiles-1.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f8979280bdafff686ba5e4d8f97840f929a87ed9cdf133cbbd42f7766774d2aa", size = 594816, upload-time = "2025-10-14T15:04:52.031Z" }, + { url = "https://files.pythonhosted.org/packages/ce/d2/f5f9fb49489f184f18470d4f99f4e862a4b3e9ac2865688eb2099e3d837a/watchfiles-1.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dcc5c24523771db3a294c77d94771abcfcb82a0e0ee8efd910c37c59ec1b31bb", size = 475186, upload-time = "2025-10-14T15:04:53.064Z" }, + { url = "https://files.pythonhosted.org/packages/cf/68/5707da262a119fb06fbe214d82dd1fe4a6f4af32d2d14de368d0349eb52a/watchfiles-1.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1db5d7ae38ff20153d542460752ff397fcf5c96090c1230803713cf3147a6803", size = 456812, upload-time = "2025-10-14T15:04:55.174Z" }, + { url = "https://files.pythonhosted.org/packages/66/ab/3cbb8756323e8f9b6f9acb9ef4ec26d42b2109bce830cc1f3468df20511d/watchfiles-1.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:28475ddbde92df1874b6c5c8aaeb24ad5be47a11f87cde5a28ef3835932e3e94", size = 630196, upload-time = "2025-10-14T15:04:56.22Z" }, + { url = "https://files.pythonhosted.org/packages/78/46/7152ec29b8335f80167928944a94955015a345440f524d2dfe63fc2f437b/watchfiles-1.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:36193ed342f5b9842edd3532729a2ad55c4160ffcfa3700e0d54be496b70dd43", size = 622657, upload-time = "2025-10-14T15:04:57.521Z" }, + { url = "https://files.pythonhosted.org/packages/0a/bf/95895e78dd75efe9a7f31733607f384b42eb5feb54bd2eb6ed57cc2e94f4/watchfiles-1.1.1-cp312-cp312-win32.whl", hash = "sha256:859e43a1951717cc8de7f4c77674a6d389b106361585951d9e69572823f311d9", size = 272042, upload-time = "2025-10-14T15:04:59.046Z" }, + { url = "https://files.pythonhosted.org/packages/87/0a/90eb755f568de2688cb220171c4191df932232c20946966c27a59c400850/watchfiles-1.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:91d4c9a823a8c987cce8fa2690923b069966dabb196dd8d137ea2cede885fde9", size = 288410, upload-time = "2025-10-14T15:05:00.081Z" }, + { url = "https://files.pythonhosted.org/packages/36/76/f322701530586922fbd6723c4f91ace21364924822a8772c549483abed13/watchfiles-1.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:a625815d4a2bdca61953dbba5a39d60164451ef34c88d751f6c368c3ea73d404", size = 278209, upload-time = "2025-10-14T15:05:01.168Z" }, ] [[package]] name = "wcwidth" -version = "0.2.13" +version = "0.2.14" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/63/53559446a878410fc5a5974feb13d31d78d752eb18aeba59c7fef1af7598/wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5", size = 101301, upload-time = "2024-01-06T02:10:57.829Z" } +sdist = { url = "https://files.pythonhosted.org/packages/24/30/6b0809f4510673dc723187aeaf24c7f5459922d01e2f794277a3dfb90345/wcwidth-0.2.14.tar.gz", hash = "sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605", size = 102293, upload-time = "2025-09-22T16:29:53.023Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166, upload-time = "2024-01-06T02:10:55.763Z" }, + { url = "https://files.pythonhosted.org/packages/af/b5/123f13c975e9f27ab9c0770f514345bd406d0e8d3b7a0723af9d43f710af/wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1", size = 37286, upload-time = "2025-09-22T16:29:51.641Z" }, ] [[package]] name = "webcolors" -version = "24.11.1" +version = "25.10.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7b/29/061ec845fb58521848f3739e466efd8250b4b7b98c1b6c5bf4d40b419b7e/webcolors-24.11.1.tar.gz", hash = "sha256:ecb3d768f32202af770477b8b65f318fa4f566c22948673a977b00d589dd80f6", size = 45064, upload-time = "2024-11-11T07:43:24.224Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/7a/eb316761ec35664ea5174709a68bbd3389de60d4a1ebab8808bfc264ed67/webcolors-25.10.0.tar.gz", hash = "sha256:62abae86504f66d0f6364c2a8520de4a0c47b80c03fc3a5f1815fedbef7c19bf", size = 53491, upload-time = "2025-10-31T07:51:03.977Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/60/e8/c0e05e4684d13459f93d312077a9a2efbe04d59c393bc2b8802248c908d4/webcolors-24.11.1-py3-none-any.whl", hash = "sha256:515291393b4cdf0eb19c155749a096f779f7d909f7cceea072791cb9095b92e9", size = 14934, upload-time = "2024-11-11T07:43:22.529Z" }, + { url = "https://files.pythonhosted.org/packages/e2/cc/e097523dd85c9cf5d354f78310927f1656c422bd7b2613b2db3e3f9a0f2c/webcolors-25.10.0-py3-none-any.whl", hash = "sha256:032c727334856fc0b968f63daa252a1ac93d33db2f5267756623c210e57a4f1d", size = 14905, upload-time = "2025-10-31T07:51:01.778Z" }, ] [[package]] @@ -2554,20 +2716,20 @@ wheels = [ [[package]] name = "websocket-client" -version = "1.8.0" +version = "1.9.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e6/30/fba0d96b4b5fbf5948ed3f4681f7da2f9f64512e1d303f94b4cc174c24a5/websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da", size = 54648, upload-time = "2024-04-23T22:16:16.976Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2c/41/aa4bf9664e4cda14c3b39865b12251e8e7d239f4cd0e3cc1b6c2ccde25c1/websocket_client-1.9.0.tar.gz", hash = "sha256:9e813624b6eb619999a97dc7958469217c3176312b3a16a4bd1bc7e08a46ec98", size = 70576, upload-time = "2025-10-07T21:16:36.495Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526", size = 58826, upload-time = "2024-04-23T22:16:14.422Z" }, + { url = "https://files.pythonhosted.org/packages/34/db/b10e48aa8fff7407e67470363eac595018441cf32d5e1001567a7aeba5d2/websocket_client-1.9.0-py3-none-any.whl", hash = "sha256:af248a825037ef591efbf6ed20cc5faa03d3b47b9e5a2230a529eeee1c1fc3ef", size = 82616, upload-time = "2025-10-07T21:16:34.951Z" }, ] [[package]] name = "widgetsnbextension" -version = "4.0.14" +version = "4.0.15" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/41/53/2e0253c5efd69c9656b1843892052a31c36d37ad42812b5da45c62191f7e/widgetsnbextension-4.0.14.tar.gz", hash = "sha256:a3629b04e3edb893212df862038c7232f62973373869db5084aed739b437b5af", size = 1097428, upload-time = "2025-04-10T13:01:25.628Z" } +sdist = { url = "https://files.pythonhosted.org/packages/bd/f4/c67440c7fb409a71b7404b7aefcd7569a9c0d6bd071299bf4198ae7a5d95/widgetsnbextension-4.0.15.tar.gz", hash = "sha256:de8610639996f1567952d763a5a41af8af37f2575a41f9852a38f947eb82a3b9", size = 1097402, upload-time = "2025-11-01T21:15:55.178Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ca/51/5447876806d1088a0f8f71e16542bf350918128d0a69437df26047c8e46f/widgetsnbextension-4.0.14-py3-none-any.whl", hash = "sha256:4875a9eaf72fbf5079dc372a51a9f268fc38d46f767cbf85c43a36da5cb9b575", size = 2196503, upload-time = "2025-04-10T13:01:23.086Z" }, + { url = "https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl", hash = "sha256:8156704e4346a571d9ce73b84bee86a29906c9abfd7223b7228a28899ccf3366", size = 2196503, upload-time = "2025-11-01T21:15:53.565Z" }, ] [[package]] @@ -2584,54 +2746,53 @@ wheels = [ [[package]] name = "xxhash" -version = "3.5.0" +version = "3.6.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/00/5e/d6e5258d69df8b4ed8c83b6664f2b47d30d2dec551a29ad72a6c69eafd31/xxhash-3.5.0.tar.gz", hash = "sha256:84f2caddf951c9cbf8dc2e22a89d4ccf5d86391ac6418fe81e3c67d0cf60b45f", size = 84241, upload-time = "2024-08-17T09:20:38.972Z" } +sdist = { url = "https://files.pythonhosted.org/packages/02/84/30869e01909fb37a6cc7e18688ee8bf1e42d57e7e0777636bd47524c43c7/xxhash-3.6.0.tar.gz", hash = "sha256:f0162a78b13a0d7617b2845b90c763339d1f1d82bb04a4b07f4ab535cc5e05d6", size = 85160, upload-time = "2025-10-02T14:37:08.097Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/07/0e/1bfce2502c57d7e2e787600b31c83535af83746885aa1a5f153d8c8059d6/xxhash-3.5.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:14470ace8bd3b5d51318782cd94e6f94431974f16cb3b8dc15d52f3b69df8e00", size = 31969, upload-time = "2024-08-17T09:18:24.025Z" }, - { url = "https://files.pythonhosted.org/packages/3f/d6/8ca450d6fe5b71ce521b4e5db69622383d039e2b253e9b2f24f93265b52c/xxhash-3.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:59aa1203de1cb96dbeab595ded0ad0c0056bb2245ae11fac11c0ceea861382b9", size = 30787, upload-time = "2024-08-17T09:18:25.318Z" }, - { url = "https://files.pythonhosted.org/packages/5b/84/de7c89bc6ef63d750159086a6ada6416cc4349eab23f76ab870407178b93/xxhash-3.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08424f6648526076e28fae6ea2806c0a7d504b9ef05ae61d196d571e5c879c84", size = 220959, upload-time = "2024-08-17T09:18:26.518Z" }, - { url = "https://files.pythonhosted.org/packages/fe/86/51258d3e8a8545ff26468c977101964c14d56a8a37f5835bc0082426c672/xxhash-3.5.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:61a1ff00674879725b194695e17f23d3248998b843eb5e933007ca743310f793", size = 200006, upload-time = "2024-08-17T09:18:27.905Z" }, - { url = "https://files.pythonhosted.org/packages/02/0a/96973bd325412feccf23cf3680fd2246aebf4b789122f938d5557c54a6b2/xxhash-3.5.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2f2c61bee5844d41c3eb015ac652a0229e901074951ae48581d58bfb2ba01be", size = 428326, upload-time = "2024-08-17T09:18:29.335Z" }, - { url = "https://files.pythonhosted.org/packages/11/a7/81dba5010f7e733de88af9555725146fc133be97ce36533867f4c7e75066/xxhash-3.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d32a592cac88d18cc09a89172e1c32d7f2a6e516c3dfde1b9adb90ab5df54a6", size = 194380, upload-time = "2024-08-17T09:18:30.706Z" }, - { url = "https://files.pythonhosted.org/packages/fb/7d/f29006ab398a173f4501c0e4977ba288f1c621d878ec217b4ff516810c04/xxhash-3.5.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70dabf941dede727cca579e8c205e61121afc9b28516752fd65724be1355cc90", size = 207934, upload-time = "2024-08-17T09:18:32.133Z" }, - { url = "https://files.pythonhosted.org/packages/8a/6e/6e88b8f24612510e73d4d70d9b0c7dff62a2e78451b9f0d042a5462c8d03/xxhash-3.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e5d0ddaca65ecca9c10dcf01730165fd858533d0be84c75c327487c37a906a27", size = 216301, upload-time = "2024-08-17T09:18:33.474Z" }, - { url = "https://files.pythonhosted.org/packages/af/51/7862f4fa4b75a25c3b4163c8a873f070532fe5f2d3f9b3fc869c8337a398/xxhash-3.5.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e5b5e16c5a480fe5f59f56c30abdeba09ffd75da8d13f6b9b6fd224d0b4d0a2", size = 203351, upload-time = "2024-08-17T09:18:34.889Z" }, - { url = "https://files.pythonhosted.org/packages/22/61/8d6a40f288f791cf79ed5bb113159abf0c81d6efb86e734334f698eb4c59/xxhash-3.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149b7914451eb154b3dfaa721315117ea1dac2cc55a01bfbd4df7c68c5dd683d", size = 210294, upload-time = "2024-08-17T09:18:36.355Z" }, - { url = "https://files.pythonhosted.org/packages/17/02/215c4698955762d45a8158117190261b2dbefe9ae7e5b906768c09d8bc74/xxhash-3.5.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:eade977f5c96c677035ff39c56ac74d851b1cca7d607ab3d8f23c6b859379cab", size = 414674, upload-time = "2024-08-17T09:18:38.536Z" }, - { url = "https://files.pythonhosted.org/packages/31/5c/b7a8db8a3237cff3d535261325d95de509f6a8ae439a5a7a4ffcff478189/xxhash-3.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fa9f547bd98f5553d03160967866a71056a60960be00356a15ecc44efb40ba8e", size = 192022, upload-time = "2024-08-17T09:18:40.138Z" }, - { url = "https://files.pythonhosted.org/packages/78/e3/dd76659b2811b3fd06892a8beb850e1996b63e9235af5a86ea348f053e9e/xxhash-3.5.0-cp312-cp312-win32.whl", hash = "sha256:f7b58d1fd3551b8c80a971199543379be1cee3d0d409e1f6d8b01c1a2eebf1f8", size = 30170, upload-time = "2024-08-17T09:18:42.163Z" }, - { url = "https://files.pythonhosted.org/packages/d9/6b/1c443fe6cfeb4ad1dcf231cdec96eb94fb43d6498b4469ed8b51f8b59a37/xxhash-3.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:fa0cafd3a2af231b4e113fba24a65d7922af91aeb23774a8b78228e6cd785e3e", size = 30040, upload-time = "2024-08-17T09:18:43.699Z" }, - { url = "https://files.pythonhosted.org/packages/0f/eb/04405305f290173acc0350eba6d2f1a794b57925df0398861a20fbafa415/xxhash-3.5.0-cp312-cp312-win_arm64.whl", hash = "sha256:586886c7e89cb9828bcd8a5686b12e161368e0064d040e225e72607b43858ba2", size = 26796, upload-time = "2024-08-17T09:18:45.29Z" }, + { url = "https://files.pythonhosted.org/packages/9a/07/d9412f3d7d462347e4511181dea65e47e0d0e16e26fbee2ea86a2aefb657/xxhash-3.6.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:01362c4331775398e7bb34e3ab403bc9ee9f7c497bc7dee6272114055277dd3c", size = 32744, upload-time = "2025-10-02T14:34:34.622Z" }, + { url = "https://files.pythonhosted.org/packages/79/35/0429ee11d035fc33abe32dca1b2b69e8c18d236547b9a9b72c1929189b9a/xxhash-3.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b7b2df81a23f8cb99656378e72501b2cb41b1827c0f5a86f87d6b06b69f9f204", size = 30816, upload-time = "2025-10-02T14:34:36.043Z" }, + { url = "https://files.pythonhosted.org/packages/b7/f2/57eb99aa0f7d98624c0932c5b9a170e1806406cdbcdb510546634a1359e0/xxhash-3.6.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:dc94790144e66b14f67b10ac8ed75b39ca47536bf8800eb7c24b50271ea0c490", size = 194035, upload-time = "2025-10-02T14:34:37.354Z" }, + { url = "https://files.pythonhosted.org/packages/4c/ed/6224ba353690d73af7a3f1c7cdb1fc1b002e38f783cb991ae338e1eb3d79/xxhash-3.6.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:93f107c673bccf0d592cdba077dedaf52fe7f42dcd7676eba1f6d6f0c3efffd2", size = 212914, upload-time = "2025-10-02T14:34:38.6Z" }, + { url = "https://files.pythonhosted.org/packages/38/86/fb6b6130d8dd6b8942cc17ab4d90e223653a89aa32ad2776f8af7064ed13/xxhash-3.6.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2aa5ee3444c25b69813663c9f8067dcfaa2e126dc55e8dddf40f4d1c25d7effa", size = 212163, upload-time = "2025-10-02T14:34:39.872Z" }, + { url = "https://files.pythonhosted.org/packages/ee/dc/e84875682b0593e884ad73b2d40767b5790d417bde603cceb6878901d647/xxhash-3.6.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f7f99123f0e1194fa59cc69ad46dbae2e07becec5df50a0509a808f90a0f03f0", size = 445411, upload-time = "2025-10-02T14:34:41.569Z" }, + { url = "https://files.pythonhosted.org/packages/11/4f/426f91b96701ec2f37bb2b8cec664eff4f658a11f3fa9d94f0a887ea6d2b/xxhash-3.6.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:49e03e6fe2cac4a1bc64952dd250cf0dbc5ef4ebb7b8d96bce82e2de163c82a2", size = 193883, upload-time = "2025-10-02T14:34:43.249Z" }, + { url = "https://files.pythonhosted.org/packages/53/5a/ddbb83eee8e28b778eacfc5a85c969673e4023cdeedcfcef61f36731610b/xxhash-3.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bd17fede52a17a4f9a7bc4472a5867cb0b160deeb431795c0e4abe158bc784e9", size = 210392, upload-time = "2025-10-02T14:34:45.042Z" }, + { url = "https://files.pythonhosted.org/packages/1e/c2/ff69efd07c8c074ccdf0a4f36fcdd3d27363665bcdf4ba399abebe643465/xxhash-3.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:6fb5f5476bef678f69db04f2bd1efbed3030d2aba305b0fc1773645f187d6a4e", size = 197898, upload-time = "2025-10-02T14:34:46.302Z" }, + { url = "https://files.pythonhosted.org/packages/58/ca/faa05ac19b3b622c7c9317ac3e23954187516298a091eb02c976d0d3dd45/xxhash-3.6.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:843b52f6d88071f87eba1631b684fcb4b2068cd2180a0224122fe4ef011a9374", size = 210655, upload-time = "2025-10-02T14:34:47.571Z" }, + { url = "https://files.pythonhosted.org/packages/d4/7a/06aa7482345480cc0cb597f5c875b11a82c3953f534394f620b0be2f700c/xxhash-3.6.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7d14a6cfaf03b1b6f5f9790f76880601ccc7896aff7ab9cd8978a939c1eb7e0d", size = 414001, upload-time = "2025-10-02T14:34:49.273Z" }, + { url = "https://files.pythonhosted.org/packages/23/07/63ffb386cd47029aa2916b3d2f454e6cc5b9f5c5ada3790377d5430084e7/xxhash-3.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:418daf3db71e1413cfe211c2f9a528456936645c17f46b5204705581a45390ae", size = 191431, upload-time = "2025-10-02T14:34:50.798Z" }, + { url = "https://files.pythonhosted.org/packages/0f/93/14fde614cadb4ddf5e7cebf8918b7e8fac5ae7861c1875964f17e678205c/xxhash-3.6.0-cp312-cp312-win32.whl", hash = "sha256:50fc255f39428a27299c20e280d6193d8b63b8ef8028995323bf834a026b4fbb", size = 30617, upload-time = "2025-10-02T14:34:51.954Z" }, + { url = "https://files.pythonhosted.org/packages/13/5d/0d125536cbe7565a83d06e43783389ecae0c0f2ed037b48ede185de477c0/xxhash-3.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:c0f2ab8c715630565ab8991b536ecded9416d615538be8ecddce43ccf26cbc7c", size = 31534, upload-time = "2025-10-02T14:34:53.276Z" }, + { url = "https://files.pythonhosted.org/packages/54/85/6ec269b0952ec7e36ba019125982cf11d91256a778c7c3f98a4c5043d283/xxhash-3.6.0-cp312-cp312-win_arm64.whl", hash = "sha256:eae5c13f3bc455a3bbb68bdc513912dc7356de7e2280363ea235f71f54064829", size = 27876, upload-time = "2025-10-02T14:34:54.371Z" }, ] [[package]] name = "yarl" -version = "1.20.0" +version = "1.22.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "multidict" }, { name = "propcache" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/62/51/c0edba5219027f6eab262e139f73e2417b0f4efffa23bf562f6e18f76ca5/yarl-1.20.0.tar.gz", hash = "sha256:686d51e51ee5dfe62dec86e4866ee0e9ed66df700d55c828a615640adc885307", size = 185258, upload-time = "2025-04-17T00:45:14.661Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c3/e8/3efdcb83073df978bb5b1a9cc0360ce596680e6c3fac01f2a994ccbb8939/yarl-1.20.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e06b9f6cdd772f9b665e5ba8161968e11e403774114420737f7884b5bd7bdf6f", size = 147089, upload-time = "2025-04-17T00:42:39.602Z" }, - { url = "https://files.pythonhosted.org/packages/60/c3/9e776e98ea350f76f94dd80b408eaa54e5092643dbf65fd9babcffb60509/yarl-1.20.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b9ae2fbe54d859b3ade40290f60fe40e7f969d83d482e84d2c31b9bff03e359e", size = 97706, upload-time = "2025-04-17T00:42:41.469Z" }, - { url = "https://files.pythonhosted.org/packages/0c/5b/45cdfb64a3b855ce074ae607b9fc40bc82e7613b94e7612b030255c93a09/yarl-1.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6d12b8945250d80c67688602c891237994d203d42427cb14e36d1a732eda480e", size = 95719, upload-time = "2025-04-17T00:42:43.666Z" }, - { url = "https://files.pythonhosted.org/packages/2d/4e/929633b249611eeed04e2f861a14ed001acca3ef9ec2a984a757b1515889/yarl-1.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:087e9731884621b162a3e06dc0d2d626e1542a617f65ba7cc7aeab279d55ad33", size = 343972, upload-time = "2025-04-17T00:42:45.391Z" }, - { url = "https://files.pythonhosted.org/packages/49/fd/047535d326c913f1a90407a3baf7ff535b10098611eaef2c527e32e81ca1/yarl-1.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:69df35468b66c1a6e6556248e6443ef0ec5f11a7a4428cf1f6281f1879220f58", size = 339639, upload-time = "2025-04-17T00:42:47.552Z" }, - { url = "https://files.pythonhosted.org/packages/48/2f/11566f1176a78f4bafb0937c0072410b1b0d3640b297944a6a7a556e1d0b/yarl-1.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b2992fe29002fd0d4cbaea9428b09af9b8686a9024c840b8a2b8f4ea4abc16f", size = 353745, upload-time = "2025-04-17T00:42:49.406Z" }, - { url = "https://files.pythonhosted.org/packages/26/17/07dfcf034d6ae8837b33988be66045dd52f878dfb1c4e8f80a7343f677be/yarl-1.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4c903e0b42aab48abfbac668b5a9d7b6938e721a6341751331bcd7553de2dcae", size = 354178, upload-time = "2025-04-17T00:42:51.588Z" }, - { url = "https://files.pythonhosted.org/packages/15/45/212604d3142d84b4065d5f8cab6582ed3d78e4cc250568ef2a36fe1cf0a5/yarl-1.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf099e2432131093cc611623e0b0bcc399b8cddd9a91eded8bfb50402ec35018", size = 349219, upload-time = "2025-04-17T00:42:53.674Z" }, - { url = "https://files.pythonhosted.org/packages/e6/e0/a10b30f294111c5f1c682461e9459935c17d467a760c21e1f7db400ff499/yarl-1.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8a7f62f5dc70a6c763bec9ebf922be52aa22863d9496a9a30124d65b489ea672", size = 337266, upload-time = "2025-04-17T00:42:55.49Z" }, - { url = "https://files.pythonhosted.org/packages/33/a6/6efa1d85a675d25a46a167f9f3e80104cde317dfdf7f53f112ae6b16a60a/yarl-1.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:54ac15a8b60382b2bcefd9a289ee26dc0920cf59b05368c9b2b72450751c6eb8", size = 360873, upload-time = "2025-04-17T00:42:57.895Z" }, - { url = "https://files.pythonhosted.org/packages/77/67/c8ab718cb98dfa2ae9ba0f97bf3cbb7d45d37f13fe1fbad25ac92940954e/yarl-1.20.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:25b3bc0763a7aca16a0f1b5e8ef0f23829df11fb539a1b70476dcab28bd83da7", size = 360524, upload-time = "2025-04-17T00:43:00.094Z" }, - { url = "https://files.pythonhosted.org/packages/bd/e8/c3f18660cea1bc73d9f8a2b3ef423def8dadbbae6c4afabdb920b73e0ead/yarl-1.20.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b2586e36dc070fc8fad6270f93242124df68b379c3a251af534030a4a33ef594", size = 365370, upload-time = "2025-04-17T00:43:02.242Z" }, - { url = "https://files.pythonhosted.org/packages/c9/99/33f3b97b065e62ff2d52817155a89cfa030a1a9b43fee7843ef560ad9603/yarl-1.20.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:866349da9d8c5290cfefb7fcc47721e94de3f315433613e01b435473be63daa6", size = 373297, upload-time = "2025-04-17T00:43:04.189Z" }, - { url = "https://files.pythonhosted.org/packages/3d/89/7519e79e264a5f08653d2446b26d4724b01198a93a74d2e259291d538ab1/yarl-1.20.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:33bb660b390a0554d41f8ebec5cd4475502d84104b27e9b42f5321c5192bfcd1", size = 378771, upload-time = "2025-04-17T00:43:06.609Z" }, - { url = "https://files.pythonhosted.org/packages/3a/58/6c460bbb884abd2917c3eef6f663a4a873f8dc6f498561fc0ad92231c113/yarl-1.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:737e9f171e5a07031cbee5e9180f6ce21a6c599b9d4b2c24d35df20a52fabf4b", size = 375000, upload-time = "2025-04-17T00:43:09.01Z" }, - { url = "https://files.pythonhosted.org/packages/3b/2a/dd7ed1aa23fea996834278d7ff178f215b24324ee527df53d45e34d21d28/yarl-1.20.0-cp312-cp312-win32.whl", hash = "sha256:839de4c574169b6598d47ad61534e6981979ca2c820ccb77bf70f4311dd2cc64", size = 86355, upload-time = "2025-04-17T00:43:11.311Z" }, - { url = "https://files.pythonhosted.org/packages/ca/c6/333fe0338305c0ac1c16d5aa7cc4841208d3252bbe62172e0051006b5445/yarl-1.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:3d7dbbe44b443b0c4aa0971cb07dcb2c2060e4a9bf8d1301140a33a93c98e18c", size = 92904, upload-time = "2025-04-17T00:43:13.087Z" }, - { url = "https://files.pythonhosted.org/packages/ea/1f/70c57b3d7278e94ed22d85e09685d3f0a38ebdd8c5c73b65ba4c0d0fe002/yarl-1.20.0-py3-none-any.whl", hash = "sha256:5d0fe6af927a47a230f31e6004621fd0959eaa915fc62acfafa67ff7229a3124", size = 46124, upload-time = "2025-04-17T00:45:12.199Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/57/63/0c6ebca57330cd313f6102b16dd57ffaf3ec4c83403dcb45dbd15c6f3ea1/yarl-1.22.0.tar.gz", hash = "sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71", size = 187169, upload-time = "2025-10-06T14:12:55.963Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/75/ff/46736024fee3429b80a165a732e38e5d5a238721e634ab41b040d49f8738/yarl-1.22.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e340382d1afa5d32b892b3ff062436d592ec3d692aeea3bef3a5cfe11bbf8c6f", size = 142000, upload-time = "2025-10-06T14:09:44.631Z" }, + { url = "https://files.pythonhosted.org/packages/5a/9a/b312ed670df903145598914770eb12de1bac44599549b3360acc96878df8/yarl-1.22.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f1e09112a2c31ffe8d80be1b0988fa6a18c5d5cad92a9ffbb1c04c91bfe52ad2", size = 94338, upload-time = "2025-10-06T14:09:46.372Z" }, + { url = "https://files.pythonhosted.org/packages/ba/f5/0601483296f09c3c65e303d60c070a5c19fcdbc72daa061e96170785bc7d/yarl-1.22.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:939fe60db294c786f6b7c2d2e121576628468f65453d86b0fe36cb52f987bd74", size = 94909, upload-time = "2025-10-06T14:09:48.648Z" }, + { url = "https://files.pythonhosted.org/packages/60/41/9a1fe0b73dbcefce72e46cf149b0e0a67612d60bfc90fb59c2b2efdfbd86/yarl-1.22.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e1651bf8e0398574646744c1885a41198eba53dc8a9312b954073f845c90a8df", size = 372940, upload-time = "2025-10-06T14:09:50.089Z" }, + { url = "https://files.pythonhosted.org/packages/17/7a/795cb6dfee561961c30b800f0ed616b923a2ec6258b5def2a00bf8231334/yarl-1.22.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b8a0588521a26bf92a57a1705b77b8b59044cdceccac7151bd8d229e66b8dedb", size = 345825, upload-time = "2025-10-06T14:09:52.142Z" }, + { url = "https://files.pythonhosted.org/packages/d7/93/a58f4d596d2be2ae7bab1a5846c4d270b894958845753b2c606d666744d3/yarl-1.22.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42188e6a615c1a75bcaa6e150c3fe8f3e8680471a6b10150c5f7e83f47cc34d2", size = 386705, upload-time = "2025-10-06T14:09:54.128Z" }, + { url = "https://files.pythonhosted.org/packages/61/92/682279d0e099d0e14d7fd2e176bd04f48de1484f56546a3e1313cd6c8e7c/yarl-1.22.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6d2cb59377d99718913ad9a151030d6f83ef420a2b8f521d94609ecc106ee82", size = 396518, upload-time = "2025-10-06T14:09:55.762Z" }, + { url = "https://files.pythonhosted.org/packages/db/0f/0d52c98b8a885aeda831224b78f3be7ec2e1aa4a62091f9f9188c3c65b56/yarl-1.22.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50678a3b71c751d58d7908edc96d332af328839eea883bb554a43f539101277a", size = 377267, upload-time = "2025-10-06T14:09:57.958Z" }, + { url = "https://files.pythonhosted.org/packages/22/42/d2685e35908cbeaa6532c1fc73e89e7f2efb5d8a7df3959ea8e37177c5a3/yarl-1.22.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e8fbaa7cec507aa24ea27a01456e8dd4b6fab829059b69844bd348f2d467124", size = 365797, upload-time = "2025-10-06T14:09:59.527Z" }, + { url = "https://files.pythonhosted.org/packages/a2/83/cf8c7bcc6355631762f7d8bdab920ad09b82efa6b722999dfb05afa6cfac/yarl-1.22.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:433885ab5431bc3d3d4f2f9bd15bfa1614c522b0f1405d62c4f926ccd69d04fa", size = 365535, upload-time = "2025-10-06T14:10:01.139Z" }, + { url = "https://files.pythonhosted.org/packages/25/e1/5302ff9b28f0c59cac913b91fe3f16c59a033887e57ce9ca5d41a3a94737/yarl-1.22.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b790b39c7e9a4192dc2e201a282109ed2985a1ddbd5ac08dc56d0e121400a8f7", size = 382324, upload-time = "2025-10-06T14:10:02.756Z" }, + { url = "https://files.pythonhosted.org/packages/bf/cd/4617eb60f032f19ae3a688dc990d8f0d89ee0ea378b61cac81ede3e52fae/yarl-1.22.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:31f0b53913220599446872d757257be5898019c85e7971599065bc55065dc99d", size = 383803, upload-time = "2025-10-06T14:10:04.552Z" }, + { url = "https://files.pythonhosted.org/packages/59/65/afc6e62bb506a319ea67b694551dab4a7e6fb7bf604e9bd9f3e11d575fec/yarl-1.22.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a49370e8f711daec68d09b821a34e1167792ee2d24d405cbc2387be4f158b520", size = 374220, upload-time = "2025-10-06T14:10:06.489Z" }, + { url = "https://files.pythonhosted.org/packages/e7/3d/68bf18d50dc674b942daec86a9ba922d3113d8399b0e52b9897530442da2/yarl-1.22.0-cp312-cp312-win32.whl", hash = "sha256:70dfd4f241c04bd9239d53b17f11e6ab672b9f1420364af63e8531198e3f5fe8", size = 81589, upload-time = "2025-10-06T14:10:09.254Z" }, + { url = "https://files.pythonhosted.org/packages/c8/9a/6ad1a9b37c2f72874f93e691b2e7ecb6137fb2b899983125db4204e47575/yarl-1.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:8884d8b332a5e9b88e23f60bb166890009429391864c685e17bd73a9eda9105c", size = 87213, upload-time = "2025-10-06T14:10:11.369Z" }, + { url = "https://files.pythonhosted.org/packages/44/c5/c21b562d1680a77634d748e30c653c3ca918beb35555cff24986fff54598/yarl-1.22.0-cp312-cp312-win_arm64.whl", hash = "sha256:ea70f61a47f3cc93bdf8b2f368ed359ef02a01ca6393916bc8ff877427181e74", size = 81330, upload-time = "2025-10-06T14:10:13.112Z" }, + { url = "https://files.pythonhosted.org/packages/73/ae/b48f95715333080afb75a4504487cbe142cae1268afc482d06692d605ae6/yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff", size = 46814, upload-time = "2025-10-06T14:12:53.872Z" }, ] From e682bd2493c0ded56f0c47e1e8b21a7a24748cac Mon Sep 17 00:00:00 2001 From: jiito Date: Tue, 16 Sep 2025 08:43:01 -0700 Subject: [PATCH 06/99] trust remote code --- crosslayer_transcoder/data/data_generator.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/crosslayer_transcoder/data/data_generator.py b/crosslayer_transcoder/data/data_generator.py index 5bd5e2f..7685d35 100644 --- a/crosslayer_transcoder/data/data_generator.py +++ b/crosslayer_transcoder/data/data_generator.py @@ -14,12 +14,18 @@ from torch.utils.data import DataLoader from crosslayer_transcoder.data import text_dataset -from crosslayer_transcoder.data.activation_sources import ActivationComputer, DiskActivationSource +from crosslayer_transcoder.data.activation_sources import ( + ActivationComputer, + DiskActivationSource, +) from crosslayer_transcoder.data.deployment_policy import DeploymentPolicy # DataLoaderConfig no longer needed - using individual parameters from crosslayer_transcoder.data.generation_loop import DataGenerationLoop -from crosslayer_transcoder.data.process_monitor import ProcessMonitor, WandBProcessMonitor +from crosslayer_transcoder.data.process_monitor import ( + ProcessMonitor, + WandBProcessMonitor, +) from crosslayer_transcoder.data.shared_memory import SharedActivationBuffer logger = logging.getLogger(__name__) @@ -52,7 +58,9 @@ def __init__( device_map: str = "auto", wandb_logging: Optional[dict] = None, ): - super().__init__(daemon=False) # Can't be daemon if we want to use DataLoader workers + super().__init__( + daemon=False + ) # Can't be daemon if we want to use DataLoader workers self.shared_buffer = shared_buffer # Store parameters directly instead of config object @@ -160,7 +168,11 @@ def setup(self): # 2. Load dataset in the process logger.info(f"Loading dataset: {self.dataset_name}") - dataset = load_dataset(self.dataset_name, split=self.dataset_split) + dataset = load_dataset( + self.dataset_name, + split=self.dataset_split, + trust_remote_code=True, + ) # 3. Create components activation_computer = ActivationComputer(self.n_layers) From 67eb715aed2be86a0544f740db6da606f77805ec Mon Sep 17 00:00:00 2001 From: jiito Date: Tue, 16 Sep 2025 08:43:41 -0700 Subject: [PATCH 07/99] add HF_HOME env vars --- crosslayer_transcoder/modal/train.py | 124 ++++++++++++++++++++------- 1 file changed, 95 insertions(+), 29 deletions(-) diff --git a/crosslayer_transcoder/modal/train.py b/crosslayer_transcoder/modal/train.py index 3243a87..1c3d53c 100644 --- a/crosslayer_transcoder/modal/train.py +++ b/crosslayer_transcoder/modal/train.py @@ -8,38 +8,44 @@ import torch as t volume = modal.Volume.from_name("clt-checkpoints", create_if_missing=True) +cache_volume = modal.Volume.from_name("cache", create_if_missing=True) -image = modal.Image.debian_slim(python_version="3.12").pip_install( - "torch>=2.8.0", - "nnsight==0.5.0.dev7", - "datasets==3.6.0", - "h5py>=3.13.0", - "einops>=0.8.1", - "jaxtyping>=0.3.2", - "lightning>=2.5.1", - "wandb>=0.19.11", - "transformers>=4.46.0", - "numpy>=1.24.0", - "jsonargparse[signatures]>=4.27.7", -) - -image = image.add_local_python_source("crosslayer_transcoder") - - -app = modal.App("clt-train", image=image) - -wandb_secret = modal.Secret.from_name("wandb-secret") - - +cache_volume_path = Path("/hf") volume_path = Path("/experiments") +HF_HOME_PATH = cache_volume_path ACTIVATIONS_PATH = volume_path / "activations" CHECKPOINTS_PATH = volume_path / "checkpoints" WANDB_PATH = volume_path / "wandb" -volumes = {volume_path: volume} +volumes = {volume_path: volume, cache_volume_path: cache_volume} + +image = ( + modal.Image.debian_slim(python_version="3.12") + .pip_install( + "torch>=2.8.0", + "nnsight==0.5.0.dev7", + "datasets==3.6.0", + "h5py>=3.13.0", + "einops>=0.8.1", + "jaxtyping>=0.3.2", + "lightning>=2.5.1", + "wandb>=0.19.11", + "transformers>=4.46.0", + "numpy>=1.24.0", + "jsonargparse[signatures]>=4.27.7", + "huggingface_hub[hf_transfer]", + ) + .env({"HF_HUB_ENABLE_HF_TRANSFER": "1", "HF_HOME": HF_HOME_PATH.as_posix()}) + .add_local_python_source("crosslayer_transcoder") +) + +wandb_secret = modal.Secret.from_name("wandb-secret") retries = modal.Retries(initial_delay=0.0, max_retries=10) +app = modal.App("clt-train", image=image) + + logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) @@ -59,10 +65,10 @@ def ensure_directories(): secrets=[wandb_secret], ) def train_interruptible(*args, **kwargs): - train(*args, **kwargs) + train(*args, **kwargs, volume=volume) -def train(experiment): +def train(experiment, volume=None): ensure_directories() experiment_dir = CHECKPOINTS_PATH / experiment last_checkpoint = experiment_dir / "last.ckpt" @@ -73,6 +79,7 @@ def train(experiment): ACTIVATIONS_PATH, experiment_dir, resume_from_checkpoint=last_checkpoint, + volume=volume, ) print("⚡️ training finished successfully") else: @@ -106,10 +113,12 @@ def get_checkpoint(checkpoint_dir): ) -def train_model(data_dir, checkpoint_dir, resume_from_checkpoint=None): +def train_model(data_dir, checkpoint_dir, resume_from_checkpoint=None, volume=None): import lightning as L from lightning.pytorch.loggers import WandbLogger + L.seed_everything(42) + model = get_model() train_loader = get_train_loader( data_dir=data_dir, file_name="openai-community_gpt2.h5", accessor="activations" @@ -118,7 +127,7 @@ def train_model(data_dir, checkpoint_dir, resume_from_checkpoint=None): wandb_logger = WandbLogger(project="clt-train-modal") logger.info("Compiling model") - # model = t.compile(model) + model = t.compile(model) logger.info("Model compiled") trainer = L.Trainer( @@ -126,6 +135,7 @@ def train_model(data_dir, checkpoint_dir, resume_from_checkpoint=None): val_check_interval=1_000, limit_val_batches=1, check_val_every_n_epoch=None, + num_sanity_val_steps=0, callbacks=[checkpoint_callback], precision="16-true", accelerator="gpu", @@ -136,17 +146,72 @@ def train_model(data_dir, checkpoint_dir, resume_from_checkpoint=None): accumulate_grad_batches=1, ) + datamodule = get_datamodule() + if resume_from_checkpoint is not None: trainer.fit( model=model, - train_dataloaders=train_loader, + # train_dataloaders=train_loader, ckpt_path=resume_from_checkpoint, + datamodule=datamodule, ) else: logger.info("Training model from scratch") - trainer.fit(model, train_loader) + trainer.fit(model, datamodule=datamodule) +def get_datamodule(): + from crosslayer_transcoder.data.datamodule import ActivationDataModule + + return ActivationDataModule( + # Buffer settings + buffer_size=1_000_000, + n_in_out=2, + n_layers=12, + activation_dim=768, + dtype="float16", + max_batch_size=50000, + # Model settings for activation generation + model_name="openai-community/gpt2", + model_dtype="float32", + # Dataset settings + dataset_name="Skylion007/openwebtext", + dataset_split="train", + max_sequence_length=1024, + # Generation settings + generation_batch_size=10, + refresh_interval=0.1, + # Memory settings + shared_memory_name="activation_buffer", + timeout_seconds=30, + # File paths + init_file=None, + # DataLoader settings + batch_size=1000, + num_workers=10, + prefetch_factor=2, + shuffle=True, + persistent_workers=True, + pin_memory=True, + minimum_fill_threshold=0.2, + use_shared_memory=True, + # Device configuration + device_map="cuda:0", + deployment_policy="gpu_only", + # WandB logging configuration for data generation + wandb_logging={ + "enabled": True, + "project": "clt", + "group": None, + "run_name": "data-generator-jumprelu", + "tags": ["data-generation"], + "save_dir": "./wandb", + "log_interval": 5.0, + }, + ) + + +@volume_commit(volume) def get_model(checkpoint_path=None): from crosslayer_transcoder.model.clt_lightning import ( JumpReLUCrossLayerTranscoderModule, @@ -218,6 +283,7 @@ def get_model(checkpoint_path=None): ) +@volume_commit(volume) def get_train_loader(data_dir, file_name="clt-activations-10M.h5", accessor="tensor"): print("⚡ setting up data") buffer = DiscBuffer(data_dir / file_name, accessor) From 0234e731b14bb40eeaa94ae2760d43030db18949 Mon Sep 17 00:00:00 2001 From: jiito Date: Tue, 16 Sep 2025 17:41:00 -0700 Subject: [PATCH 08/99] working modal code w/o cleanup --- crosslayer_transcoder/data/data_generator.py | 45 ++++--- crosslayer_transcoder/data/datamodule.py | 37 ++++-- .../metrics/dead_features.py | 8 +- crosslayer_transcoder/modal/app.py | 58 +++++++++ .../modal/benchmark_text_dataloader.py | 25 ++++ crosslayer_transcoder/modal/train.py | 123 ++++++------------ crosslayer_transcoder/model/clt.py | 42 +++++- crosslayer_transcoder/model/clt_lightning.py | 28 +++- crosslayer_transcoder/model/jumprelu.py | 13 +- tests/benchmark_text_dataloader.py | 4 +- 10 files changed, 268 insertions(+), 115 deletions(-) create mode 100644 crosslayer_transcoder/modal/app.py create mode 100644 crosslayer_transcoder/modal/benchmark_text_dataloader.py diff --git a/crosslayer_transcoder/data/data_generator.py b/crosslayer_transcoder/data/data_generator.py index 7685d35..d897298 100644 --- a/crosslayer_transcoder/data/data_generator.py +++ b/crosslayer_transcoder/data/data_generator.py @@ -55,6 +55,7 @@ def __init__( refresh_interval: float, deployment_policy: DeploymentPolicy = DeploymentPolicy.DYNAMIC, init_file: Optional[str] = None, + accessor: str = "tensor", device_map: str = "auto", wandb_logging: Optional[dict] = None, ): @@ -79,6 +80,7 @@ def __init__( self.refresh_interval = refresh_interval self.deployment_policy = deployment_policy self.init_file = init_file + self.accessor = accessor self.device_map = device_map # WandB configuration @@ -107,7 +109,9 @@ def setup(self): # 5. Setup disk source if available if self.init_file and os.path.exists(self.init_file): logger.info(f"Setting up disk source: {self.init_file}") - self.disk_source = DiskActivationSource(self.init_file, dtype=self.dtype) + self.disk_source = DiskActivationSource( + self.init_file, dtype=self.dtype, accessor=self.accessor + ) else: self.disk_source = None print("disk source available", self.disk_source is not None) @@ -147,24 +151,29 @@ def setup(self): # 6. Create generation loop with all dependencies # Note: DataGenerationLoop will need to be updated to accept individual parameters too - self.generation_loop = DataGenerationLoop( - shared_buffer=self.shared_buffer, - buffer_size=self.buffer_size, - n_in_out=self.n_in_out, - n_layers=self.n_layers, - activation_dim=self.activation_dim, - dtype=self.dtype, - max_batch_size=self.max_batch_size, - refresh_interval=self.refresh_interval, - monitor=self.monitor, - deployment_policy=self.deployment_policy, - device_map=self.device_map, - disk_source=self.disk_source, - generation_batch_size=self.generation_batch_size, - max_sequence_length=self.max_sequence_length, - ) + try: + self.generation_loop = DataGenerationLoop( + shared_buffer=self.shared_buffer, + buffer_size=self.buffer_size, + n_in_out=self.n_in_out, + n_layers=self.n_layers, + activation_dim=self.activation_dim, + dtype=self.dtype, + max_batch_size=self.max_batch_size, + refresh_interval=self.refresh_interval, + monitor=self.monitor, + deployment_policy=self.deployment_policy, + device_map=self.device_map, + disk_source=self.disk_source, + generation_batch_size=self.generation_batch_size, + max_sequence_length=self.max_sequence_length, + ) - self.generation_loop.refill_from_disk() + logger.info("Refilling from disk") + self.generation_loop.refill_from_disk() + logger.info("Refilled from disk") + except Exception as e: + logger.error(f"Error refilling from disk: {e}") # 2. Load dataset in the process logger.info(f"Loading dataset: {self.dataset_name}") diff --git a/crosslayer_transcoder/data/datamodule.py b/crosslayer_transcoder/data/datamodule.py index 5df6778..2a7e30e 100644 --- a/crosslayer_transcoder/data/datamodule.py +++ b/crosslayer_transcoder/data/datamodule.py @@ -48,6 +48,7 @@ def __init__( timeout_seconds: int = 30, # File paths init_file: Optional[str] = None, + accessor: str = "tensor", # DataLoader settings batch_size: int = 4000, num_workers: int = 20, @@ -96,6 +97,7 @@ def __init__( # File paths init_file: Path to initial HDF5 activation file + accessor: Accessor for the initial HDF5 activation file # DataLoader settings batch_size: Training batch size @@ -144,6 +146,7 @@ def __init__( # File paths self.init_file = init_file + self.accessor = accessor # DataLoader settings self.batch_size = batch_size @@ -176,7 +179,13 @@ def get_memory_estimate_gb(self) -> float: """Estimate total memory usage in GB.""" # Buffer memory: [buffer_size, n_in_out, n_layers, activation_dim] element_size = torch.tensor([], dtype=self.torch_dtype).element_size() - buffer_memory = self.buffer_size * self.n_in_out * self.n_layers * self.activation_dim * element_size + buffer_memory = ( + self.buffer_size + * self.n_in_out + * self.n_layers + * self.activation_dim + * element_size + ) # Validity mask memory validity_memory = self.buffer_size # 1 byte per sample @@ -230,9 +239,13 @@ def _setup_shared_memory_loader(self): try: if mp.get_start_method(allow_none=True) != "spawn": mp.set_start_method("spawn", force=True) - logger.info("Set multiprocessing method to 'spawn' for shared memory compatibility") + logger.info( + "Set multiprocessing method to 'spawn' for shared memory compatibility" + ) except RuntimeError as e: - logger.warning(f"Could not set spawn method: {e}. Disabling multiprocessing in DataLoader") + logger.warning( + f"Could not set spawn method: {e}. Disabling multiprocessing in DataLoader" + ) # If we can't set spawn, disable multiprocessing in the DataLoader # 1. Create shared memory buffer @@ -268,6 +281,7 @@ def _setup_shared_memory_loader(self): refresh_interval=self.refresh_interval, deployment_policy=self.deployment_policy, init_file=self.init_file, + accessor=self.accessor, device_map=self.device_map, wandb_logging=self.wandb_logging, ) @@ -294,12 +308,19 @@ def _setup_simple_buffer_loader(self): import torch.multiprocessing as mp - if sys.platform.startswith("linux") and mp.get_start_method(allow_none=True) != "fork": + if ( + sys.platform.startswith("linux") + and mp.get_start_method(allow_none=True) != "fork" + ): try: mp.set_start_method("fork", force=True) - logger.info("Set multiprocessing method to 'fork' for h5py compatibility") + logger.info( + "Set multiprocessing method to 'fork' for h5py compatibility" + ) except RuntimeError: - logger.warning("Could not set fork method, using num_workers=0 for h5py safety") + logger.warning( + "Could not set fork method, using num_workers=0 for h5py safety" + ) # If we can't set fork, force single-threaded to avoid pickling issues self.num_workers = 0 self.persistent_workers = False @@ -310,9 +331,9 @@ def _setup_simple_buffer_loader(self): ) # Use simple DiscBuffer approach (like current train.py) - from utils.buffer import DiscBuffer + from crosslayer_transcoder.utils.buffer import DiscBuffer - buffer = DiscBuffer(self.init_file, "tensor") + buffer = DiscBuffer(self.init_file, self.accessor) self.data_loader = torch.utils.data.DataLoader( buffer, diff --git a/crosslayer_transcoder/metrics/dead_features.py b/crosslayer_transcoder/metrics/dead_features.py index ac40998..add17ad 100644 --- a/crosslayer_transcoder/metrics/dead_features.py +++ b/crosslayer_transcoder/metrics/dead_features.py @@ -38,7 +38,9 @@ def __init__( ) def update(self, features: torch.Tensor): - self.n_active += (features.detach().cpu() > 0.0).sum(dim=0).to(self.n_active.device) + self.n_active += ( + (features.detach().cpu() > 0.0).sum(dim=0).to(self.n_active.device) + ) self.n_total += features.shape[0] def compute(self): @@ -53,5 +55,7 @@ def compute(self): if self.return_per_layer: return_dict["per_layer"] = (self.n_active == 0.0).float().mean(dim=1) if self.return_log_freqs: - return_dict["log_freqs"] = torch.clamp(torch.log10(self.n_active / self.n_total), min=-10) + return_dict["log_freqs"] = torch.clamp( + torch.log10(self.n_active / self.n_total), min=-10 + ) return return_dict diff --git a/crosslayer_transcoder/modal/app.py b/crosslayer_transcoder/modal/app.py new file mode 100644 index 0000000..bd442d6 --- /dev/null +++ b/crosslayer_transcoder/modal/app.py @@ -0,0 +1,58 @@ +import modal +from pathlib import Path +import logging + +volume = modal.Volume.from_name("clt-checkpoints", create_if_missing=True) +cache_volume = modal.Volume.from_name("cache", create_if_missing=True) + +cache_volume_path = Path("/hf") +volume_path = Path("/experiments") +HF_HOME_PATH = cache_volume_path +ACTIVATIONS_PATH = volume_path / "activations" +CHECKPOINTS_PATH = volume_path / "checkpoints" +WANDB_PATH = volume_path / "wandb" + +volumes = {volume_path: volume, cache_volume_path: cache_volume} + +image = ( + modal.Image.debian_slim(python_version="3.12") + .pip_install( + "torch>=2.8.0", + "nnsight==0.5.0.dev7", + "datasets==3.6.0", + "h5py>=3.13.0", + "einops>=0.8.1", + "jaxtyping>=0.3.2", + "lightning>=2.5.1", + "wandb>=0.19.11", + "transformers>=4.46.0", + "numpy>=1.24.0", + "jsonargparse[signatures]>=4.27.7", + "huggingface_hub[hf_transfer]", + ) + .env({"HF_HUB_ENABLE_HF_TRANSFER": "1", "HF_HOME": HF_HOME_PATH.as_posix()}) + .add_local_python_source("crosslayer_transcoder", "tests") +) + +wandb_secret = modal.Secret.from_name("wandb-secret") + +retries = modal.Retries(initial_delay=0.0, max_retries=3) + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +app = modal.App("clt-trainer", image=image) + + +def volume_commit(volume): + def inner(func): + def wrapper(*args, **kwargs): + logger.info("Committing volume") + result = func(*args, **kwargs) + volume.commit() + logger.info("Volume committed") + return result + + return wrapper + + return inner diff --git a/crosslayer_transcoder/modal/benchmark_text_dataloader.py b/crosslayer_transcoder/modal/benchmark_text_dataloader.py new file mode 100644 index 0000000..ffe1ee7 --- /dev/null +++ b/crosslayer_transcoder/modal/benchmark_text_dataloader.py @@ -0,0 +1,25 @@ +from crosslayer_transcoder.modal.app import app, volumes +from tests.benchmark_text_dataloader import benchmark_textdataset + + +@app.function( + gpu="a10g", + timeout=60 * 60 * 24, + volumes=volumes, +) +def benchmark_text_dataloader(): + # TODO: This doesn't work quite yet + benchmark_textdataset( + dataset_name="Skylion006/openwebtext", + model_name="openai-community/gpt2", + batch_size=32, + seq_len=1024, + num_workers=0, + max_batches=10, + max_duration=60.0, + ) + + +@app.local_entrypoint() +def main(): + benchmark_text_dataloader.remote() diff --git a/crosslayer_transcoder/modal/train.py b/crosslayer_transcoder/modal/train.py index 1c3d53c..c764c8a 100644 --- a/crosslayer_transcoder/modal/train.py +++ b/crosslayer_transcoder/modal/train.py @@ -1,51 +1,21 @@ -from pathlib import Path import logging from typing import Optional -from crosslayer_transcoder.model.jumprelu import JumpReLU from crosslayer_transcoder.utils.buffer import DiscBuffer -import modal import torch as t -volume = modal.Volume.from_name("clt-checkpoints", create_if_missing=True) -cache_volume = modal.Volume.from_name("cache", create_if_missing=True) - -cache_volume_path = Path("/hf") -volume_path = Path("/experiments") -HF_HOME_PATH = cache_volume_path -ACTIVATIONS_PATH = volume_path / "activations" -CHECKPOINTS_PATH = volume_path / "checkpoints" -WANDB_PATH = volume_path / "wandb" - -volumes = {volume_path: volume, cache_volume_path: cache_volume} - -image = ( - modal.Image.debian_slim(python_version="3.12") - .pip_install( - "torch>=2.8.0", - "nnsight==0.5.0.dev7", - "datasets==3.6.0", - "h5py>=3.13.0", - "einops>=0.8.1", - "jaxtyping>=0.3.2", - "lightning>=2.5.1", - "wandb>=0.19.11", - "transformers>=4.46.0", - "numpy>=1.24.0", - "jsonargparse[signatures]>=4.27.7", - "huggingface_hub[hf_transfer]", - ) - .env({"HF_HUB_ENABLE_HF_TRANSFER": "1", "HF_HOME": HF_HOME_PATH.as_posix()}) - .add_local_python_source("crosslayer_transcoder") +from crosslayer_transcoder.modal.app import ( + app, + volume_commit, + volumes, + retries, + wandb_secret, + volume, + ACTIVATIONS_PATH, + CHECKPOINTS_PATH, + WANDB_PATH, ) -wandb_secret = modal.Secret.from_name("wandb-secret") - -retries = modal.Retries(initial_delay=0.0, max_retries=10) - -app = modal.App("clt-train", image=image) - - logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) @@ -58,8 +28,8 @@ def ensure_directories(): @app.function( volumes=volumes, - gpu="a10g", - retries=retries, + gpu="A100-40GB", + # retries=retries, max_inputs=1, timeout=60 * 60 * 24, secrets=[wandb_secret], @@ -70,6 +40,7 @@ def train_interruptible(*args, **kwargs): def train(experiment, volume=None): ensure_directories() + experiment_dir = CHECKPOINTS_PATH / experiment last_checkpoint = experiment_dir / "last.ckpt" @@ -87,20 +58,6 @@ def train(experiment, volume=None): train_model(ACTIVATIONS_PATH, experiment_dir) -def volume_commit(volume): - def inner(func): - def wrapper(*args, **kwargs): - logger.info("Committing volume") - result = func(*args, **kwargs) - volume.commit() - logger.info("Volume committed") - return result - - return wrapper - - return inner - - @volume_commit(volume) def get_checkpoint(checkpoint_dir): from lightning.pytorch.callbacks import ModelCheckpoint @@ -120,15 +77,12 @@ def train_model(data_dir, checkpoint_dir, resume_from_checkpoint=None, volume=No L.seed_everything(42) model = get_model() - train_loader = get_train_loader( - data_dir=data_dir, file_name="openai-community_gpt2.h5", accessor="activations" - ) checkpoint_callback = get_checkpoint(checkpoint_dir) wandb_logger = WandbLogger(project="clt-train-modal") - logger.info("Compiling model") - model = t.compile(model) - logger.info("Model compiled") + # logger.info("Compiling model") + # model = t.compile(model) + # logger.info("Model compiled") trainer = L.Trainer( max_steps=100_000, @@ -137,13 +91,15 @@ def train_model(data_dir, checkpoint_dir, resume_from_checkpoint=None, volume=No check_val_every_n_epoch=None, num_sanity_val_steps=0, callbacks=[checkpoint_callback], - precision="16-true", + precision="16-mixed", accelerator="gpu", devices=[0], logger=wandb_logger, # strategy="ddp", # callbacks=[TBProfilerCallback()], accumulate_grad_batches=1, + # gradient_clip_val=0.5, + # gradient_clip_algorithm="norm", ) datamodule = get_datamodule() @@ -173,7 +129,7 @@ def get_datamodule(): max_batch_size=50000, # Model settings for activation generation model_name="openai-community/gpt2", - model_dtype="float32", + model_dtype="float16", # Dataset settings dataset_name="Skylion007/openwebtext", dataset_split="train", @@ -185,7 +141,8 @@ def get_datamodule(): shared_memory_name="activation_buffer", timeout_seconds=30, # File paths - init_file=None, + init_file=str(ACTIVATIONS_PATH / "openai-community_gpt2.h5"), + accessor="activations", # DataLoader settings batch_size=1000, num_workers=10, @@ -194,7 +151,7 @@ def get_datamodule(): persistent_workers=True, pin_memory=True, minimum_fill_threshold=0.2, - use_shared_memory=True, + use_shared_memory=False, # Device configuration device_map="cuda:0", deployment_policy="gpu_only", @@ -206,17 +163,20 @@ def get_datamodule(): "run_name": "data-generator-jumprelu", "tags": ["data-generation"], "save_dir": "./wandb", - "log_interval": 5.0, + "log_interval": 1.0, }, ) @volume_commit(volume) -def get_model(checkpoint_path=None): +def get_model( + checkpoint_path=None, +): from crosslayer_transcoder.model.clt_lightning import ( JumpReLUCrossLayerTranscoderModule, ) from crosslayer_transcoder.model.clt import CrossLayerTranscoder + from crosslayer_transcoder.model.jumprelu import JumpReLU from crosslayer_transcoder.model.clt import Encoder from crosslayer_transcoder.model.clt import CrosslayerDecoder from crosslayer_transcoder.model.standardize import DimensionwiseInputStandardizer @@ -236,6 +196,7 @@ def get_model(checkpoint_path=None): d_features=10_000, n_layers=12, ) + replacement_model = ReplacementModelAccuracy( model_name="openai-community/gpt2", device_map="cuda:0", @@ -250,20 +211,22 @@ def get_model(checkpoint_path=None): return_neuron_indices=True, ) + input_standardizer = DimensionwiseInputStandardizer( + n_layers=12, + activation_dim=768, + ) + output_standardizer = DimensionwiseOutputStandardizer( + n_layers=12, + activation_dim=768, + ) + nonlinearity = JumpReLU(theta=0.03, bandwidth=0.01, n_layers=12, d_features=10_000) + clt = CrossLayerTranscoder( encoder=encoder, decoder=decoder, - input_standardizer=DimensionwiseInputStandardizer( - n_layers=12, - activation_dim=768, - ), - output_standardizer=DimensionwiseOutputStandardizer( - n_layers=12, - activation_dim=768, - ), - nonlinearity=JumpReLU( - theta=0.03, bandwidth=0.01, n_layers=12, d_features=10_000 - ), + input_standardizer=input_standardizer, + output_standardizer=output_standardizer, + nonlinearity=nonlinearity, ) return JumpReLUCrossLayerTranscoderModule( @@ -271,7 +234,7 @@ def get_model(checkpoint_path=None): replacement_model=replacement_model, dead_features=dead_features, learning_rate=1e-4, - compile=True, + compile=False, lr_decay_step=80_000, lr_decay_factor=0.1, lambda_sparsity=0.0007, diff --git a/crosslayer_transcoder/model/clt.py b/crosslayer_transcoder/model/clt.py index 7090d57..324e43c 100644 --- a/crosslayer_transcoder/model/clt.py +++ b/crosslayer_transcoder/model/clt.py @@ -148,17 +148,40 @@ def forward( if layer != "all": return self.forward_layer(acts_norm, layer) + assert acts_norm.shape == (acts_norm.shape[0], self.n_layers, self.d_acts), ( + f"acts_norm shape: {acts_norm.shape}, expected: {(acts_norm.shape[0], self.n_layers, self.d_acts)}" + ) + # for training pre_actvs = einsum( acts_norm, self.W, "batch_size n_layers d_acts, n_layers d_acts d_features -> batch_size n_layers d_features", ) + + assert not pre_actvs.isnan().any(), "pre_actvs contains NaN values" + pre_actvs = pre_actvs.contiguous() + assert pre_actvs.shape == ( + acts_norm.shape[0], + self.n_layers, + self.d_features, + ), ( + f"pre_actvs shape: {pre_actvs.shape}, expected: {(acts_norm.shape[0], self.n_layers, self.d_features)}" + ) + if self.bias: pre_actvs = pre_actvs + self.b.to(acts_norm.dtype) + assert pre_actvs.shape == ( + acts_norm.shape[0], + self.n_layers, + self.d_features, + ), ( + f"pre_actvs shape: {pre_actvs.shape}, expected: {(acts_norm.shape[0], self.n_layers, self.d_features)}" + ) + return pre_actvs @@ -297,7 +320,6 @@ def reset_parameters(self): self.encoder.reset_parameters() self.decoder.reset_parameters() - @torch._dynamo.disable() def initialize_standardizers( self, batch: Float[torch.Tensor, "batch_size io n_layers d_acts"] ): @@ -314,12 +336,30 @@ def forward( ]: acts = self.input_standardizer(acts) + # detect NaN values in input batch + if torch.isnan(acts).any(): + raise ValueError("NaN values in input batch after standardization") + pre_actvs = self.encoder(acts) + if torch.isnan(pre_actvs).any(): + raise ValueError("NaN values in output batch after encoder") + features = self.nonlinearity(pre_actvs) + if torch.isnan(features).any(): + raise ValueError("NaN values in output batch after nonlinearity") + recons_norm = self.decoder(features) + # detect NaN values in output batch + if torch.isnan(recons_norm).any(): + raise ValueError("NaN values in output batch after decoder") + recons = self.output_standardizer(recons_norm) + # detect NaN values in output batch + if torch.isnan(recons).any(): + raise ValueError("NaN values in output batch after output standardization") + return pre_actvs, features, recons_norm, recons diff --git a/crosslayer_transcoder/model/clt_lightning.py b/crosslayer_transcoder/model/clt_lightning.py index 39a874a..a3df8aa 100644 --- a/crosslayer_transcoder/model/clt_lightning.py +++ b/crosslayer_transcoder/model/clt_lightning.py @@ -291,7 +291,8 @@ def training_step(self, batch, batch_idx): self.model.initialize_standardizers(batch) resid, mlp_out = batch[:, 0], batch[:, 1] - _, features, recons_norm, recons = self.forward(resid) + with torch.autograd.detect_anomaly(True): + _, features, recons_norm, recons = self.forward(resid) self.update_dead_features(features) @@ -420,10 +421,27 @@ def training_step(self, batch, batch_idx): if batch_idx == 0: self.model.initialize_standardizers(batch) + # detect NaN values in input batch + if torch.isnan(batch).any(): + raise ValueError("NaN values in input batch") + # Forward pass resid, mlp_out = batch[:, 0], batch[:, 1] pre_actvs, features, recons_norm, recons = self.forward(resid) + # detect NaN values in output batch + if ( + torch.isnan(pre_actvs).any() + or torch.isnan(features).any() + or torch.isnan(recons_norm).any() + or torch.isnan(recons).any() + ): + print(f"pre_actvs: {torch.isnan(pre_actvs)}") + print(f"features: {torch.isnan(features)}") + print(f"recons_norm: {torch.isnan(recons_norm)}") + print(f"recons: {torch.isnan(recons)}") + raise ValueError("NaN values in output batch") + self.update_dead_features(features) # Compute MSE loss mse = (recons_norm - self.model.output_standardizer.standardize(mlp_out)) ** 2 @@ -431,6 +449,7 @@ def training_step(self, batch, batch_idx): # Compute Sparsity Loss # with torch.no_grad(): if isinstance(self.model.decoder, CrosslayerDecoder): + # shape(features):[batch, n_layers, d_features]] dec_norms = torch.zeros_like(features[:1]) for l in range(self.model.decoder.n_layers): W = self.model.decoder.get_parameter( @@ -442,11 +461,18 @@ def training_step(self, batch, batch_idx): elif isinstance(self.model.decoder, Decoder): dec_norms = torch.sqrt((self.model.decoder.W**2).sum(dim=-1)) + assert not dec_norms.isnan().any(), "dec_norms contains NaN values" + assert not features.isnan().any(), "features contains NaN values" + weighted_features = features * dec_norms * self.c self.log( "model/weighted_features_mean", weighted_features.detach().mean().cpu() ) + assert not weighted_features.isnan().any(), ( + "weighted_features contains NaN values" + ) + if self.use_tanh: weighted_features = torch.tanh( weighted_features diff --git a/crosslayer_transcoder/model/jumprelu.py b/crosslayer_transcoder/model/jumprelu.py index 2c67756..f6b4e26 100644 --- a/crosslayer_transcoder/model/jumprelu.py +++ b/crosslayer_transcoder/model/jumprelu.py @@ -26,7 +26,10 @@ def backward(ctx, grad_output): grad_input = grad_output.clone() grad_input[input < 0] = 0 - theta_grad = -(theta / bandwidth) * rectangle((input - theta) / bandwidth) * grad_output + theta_grad = ( + -(theta / bandwidth) * rectangle((input - theta) / bandwidth) * grad_output + ) + return grad_input, theta_grad, None @@ -46,7 +49,9 @@ class HeavysideStep(torch.autograd.Function): def forward(ctx, input, theta, bandwidth): ctx.save_for_backward(input, theta) ctx.bandwidth = bandwidth - return torch.where(input - theta > 0, torch.ones_like(input), torch.zeros_like(input)) + return torch.where( + input - theta > 0, torch.ones_like(input), torch.zeros_like(input) + ) @staticmethod def backward(ctx, grad_output): @@ -55,5 +60,7 @@ def backward(ctx, grad_output): grad_input = grad_output.clone() grad_input = grad_output * 0.0 - theta_grad = -(1.0 / bandwidth) * rectangle((input - theta) / bandwidth) * grad_output + theta_grad = ( + -(1.0 / bandwidth) * rectangle((input - theta) / bandwidth) * grad_output + ) return grad_input, theta_grad, None diff --git a/tests/benchmark_text_dataloader.py b/tests/benchmark_text_dataloader.py index d29d25f..4fe1413 100644 --- a/tests/benchmark_text_dataloader.py +++ b/tests/benchmark_text_dataloader.py @@ -11,7 +11,7 @@ from datasets import load_dataset from torch.utils.data import DataLoader -from data import text_dataset +from crosslayer_transcoder.data import text_dataset def benchmark_textdataset( @@ -187,7 +187,7 @@ def compare_workers(): worker_configs = [0, 1, 2, 4] for num_workers in worker_configs: - print(f"\n{'='*50}") + print(f"\n{'=' * 50}") print(f"Testing with {num_workers} workers") print("=" * 50) From 6125bbc56c6734f15002e5e43c0f61e6aec9ae10 Mon Sep 17 00:00:00 2001 From: jiito Date: Wed, 17 Sep 2025 15:44:14 -0700 Subject: [PATCH 09/99] reinit logs incase of modal preemption --- crosslayer_transcoder/modal/train.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/crosslayer_transcoder/modal/train.py b/crosslayer_transcoder/modal/train.py index c764c8a..38e28d8 100644 --- a/crosslayer_transcoder/modal/train.py +++ b/crosslayer_transcoder/modal/train.py @@ -51,11 +51,12 @@ def train(experiment, volume=None): experiment_dir, resume_from_checkpoint=last_checkpoint, volume=volume, + experiment_id=experiment, ) print("⚡️ training finished successfully") else: print("⚡️ starting training from scratch") - train_model(ACTIVATIONS_PATH, experiment_dir) + train_model(ACTIVATIONS_PATH, experiment_dir, experiment_id=experiment) @volume_commit(volume) @@ -70,7 +71,13 @@ def get_checkpoint(checkpoint_dir): ) -def train_model(data_dir, checkpoint_dir, resume_from_checkpoint=None, volume=None): +def train_model( + data_dir, + checkpoint_dir, + resume_from_checkpoint=None, + volume=None, + experiment_id=None, +): import lightning as L from lightning.pytorch.loggers import WandbLogger @@ -78,7 +85,11 @@ def train_model(data_dir, checkpoint_dir, resume_from_checkpoint=None, volume=No model = get_model() checkpoint_callback = get_checkpoint(checkpoint_dir) - wandb_logger = WandbLogger(project="clt-train-modal") + wandb_id = experiment_id if experiment_id is not None else uuid4().hex[:8] + wandb_name = f"jumprelu{'-' + experiment_id if experiment_id is not None else ''}" + wandb_logger = WandbLogger( + project="clt-train-modal", id=wandb_id, resume="allow", name=wandb_name + ) # logger.info("Compiling model") # model = t.compile(model) From e07e0638d967074af59a2062d2d7bbec72af7945 Mon Sep 17 00:00:00 2001 From: jiito Date: Wed, 17 Sep 2025 15:44:52 -0700 Subject: [PATCH 10/99] replacment model config --- .../metrics/replacement_model_accuracy.py | 40 +++++++++++++++---- crosslayer_transcoder/modal/train.py | 2 + 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/crosslayer_transcoder/metrics/replacement_model_accuracy.py b/crosslayer_transcoder/metrics/replacement_model_accuracy.py index 2e11c01..767b9e4 100644 --- a/crosslayer_transcoder/metrics/replacement_model_accuracy.py +++ b/crosslayer_transcoder/metrics/replacement_model_accuracy.py @@ -26,7 +26,9 @@ def forward(self, tokens, clt): ) for layer in range(self.n_layers): - mlp_in = self.gpt2.transformer.h[layer].ln_2.input # (batch, seq, d_acts) + mlp_in = self.gpt2.transformer.h[ + layer + ].ln_2.input # (batch, seq, d_acts) mlp_in_norm = clt.input_standardizer(mlp_in, layer=layer).detach() @@ -42,7 +44,9 @@ def forward(self, tokens, clt): elif isinstance(clt.nonlinearity, torch.nn.ReLU): features[..., layer, :] = torch.relu(pre_actvs) else: - post_actvs = clt.nonlinearity(pre_actvs, layer=layer).detach() # batchxseq, 1, n_features + post_actvs = clt.nonlinearity( + pre_actvs, layer=layer + ).detach() # batchxseq, 1, n_features features[..., layer, :] = post_actvs.reshape( tokens.shape[0], tokens.shape[1], self.n_features ) @@ -64,12 +68,22 @@ class ReplacementModelAccuracy(Metric): Computes the accuracy of the replacement model and the KL divergence between the logits of the GPT-2 and the replacement model. """ - def __init__(self, model_name="openai-community/gpt2", device_map="auto", loader_batch_size=5): + def __init__( + self, + model_name="openai-community/gpt2", + device_map="auto", + loader_batch_size=5, + dataset_name="Skylion007/openwebtext", + ): super().__init__() - self.gpt2 = nnsight.LanguageModel(model_name, device_map=device_map, dispatch=True) + self.gpt2 = nnsight.LanguageModel( + model_name, device_map=device_map, dispatch=True + ) self.gpt2.requires_grad_(False) self.replacement_model = ReplacementModel(self.gpt2) - self.loader = get_webtext_dataloader(self.gpt2, batch_size=loader_batch_size) + self.loader = get_webtext_dataloader( + self.gpt2, dataset_name=dataset_name, batch_size=loader_batch_size + ) self.add_state("n_correct", default=torch.tensor(0), dist_reduce_fx="sum") self.add_state("n_total", default=torch.tensor(0), dist_reduce_fx="sum") self.add_state( @@ -92,7 +106,13 @@ def prepend_bos(self, tokens, mask): ) tokens = torch.cat([bos, tokens], dim=1) mask = torch.cat( - [torch.zeros((tokens.shape[0], 1), dtype=torch.bool, device=tokens.device), mask], dim=1 + [ + torch.zeros( + (tokens.shape[0], 1), dtype=torch.bool, device=tokens.device + ), + mask, + ], + dim=1, ) return tokens, mask @@ -115,10 +135,14 @@ def update(self, clt, max_batches=20): mask_flat = mask.reshape(-1) logits_gpt2 = logits_gpt2.logits logits_gpt2 = logits_gpt2.reshape(-1, logits_gpt2.shape[-1])[mask_flat] - logits_replacement = logits_replacement.reshape(-1, logits_replacement.shape[-1])[mask_flat] + logits_replacement = logits_replacement.reshape( + -1, logits_replacement.shape[-1] + )[mask_flat] self.n_correct += ( - (logits_gpt2.argmax(dim=-1) == logits_replacement.argmax(dim=-1)).int().sum() + (logits_gpt2.argmax(dim=-1) == logits_replacement.argmax(dim=-1)) + .int() + .sum() ) self.n_total += mask.sum() self.kl_div += torch.nn.functional.kl_div( diff --git a/crosslayer_transcoder/modal/train.py b/crosslayer_transcoder/modal/train.py index 38e28d8..ab89c4c 100644 --- a/crosslayer_transcoder/modal/train.py +++ b/crosslayer_transcoder/modal/train.py @@ -1,5 +1,6 @@ import logging from typing import Optional +from uuid import uuid4 from crosslayer_transcoder.utils.buffer import DiscBuffer import torch as t @@ -210,6 +211,7 @@ def get_model( replacement_model = ReplacementModelAccuracy( model_name="openai-community/gpt2", + dataset_name="roneneldan/TinyStories", device_map="cuda:0", loader_batch_size=2, ) From 8a516702d4741afcfdae5531302f04a3dc38e372 Mon Sep 17 00:00:00 2001 From: jiito Date: Fri, 19 Sep 2025 09:02:34 -0700 Subject: [PATCH 11/99] basic script to test mem usage on modal --- .../modal/test_ckpt_loading.py | 125 ++++++++++++++++++ crosslayer_transcoder/model/clt_lightning.py | 30 +++-- 2 files changed, 142 insertions(+), 13 deletions(-) create mode 100644 crosslayer_transcoder/modal/test_ckpt_loading.py diff --git a/crosslayer_transcoder/modal/test_ckpt_loading.py b/crosslayer_transcoder/modal/test_ckpt_loading.py new file mode 100644 index 0000000..ae6e745 --- /dev/null +++ b/crosslayer_transcoder/modal/test_ckpt_loading.py @@ -0,0 +1,125 @@ +import psutil +import torch +from rich.console import Console + +from crosslayer_transcoder.modal.app import CHECKPOINTS_PATH, app, volumes + +console = Console() + + +def get_memory_usage(): + """Get current memory usage statistics""" + process = psutil.Process() + memory_info = process.memory_info() + + stats = { + "cpu_memory_mb": memory_info.rss / 1024 / 1024, + "cpu_memory_percent": process.memory_percent(), + } + + if torch.cuda.is_available(): + stats.update( + { + "gpu_memory_allocated_mb": torch.cuda.memory_allocated() / 1024 / 1024, + "gpu_memory_reserved_mb": torch.cuda.memory_reserved() / 1024 / 1024, + "gpu_memory_max_allocated_mb": torch.cuda.max_memory_allocated() + / 1024 + / 1024, + } + ) + + return stats + + +def log_memory_usage(stage: str): + """Log memory usage with a descriptive stage label""" + stats = get_memory_usage() + console.print(f"[bold blue]{stage}[/bold blue]") + console.print( + f" CPU Memory: {stats['cpu_memory_mb']:.1f} MB ({stats['cpu_memory_percent']:.1f}%)" + ) + + if torch.cuda.is_available(): + console.print( + f" GPU Memory Allocated: {stats['gpu_memory_allocated_mb']:.1f} MB" + ) + console.print( + f" GPU Memory Reserved: {stats['gpu_memory_reserved_mb']:.1f} MB" + ) + console.print( + f" GPU Memory Max: {stats['gpu_memory_max_allocated_mb']:.1f} MB" + ) + + +@app.function(gpu="a10g", volumes=volumes) +def load_ckpt_lightning(ckpt_path): + from crosslayer_transcoder.model.clt_lightning import ( + JumpReLUCrossLayerTranscoderModule, + ) + from crosslayer_transcoder.model.clt import CrossLayerTranscoder + from crosslayer_transcoder.model.clt import Encoder + from crosslayer_transcoder.model.clt import CrosslayerDecoder + from crosslayer_transcoder.model.standardize import DimensionwiseInputStandardizer + from crosslayer_transcoder.model.standardize import DimensionwiseOutputStandardizer + from crosslayer_transcoder.model.jumprelu import JumpReLU + from crosslayer_transcoder.metrics.replacement_model_accuracy import ( + ReplacementModelAccuracy, + ) + from crosslayer_transcoder.metrics.dead_features import DeadFeatures + + console.print("[bold yellow]Loading model from checkpoint...[/bold yellow]") + + log_memory_usage("Initial memory usage") + + encoder = Encoder( + d_acts=768, + d_features=10_000, + n_layers=12, + ) + decoder = CrosslayerDecoder( + d_acts=768, + d_features=10_000, + n_layers=12, + ) + + input_standardizer = DimensionwiseInputStandardizer( + n_layers=12, + activation_dim=768, + ) + output_standardizer = DimensionwiseOutputStandardizer( + n_layers=12, + activation_dim=768, + ) + nonlinearity = JumpReLU(theta=0.03, bandwidth=0.01, n_layers=12, d_features=10_000) + + clt = CrossLayerTranscoder( + encoder=encoder, + decoder=decoder, + input_standardizer=input_standardizer, + output_standardizer=output_standardizer, + nonlinearity=nonlinearity, + ) + + log_memory_usage("After model creation") + + model = JumpReLUCrossLayerTranscoderModule.load_from_checkpoint( + ckpt_path, + model=clt, + replacement_model=None, + dead_features=None, + ) + model.eval() + + log_memory_usage("After checkpoint loading") + + console.print("[bold green]✓ Model loaded successfully![/bold green]") + return + + +@app.local_entrypoint() +def main(): + experiment = "34f20c70" + console.print( + f"[bold cyan]Starting checkpoint loading test for experiment:[/bold cyan] {experiment}" + ) + load_ckpt_lightning.remote(f"{CHECKPOINTS_PATH}/{experiment}/last.ckpt") diff --git a/crosslayer_transcoder/model/clt_lightning.py b/crosslayer_transcoder/model/clt_lightning.py index a3df8aa..62eaef3 100644 --- a/crosslayer_transcoder/model/clt_lightning.py +++ b/crosslayer_transcoder/model/clt_lightning.py @@ -103,20 +103,24 @@ def configure_model(self): print("Compiling model") self = torch.compile(self) - if self.trainer.num_devices > 1: - from crosslayer_transcoder.model.parallel import ( - ColParallelEncoder, - ParallelNonlinearity, - RowParallelDecoder, - ) + try: + if self.__getattribute__("trainer") and self.trainer.num_devices > 1: + from crosslayer_transcoder.model.parallel import ( + ColParallelEncoder, + ParallelNonlinearity, + RowParallelDecoder, + ) - tp_mesh = self.device_mesh["tensor_parallel"] - plan = { - "encoder": ColParallelEncoder(use_local_output=False), - "nonlinearity": ParallelNonlinearity(use_local_output=False), - "decoder": RowParallelDecoder(), - } - parallelize_module(self, tp_mesh, plan) + tp_mesh = self.device_mesh["tensor_parallel"] + plan = { + "encoder": ColParallelEncoder(use_local_output=False), + "nonlinearity": ParallelNonlinearity(use_local_output=False), + "decoder": RowParallelDecoder(), + } + parallelize_module(self, tp_mesh, plan) + except Exception as e: + print(f"Error parallelizing model: {e}") + pass def forward( self, acts_norm: Float[torch.Tensor, "batch_size n_layers d_acts"] From 36d044fbe18b0faad47c45b4c2e9c8f3dcde7f49 Mon Sep 17 00:00:00 2001 From: jiito Date: Tue, 30 Sep 2025 09:23:38 -0700 Subject: [PATCH 12/99] refactor: greatly simplify modal wrapper --- crosslayer_transcoder/main.py | 3 +- crosslayer_transcoder/modal/app.py | 1 + .../modal/benchmark_text_dataloader.py | 25 -- crosslayer_transcoder/modal/main.py | 25 ++ crosslayer_transcoder/modal/train.py | 285 ------------------ 5 files changed, 28 insertions(+), 311 deletions(-) delete mode 100644 crosslayer_transcoder/modal/benchmark_text_dataloader.py create mode 100644 crosslayer_transcoder/modal/main.py delete mode 100644 crosslayer_transcoder/modal/train.py diff --git a/crosslayer_transcoder/main.py b/crosslayer_transcoder/main.py index 2afce89..d7b09d4 100755 --- a/crosslayer_transcoder/main.py +++ b/crosslayer_transcoder/main.py @@ -27,7 +27,7 @@ def add_arguments_to_parser(self, parser): ) -def main(): +def main(*args): """Main entry point for training.""" # Set up wandb directories os.environ.setdefault("WANDB_DIR", f"{os.getcwd()}/wandb") @@ -45,6 +45,7 @@ def main(): "prog": "CrossLayer Transcoder Training", "description": "Train CrossLayer Transcoder models for neural network interpretability", }, + args=args, ) diff --git a/crosslayer_transcoder/modal/app.py b/crosslayer_transcoder/modal/app.py index bd442d6..7f0122f 100644 --- a/crosslayer_transcoder/modal/app.py +++ b/crosslayer_transcoder/modal/app.py @@ -32,6 +32,7 @@ ) .env({"HF_HUB_ENABLE_HF_TRANSFER": "1", "HF_HOME": HF_HOME_PATH.as_posix()}) .add_local_python_source("crosslayer_transcoder", "tests") + .add_local_dir("config", "/config") ) wandb_secret = modal.Secret.from_name("wandb-secret") diff --git a/crosslayer_transcoder/modal/benchmark_text_dataloader.py b/crosslayer_transcoder/modal/benchmark_text_dataloader.py deleted file mode 100644 index ffe1ee7..0000000 --- a/crosslayer_transcoder/modal/benchmark_text_dataloader.py +++ /dev/null @@ -1,25 +0,0 @@ -from crosslayer_transcoder.modal.app import app, volumes -from tests.benchmark_text_dataloader import benchmark_textdataset - - -@app.function( - gpu="a10g", - timeout=60 * 60 * 24, - volumes=volumes, -) -def benchmark_text_dataloader(): - # TODO: This doesn't work quite yet - benchmark_textdataset( - dataset_name="Skylion006/openwebtext", - model_name="openai-community/gpt2", - batch_size=32, - seq_len=1024, - num_workers=0, - max_batches=10, - max_duration=60.0, - ) - - -@app.local_entrypoint() -def main(): - benchmark_text_dataloader.remote() diff --git a/crosslayer_transcoder/modal/main.py b/crosslayer_transcoder/modal/main.py new file mode 100644 index 0000000..87bd4ad --- /dev/null +++ b/crosslayer_transcoder/modal/main.py @@ -0,0 +1,25 @@ +import sys +from crosslayer_transcoder.modal.app import app, volumes, wandb_secret, retries +from crosslayer_transcoder.main import main as lightning_cli_main + + +@app.function( + gpu="A100-40GB", + volumes=volumes, + secrets=[wandb_secret], + timeout=60 * 60 * 24, + retries=retries, +) +def train(*args, **kwargs): + # TODO: try resuming from checkpoint + + # NOTE: clear sysargv to allow command-line arg parsing from lightning + if len(sys.argv) > 1: + sys.argv[1:] = [] + + lightning_cli_main(*args) + + +@app.local_entrypoint() +def main(*args): + train.remote(*args) diff --git a/crosslayer_transcoder/modal/train.py b/crosslayer_transcoder/modal/train.py deleted file mode 100644 index ab89c4c..0000000 --- a/crosslayer_transcoder/modal/train.py +++ /dev/null @@ -1,285 +0,0 @@ -import logging -from typing import Optional -from uuid import uuid4 - -from crosslayer_transcoder.utils.buffer import DiscBuffer -import torch as t - -from crosslayer_transcoder.modal.app import ( - app, - volume_commit, - volumes, - retries, - wandb_secret, - volume, - ACTIVATIONS_PATH, - CHECKPOINTS_PATH, - WANDB_PATH, -) - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - - -def ensure_directories(): - ACTIVATIONS_PATH.mkdir(parents=True, exist_ok=True) - CHECKPOINTS_PATH.mkdir(parents=True, exist_ok=True) - WANDB_PATH.mkdir(parents=True, exist_ok=True) - - -@app.function( - volumes=volumes, - gpu="A100-40GB", - # retries=retries, - max_inputs=1, - timeout=60 * 60 * 24, - secrets=[wandb_secret], -) -def train_interruptible(*args, **kwargs): - train(*args, **kwargs, volume=volume) - - -def train(experiment, volume=None): - ensure_directories() - - experiment_dir = CHECKPOINTS_PATH / experiment - last_checkpoint = experiment_dir / "last.ckpt" - - if last_checkpoint.exists(): - print(f"⚡️ resuming training from the latest checkpoint: {last_checkpoint}") - train_model( - ACTIVATIONS_PATH, - experiment_dir, - resume_from_checkpoint=last_checkpoint, - volume=volume, - experiment_id=experiment, - ) - print("⚡️ training finished successfully") - else: - print("⚡️ starting training from scratch") - train_model(ACTIVATIONS_PATH, experiment_dir, experiment_id=experiment) - - -@volume_commit(volume) -def get_checkpoint(checkpoint_dir): - from lightning.pytorch.callbacks import ModelCheckpoint - - return ModelCheckpoint( - dirpath=checkpoint_dir, - save_last=True, - every_n_epochs=10, - filename="{epoch:02d}", - ) - - -def train_model( - data_dir, - checkpoint_dir, - resume_from_checkpoint=None, - volume=None, - experiment_id=None, -): - import lightning as L - from lightning.pytorch.loggers import WandbLogger - - L.seed_everything(42) - - model = get_model() - checkpoint_callback = get_checkpoint(checkpoint_dir) - wandb_id = experiment_id if experiment_id is not None else uuid4().hex[:8] - wandb_name = f"jumprelu{'-' + experiment_id if experiment_id is not None else ''}" - wandb_logger = WandbLogger( - project="clt-train-modal", id=wandb_id, resume="allow", name=wandb_name - ) - - # logger.info("Compiling model") - # model = t.compile(model) - # logger.info("Model compiled") - - trainer = L.Trainer( - max_steps=100_000, - val_check_interval=1_000, - limit_val_batches=1, - check_val_every_n_epoch=None, - num_sanity_val_steps=0, - callbacks=[checkpoint_callback], - precision="16-mixed", - accelerator="gpu", - devices=[0], - logger=wandb_logger, - # strategy="ddp", - # callbacks=[TBProfilerCallback()], - accumulate_grad_batches=1, - # gradient_clip_val=0.5, - # gradient_clip_algorithm="norm", - ) - - datamodule = get_datamodule() - - if resume_from_checkpoint is not None: - trainer.fit( - model=model, - # train_dataloaders=train_loader, - ckpt_path=resume_from_checkpoint, - datamodule=datamodule, - ) - else: - logger.info("Training model from scratch") - trainer.fit(model, datamodule=datamodule) - - -def get_datamodule(): - from crosslayer_transcoder.data.datamodule import ActivationDataModule - - return ActivationDataModule( - # Buffer settings - buffer_size=1_000_000, - n_in_out=2, - n_layers=12, - activation_dim=768, - dtype="float16", - max_batch_size=50000, - # Model settings for activation generation - model_name="openai-community/gpt2", - model_dtype="float16", - # Dataset settings - dataset_name="Skylion007/openwebtext", - dataset_split="train", - max_sequence_length=1024, - # Generation settings - generation_batch_size=10, - refresh_interval=0.1, - # Memory settings - shared_memory_name="activation_buffer", - timeout_seconds=30, - # File paths - init_file=str(ACTIVATIONS_PATH / "openai-community_gpt2.h5"), - accessor="activations", - # DataLoader settings - batch_size=1000, - num_workers=10, - prefetch_factor=2, - shuffle=True, - persistent_workers=True, - pin_memory=True, - minimum_fill_threshold=0.2, - use_shared_memory=False, - # Device configuration - device_map="cuda:0", - deployment_policy="gpu_only", - # WandB logging configuration for data generation - wandb_logging={ - "enabled": True, - "project": "clt", - "group": None, - "run_name": "data-generator-jumprelu", - "tags": ["data-generation"], - "save_dir": "./wandb", - "log_interval": 1.0, - }, - ) - - -@volume_commit(volume) -def get_model( - checkpoint_path=None, -): - from crosslayer_transcoder.model.clt_lightning import ( - JumpReLUCrossLayerTranscoderModule, - ) - from crosslayer_transcoder.model.clt import CrossLayerTranscoder - from crosslayer_transcoder.model.jumprelu import JumpReLU - from crosslayer_transcoder.model.clt import Encoder - from crosslayer_transcoder.model.clt import CrosslayerDecoder - from crosslayer_transcoder.model.standardize import DimensionwiseInputStandardizer - from crosslayer_transcoder.model.standardize import DimensionwiseOutputStandardizer - from crosslayer_transcoder.metrics.replacement_model_accuracy import ( - ReplacementModelAccuracy, - ) - from crosslayer_transcoder.metrics.dead_features import DeadFeatures - - encoder = Encoder( - d_acts=768, - d_features=10_000, - n_layers=12, - ) - decoder = CrosslayerDecoder( - d_acts=768, - d_features=10_000, - n_layers=12, - ) - - replacement_model = ReplacementModelAccuracy( - model_name="openai-community/gpt2", - dataset_name="roneneldan/TinyStories", - device_map="cuda:0", - loader_batch_size=2, - ) - - dead_features = DeadFeatures( - n_features=10_000, - n_layers=12, - return_per_layer=True, - return_log_freqs=True, - return_neuron_indices=True, - ) - - input_standardizer = DimensionwiseInputStandardizer( - n_layers=12, - activation_dim=768, - ) - output_standardizer = DimensionwiseOutputStandardizer( - n_layers=12, - activation_dim=768, - ) - nonlinearity = JumpReLU(theta=0.03, bandwidth=0.01, n_layers=12, d_features=10_000) - - clt = CrossLayerTranscoder( - encoder=encoder, - decoder=decoder, - input_standardizer=input_standardizer, - output_standardizer=output_standardizer, - nonlinearity=nonlinearity, - ) - - return JumpReLUCrossLayerTranscoderModule( - model=clt, - replacement_model=replacement_model, - dead_features=dead_features, - learning_rate=1e-4, - compile=False, - lr_decay_step=80_000, - lr_decay_factor=0.1, - lambda_sparsity=0.0007, - c_sparsity=1, - use_tanh=True, - pre_actv_loss=1e-6, - compute_dead_features=True, - compute_dead_features_every=500, - ) - - -@volume_commit(volume) -def get_train_loader(data_dir, file_name="clt-activations-10M.h5", accessor="tensor"): - print("⚡ setting up data") - buffer = DiscBuffer(data_dir / file_name, accessor) - train_loader = t.utils.data.DataLoader( - buffer, - num_workers=20, - prefetch_factor=2, - batch_size=4000, - shuffle=True, - persistent_workers=True, - pin_memory=True, - ) - return train_loader - - -@app.local_entrypoint() -def main(experiment: Optional[str] = None): - if experiment is None: - from uuid import uuid4 - - experiment = uuid4().hex[:8] - print(f"⚡️ starting interruptible training experiment {experiment}") - train_interruptible.spawn(experiment).get() From 6d069a29edfefc06ba07efab7c84ab519c33b91d Mon Sep 17 00:00:00 2001 From: jiito Date: Tue, 30 Sep 2025 09:27:00 -0700 Subject: [PATCH 13/99] restore formatting issues --- crosslayer_transcoder/data/data_generator.py | 65 +++----- crosslayer_transcoder/data/datamodule.py | 37 +---- .../metrics/dead_features.py | 8 +- .../metrics/replacement_model_accuracy.py | 40 +---- crosslayer_transcoder/model/clt.py | 101 ++---------- crosslayer_transcoder/model/clt_lightning.py | 148 +++++------------- crosslayer_transcoder/model/jumprelu.py | 13 +- tests/benchmark_text_dataloader.py | 4 +- 8 files changed, 95 insertions(+), 321 deletions(-) diff --git a/crosslayer_transcoder/data/data_generator.py b/crosslayer_transcoder/data/data_generator.py index d897298..5bd5e2f 100644 --- a/crosslayer_transcoder/data/data_generator.py +++ b/crosslayer_transcoder/data/data_generator.py @@ -14,18 +14,12 @@ from torch.utils.data import DataLoader from crosslayer_transcoder.data import text_dataset -from crosslayer_transcoder.data.activation_sources import ( - ActivationComputer, - DiskActivationSource, -) +from crosslayer_transcoder.data.activation_sources import ActivationComputer, DiskActivationSource from crosslayer_transcoder.data.deployment_policy import DeploymentPolicy # DataLoaderConfig no longer needed - using individual parameters from crosslayer_transcoder.data.generation_loop import DataGenerationLoop -from crosslayer_transcoder.data.process_monitor import ( - ProcessMonitor, - WandBProcessMonitor, -) +from crosslayer_transcoder.data.process_monitor import ProcessMonitor, WandBProcessMonitor from crosslayer_transcoder.data.shared_memory import SharedActivationBuffer logger = logging.getLogger(__name__) @@ -55,13 +49,10 @@ def __init__( refresh_interval: float, deployment_policy: DeploymentPolicy = DeploymentPolicy.DYNAMIC, init_file: Optional[str] = None, - accessor: str = "tensor", device_map: str = "auto", wandb_logging: Optional[dict] = None, ): - super().__init__( - daemon=False - ) # Can't be daemon if we want to use DataLoader workers + super().__init__(daemon=False) # Can't be daemon if we want to use DataLoader workers self.shared_buffer = shared_buffer # Store parameters directly instead of config object @@ -80,7 +71,6 @@ def __init__( self.refresh_interval = refresh_interval self.deployment_policy = deployment_policy self.init_file = init_file - self.accessor = accessor self.device_map = device_map # WandB configuration @@ -109,9 +99,7 @@ def setup(self): # 5. Setup disk source if available if self.init_file and os.path.exists(self.init_file): logger.info(f"Setting up disk source: {self.init_file}") - self.disk_source = DiskActivationSource( - self.init_file, dtype=self.dtype, accessor=self.accessor - ) + self.disk_source = DiskActivationSource(self.init_file, dtype=self.dtype) else: self.disk_source = None print("disk source available", self.disk_source is not None) @@ -151,37 +139,28 @@ def setup(self): # 6. Create generation loop with all dependencies # Note: DataGenerationLoop will need to be updated to accept individual parameters too - try: - self.generation_loop = DataGenerationLoop( - shared_buffer=self.shared_buffer, - buffer_size=self.buffer_size, - n_in_out=self.n_in_out, - n_layers=self.n_layers, - activation_dim=self.activation_dim, - dtype=self.dtype, - max_batch_size=self.max_batch_size, - refresh_interval=self.refresh_interval, - monitor=self.monitor, - deployment_policy=self.deployment_policy, - device_map=self.device_map, - disk_source=self.disk_source, - generation_batch_size=self.generation_batch_size, - max_sequence_length=self.max_sequence_length, - ) + self.generation_loop = DataGenerationLoop( + shared_buffer=self.shared_buffer, + buffer_size=self.buffer_size, + n_in_out=self.n_in_out, + n_layers=self.n_layers, + activation_dim=self.activation_dim, + dtype=self.dtype, + max_batch_size=self.max_batch_size, + refresh_interval=self.refresh_interval, + monitor=self.monitor, + deployment_policy=self.deployment_policy, + device_map=self.device_map, + disk_source=self.disk_source, + generation_batch_size=self.generation_batch_size, + max_sequence_length=self.max_sequence_length, + ) - logger.info("Refilling from disk") - self.generation_loop.refill_from_disk() - logger.info("Refilled from disk") - except Exception as e: - logger.error(f"Error refilling from disk: {e}") + self.generation_loop.refill_from_disk() # 2. Load dataset in the process logger.info(f"Loading dataset: {self.dataset_name}") - dataset = load_dataset( - self.dataset_name, - split=self.dataset_split, - trust_remote_code=True, - ) + dataset = load_dataset(self.dataset_name, split=self.dataset_split) # 3. Create components activation_computer = ActivationComputer(self.n_layers) diff --git a/crosslayer_transcoder/data/datamodule.py b/crosslayer_transcoder/data/datamodule.py index 2a7e30e..5df6778 100644 --- a/crosslayer_transcoder/data/datamodule.py +++ b/crosslayer_transcoder/data/datamodule.py @@ -48,7 +48,6 @@ def __init__( timeout_seconds: int = 30, # File paths init_file: Optional[str] = None, - accessor: str = "tensor", # DataLoader settings batch_size: int = 4000, num_workers: int = 20, @@ -97,7 +96,6 @@ def __init__( # File paths init_file: Path to initial HDF5 activation file - accessor: Accessor for the initial HDF5 activation file # DataLoader settings batch_size: Training batch size @@ -146,7 +144,6 @@ def __init__( # File paths self.init_file = init_file - self.accessor = accessor # DataLoader settings self.batch_size = batch_size @@ -179,13 +176,7 @@ def get_memory_estimate_gb(self) -> float: """Estimate total memory usage in GB.""" # Buffer memory: [buffer_size, n_in_out, n_layers, activation_dim] element_size = torch.tensor([], dtype=self.torch_dtype).element_size() - buffer_memory = ( - self.buffer_size - * self.n_in_out - * self.n_layers - * self.activation_dim - * element_size - ) + buffer_memory = self.buffer_size * self.n_in_out * self.n_layers * self.activation_dim * element_size # Validity mask memory validity_memory = self.buffer_size # 1 byte per sample @@ -239,13 +230,9 @@ def _setup_shared_memory_loader(self): try: if mp.get_start_method(allow_none=True) != "spawn": mp.set_start_method("spawn", force=True) - logger.info( - "Set multiprocessing method to 'spawn' for shared memory compatibility" - ) + logger.info("Set multiprocessing method to 'spawn' for shared memory compatibility") except RuntimeError as e: - logger.warning( - f"Could not set spawn method: {e}. Disabling multiprocessing in DataLoader" - ) + logger.warning(f"Could not set spawn method: {e}. Disabling multiprocessing in DataLoader") # If we can't set spawn, disable multiprocessing in the DataLoader # 1. Create shared memory buffer @@ -281,7 +268,6 @@ def _setup_shared_memory_loader(self): refresh_interval=self.refresh_interval, deployment_policy=self.deployment_policy, init_file=self.init_file, - accessor=self.accessor, device_map=self.device_map, wandb_logging=self.wandb_logging, ) @@ -308,19 +294,12 @@ def _setup_simple_buffer_loader(self): import torch.multiprocessing as mp - if ( - sys.platform.startswith("linux") - and mp.get_start_method(allow_none=True) != "fork" - ): + if sys.platform.startswith("linux") and mp.get_start_method(allow_none=True) != "fork": try: mp.set_start_method("fork", force=True) - logger.info( - "Set multiprocessing method to 'fork' for h5py compatibility" - ) + logger.info("Set multiprocessing method to 'fork' for h5py compatibility") except RuntimeError: - logger.warning( - "Could not set fork method, using num_workers=0 for h5py safety" - ) + logger.warning("Could not set fork method, using num_workers=0 for h5py safety") # If we can't set fork, force single-threaded to avoid pickling issues self.num_workers = 0 self.persistent_workers = False @@ -331,9 +310,9 @@ def _setup_simple_buffer_loader(self): ) # Use simple DiscBuffer approach (like current train.py) - from crosslayer_transcoder.utils.buffer import DiscBuffer + from utils.buffer import DiscBuffer - buffer = DiscBuffer(self.init_file, self.accessor) + buffer = DiscBuffer(self.init_file, "tensor") self.data_loader = torch.utils.data.DataLoader( buffer, diff --git a/crosslayer_transcoder/metrics/dead_features.py b/crosslayer_transcoder/metrics/dead_features.py index add17ad..ac40998 100644 --- a/crosslayer_transcoder/metrics/dead_features.py +++ b/crosslayer_transcoder/metrics/dead_features.py @@ -38,9 +38,7 @@ def __init__( ) def update(self, features: torch.Tensor): - self.n_active += ( - (features.detach().cpu() > 0.0).sum(dim=0).to(self.n_active.device) - ) + self.n_active += (features.detach().cpu() > 0.0).sum(dim=0).to(self.n_active.device) self.n_total += features.shape[0] def compute(self): @@ -55,7 +53,5 @@ def compute(self): if self.return_per_layer: return_dict["per_layer"] = (self.n_active == 0.0).float().mean(dim=1) if self.return_log_freqs: - return_dict["log_freqs"] = torch.clamp( - torch.log10(self.n_active / self.n_total), min=-10 - ) + return_dict["log_freqs"] = torch.clamp(torch.log10(self.n_active / self.n_total), min=-10) return return_dict diff --git a/crosslayer_transcoder/metrics/replacement_model_accuracy.py b/crosslayer_transcoder/metrics/replacement_model_accuracy.py index 767b9e4..2e11c01 100644 --- a/crosslayer_transcoder/metrics/replacement_model_accuracy.py +++ b/crosslayer_transcoder/metrics/replacement_model_accuracy.py @@ -26,9 +26,7 @@ def forward(self, tokens, clt): ) for layer in range(self.n_layers): - mlp_in = self.gpt2.transformer.h[ - layer - ].ln_2.input # (batch, seq, d_acts) + mlp_in = self.gpt2.transformer.h[layer].ln_2.input # (batch, seq, d_acts) mlp_in_norm = clt.input_standardizer(mlp_in, layer=layer).detach() @@ -44,9 +42,7 @@ def forward(self, tokens, clt): elif isinstance(clt.nonlinearity, torch.nn.ReLU): features[..., layer, :] = torch.relu(pre_actvs) else: - post_actvs = clt.nonlinearity( - pre_actvs, layer=layer - ).detach() # batchxseq, 1, n_features + post_actvs = clt.nonlinearity(pre_actvs, layer=layer).detach() # batchxseq, 1, n_features features[..., layer, :] = post_actvs.reshape( tokens.shape[0], tokens.shape[1], self.n_features ) @@ -68,22 +64,12 @@ class ReplacementModelAccuracy(Metric): Computes the accuracy of the replacement model and the KL divergence between the logits of the GPT-2 and the replacement model. """ - def __init__( - self, - model_name="openai-community/gpt2", - device_map="auto", - loader_batch_size=5, - dataset_name="Skylion007/openwebtext", - ): + def __init__(self, model_name="openai-community/gpt2", device_map="auto", loader_batch_size=5): super().__init__() - self.gpt2 = nnsight.LanguageModel( - model_name, device_map=device_map, dispatch=True - ) + self.gpt2 = nnsight.LanguageModel(model_name, device_map=device_map, dispatch=True) self.gpt2.requires_grad_(False) self.replacement_model = ReplacementModel(self.gpt2) - self.loader = get_webtext_dataloader( - self.gpt2, dataset_name=dataset_name, batch_size=loader_batch_size - ) + self.loader = get_webtext_dataloader(self.gpt2, batch_size=loader_batch_size) self.add_state("n_correct", default=torch.tensor(0), dist_reduce_fx="sum") self.add_state("n_total", default=torch.tensor(0), dist_reduce_fx="sum") self.add_state( @@ -106,13 +92,7 @@ def prepend_bos(self, tokens, mask): ) tokens = torch.cat([bos, tokens], dim=1) mask = torch.cat( - [ - torch.zeros( - (tokens.shape[0], 1), dtype=torch.bool, device=tokens.device - ), - mask, - ], - dim=1, + [torch.zeros((tokens.shape[0], 1), dtype=torch.bool, device=tokens.device), mask], dim=1 ) return tokens, mask @@ -135,14 +115,10 @@ def update(self, clt, max_batches=20): mask_flat = mask.reshape(-1) logits_gpt2 = logits_gpt2.logits logits_gpt2 = logits_gpt2.reshape(-1, logits_gpt2.shape[-1])[mask_flat] - logits_replacement = logits_replacement.reshape( - -1, logits_replacement.shape[-1] - )[mask_flat] + logits_replacement = logits_replacement.reshape(-1, logits_replacement.shape[-1])[mask_flat] self.n_correct += ( - (logits_gpt2.argmax(dim=-1) == logits_replacement.argmax(dim=-1)) - .int() - .sum() + (logits_gpt2.argmax(dim=-1) == logits_replacement.argmax(dim=-1)).int().sum() ) self.n_total += mask.sum() self.kl_div += torch.nn.functional.kl_div( diff --git a/crosslayer_transcoder/model/clt.py b/crosslayer_transcoder/model/clt.py index 324e43c..cc58891 100644 --- a/crosslayer_transcoder/model/clt.py +++ b/crosslayer_transcoder/model/clt.py @@ -51,11 +51,7 @@ def reset_parameters(self): dec_uniform_thresh = 1 / ((self.d_acts * self.n_layers) ** 0.5) self.W_dec.data.uniform_(-dec_uniform_thresh, dec_uniform_thresh) - mask = ( - self.mask.unsqueeze(-1) - .unsqueeze(-1) - .repeat(1, 1, self.d_features, self.d_acts) - ) + mask = self.mask.unsqueeze(-1).unsqueeze(-1).repeat(1, 1, self.d_features, self.d_acts) self.W_dec.data = torch.where(mask.bool(), self.W_dec.data, 0.0) if self.tied_init: @@ -67,9 +63,7 @@ def reset_parameters(self): # norm = self.W_dec.norm(p=2, dim=-1) # self.W_dec.data = self.W_dec.data / norm.unsqueeze(-1) - def initialize_standardizers( - self, batch: Float[torch.Tensor, "batch_size io n_layers d_acts"] - ): + def initialize_standardizers(self, batch: Float[torch.Tensor, "batch_size io n_layers d_acts"]): self.input_standardizer.initialize_from_batch(batch) self.output_standardizer.initialize_from_batch(batch) @@ -84,9 +78,7 @@ def decode( "from_layer to_layer -> batch_size to_layer d_acts", ) - def forward( - self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"] - ) -> Tuple[ + def forward(self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"]) -> Tuple[ Float[torch.Tensor, "batch_size n_layers d_features"], Float[torch.Tensor, "batch_size n_layers d_features"], Float[torch.Tensor, "batch_size n_layers d_acts"], @@ -140,48 +132,23 @@ def forward_layer( return pre_actvs def forward( - self, - acts_norm: Float[torch.Tensor, "batch_size n_layers d_acts"], - layer: str = "all", + self, acts_norm: Float[torch.Tensor, "batch_size n_layers d_acts"], layer: str = "all" ) -> Float[torch.Tensor, "batch_size n_layers d_features"]: # for inference if layer != "all": return self.forward_layer(acts_norm, layer) - assert acts_norm.shape == (acts_norm.shape[0], self.n_layers, self.d_acts), ( - f"acts_norm shape: {acts_norm.shape}, expected: {(acts_norm.shape[0], self.n_layers, self.d_acts)}" - ) - # for training pre_actvs = einsum( acts_norm, self.W, "batch_size n_layers d_acts, n_layers d_acts d_features -> batch_size n_layers d_features", ) - - assert not pre_actvs.isnan().any(), "pre_actvs contains NaN values" - pre_actvs = pre_actvs.contiguous() - assert pre_actvs.shape == ( - acts_norm.shape[0], - self.n_layers, - self.d_features, - ), ( - f"pre_actvs shape: {pre_actvs.shape}, expected: {(acts_norm.shape[0], self.n_layers, self.d_features)}" - ) - if self.bias: pre_actvs = pre_actvs + self.b.to(acts_norm.dtype) - assert pre_actvs.shape == ( - acts_norm.shape[0], - self.n_layers, - self.d_features, - ), ( - f"pre_actvs shape: {pre_actvs.shape}, expected: {(acts_norm.shape[0], self.n_layers, self.d_features)}" - ) - return pre_actvs @@ -191,9 +158,7 @@ def __init__(self, d_acts: int, d_features: int, n_layers: int): self.d_acts = d_acts self.d_features = d_features self.n_layers = n_layers - self.register_parameter( - f"W", nn.Parameter(torch.empty((n_layers, d_features, d_acts))) - ) + self.register_parameter(f"W", nn.Parameter(torch.empty((n_layers, d_features, d_acts)))) self.reset_parameters() def reset_parameters(self): @@ -202,9 +167,7 @@ def reset_parameters(self): @torch.no_grad() def forward_layer( - self, - features: Float[torch.Tensor, "batch_size seq from_layer d_features"], - layer: int, + self, features: Float[torch.Tensor, "batch_size seq from_layer d_features"], layer: int ) -> Float[torch.Tensor, "batch_size seq d_acts"]: if features.ndim == 4: # (batch, seq, layer, d_features) features = features[:, :, layer, :] @@ -215,9 +178,7 @@ def forward_layer( ) def forward( - self, - features: Float[torch.Tensor, "batch_size n_layers d_features"], - layer: str = "all", + self, features: Float[torch.Tensor, "batch_size n_layers d_features"], layer: str = "all" ) -> Float[torch.Tensor, "batch_size n_layers d_acts"]: if layer != "all": return self.forward_layer(features, layer) @@ -237,18 +198,14 @@ def __init__(self, d_acts: int, d_features: int, n_layers: int): self.d_features = d_features self.n_layers = n_layers for i in range(n_layers): - self.register_parameter( - f"W_{i}", nn.Parameter(torch.empty((i + 1, d_features, d_acts))) - ) + self.register_parameter(f"W_{i}", nn.Parameter(torch.empty((i + 1, d_features, d_acts)))) self.register_parameter(f"b", nn.Parameter(torch.empty((n_layers, d_acts)))) self.reset_parameters() def reset_parameters(self): dec_uniform_thresh = 1 / ((self.d_acts * self.n_layers) ** 0.5) for i in range(self.n_layers): - self.get_parameter(f"W_{i}").data.uniform_( - -dec_uniform_thresh, dec_uniform_thresh - ) + self.get_parameter(f"W_{i}").data.uniform_(-dec_uniform_thresh, dec_uniform_thresh) # for l in range(i): # self.get_parameter(f"W_{i}").data[l, :, :] = self.get_parameter(f"W_{l}").data[l, :, :] * 0.0 @@ -256,9 +213,7 @@ def reset_parameters(self): @torch.no_grad() def forward_layer( - self, - features: Float[torch.Tensor, "batch_size seq from_layer d_features"], - layer: int, + self, features: Float[torch.Tensor, "batch_size seq from_layer d_features"], layer: int ) -> Float[torch.Tensor, "batch_size seq d_acts"]: return ( einsum( @@ -270,19 +225,13 @@ def forward_layer( ) def forward( - self, - features: Float[torch.Tensor, "batch_size n_layers d_features"], - layer: str = "all", + self, features: Float[torch.Tensor, "batch_size n_layers d_features"], layer: str = "all" ) -> Float[torch.Tensor, "batch_size n_layers d_acts"]: if layer != "all": return self.forward_layer(features, layer) recons = torch.empty( - features.shape[0], - self.n_layers, - self.d_acts, - device=features.device, - dtype=features.dtype, + features.shape[0], self.n_layers, self.d_acts, device=features.device, dtype=features.dtype ) for l in range(self.n_layers): W = self.get_parameter(f"W_{l}") @@ -320,15 +269,11 @@ def reset_parameters(self): self.encoder.reset_parameters() self.decoder.reset_parameters() - def initialize_standardizers( - self, batch: Float[torch.Tensor, "batch_size io n_layers d_acts"] - ): + def initialize_standardizers(self, batch: Float[torch.Tensor, "batch_size io n_layers d_acts"]): self.input_standardizer.initialize_from_batch(batch) self.output_standardizer.initialize_from_batch(batch) - def forward( - self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"] - ) -> Tuple[ + def forward(self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"]) -> Tuple[ Float[torch.Tensor, "batch_size n_layers d_features"], # pre_actvs Float[torch.Tensor, "batch_size n_layers d_features"], # features Float[torch.Tensor, "batch_size n_layers d_acts"], # recons_norm @@ -336,30 +281,12 @@ def forward( ]: acts = self.input_standardizer(acts) - # detect NaN values in input batch - if torch.isnan(acts).any(): - raise ValueError("NaN values in input batch after standardization") - pre_actvs = self.encoder(acts) - if torch.isnan(pre_actvs).any(): - raise ValueError("NaN values in output batch after encoder") - features = self.nonlinearity(pre_actvs) - if torch.isnan(features).any(): - raise ValueError("NaN values in output batch after nonlinearity") - recons_norm = self.decoder(features) - # detect NaN values in output batch - if torch.isnan(recons_norm).any(): - raise ValueError("NaN values in output batch after decoder") - recons = self.output_standardizer(recons_norm) - # detect NaN values in output batch - if torch.isnan(recons).any(): - raise ValueError("NaN values in output batch after output standardization") - return pre_actvs, features, recons_norm, recons diff --git a/crosslayer_transcoder/model/clt_lightning.py b/crosslayer_transcoder/model/clt_lightning.py index 62eaef3..b95fb44 100644 --- a/crosslayer_transcoder/model/clt_lightning.py +++ b/crosslayer_transcoder/model/clt_lightning.py @@ -14,14 +14,8 @@ import wandb from crosslayer_transcoder.metrics.dead_features import DeadFeatures -from crosslayer_transcoder.metrics.replacement_model_accuracy import ( - ReplacementModelAccuracy, -) -from crosslayer_transcoder.model.clt import ( - CrosslayerDecoder, - CrossLayerTranscoder, - Decoder, -) +from crosslayer_transcoder.metrics.replacement_model_accuracy import ReplacementModelAccuracy +from crosslayer_transcoder.model.clt import CrosslayerDecoder, CrossLayerTranscoder, Decoder from crosslayer_transcoder.model.jumprelu import JumpReLU from crosslayer_transcoder.model.topk import BatchTopK @@ -55,9 +49,7 @@ def __init__( ): super().__init__(*args, **kwargs) - self.save_hyperparameters( - ignore=["model", "replacement_model", "dead_features"] - ) + self.save_hyperparameters(ignore=["model", "replacement_model", "dead_features"]) # torch.cuda.memory._record_memory_history(max_entries=100_000) # Store pre-constructed modules @@ -85,16 +77,13 @@ def __init__( self.beta2 = beta2 self.log_metrics_every = log_metrics_every - assert self.model.encoder.n_layers == self.model.decoder.n_layers, ( - "Encoder and decoder must have the same number of layers" - ) + assert ( + self.model.encoder.n_layers == self.model.decoder.n_layers + ), "Encoder and decoder must have the same number of layers" self.register_buffer( "last_active", - torch.zeros( - (self.model.encoder.n_layers, self.model.encoder.d_features), - dtype=torch.long, - ), + torch.zeros((self.model.encoder.n_layers, self.model.encoder.d_features), dtype=torch.long), ) def configure_model(self): @@ -103,28 +92,22 @@ def configure_model(self): print("Compiling model") self = torch.compile(self) - try: - if self.__getattribute__("trainer") and self.trainer.num_devices > 1: - from crosslayer_transcoder.model.parallel import ( - ColParallelEncoder, - ParallelNonlinearity, - RowParallelDecoder, - ) + if self.trainer.num_devices > 1: + from crosslayer_transcoder.model.parallel import ( + ColParallelEncoder, + ParallelNonlinearity, + RowParallelDecoder, + ) + + tp_mesh = self.device_mesh["tensor_parallel"] + plan = { + "encoder": ColParallelEncoder(use_local_output=False), + "nonlinearity": ParallelNonlinearity(use_local_output=False), + "decoder": RowParallelDecoder(), + } + parallelize_module(self, tp_mesh, plan) - tp_mesh = self.device_mesh["tensor_parallel"] - plan = { - "encoder": ColParallelEncoder(use_local_output=False), - "nonlinearity": ParallelNonlinearity(use_local_output=False), - "decoder": RowParallelDecoder(), - } - parallelize_module(self, tp_mesh, plan) - except Exception as e: - print(f"Error parallelizing model: {e}") - pass - - def forward( - self, acts_norm: Float[torch.Tensor, "batch_size n_layers d_acts"] - ) -> Tuple[ + def forward(self, acts_norm: Float[torch.Tensor, "batch_size n_layers d_acts"]) -> Tuple[ Float[torch.Tensor, "batch_size n_layers d_features"], # pre_actvs Float[torch.Tensor, "batch_size n_layers d_features"], # features Float[torch.Tensor, "batch_size n_layers d_acts"], # recons_norm @@ -147,18 +130,13 @@ def log_training_metrics(self, features, recons_norm, recons, mlp_out, batch_idx ss_err = (mlp_out_norm - recons_norm) ** 2 ss_err = ss_err.sum(dim=0) - ss_total = ((mlp_out_norm - mlp_out_norm.mean(dim=0, keepdim=True)) ** 2).sum( - dim=0 - ) + ss_total = ((mlp_out_norm - mlp_out_norm.mean(dim=0, keepdim=True)) ** 2).sum(dim=0) fvu = (ss_err / ss_total).mean() # (n_layers, d_model) self.log("metrics/fraction_of_variance_unexplained", fvu) fvu_per_layer = (ss_err / ss_total).mean(dim=-1) assert fvu_per_layer.shape == (self.model.encoder.n_layers,) for layer in range(self.model.encoder.n_layers): - self.log( - f"layers/fraction_of_variance_unexplained/layer_{layer}", - fvu_per_layer[layer], - ) + self.log(f"layers/fraction_of_variance_unexplained/layer_{layer}", fvu_per_layer[layer]) # number of tokens seen if not hasattr(self, "tokens_seen"): @@ -193,8 +171,7 @@ def log_training_metrics(self, features, recons_norm, recons, mlp_out, batch_idx self.log("metrics/recons_standardized_std", recons_norm.std()) self.log( "metrics/L0_avg_per_layer", - torch.count_nonzero(active_features) - / (features.shape[0] * features.shape[1]), + torch.count_nonzero(active_features) / (features.shape[0] * features.shape[1]), ) # Magnitude of feature activations - memory efficient version @@ -220,9 +197,7 @@ def log_training_metrics(self, features, recons_norm, recons, mlp_out, batch_idx # Log L0 table per layer if batch_idx % 500 == 1: - l0_per_layer = ( - torch.count_nonzero(active_features, dim=(0, 2)) / features.shape[0] - ) + l0_per_layer = torch.count_nonzero(active_features, dim=(0, 2)) / features.shape[0] if self.logger and isinstance(self.logger.experiment, wandb.wandb_run.Run): table = wandb.Table( @@ -230,11 +205,7 @@ def log_training_metrics(self, features, recons_norm, recons, mlp_out, batch_idx columns=["layer", "L0"], ) self.logger.experiment.log( - { - "layers/L0_per_layer": wandb.plot.bar( - table, "layer", "L0", title="L0 per Layer" - ) - }, + {"layers/L0_per_layer": wandb.plot.bar(table, "layer", "L0", title="L0 per Layer")}, step=self.global_step, ) @@ -263,11 +234,7 @@ def log_training_metrics(self, features, recons_norm, recons, mlp_out, batch_idx ): for layer in range(dead_log_freqs.shape[0]): self.logger.experiment.log( - { - f"layers/log_feature_density/layer_{layer}": dead_log_freqs[ - layer - ] - }, + {f"layers/log_feature_density/layer_{layer}": dead_log_freqs[layer]}, step=self.global_step, ) self.logger.experiment.log( @@ -295,8 +262,7 @@ def training_step(self, batch, batch_idx): self.model.initialize_standardizers(batch) resid, mlp_out = batch[:, 0], batch[:, 1] - with torch.autograd.detect_anomaly(True): - _, features, recons_norm, recons = self.forward(resid) + _, features, recons_norm, recons = self.forward(resid) self.update_dead_features(features) @@ -338,17 +304,11 @@ def configure_optimizers(self): if self.optimizer == "adam": optimizer = torch.optim.Adam( - self.parameters(), - lr=self.learning_rate, - betas=(self.beta1, self.beta2), - fused=True, + self.parameters(), lr=self.learning_rate, betas=(self.beta1, self.beta2), fused=True ) elif self.optimizer == "adamw": optimizer = torch.optim.AdamW( - self.parameters(), - lr=self.learning_rate, - betas=(self.beta1, self.beta2), - fused=True, + self.parameters(), lr=self.learning_rate, betas=(self.beta1, self.beta2), fused=True ) else: raise ValueError(f"Optimizer {self.optimizer} not supported") @@ -425,27 +385,10 @@ def training_step(self, batch, batch_idx): if batch_idx == 0: self.model.initialize_standardizers(batch) - # detect NaN values in input batch - if torch.isnan(batch).any(): - raise ValueError("NaN values in input batch") - # Forward pass resid, mlp_out = batch[:, 0], batch[:, 1] pre_actvs, features, recons_norm, recons = self.forward(resid) - # detect NaN values in output batch - if ( - torch.isnan(pre_actvs).any() - or torch.isnan(features).any() - or torch.isnan(recons_norm).any() - or torch.isnan(recons).any() - ): - print(f"pre_actvs: {torch.isnan(pre_actvs)}") - print(f"features: {torch.isnan(features)}") - print(f"recons_norm: {torch.isnan(recons_norm)}") - print(f"recons: {torch.isnan(recons)}") - raise ValueError("NaN values in output batch") - self.update_dead_features(features) # Compute MSE loss mse = (recons_norm - self.model.output_standardizer.standardize(mlp_out)) ** 2 @@ -453,37 +396,21 @@ def training_step(self, batch, batch_idx): # Compute Sparsity Loss # with torch.no_grad(): if isinstance(self.model.decoder, CrosslayerDecoder): - # shape(features):[batch, n_layers, d_features]] dec_norms = torch.zeros_like(features[:1]) for l in range(self.model.decoder.n_layers): - W = self.model.decoder.get_parameter( - f"W_{l}" - ) # (from_layer, d_features, d_acts) + W = self.model.decoder.get_parameter(f"W_{l}") # (from_layer, d_features, d_acts) dec_norms[:, : l + 1] = dec_norms[:, : l + 1] + (W**2).sum(dim=-1) dec_norms = dec_norms.sqrt() elif isinstance(self.model.decoder, Decoder): dec_norms = torch.sqrt((self.model.decoder.W**2).sum(dim=-1)) - assert not dec_norms.isnan().any(), "dec_norms contains NaN values" - assert not features.isnan().any(), "features contains NaN values" - weighted_features = features * dec_norms * self.c - self.log( - "model/weighted_features_mean", weighted_features.detach().mean().cpu() - ) - - assert not weighted_features.isnan().any(), ( - "weighted_features contains NaN values" - ) + self.log("model/weighted_features_mean", weighted_features.detach().mean().cpu()) if self.use_tanh: - weighted_features = torch.tanh( - weighted_features - ) # (batch_size, n_layers, d_features) - sparsity = ( - self.current_sparsity_penalty() * weighted_features.sum(dim=[1, 2]).mean() - ) + weighted_features = torch.tanh(weighted_features) # (batch_size, n_layers, d_features) + sparsity = self.current_sparsity_penalty() * weighted_features.sum(dim=[1, 2]).mean() self.log("training/sparsity_loss", sparsity) # Compute Pre-activation Loss @@ -535,10 +462,7 @@ def __init__( self.aux_loss_scale = aux_loss_scale self.register_buffer( "last_active", - torch.zeros( - (self.model.encoder.n_layers, self.model.encoder.d_features), - dtype=torch.long, - ), + torch.zeros((self.model.encoder.n_layers, self.model.encoder.d_features), dtype=torch.long), ) def training_step(self, batch, batch_idx): diff --git a/crosslayer_transcoder/model/jumprelu.py b/crosslayer_transcoder/model/jumprelu.py index f6b4e26..2c67756 100644 --- a/crosslayer_transcoder/model/jumprelu.py +++ b/crosslayer_transcoder/model/jumprelu.py @@ -26,10 +26,7 @@ def backward(ctx, grad_output): grad_input = grad_output.clone() grad_input[input < 0] = 0 - theta_grad = ( - -(theta / bandwidth) * rectangle((input - theta) / bandwidth) * grad_output - ) - + theta_grad = -(theta / bandwidth) * rectangle((input - theta) / bandwidth) * grad_output return grad_input, theta_grad, None @@ -49,9 +46,7 @@ class HeavysideStep(torch.autograd.Function): def forward(ctx, input, theta, bandwidth): ctx.save_for_backward(input, theta) ctx.bandwidth = bandwidth - return torch.where( - input - theta > 0, torch.ones_like(input), torch.zeros_like(input) - ) + return torch.where(input - theta > 0, torch.ones_like(input), torch.zeros_like(input)) @staticmethod def backward(ctx, grad_output): @@ -60,7 +55,5 @@ def backward(ctx, grad_output): grad_input = grad_output.clone() grad_input = grad_output * 0.0 - theta_grad = ( - -(1.0 / bandwidth) * rectangle((input - theta) / bandwidth) * grad_output - ) + theta_grad = -(1.0 / bandwidth) * rectangle((input - theta) / bandwidth) * grad_output return grad_input, theta_grad, None diff --git a/tests/benchmark_text_dataloader.py b/tests/benchmark_text_dataloader.py index 4fe1413..d29d25f 100644 --- a/tests/benchmark_text_dataloader.py +++ b/tests/benchmark_text_dataloader.py @@ -11,7 +11,7 @@ from datasets import load_dataset from torch.utils.data import DataLoader -from crosslayer_transcoder.data import text_dataset +from data import text_dataset def benchmark_textdataset( @@ -187,7 +187,7 @@ def compare_workers(): worker_configs = [0, 1, 2, 4] for num_workers in worker_configs: - print(f"\n{'=' * 50}") + print(f"\n{'='*50}") print(f"Testing with {num_workers} workers") print("=" * 50) From f6bd08e90df54b7de518393068f3d3e637068f0b Mon Sep 17 00:00:00 2001 From: jiito Date: Wed, 1 Oct 2025 11:05:40 -0700 Subject: [PATCH 14/99] remove unused import --- crosslayer_transcoder/modal/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/crosslayer_transcoder/modal/main.py b/crosslayer_transcoder/modal/main.py index 87bd4ad..0a24028 100644 --- a/crosslayer_transcoder/modal/main.py +++ b/crosslayer_transcoder/modal/main.py @@ -1,3 +1,4 @@ +import os import sys from crosslayer_transcoder.modal.app import app, volumes, wandb_secret, retries from crosslayer_transcoder.main import main as lightning_cli_main From 7c0a36a29533e2b0746a901fd0f2c421c9b59f9d Mon Sep 17 00:00:00 2001 From: jiito Date: Wed, 1 Oct 2025 11:07:02 -0700 Subject: [PATCH 15/99] uv sync --- uv.lock | 483 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 483 insertions(+) diff --git a/uv.lock b/uv.lock index 334ea17..c06e756 100644 --- a/uv.lock +++ b/uv.lock @@ -8,7 +8,11 @@ resolution-markers = [ [[package]] name = "accelerate" +<<<<<<< HEAD version = "1.11.0" +======= +version = "1.10.1" +>>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "huggingface-hub" }, @@ -19,9 +23,15 @@ dependencies = [ { name = "safetensors" }, { name = "torch" }, ] +<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/23/60/2757c4f03a8705dbf80b1268b03881927878dca5ed07d74f733fb6c219e0/accelerate-1.11.0.tar.gz", hash = "sha256:bb1caf2597b4cd632b917b5000c591d10730bb024a79746f1ee205bba80bd229", size = 393715, upload-time = "2025-10-20T14:42:25.025Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/77/85/85951bc0f9843e2c10baaa1b6657227056095de08f4d1eea7d8b423a6832/accelerate-1.11.0-py3-none-any.whl", hash = "sha256:a628fa6beb069b8e549460fc449135d5bd8d73e7a11fd09f0bc9fc4ace7f06f1", size = 375777, upload-time = "2025-10-20T14:42:23.256Z" }, +======= +sdist = { url = "https://files.pythonhosted.org/packages/b1/72/ff3961c19ee395c3d30ac630ee77bfb0e1b46b87edc504d4f83bb4a89705/accelerate-1.10.1.tar.gz", hash = "sha256:3dea89e433420e4bfac0369cae7e36dcd6a56adfcfd38cdda145c6225eab5df8", size = 392446, upload-time = "2025-08-25T13:57:06.21Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/a0/d9ef19f780f319c21ee90ecfef4431cbeeca95bec7f14071785c17b6029b/accelerate-1.10.1-py3-none-any.whl", hash = "sha256:3621cff60b9a27ce798857ece05e2b9f56fcc71631cfb31ccf71f0359c311f11", size = 374909, upload-time = "2025-08-25T13:57:04.55Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -35,7 +45,11 @@ wheels = [ [[package]] name = "aiohttp" +<<<<<<< HEAD version = "3.13.2" +======= +version = "3.12.15" +>>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, @@ -46,6 +60,7 @@ dependencies = [ { name = "propcache" }, { name = "yarl" }, ] +<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/1c/ce/3b83ebba6b3207a7135e5fcaba49706f8a4b6008153b4e30540c982fae26/aiohttp-3.13.2.tar.gz", hash = "sha256:40176a52c186aefef6eb3cad2cdd30cd06e3afbe88fe8ab2af9c0b90f228daca", size = 7837994, upload-time = "2025-10-28T20:59:39.937Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/29/9b/01f00e9856d0a73260e86dd8ed0c2234a466c5c1712ce1c281548df39777/aiohttp-3.13.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b1e56bab2e12b2b9ed300218c351ee2a3d8c8fdab5b1ec6193e11a817767e47b", size = 737623, upload-time = "2025-10-28T20:56:30.797Z" }, @@ -65,6 +80,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ba/e4/19ce547b58ab2a385e5f0b8aa3db38674785085abcf79b6e0edd1632b12f/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ff15c147b2ad66da1f2cbb0622313f2242d8e6e8f9b79b5206c84523a4473248", size = 1719512, upload-time = "2025-10-28T20:56:56.428Z" }, { url = "https://files.pythonhosted.org/packages/70/30/6355a737fed29dcb6dfdd48682d5790cb5eab050f7b4e01f49b121d3acad/aiohttp-3.13.2-cp312-cp312-win32.whl", hash = "sha256:27e569eb9d9e95dbd55c0fc3ec3a9335defbf1d8bc1d20171a49f3c4c607b93e", size = 426690, upload-time = "2025-10-28T20:56:58.736Z" }, { url = "https://files.pythonhosted.org/packages/0a/0d/b10ac09069973d112de6ef980c1f6bb31cb7dcd0bc363acbdad58f927873/aiohttp-3.13.2-cp312-cp312-win_amd64.whl", hash = "sha256:8709a0f05d59a71f33fd05c17fc11fcb8c30140506e13c2f5e8ee1b8964e1b45", size = 453465, upload-time = "2025-10-28T20:57:00.795Z" }, +======= +sdist = { url = "https://files.pythonhosted.org/packages/9b/e7/d92a237d8802ca88483906c388f7c201bbe96cd80a165ffd0ac2f6a8d59f/aiohttp-3.12.15.tar.gz", hash = "sha256:4fc61385e9c98d72fcdf47e6dd81833f47b2f77c114c29cd64a361be57a763a2", size = 7823716, upload-time = "2025-07-29T05:52:32.215Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/63/97/77cb2450d9b35f517d6cf506256bf4f5bda3f93a66b4ad64ba7fc917899c/aiohttp-3.12.15-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:802d3868f5776e28f7bf69d349c26fc0efadb81676d0afa88ed00d98a26340b7", size = 702333, upload-time = "2025-07-29T05:50:46.507Z" }, + { url = "https://files.pythonhosted.org/packages/83/6d/0544e6b08b748682c30b9f65640d006e51f90763b41d7c546693bc22900d/aiohttp-3.12.15-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2800614cd560287be05e33a679638e586a2d7401f4ddf99e304d98878c29444", size = 476948, upload-time = "2025-07-29T05:50:48.067Z" }, + { url = "https://files.pythonhosted.org/packages/3a/1d/c8c40e611e5094330284b1aea8a4b02ca0858f8458614fa35754cab42b9c/aiohttp-3.12.15-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8466151554b593909d30a0a125d638b4e5f3836e5aecde85b66b80ded1cb5b0d", size = 469787, upload-time = "2025-07-29T05:50:49.669Z" }, + { url = "https://files.pythonhosted.org/packages/38/7d/b76438e70319796bfff717f325d97ce2e9310f752a267bfdf5192ac6082b/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e5a495cb1be69dae4b08f35a6c4579c539e9b5706f606632102c0f855bcba7c", size = 1716590, upload-time = "2025-07-29T05:50:51.368Z" }, + { url = "https://files.pythonhosted.org/packages/79/b1/60370d70cdf8b269ee1444b390cbd72ce514f0d1cd1a715821c784d272c9/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6404dfc8cdde35c69aaa489bb3542fb86ef215fc70277c892be8af540e5e21c0", size = 1699241, upload-time = "2025-07-29T05:50:53.628Z" }, + { url = "https://files.pythonhosted.org/packages/a3/2b/4968a7b8792437ebc12186db31523f541943e99bda8f30335c482bea6879/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3ead1c00f8521a5c9070fcb88f02967b1d8a0544e6d85c253f6968b785e1a2ab", size = 1754335, upload-time = "2025-07-29T05:50:55.394Z" }, + { url = "https://files.pythonhosted.org/packages/fb/c1/49524ed553f9a0bec1a11fac09e790f49ff669bcd14164f9fab608831c4d/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6990ef617f14450bc6b34941dba4f12d5613cbf4e33805932f853fbd1cf18bfb", size = 1800491, upload-time = "2025-07-29T05:50:57.202Z" }, + { url = "https://files.pythonhosted.org/packages/de/5e/3bf5acea47a96a28c121b167f5ef659cf71208b19e52a88cdfa5c37f1fcc/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd736ed420f4db2b8148b52b46b88ed038d0354255f9a73196b7bbce3ea97545", size = 1719929, upload-time = "2025-07-29T05:50:59.192Z" }, + { url = "https://files.pythonhosted.org/packages/39/94/8ae30b806835bcd1cba799ba35347dee6961a11bd507db634516210e91d8/aiohttp-3.12.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c5092ce14361a73086b90c6efb3948ffa5be2f5b6fbcf52e8d8c8b8848bb97c", size = 1635733, upload-time = "2025-07-29T05:51:01.394Z" }, + { url = "https://files.pythonhosted.org/packages/7a/46/06cdef71dd03acd9da7f51ab3a9107318aee12ad38d273f654e4f981583a/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:aaa2234bb60c4dbf82893e934d8ee8dea30446f0647e024074237a56a08c01bd", size = 1696790, upload-time = "2025-07-29T05:51:03.657Z" }, + { url = "https://files.pythonhosted.org/packages/02/90/6b4cfaaf92ed98d0ec4d173e78b99b4b1a7551250be8937d9d67ecb356b4/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6d86a2fbdd14192e2f234a92d3b494dd4457e683ba07e5905a0b3ee25389ac9f", size = 1718245, upload-time = "2025-07-29T05:51:05.911Z" }, + { url = "https://files.pythonhosted.org/packages/2e/e6/2593751670fa06f080a846f37f112cbe6f873ba510d070136a6ed46117c6/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a041e7e2612041a6ddf1c6a33b883be6a421247c7afd47e885969ee4cc58bd8d", size = 1658899, upload-time = "2025-07-29T05:51:07.753Z" }, + { url = "https://files.pythonhosted.org/packages/8f/28/c15bacbdb8b8eb5bf39b10680d129ea7410b859e379b03190f02fa104ffd/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5015082477abeafad7203757ae44299a610e89ee82a1503e3d4184e6bafdd519", size = 1738459, upload-time = "2025-07-29T05:51:09.56Z" }, + { url = "https://files.pythonhosted.org/packages/00/de/c269cbc4faa01fb10f143b1670633a8ddd5b2e1ffd0548f7aa49cb5c70e2/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:56822ff5ddfd1b745534e658faba944012346184fbfe732e0d6134b744516eea", size = 1766434, upload-time = "2025-07-29T05:51:11.423Z" }, + { url = "https://files.pythonhosted.org/packages/52/b0/4ff3abd81aa7d929b27d2e1403722a65fc87b763e3a97b3a2a494bfc63bc/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b2acbbfff69019d9014508c4ba0401822e8bae5a5fdc3b6814285b71231b60f3", size = 1726045, upload-time = "2025-07-29T05:51:13.689Z" }, + { url = "https://files.pythonhosted.org/packages/71/16/949225a6a2dd6efcbd855fbd90cf476052e648fb011aa538e3b15b89a57a/aiohttp-3.12.15-cp312-cp312-win32.whl", hash = "sha256:d849b0901b50f2185874b9a232f38e26b9b3d4810095a7572eacea939132d4e1", size = 423591, upload-time = "2025-07-29T05:51:15.452Z" }, + { url = "https://files.pythonhosted.org/packages/2b/d8/fa65d2a349fe938b76d309db1a56a75c4fb8cc7b17a398b698488a939903/aiohttp-3.12.15-cp312-cp312-win_amd64.whl", hash = "sha256:b390ef5f62bb508a9d67cb3bba9b8356e23b3996da7062f1a57ce1a79d2b3d34", size = 450266, upload-time = "2025-07-29T05:51:17.239Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -261,6 +297,7 @@ css = [ ] [[package]] +<<<<<<< HEAD name = "cbor2" version = "5.7.1" source = { registry = "https://pypi.org/simple" } @@ -284,6 +321,14 @@ source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/4c/5b/b6ce21586237c77ce67d01dc5507039d444b630dd76611bbca2d8e5dcd91/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43", size = 164519, upload-time = "2025-10-05T04:12:15.808Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e4/37/af0d2ef3967ac0d6113837b44a4f0bfe1328c2b9763bd5b1744520e5cfed/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", size = 163286, upload-time = "2025-10-05T04:12:14.03Z" }, +======= +name = "certifi" +version = "2025.8.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/dc/67/960ebe6bf230a96cda2e0abcf73af550ec4f090005363542f0765df162e0/certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407", size = 162386, upload-time = "2025-08-03T03:07:47.08Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5", size = 161216, upload-time = "2025-08-03T03:07:45.777Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -311,6 +356,7 @@ wheels = [ [[package]] name = "charset-normalizer" +<<<<<<< HEAD version = "3.4.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } @@ -332,6 +378,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" }, { url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" }, { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, +======= +version = "3.4.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/83/2d/5fd176ceb9b2fc619e63405525573493ca23441330fcdaee6bef9460e924/charset_normalizer-3.4.3.tar.gz", hash = "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14", size = 122371, upload-time = "2025-08-09T07:57:28.46Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/5e/14c94999e418d9b87682734589404a25854d5f5d0408df68bc15b6ff54bb/charset_normalizer-3.4.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1", size = 205655, upload-time = "2025-08-09T07:56:08.475Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a8/c6ec5d389672521f644505a257f50544c074cf5fc292d5390331cd6fc9c3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884", size = 146223, upload-time = "2025-08-09T07:56:09.708Z" }, + { url = "https://files.pythonhosted.org/packages/fc/eb/a2ffb08547f4e1e5415fb69eb7db25932c52a52bed371429648db4d84fb1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018", size = 159366, upload-time = "2025-08-09T07:56:11.326Z" }, + { url = "https://files.pythonhosted.org/packages/82/10/0fd19f20c624b278dddaf83b8464dcddc2456cb4b02bb902a6da126b87a1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392", size = 157104, upload-time = "2025-08-09T07:56:13.014Z" }, + { url = "https://files.pythonhosted.org/packages/16/ab/0233c3231af734f5dfcf0844aa9582d5a1466c985bbed6cedab85af9bfe3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f", size = 151830, upload-time = "2025-08-09T07:56:14.428Z" }, + { url = "https://files.pythonhosted.org/packages/ae/02/e29e22b4e02839a0e4a06557b1999d0a47db3567e82989b5bb21f3fbbd9f/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154", size = 148854, upload-time = "2025-08-09T07:56:16.051Z" }, + { url = "https://files.pythonhosted.org/packages/05/6b/e2539a0a4be302b481e8cafb5af8792da8093b486885a1ae4d15d452bcec/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491", size = 160670, upload-time = "2025-08-09T07:56:17.314Z" }, + { url = "https://files.pythonhosted.org/packages/31/e7/883ee5676a2ef217a40ce0bffcc3d0dfbf9e64cbcfbdf822c52981c3304b/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93", size = 158501, upload-time = "2025-08-09T07:56:18.641Z" }, + { url = "https://files.pythonhosted.org/packages/c1/35/6525b21aa0db614cf8b5792d232021dca3df7f90a1944db934efa5d20bb1/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f", size = 153173, upload-time = "2025-08-09T07:56:20.289Z" }, + { url = "https://files.pythonhosted.org/packages/50/ee/f4704bad8201de513fdc8aac1cabc87e38c5818c93857140e06e772b5892/charset_normalizer-3.4.3-cp312-cp312-win32.whl", hash = "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37", size = 99822, upload-time = "2025-08-09T07:56:21.551Z" }, + { url = "https://files.pythonhosted.org/packages/39/f5/3b3836ca6064d0992c58c7561c6b6eee1b3892e9665d650c803bd5614522/charset_normalizer-3.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc", size = 107543, upload-time = "2025-08-09T07:56:23.115Z" }, + { url = "https://files.pythonhosted.org/packages/8a/1f/f041989e93b001bc4e44bb1669ccdcf54d3f00e628229a85b08d330615c5/charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", size = 53175, upload-time = "2025-08-09T07:57:26.864Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -468,7 +532,11 @@ dev = [ [[package]] name = "datasets" +<<<<<<< HEAD version = "4.4.1" +======= +version = "4.1.1" +>>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "dill" }, @@ -486,9 +554,15 @@ dependencies = [ { name = "tqdm" }, { name = "xxhash" }, ] +<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/93/bf/0dae295d6d1ba0b1a200a9dd216838464b5bbd05da01407cb1330b377445/datasets-4.4.1.tar.gz", hash = "sha256:80322699aa8c0bbbdb7caa87906da689c3c2e29523cff698775c67f28fdab1fc", size = 585341, upload-time = "2025-11-05T16:00:38.162Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/3b/5e/6f8d874366788ad5d549e9ba258037d974dda6e004843be1bda794571701/datasets-4.4.1-py3-none-any.whl", hash = "sha256:c1163de5211e42546079ab355cc0250c7e6db16eb209ac5ac6252f801f596c44", size = 511591, upload-time = "2025-11-05T16:00:36.365Z" }, +======= +sdist = { url = "https://files.pythonhosted.org/packages/91/a4/73f8e6ef52c535e1d20d5b2ca83bfe6de399d8b8b8a61ccc8d63d60735aa/datasets-4.1.1.tar.gz", hash = "sha256:7d8d5ba8b12861d2c44bfff9c83484ebfafff1ff553371e5901a8d3aab5450e2", size = 579324, upload-time = "2025-09-18T13:14:27.108Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/c8/09012ac195a0aab58755800d2efdc0e7d5905053509f12cb5d136c911cda/datasets-4.1.1-py3-none-any.whl", hash = "sha256:62e4f6899a36be9ec74a7e759a6951253cc85b3fcfa0a759b0efa8353b149dac", size = 503623, upload-time = "2025-09-18T13:14:25.111Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -578,11 +652,19 @@ wheels = [ [[package]] name = "filelock" +<<<<<<< HEAD version = "3.20.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/58/46/0028a82567109b5ef6e4d2a1f04a583fb513e6cf9527fcdd09afd817deeb/filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4", size = 18922, upload-time = "2025-10-08T18:03:50.056Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" }, +======= +version = "3.19.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/40/bb/0ab3e58d22305b6f5440629d20683af28959bf793d98d11950e305c1c326/filelock-3.19.1.tar.gz", hash = "sha256:66eda1888b0171c998b35be2bcc0f6d75c388a7ce20c3f3f37aa8e96c2dddf58", size = 17687, upload-time = "2025-08-14T16:56:03.016Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/14/42b2651a2f46b022ccd948bca9f2d5af0fd8929c4eec235b8d6d844fbe67/filelock-3.19.1-py3-none-any.whl", hash = "sha256:d38e30481def20772f5baf097c122c3babc4fcdb7e14e57049eb9d88c6dc017d", size = 15988, upload-time = "2025-08-14T16:56:01.633Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -596,6 +678,7 @@ wheels = [ [[package]] name = "frozenlist" +<<<<<<< HEAD version = "1.8.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875, upload-time = "2025-10-06T05:38:17.865Z" } @@ -617,15 +700,47 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b8/af/38e51a553dd66eb064cdf193841f16f077585d4d28394c2fa6235cb41765/frozenlist-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746", size = 44591, upload-time = "2025-10-06T05:36:24.958Z" }, { url = "https://files.pythonhosted.org/packages/a7/06/1dc65480ab147339fecc70797e9c2f69d9cea9cf38934ce08df070fdb9cb/frozenlist-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd", size = 40102, upload-time = "2025-10-06T05:36:26.333Z" }, { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, +======= +version = "1.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/79/b1/b64018016eeb087db503b038296fd782586432b9c077fc5c7839e9cb6ef6/frozenlist-1.7.0.tar.gz", hash = "sha256:2e310d81923c2437ea8670467121cc3e9b0f76d3043cc1d2331d56c7fb7a3a8f", size = 45078, upload-time = "2025-06-09T23:02:35.538Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/a2/c8131383f1e66adad5f6ecfcce383d584ca94055a34d683bbb24ac5f2f1c/frozenlist-1.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3dbf9952c4bb0e90e98aec1bd992b3318685005702656bc6f67c1a32b76787f2", size = 81424, upload-time = "2025-06-09T23:00:42.24Z" }, + { url = "https://files.pythonhosted.org/packages/4c/9d/02754159955088cb52567337d1113f945b9e444c4960771ea90eb73de8db/frozenlist-1.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1f5906d3359300b8a9bb194239491122e6cf1444c2efb88865426f170c262cdb", size = 47952, upload-time = "2025-06-09T23:00:43.481Z" }, + { url = "https://files.pythonhosted.org/packages/01/7a/0046ef1bd6699b40acd2067ed6d6670b4db2f425c56980fa21c982c2a9db/frozenlist-1.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3dabd5a8f84573c8d10d8859a50ea2dec01eea372031929871368c09fa103478", size = 46688, upload-time = "2025-06-09T23:00:44.793Z" }, + { url = "https://files.pythonhosted.org/packages/d6/a2/a910bafe29c86997363fb4c02069df4ff0b5bc39d33c5198b4e9dd42d8f8/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa57daa5917f1738064f302bf2626281a1cb01920c32f711fbc7bc36111058a8", size = 243084, upload-time = "2025-06-09T23:00:46.125Z" }, + { url = "https://files.pythonhosted.org/packages/64/3e/5036af9d5031374c64c387469bfcc3af537fc0f5b1187d83a1cf6fab1639/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c193dda2b6d49f4c4398962810fa7d7c78f032bf45572b3e04dd5249dff27e08", size = 233524, upload-time = "2025-06-09T23:00:47.73Z" }, + { url = "https://files.pythonhosted.org/packages/06/39/6a17b7c107a2887e781a48ecf20ad20f1c39d94b2a548c83615b5b879f28/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe2b675cf0aaa6d61bf8fbffd3c274b3c9b7b1623beb3809df8a81399a4a9c4", size = 248493, upload-time = "2025-06-09T23:00:49.742Z" }, + { url = "https://files.pythonhosted.org/packages/be/00/711d1337c7327d88c44d91dd0f556a1c47fb99afc060ae0ef66b4d24793d/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8fc5d5cda37f62b262405cf9652cf0856839c4be8ee41be0afe8858f17f4c94b", size = 244116, upload-time = "2025-06-09T23:00:51.352Z" }, + { url = "https://files.pythonhosted.org/packages/24/fe/74e6ec0639c115df13d5850e75722750adabdc7de24e37e05a40527ca539/frozenlist-1.7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0d5ce521d1dd7d620198829b87ea002956e4319002ef0bc8d3e6d045cb4646e", size = 224557, upload-time = "2025-06-09T23:00:52.855Z" }, + { url = "https://files.pythonhosted.org/packages/8d/db/48421f62a6f77c553575201e89048e97198046b793f4a089c79a6e3268bd/frozenlist-1.7.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:488d0a7d6a0008ca0db273c542098a0fa9e7dfaa7e57f70acef43f32b3f69dca", size = 241820, upload-time = "2025-06-09T23:00:54.43Z" }, + { url = "https://files.pythonhosted.org/packages/1d/fa/cb4a76bea23047c8462976ea7b7a2bf53997a0ca171302deae9d6dd12096/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:15a7eaba63983d22c54d255b854e8108e7e5f3e89f647fc854bd77a237e767df", size = 236542, upload-time = "2025-06-09T23:00:56.409Z" }, + { url = "https://files.pythonhosted.org/packages/5d/32/476a4b5cfaa0ec94d3f808f193301debff2ea42288a099afe60757ef6282/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1eaa7e9c6d15df825bf255649e05bd8a74b04a4d2baa1ae46d9c2d00b2ca2cb5", size = 249350, upload-time = "2025-06-09T23:00:58.468Z" }, + { url = "https://files.pythonhosted.org/packages/8d/ba/9a28042f84a6bf8ea5dbc81cfff8eaef18d78b2a1ad9d51c7bc5b029ad16/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4389e06714cfa9d47ab87f784a7c5be91d3934cd6e9a7b85beef808297cc025", size = 225093, upload-time = "2025-06-09T23:01:00.015Z" }, + { url = "https://files.pythonhosted.org/packages/bc/29/3a32959e68f9cf000b04e79ba574527c17e8842e38c91d68214a37455786/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:73bd45e1488c40b63fe5a7df892baf9e2a4d4bb6409a2b3b78ac1c6236178e01", size = 245482, upload-time = "2025-06-09T23:01:01.474Z" }, + { url = "https://files.pythonhosted.org/packages/80/e8/edf2f9e00da553f07f5fa165325cfc302dead715cab6ac8336a5f3d0adc2/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:99886d98e1643269760e5fe0df31e5ae7050788dd288947f7f007209b8c33f08", size = 249590, upload-time = "2025-06-09T23:01:02.961Z" }, + { url = "https://files.pythonhosted.org/packages/1c/80/9a0eb48b944050f94cc51ee1c413eb14a39543cc4f760ed12657a5a3c45a/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:290a172aae5a4c278c6da8a96222e6337744cd9c77313efe33d5670b9f65fc43", size = 237785, upload-time = "2025-06-09T23:01:05.095Z" }, + { url = "https://files.pythonhosted.org/packages/f3/74/87601e0fb0369b7a2baf404ea921769c53b7ae00dee7dcfe5162c8c6dbf0/frozenlist-1.7.0-cp312-cp312-win32.whl", hash = "sha256:426c7bc70e07cfebc178bc4c2bf2d861d720c4fff172181eeb4a4c41d4ca2ad3", size = 39487, upload-time = "2025-06-09T23:01:06.54Z" }, + { url = "https://files.pythonhosted.org/packages/0b/15/c026e9a9fc17585a9d461f65d8593d281fedf55fbf7eb53f16c6df2392f9/frozenlist-1.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:563b72efe5da92e02eb68c59cb37205457c977aa7a449ed1b37e6939e5c47c6a", size = 43874, upload-time = "2025-06-09T23:01:07.752Z" }, + { url = "https://files.pythonhosted.org/packages/ee/45/b82e3c16be2182bff01179db177fe144d58b5dc787a7d4492c6ed8b9317f/frozenlist-1.7.0-py3-none-any.whl", hash = "sha256:9a5af342e34f7e97caf8c995864c7a396418ae2859cc6fdf1b1073020d516a7e", size = 13106, upload-time = "2025-06-09T23:02:34.204Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] name = "fsspec" +<<<<<<< HEAD version = "2025.10.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/24/7f/2747c0d332b9acfa75dc84447a066fdf812b5a6b8d30472b74d309bfe8cb/fsspec-2025.10.0.tar.gz", hash = "sha256:b6789427626f068f9a83ca4e8a3cc050850b6c0f71f99ddb4f542b8266a26a59", size = 309285, upload-time = "2025-10-30T14:58:44.036Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/eb/02/a6b21098b1d5d6249b7c5ab69dde30108a71e4e819d4a9778f1de1d5b70d/fsspec-2025.10.0-py3-none-any.whl", hash = "sha256:7c7712353ae7d875407f97715f0e1ffcc21e33d5b24556cb1e090ae9409ec61d", size = 200966, upload-time = "2025-10-30T14:58:42.53Z" }, +======= +version = "2025.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/de/e0/bab50af11c2d75c9c4a2a26a5254573c0bd97cea152254401510950486fa/fsspec-2025.9.0.tar.gz", hash = "sha256:19fd429483d25d28b65ec68f9f4adc16c17ea2c7c7bf54ec61360d478fb19c19", size = 304847, upload-time = "2025-09-02T19:10:49.215Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/47/71/70db47e4f6ce3e5c37a607355f80da8860a33226be640226ac52cb05ef2e/fsspec-2025.9.0-py3-none-any.whl", hash = "sha256:530dc2a2af60a414a832059574df4a6e10cce927f6f4a78209390fe38955cfb7", size = 199289, upload-time = "2025-09-02T19:10:47.708Z" }, +>>>>>>> 8387c31 (uv sync) ] [package.optional-dependencies] @@ -713,6 +828,7 @@ wheels = [ [[package]] name = "hf-xet" +<<<<<<< HEAD version = "1.2.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/5e/6e/0f11bacf08a67f7fb5ee09740f2ca54163863b07b70d579356e9222ce5d8/hf_xet-1.2.0.tar.gz", hash = "sha256:a8c27070ca547293b6890c4bf389f713f80e8c478631432962bb7f4bc0bd7d7f", size = 506020, upload-time = "2025-10-24T19:04:32.129Z" } @@ -724,6 +840,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0b/dd/7ac658d54b9fb7999a0ccb07ad863b413cbaf5cf172f48ebcd9497ec7263/hf_xet-1.2.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:4c1428c9ae73ec0939410ec73023c4f842927f39db09b063b9482dac5a3bb737", size = 3413812, upload-time = "2025-10-24T19:04:24.585Z" }, { url = "https://files.pythonhosted.org/packages/92/68/89ac4e5b12a9ff6286a12174c8538a5930e2ed662091dd2572bbe0a18c8a/hf_xet-1.2.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a55558084c16b09b5ed32ab9ed38421e2d87cf3f1f89815764d1177081b99865", size = 3508920, upload-time = "2025-10-24T19:04:26.927Z" }, { url = "https://files.pythonhosted.org/packages/cb/44/870d44b30e1dcfb6a65932e3e1506c103a8a5aea9103c337e7a53180322c/hf_xet-1.2.0-cp37-abi3-win_amd64.whl", hash = "sha256:e6584a52253f72c9f52f9e549d5895ca7a471608495c4ecaa6cc73dba2b24d69", size = 2905735, upload-time = "2025-10-24T19:04:35.928Z" }, +======= +version = "1.1.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/74/31/feeddfce1748c4a233ec1aa5b7396161c07ae1aa9b7bdbc9a72c3c7dd768/hf_xet-1.1.10.tar.gz", hash = "sha256:408aef343800a2102374a883f283ff29068055c111f003ff840733d3b715bb97", size = 487910, upload-time = "2025-09-12T20:10:27.12Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/a2/343e6d05de96908366bdc0081f2d8607d61200be2ac802769c4284cc65bd/hf_xet-1.1.10-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:686083aca1a6669bc85c21c0563551cbcdaa5cf7876a91f3d074a030b577231d", size = 2761466, upload-time = "2025-09-12T20:10:22.836Z" }, + { url = "https://files.pythonhosted.org/packages/31/f9/6215f948ac8f17566ee27af6430ea72045e0418ce757260248b483f4183b/hf_xet-1.1.10-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:71081925383b66b24eedff3013f8e6bbd41215c3338be4b94ba75fd75b21513b", size = 2623807, upload-time = "2025-09-12T20:10:21.118Z" }, + { url = "https://files.pythonhosted.org/packages/15/07/86397573efefff941e100367bbda0b21496ffcdb34db7ab51912994c32a2/hf_xet-1.1.10-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b6bceb6361c80c1cc42b5a7b4e3efd90e64630bcf11224dcac50ef30a47e435", size = 3186960, upload-time = "2025-09-12T20:10:19.336Z" }, + { url = "https://files.pythonhosted.org/packages/01/a7/0b2e242b918cc30e1f91980f3c4b026ff2eedaf1e2ad96933bca164b2869/hf_xet-1.1.10-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:eae7c1fc8a664e54753ffc235e11427ca61f4b0477d757cc4eb9ae374b69f09c", size = 3087167, upload-time = "2025-09-12T20:10:17.255Z" }, + { url = "https://files.pythonhosted.org/packages/4a/25/3e32ab61cc7145b11eee9d745988e2f0f4fafda81b25980eebf97d8cff15/hf_xet-1.1.10-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0a0005fd08f002180f7a12d4e13b22be277725bc23ed0529f8add5c7a6309c06", size = 3248612, upload-time = "2025-09-12T20:10:24.093Z" }, + { url = "https://files.pythonhosted.org/packages/2c/3d/ab7109e607ed321afaa690f557a9ada6d6d164ec852fd6bf9979665dc3d6/hf_xet-1.1.10-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f900481cf6e362a6c549c61ff77468bd59d6dd082f3170a36acfef2eb6a6793f", size = 3353360, upload-time = "2025-09-12T20:10:25.563Z" }, + { url = "https://files.pythonhosted.org/packages/ee/0e/471f0a21db36e71a2f1752767ad77e92d8cde24e974e03d662931b1305ec/hf_xet-1.1.10-cp37-abi3-win_amd64.whl", hash = "sha256:5f54b19cc347c13235ae7ee98b330c26dd65ef1df47e5316ffb1e87713ca7045", size = 2804691, upload-time = "2025-09-12T20:10:28.433Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -765,7 +894,11 @@ wheels = [ [[package]] name = "huggingface-hub" +<<<<<<< HEAD version = "0.36.0" +======= +version = "0.35.3" +>>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "filelock" }, @@ -777,9 +910,15 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] +<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/98/63/4910c5fa9128fdadf6a9c5ac138e8b1b6cee4ca44bf7915bbfbce4e355ee/huggingface_hub-0.36.0.tar.gz", hash = "sha256:47b3f0e2539c39bf5cde015d63b72ec49baff67b6931c3d97f3f84532e2b8d25", size = 463358, upload-time = "2025-10-23T12:12:01.413Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/cb/bd/1a875e0d592d447cbc02805fd3fe0f497714d6a2583f59d14fa9ebad96eb/huggingface_hub-0.36.0-py3-none-any.whl", hash = "sha256:7bcc9ad17d5b3f07b57c78e79d527102d08313caa278a641993acddcb894548d", size = 566094, upload-time = "2025-10-23T12:11:59.557Z" }, +======= +sdist = { url = "https://files.pythonhosted.org/packages/10/7e/a0a97de7c73671863ca6b3f61fa12518caf35db37825e43d63a70956738c/huggingface_hub-0.35.3.tar.gz", hash = "sha256:350932eaa5cc6a4747efae85126ee220e4ef1b54e29d31c3b45c5612ddf0b32a", size = 461798, upload-time = "2025-09-29T14:29:58.625Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/31/a0/651f93d154cb72323358bf2bbae3e642bdb5d2f1bfc874d096f7cb159fa0/huggingface_hub-0.35.3-py3-none-any.whl", hash = "sha256:0e3a01829c19d86d03793e4577816fe3bdfc1602ac62c7fb220d593d351224ba", size = 564262, upload-time = "2025-09-29T14:29:55.813Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -820,7 +959,11 @@ wheels = [ [[package]] name = "ipykernel" +<<<<<<< HEAD version = "7.1.0" +======= +version = "6.30.1" +>>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "appnope", marker = "sys_platform == 'darwin'" }, @@ -837,14 +980,24 @@ dependencies = [ { name = "tornado" }, { name = "traitlets" }, ] +<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/b9/a4/4948be6eb88628505b83a1f2f40d90254cab66abf2043b3c40fa07dfce0f/ipykernel-7.1.0.tar.gz", hash = "sha256:58a3fc88533d5930c3546dc7eac66c6d288acde4f801e2001e65edc5dc9cf0db", size = 174579, upload-time = "2025-10-27T09:46:39.471Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/a3/17/20c2552266728ceba271967b87919664ecc0e33efca29c3efc6baf88c5f9/ipykernel-7.1.0-py3-none-any.whl", hash = "sha256:763b5ec6c5b7776f6a8d7ce09b267693b4e5ce75cb50ae696aaefb3c85e1ea4c", size = 117968, upload-time = "2025-10-27T09:46:37.805Z" }, +======= +sdist = { url = "https://files.pythonhosted.org/packages/bb/76/11082e338e0daadc89c8ff866185de11daf67d181901038f9e139d109761/ipykernel-6.30.1.tar.gz", hash = "sha256:6abb270161896402e76b91394fcdce5d1be5d45f456671e5080572f8505be39b", size = 166260, upload-time = "2025-08-04T15:47:35.018Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fc/c7/b445faca8deb954fe536abebff4ece5b097b923de482b26e78448c89d1dd/ipykernel-6.30.1-py3-none-any.whl", hash = "sha256:aa6b9fb93dca949069d8b85b6c79b2518e32ac583ae9c7d37c51d119e18b3fb4", size = 117484, upload-time = "2025-08-04T15:47:32.622Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] name = "ipython" +<<<<<<< HEAD version = "9.7.0" +======= +version = "9.6.0" +>>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -858,9 +1011,15 @@ dependencies = [ { name = "stack-data" }, { name = "traitlets" }, ] +<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/29/e6/48c74d54039241a456add616464ea28c6ebf782e4110d419411b83dae06f/ipython-9.7.0.tar.gz", hash = "sha256:5f6de88c905a566c6a9d6c400a8fed54a638e1f7543d17aae2551133216b1e4e", size = 4422115, upload-time = "2025-11-05T12:18:54.646Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/05/aa/62893d6a591d337aa59dcc4c6f6c842f1fe20cd72c8c5c1f980255243252/ipython-9.7.0-py3-none-any.whl", hash = "sha256:bce8ac85eb9521adc94e1845b4c03d88365fd6ac2f4908ec4ed1eb1b0a065f9f", size = 618911, upload-time = "2025-11-05T12:18:52.484Z" }, +======= +sdist = { url = "https://files.pythonhosted.org/packages/2a/34/29b18c62e39ee2f7a6a3bba7efd952729d8aadd45ca17efc34453b717665/ipython-9.6.0.tar.gz", hash = "sha256:5603d6d5d356378be5043e69441a072b50a5b33b4503428c77b04cb8ce7bc731", size = 4396932, upload-time = "2025-09-29T10:55:53.948Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/c5/d5e07995077e48220269c28a221e168c91123ad5ceee44d548f54a057fc0/ipython-9.6.0-py3-none-any.whl", hash = "sha256:5f77efafc886d2f023442479b8149e7d86547ad0a979e9da9f045d252f648196", size = 616170, upload-time = "2025-09-29T10:55:47.676Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -950,14 +1109,24 @@ wheels = [ [[package]] name = "jsonargparse" +<<<<<<< HEAD version = "4.42.0" +======= +version = "4.41.0" +>>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyyaml" }, ] +<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/32/ef/6bcc6d88e401af6d1c05c6a3f3955ebeae538711f1199e25c53326c921e5/jsonargparse-4.42.0.tar.gz", hash = "sha256:170551344f06500091ca6732bf93726c5aa79f4f2632a7f2a18d7a897ae2c5c1", size = 212273, upload-time = "2025-10-14T05:23:43.15Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/0b/a1/3f06c00dc217baaa273b08022c00bc6c71d619c4d03325179b8fec80d90f/jsonargparse-4.42.0-py3-none-any.whl", hash = "sha256:d112bdaab22918ff5a8fb2d6036596f8527961922fd972b6e50afc6340514a28", size = 235760, upload-time = "2025-10-14T05:23:40.849Z" }, +======= +sdist = { url = "https://files.pythonhosted.org/packages/44/86/60032fb5623df8d938d31f733e4b3385c40791d85d0fae3dfb4e3be10c42/jsonargparse-4.41.0.tar.gz", hash = "sha256:ba1806bf0ed0ad1975e403dffb18b3a755fee3bfe4e7b36d8cce2f297b552b5f", size = 206634, upload-time = "2025-09-04T03:46:34.715Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/fc/6ac1943f22f3d2e14703335d64a7d68496f0480c82a3077cde44b2c55ef5/jsonargparse-4.41.0-py3-none-any.whl", hash = "sha256:cd49b6a2fea723ee4d80f9df034f51af226128a7f166be8755d6acdeb3e077a7", size = 228528, upload-time = "2025-09-04T03:46:32.668Z" }, +>>>>>>> 8387c31 (uv sync) ] [package.optional-dependencies] @@ -1119,7 +1288,11 @@ wheels = [ [[package]] name = "jupyterlab" +<<<<<<< HEAD version = "4.4.10" +======= +version = "4.4.9" +>>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "async-lru" }, @@ -1136,9 +1309,15 @@ dependencies = [ { name = "tornado" }, { name = "traitlets" }, ] +<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/6a/5d/75c42a48ff5fc826a7dff3fe4004cda47c54f9d981c351efacfbc9139d3c/jupyterlab-4.4.10.tar.gz", hash = "sha256:521c017508af4e1d6d9d8a9d90f47a11c61197ad63b2178342489de42540a615", size = 22969303, upload-time = "2025-10-22T14:50:58.768Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/f7/46/1eaa5db8d54a594bdade67afbcae42e9a2da676628be3eb39f36dcff6390/jupyterlab-4.4.10-py3-none-any.whl", hash = "sha256:65939ab4c8dcd0c42185c2d0d1a9d60b254dc8c46fc4fdb286b63c51e9358e07", size = 12293385, upload-time = "2025-10-22T14:50:54.075Z" }, +======= +sdist = { url = "https://files.pythonhosted.org/packages/45/b2/7dad2d0049a904d17c070226a4f78f81905f93bfe09503722d210ccf9335/jupyterlab-4.4.9.tar.gz", hash = "sha256:ea55aca8269909016d5fde2dc09b97128bc931230183fe7e2920ede5154ad9c2", size = 22966654, upload-time = "2025-09-26T17:28:20.158Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1f/fd/ac0979ebd1b1975c266c99b96930b0a66609c3f6e5d76979ca6eb3073896/jupyterlab-4.4.9-py3-none-any.whl", hash = "sha256:394c902827350c017430a8370b9f40c03c098773084bc53930145c146d3d2cb2", size = 12292552, upload-time = "2025-09-26T17:28:15.663Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -1186,9 +1365,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl", hash = "sha256:c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12", size = 113151, upload-time = "2025-10-27T18:25:54.882Z" }, ] +[[package]] +name = "lark" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/37/a13baf0135f348af608c667633cbe5d13aa2c5c15a56ae9ad3e6cba45ae3/lark-1.3.0.tar.gz", hash = "sha256:9a3839d0ca5e1faf7cfa3460e420e859b66bcbde05b634e73c369c8244c5fa48", size = 259551, upload-time = "2025-09-22T13:45:05.072Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a8/3e/1c6b43277de64fc3c0333b0e72ab7b52ddaaea205210d60d9b9f83c3d0c7/lark-1.3.0-py3-none-any.whl", hash = "sha256:80661f261fb2584a9828a097a2432efd575af27d20be0fd35d17f0fe37253831", size = 113002, upload-time = "2025-09-22T13:45:03.747Z" }, +] + [[package]] name = "lightning" +<<<<<<< HEAD version = "2.5.6" +======= +version = "2.5.5" +>>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "fsspec", extra = ["http"] }, @@ -1201,9 +1393,15 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] +<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/e9/da/289e17b2d4631b885771ce10ab7fe19c6c0ab2b1208d1dda418818ffbbfd/lightning-2.5.6.tar.gz", hash = "sha256:57b6abe87080895bc237fb7f36b7b4abaa2793760cbca00e3907e56607e0ed27", size = 640106, upload-time = "2025-11-05T20:53:06.823Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/23/dc/d7804f13928b6a81a0e948cfecbf0071e8cc74e3f341c704e23e75e504ad/lightning-2.5.6-py3-none-any.whl", hash = "sha256:25bb2053078c2efc57c082fda89dfbd975dfa76beb08def191947c2b571a8c8a", size = 827915, upload-time = "2025-11-05T20:53:03.169Z" }, +======= +sdist = { url = "https://files.pythonhosted.org/packages/0f/dd/86bb3bebadcdbc6e6e5a63657f0a03f74cd065b5ea965896679f76fec0b4/lightning-2.5.5.tar.gz", hash = "sha256:4d3d66c5b1481364a7e6a1ce8ddde1777a04fa740a3145ec218a9941aed7dd30", size = 640770, upload-time = "2025-09-05T16:01:21.026Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2e/d0/4b4fbafc3b18df91207a6e46782d9fd1905f9f45cb2c3b8dfbb239aef781/lightning-2.5.5-py3-none-any.whl", hash = "sha256:69eb248beadd7b600bf48eff00a0ec8af171ec7a678d23787c4aedf12e225e8f", size = 828490, upload-time = "2025-09-05T16:01:17.845Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -1317,6 +1515,7 @@ wheels = [ [[package]] name = "multidict" +<<<<<<< HEAD version = "6.7.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/80/1e/5492c365f222f907de1039b91f922b93fa4f764c713ee858d235495d8f50/multidict-6.7.0.tar.gz", hash = "sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5", size = 101834, upload-time = "2025-10-06T14:52:30.657Z" } @@ -1340,6 +1539,31 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/46/e2/348cd32faad84eaf1d20cce80e2bb0ef8d312c55bca1f7fa9865e7770aaf/multidict-6.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:92abb658ef2d7ef22ac9f8bb88e8b6c3e571671534e029359b6d9e845923eb1b", size = 46073, upload-time = "2025-10-06T14:49:50.28Z" }, { url = "https://files.pythonhosted.org/packages/25/ec/aad2613c1910dce907480e0c3aa306905830f25df2e54ccc9dea450cb5aa/multidict-6.7.0-cp312-cp312-win_arm64.whl", hash = "sha256:490dab541a6a642ce1a9d61a4781656b346a55c13038f0b1244653828e3a83ec", size = 43226, upload-time = "2025-10-06T14:49:52.304Z" }, { url = "https://files.pythonhosted.org/packages/b7/da/7d22601b625e241d4f23ef1ebff8acfc60da633c9e7e7922e24d10f592b3/multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3", size = 12317, upload-time = "2025-10-06T14:52:29.272Z" }, +======= +version = "6.6.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/69/7f/0652e6ed47ab288e3756ea9c0df8b14950781184d4bd7883f4d87dd41245/multidict-6.6.4.tar.gz", hash = "sha256:d2d4e4787672911b48350df02ed3fa3fffdc2f2e8ca06dd6afdf34189b76a9dd", size = 101843, upload-time = "2025-08-11T12:08:48.217Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/05/f6/512ffd8fd8b37fb2680e5ac35d788f1d71bbaf37789d21a820bdc441e565/multidict-6.6.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0ffb87be160942d56d7b87b0fdf098e81ed565add09eaa1294268c7f3caac4c8", size = 76516, upload-time = "2025-08-11T12:06:53.393Z" }, + { url = "https://files.pythonhosted.org/packages/99/58/45c3e75deb8855c36bd66cc1658007589662ba584dbf423d01df478dd1c5/multidict-6.6.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d191de6cbab2aff5de6c5723101705fd044b3e4c7cfd587a1929b5028b9714b3", size = 45394, upload-time = "2025-08-11T12:06:54.555Z" }, + { url = "https://files.pythonhosted.org/packages/fd/ca/e8c4472a93a26e4507c0b8e1f0762c0d8a32de1328ef72fd704ef9cc5447/multidict-6.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:38a0956dd92d918ad5feff3db8fcb4a5eb7dba114da917e1a88475619781b57b", size = 43591, upload-time = "2025-08-11T12:06:55.672Z" }, + { url = "https://files.pythonhosted.org/packages/05/51/edf414f4df058574a7265034d04c935aa84a89e79ce90fcf4df211f47b16/multidict-6.6.4-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:6865f6d3b7900ae020b495d599fcf3765653bc927951c1abb959017f81ae8287", size = 237215, upload-time = "2025-08-11T12:06:57.213Z" }, + { url = "https://files.pythonhosted.org/packages/c8/45/8b3d6dbad8cf3252553cc41abea09ad527b33ce47a5e199072620b296902/multidict-6.6.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a2088c126b6f72db6c9212ad827d0ba088c01d951cee25e758c450da732c138", size = 258299, upload-time = "2025-08-11T12:06:58.946Z" }, + { url = "https://files.pythonhosted.org/packages/3c/e8/8ca2e9a9f5a435fc6db40438a55730a4bf4956b554e487fa1b9ae920f825/multidict-6.6.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0f37bed7319b848097085d7d48116f545985db988e2256b2e6f00563a3416ee6", size = 242357, upload-time = "2025-08-11T12:07:00.301Z" }, + { url = "https://files.pythonhosted.org/packages/0f/84/80c77c99df05a75c28490b2af8f7cba2a12621186e0a8b0865d8e745c104/multidict-6.6.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:01368e3c94032ba6ca0b78e7ccb099643466cf24f8dc8eefcfdc0571d56e58f9", size = 268369, upload-time = "2025-08-11T12:07:01.638Z" }, + { url = "https://files.pythonhosted.org/packages/0d/e9/920bfa46c27b05fb3e1ad85121fd49f441492dca2449c5bcfe42e4565d8a/multidict-6.6.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8fe323540c255db0bffee79ad7f048c909f2ab0edb87a597e1c17da6a54e493c", size = 269341, upload-time = "2025-08-11T12:07:02.943Z" }, + { url = "https://files.pythonhosted.org/packages/af/65/753a2d8b05daf496f4a9c367fe844e90a1b2cac78e2be2c844200d10cc4c/multidict-6.6.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8eb3025f17b0a4c3cd08cda49acf312a19ad6e8a4edd9dbd591e6506d999402", size = 256100, upload-time = "2025-08-11T12:07:04.564Z" }, + { url = "https://files.pythonhosted.org/packages/09/54/655be13ae324212bf0bc15d665a4e34844f34c206f78801be42f7a0a8aaa/multidict-6.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bbc14f0365534d35a06970d6a83478b249752e922d662dc24d489af1aa0d1be7", size = 253584, upload-time = "2025-08-11T12:07:05.914Z" }, + { url = "https://files.pythonhosted.org/packages/5c/74/ab2039ecc05264b5cec73eb018ce417af3ebb384ae9c0e9ed42cb33f8151/multidict-6.6.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:75aa52fba2d96bf972e85451b99d8e19cc37ce26fd016f6d4aa60da9ab2b005f", size = 251018, upload-time = "2025-08-11T12:07:08.301Z" }, + { url = "https://files.pythonhosted.org/packages/af/0a/ccbb244ac848e56c6427f2392741c06302bbfba49c0042f1eb3c5b606497/multidict-6.6.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4fefd4a815e362d4f011919d97d7b4a1e566f1dde83dc4ad8cfb5b41de1df68d", size = 251477, upload-time = "2025-08-11T12:07:10.248Z" }, + { url = "https://files.pythonhosted.org/packages/0e/b0/0ed49bba775b135937f52fe13922bc64a7eaf0a3ead84a36e8e4e446e096/multidict-6.6.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:db9801fe021f59a5b375ab778973127ca0ac52429a26e2fd86aa9508f4d26eb7", size = 263575, upload-time = "2025-08-11T12:07:11.928Z" }, + { url = "https://files.pythonhosted.org/packages/3e/d9/7fb85a85e14de2e44dfb6a24f03c41e2af8697a6df83daddb0e9b7569f73/multidict-6.6.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a650629970fa21ac1fb06ba25dabfc5b8a2054fcbf6ae97c758aa956b8dba802", size = 259649, upload-time = "2025-08-11T12:07:13.244Z" }, + { url = "https://files.pythonhosted.org/packages/03/9e/b3a459bcf9b6e74fa461a5222a10ff9b544cb1cd52fd482fb1b75ecda2a2/multidict-6.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:452ff5da78d4720d7516a3a2abd804957532dd69296cb77319c193e3ffb87e24", size = 251505, upload-time = "2025-08-11T12:07:14.57Z" }, + { url = "https://files.pythonhosted.org/packages/86/a2/8022f78f041dfe6d71e364001a5cf987c30edfc83c8a5fb7a3f0974cff39/multidict-6.6.4-cp312-cp312-win32.whl", hash = "sha256:8c2fcb12136530ed19572bbba61b407f655e3953ba669b96a35036a11a485793", size = 41888, upload-time = "2025-08-11T12:07:15.904Z" }, + { url = "https://files.pythonhosted.org/packages/c7/eb/d88b1780d43a56db2cba24289fa744a9d216c1a8546a0dc3956563fd53ea/multidict-6.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:047d9425860a8c9544fed1b9584f0c8bcd31bcde9568b047c5e567a1025ecd6e", size = 46072, upload-time = "2025-08-11T12:07:17.045Z" }, + { url = "https://files.pythonhosted.org/packages/9f/16/b929320bf5750e2d9d4931835a4c638a19d2494a5b519caaaa7492ebe105/multidict-6.6.4-cp312-cp312-win_arm64.whl", hash = "sha256:14754eb72feaa1e8ae528468f24250dd997b8e2188c3d2f593f9eba259e4b364", size = 43222, upload-time = "2025-08-11T12:07:18.328Z" }, + { url = "https://files.pythonhosted.org/packages/fd/69/b547032297c7e63ba2af494edba695d781af8a0c6e89e4d06cf848b21d80/multidict-6.6.4-py3-none-any.whl", hash = "sha256:27d8f8e125c07cb954e54d75d04905a9bba8a439c1d84aca94949d4d03d8601c", size = 12313, upload-time = "2025-08-11T12:08:46.891Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -1675,11 +1899,19 @@ wheels = [ [[package]] name = "platformdirs" +<<<<<<< HEAD version = "4.5.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/61/33/9611380c2bdb1225fdef633e2a9610622310fed35ab11dac9620972ee088/platformdirs-4.5.0.tar.gz", hash = "sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312", size = 21632, upload-time = "2025-10-08T17:44:48.791Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl", hash = "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3", size = 18651, upload-time = "2025-10-08T17:44:47.223Z" }, +======= +version = "4.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/23/e8/21db9c9987b0e728855bd57bff6984f67952bea55d6f75e055c46b5383e8/platformdirs-4.4.0.tar.gz", hash = "sha256:ca753cf4d81dc309bc67b0ea38fd15dc97bc30ce419a7f58d13eb3bf14c4febf", size = 21634, upload-time = "2025-08-26T14:32:04.268Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/4b/2028861e724d3bd36227adfa20d3fd24c3fc6d52032f4a93c133be5d17ce/platformdirs-4.4.0-py3-none-any.whl", hash = "sha256:abd01743f24e5287cd7a5db3752faf1a2d65353f38ec26d98e25a6db65958c85", size = 18654, upload-time = "2025-08-26T14:32:02.735Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -1714,6 +1946,7 @@ wheels = [ [[package]] name = "propcache" +<<<<<<< HEAD version = "0.4.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/9e/da/e9fc233cf63743258bff22b3dfa7ea5baef7b5bc324af47a0ad89b8ffc6f/propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", size = 46442, upload-time = "2025-10-08T19:49:02.291Z" } @@ -1734,10 +1967,34 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/09/d19cff2a5aaac632ec8fc03737b223597b1e347416934c1b3a7df079784c/propcache-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db", size = 41655, upload-time = "2025-10-08T19:47:04.973Z" }, { url = "https://files.pythonhosted.org/packages/68/ab/6b5c191bb5de08036a8c697b265d4ca76148efb10fa162f14af14fb5f076/propcache-0.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1", size = 37789, upload-time = "2025-10-08T19:47:06.077Z" }, { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" }, +======= +version = "0.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/16/43264e4a779dd8588c21a70f0709665ee8f611211bdd2c87d952cfa7c776/propcache-0.3.2.tar.gz", hash = "sha256:20d7d62e4e7ef05f221e0db2856b979540686342e7dd9973b815599c7057e168", size = 44139, upload-time = "2025-06-09T22:56:06.081Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a8/42/9ca01b0a6f48e81615dca4765a8f1dd2c057e0540f6116a27dc5ee01dfb6/propcache-0.3.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8de106b6c84506b31c27168582cd3cb3000a6412c16df14a8628e5871ff83c10", size = 73674, upload-time = "2025-06-09T22:54:30.551Z" }, + { url = "https://files.pythonhosted.org/packages/af/6e/21293133beb550f9c901bbece755d582bfaf2176bee4774000bd4dd41884/propcache-0.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:28710b0d3975117239c76600ea351934ac7b5ff56e60953474342608dbbb6154", size = 43570, upload-time = "2025-06-09T22:54:32.296Z" }, + { url = "https://files.pythonhosted.org/packages/0c/c8/0393a0a3a2b8760eb3bde3c147f62b20044f0ddac81e9d6ed7318ec0d852/propcache-0.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce26862344bdf836650ed2487c3d724b00fbfec4233a1013f597b78c1cb73615", size = 43094, upload-time = "2025-06-09T22:54:33.929Z" }, + { url = "https://files.pythonhosted.org/packages/37/2c/489afe311a690399d04a3e03b069225670c1d489eb7b044a566511c1c498/propcache-0.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bca54bd347a253af2cf4544bbec232ab982f4868de0dd684246b67a51bc6b1db", size = 226958, upload-time = "2025-06-09T22:54:35.186Z" }, + { url = "https://files.pythonhosted.org/packages/9d/ca/63b520d2f3d418c968bf596839ae26cf7f87bead026b6192d4da6a08c467/propcache-0.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55780d5e9a2ddc59711d727226bb1ba83a22dd32f64ee15594b9392b1f544eb1", size = 234894, upload-time = "2025-06-09T22:54:36.708Z" }, + { url = "https://files.pythonhosted.org/packages/11/60/1d0ed6fff455a028d678df30cc28dcee7af77fa2b0e6962ce1df95c9a2a9/propcache-0.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:035e631be25d6975ed87ab23153db6a73426a48db688070d925aa27e996fe93c", size = 233672, upload-time = "2025-06-09T22:54:38.062Z" }, + { url = "https://files.pythonhosted.org/packages/37/7c/54fd5301ef38505ab235d98827207176a5c9b2aa61939b10a460ca53e123/propcache-0.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee6f22b6eaa39297c751d0e80c0d3a454f112f5c6481214fcf4c092074cecd67", size = 224395, upload-time = "2025-06-09T22:54:39.634Z" }, + { url = "https://files.pythonhosted.org/packages/ee/1a/89a40e0846f5de05fdc6779883bf46ba980e6df4d2ff8fb02643de126592/propcache-0.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ca3aee1aa955438c4dba34fc20a9f390e4c79967257d830f137bd5a8a32ed3b", size = 212510, upload-time = "2025-06-09T22:54:41.565Z" }, + { url = "https://files.pythonhosted.org/packages/5e/33/ca98368586c9566a6b8d5ef66e30484f8da84c0aac3f2d9aec6d31a11bd5/propcache-0.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7a4f30862869fa2b68380d677cc1c5fcf1e0f2b9ea0cf665812895c75d0ca3b8", size = 222949, upload-time = "2025-06-09T22:54:43.038Z" }, + { url = "https://files.pythonhosted.org/packages/ba/11/ace870d0aafe443b33b2f0b7efdb872b7c3abd505bfb4890716ad7865e9d/propcache-0.3.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b77ec3c257d7816d9f3700013639db7491a434644c906a2578a11daf13176251", size = 217258, upload-time = "2025-06-09T22:54:44.376Z" }, + { url = "https://files.pythonhosted.org/packages/5b/d2/86fd6f7adffcfc74b42c10a6b7db721d1d9ca1055c45d39a1a8f2a740a21/propcache-0.3.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:cab90ac9d3f14b2d5050928483d3d3b8fb6b4018893fc75710e6aa361ecb2474", size = 213036, upload-time = "2025-06-09T22:54:46.243Z" }, + { url = "https://files.pythonhosted.org/packages/07/94/2d7d1e328f45ff34a0a284cf5a2847013701e24c2a53117e7c280a4316b3/propcache-0.3.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0b504d29f3c47cf6b9e936c1852246c83d450e8e063d50562115a6be6d3a2535", size = 227684, upload-time = "2025-06-09T22:54:47.63Z" }, + { url = "https://files.pythonhosted.org/packages/b7/05/37ae63a0087677e90b1d14710e532ff104d44bc1efa3b3970fff99b891dc/propcache-0.3.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:ce2ac2675a6aa41ddb2a0c9cbff53780a617ac3d43e620f8fd77ba1c84dcfc06", size = 234562, upload-time = "2025-06-09T22:54:48.982Z" }, + { url = "https://files.pythonhosted.org/packages/a4/7c/3f539fcae630408d0bd8bf3208b9a647ccad10976eda62402a80adf8fc34/propcache-0.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:62b4239611205294cc433845b914131b2a1f03500ff3c1ed093ed216b82621e1", size = 222142, upload-time = "2025-06-09T22:54:50.424Z" }, + { url = "https://files.pythonhosted.org/packages/7c/d2/34b9eac8c35f79f8a962546b3e97e9d4b990c420ee66ac8255d5d9611648/propcache-0.3.2-cp312-cp312-win32.whl", hash = "sha256:df4a81b9b53449ebc90cc4deefb052c1dd934ba85012aa912c7ea7b7e38b60c1", size = 37711, upload-time = "2025-06-09T22:54:52.072Z" }, + { url = "https://files.pythonhosted.org/packages/19/61/d582be5d226cf79071681d1b46b848d6cb03d7b70af7063e33a2787eaa03/propcache-0.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7046e79b989d7fe457bb755844019e10f693752d169076138abf17f31380800c", size = 41479, upload-time = "2025-06-09T22:54:53.234Z" }, + { url = "https://files.pythonhosted.org/packages/cc/35/cc0aaecf278bb4575b8555f2b137de5ab821595ddae9da9d3cd1da4072c7/propcache-0.3.2-py3-none-any.whl", hash = "sha256:98f1ec44fb675f5052cccc8e609c46ed23a35a1cfd18545ad4e29002d858a43f", size = 12663, upload-time = "2025-06-09T22:56:04.484Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] name = "protobuf" +<<<<<<< HEAD version = "6.33.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/19/ff/64a6c8f420818bb873713988ca5492cba3a7946be57e027ac63495157d97/protobuf-6.33.0.tar.gz", hash = "sha256:140303d5c8d2037730c548f8c7b93b20bb1dc301be280c378b82b8894589c954", size = 443463, upload-time = "2025-10-15T20:39:52.159Z" } @@ -1749,10 +2006,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e6/eb/2a981a13e35cda8b75b5585aaffae2eb904f8f351bdd3870769692acbd8a/protobuf-6.33.0-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:e0a1715e4f27355afd9570f3ea369735afc853a6c3951a6afe1f80d8569ad298", size = 339159, upload-time = "2025-10-15T20:39:46.186Z" }, { url = "https://files.pythonhosted.org/packages/21/51/0b1cbad62074439b867b4e04cc09b93f6699d78fd191bed2bbb44562e077/protobuf-6.33.0-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:35be49fd3f4fefa4e6e2aacc35e8b837d6703c37a2168a55ac21e9b1bc7559ef", size = 323172, upload-time = "2025-10-15T20:39:47.465Z" }, { url = "https://files.pythonhosted.org/packages/07/d1/0a28c21707807c6aacd5dc9c3704b2aa1effbf37adebd8caeaf68b17a636/protobuf-6.33.0-py3-none-any.whl", hash = "sha256:25c9e1963c6734448ea2d308cfa610e692b801304ba0908d7bfa564ac5132995", size = 170477, upload-time = "2025-10-15T20:39:51.311Z" }, +======= +version = "6.32.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fa/a4/cc17347aa2897568beece2e674674359f911d6fe21b0b8d6268cd42727ac/protobuf-6.32.1.tar.gz", hash = "sha256:ee2469e4a021474ab9baafea6cd070e5bf27c7d29433504ddea1a4ee5850f68d", size = 440635, upload-time = "2025-09-11T21:38:42.935Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/98/645183ea03ab3995d29086b8bf4f7562ebd3d10c9a4b14ee3f20d47cfe50/protobuf-6.32.1-cp310-abi3-win32.whl", hash = "sha256:a8a32a84bc9f2aad712041b8b366190f71dde248926da517bde9e832e4412085", size = 424411, upload-time = "2025-09-11T21:38:27.427Z" }, + { url = "https://files.pythonhosted.org/packages/8c/f3/6f58f841f6ebafe076cebeae33fc336e900619d34b1c93e4b5c97a81fdfa/protobuf-6.32.1-cp310-abi3-win_amd64.whl", hash = "sha256:b00a7d8c25fa471f16bc8153d0e53d6c9e827f0953f3c09aaa4331c718cae5e1", size = 435738, upload-time = "2025-09-11T21:38:30.959Z" }, + { url = "https://files.pythonhosted.org/packages/10/56/a8a3f4e7190837139e68c7002ec749190a163af3e330f65d90309145a210/protobuf-6.32.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d8c7e6eb619ffdf105ee4ab76af5a68b60a9d0f66da3ea12d1640e6d8dab7281", size = 426454, upload-time = "2025-09-11T21:38:34.076Z" }, + { url = "https://files.pythonhosted.org/packages/3f/be/8dd0a927c559b37d7a6c8ab79034fd167dcc1f851595f2e641ad62be8643/protobuf-6.32.1-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:2f5b80a49e1eb7b86d85fcd23fe92df154b9730a725c3b38c4e43b9d77018bf4", size = 322874, upload-time = "2025-09-11T21:38:35.509Z" }, + { url = "https://files.pythonhosted.org/packages/5c/f6/88d77011b605ef979aace37b7703e4eefad066f7e84d935e5a696515c2dd/protobuf-6.32.1-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:b1864818300c297265c83a4982fd3169f97122c299f56a56e2445c3698d34710", size = 322013, upload-time = "2025-09-11T21:38:37.017Z" }, + { url = "https://files.pythonhosted.org/packages/97/b7/15cc7d93443d6c6a84626ae3258a91f4c6ac8c0edd5df35ea7658f71b79c/protobuf-6.32.1-py3-none-any.whl", hash = "sha256:2601b779fc7d32a866c6b4404f9d42a3f67c5b9f3f15b4db3cccabe06b95c346", size = 169289, upload-time = "2025-09-11T21:38:41.234Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] name = "psutil" +<<<<<<< HEAD version = "7.1.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/e1/88/bdd0a41e5857d5d703287598cbf08dad90aed56774ea52ae071bae9071b6/psutil-7.1.3.tar.gz", hash = "sha256:6c86281738d77335af7aec228328e944b30930899ea760ecf33a4dba66be5e74", size = 489059, upload-time = "2025-11-02T12:25:54.619Z" } @@ -1763,6 +2033,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e0/95/992c8816a74016eb095e73585d747e0a8ea21a061ed3689474fabb29a395/psutil-7.1.3-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:56d974e02ca2c8eb4812c3f76c30e28836fffc311d55d979f1465c1feeb2b68b", size = 264635, upload-time = "2025-11-02T12:26:31.74Z" }, { url = "https://files.pythonhosted.org/packages/55/4c/c3ed1a622b6ae2fd3c945a366e64eb35247a31e4db16cf5095e269e8eb3c/psutil-7.1.3-cp37-abi3-win_amd64.whl", hash = "sha256:f39c2c19fe824b47484b96f9692932248a54c43799a84282cfe58d05a6449efd", size = 247633, upload-time = "2025-11-02T12:26:33.887Z" }, { url = "https://files.pythonhosted.org/packages/c9/ad/33b2ccec09bf96c2b2ef3f9a6f66baac8253d7565d8839e024a6b905d45d/psutil-7.1.3-cp37-abi3-win_arm64.whl", hash = "sha256:bd0d69cee829226a761e92f28140bec9a5ee9d5b4fb4b0cc589068dbfff559b1", size = 244608, upload-time = "2025-11-02T12:26:36.136Z" }, +======= +version = "7.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b3/31/4723d756b59344b643542936e37a31d1d3204bcdc42a7daa8ee9eb06fb50/psutil-7.1.0.tar.gz", hash = "sha256:655708b3c069387c8b77b072fc429a57d0e214221d01c0a772df7dfedcb3bcd2", size = 497660, upload-time = "2025-09-17T20:14:52.902Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/62/ce4051019ee20ce0ed74432dd73a5bb087a6704284a470bb8adff69a0932/psutil-7.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:76168cef4397494250e9f4e73eb3752b146de1dd950040b29186d0cce1d5ca13", size = 245242, upload-time = "2025-09-17T20:14:56.126Z" }, + { url = "https://files.pythonhosted.org/packages/38/61/f76959fba841bf5b61123fbf4b650886dc4094c6858008b5bf73d9057216/psutil-7.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:5d007560c8c372efdff9e4579c2846d71de737e4605f611437255e81efcca2c5", size = 246682, upload-time = "2025-09-17T20:14:58.25Z" }, + { url = "https://files.pythonhosted.org/packages/88/7a/37c99d2e77ec30d63398ffa6a660450b8a62517cabe44b3e9bae97696e8d/psutil-7.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22e4454970b32472ce7deaa45d045b34d3648ce478e26a04c7e858a0a6e75ff3", size = 287994, upload-time = "2025-09-17T20:14:59.901Z" }, + { url = "https://files.pythonhosted.org/packages/9d/de/04c8c61232f7244aa0a4b9a9fbd63a89d5aeaf94b2fc9d1d16e2faa5cbb0/psutil-7.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c70e113920d51e89f212dd7be06219a9b88014e63a4cec69b684c327bc474e3", size = 291163, upload-time = "2025-09-17T20:15:01.481Z" }, + { url = "https://files.pythonhosted.org/packages/f4/58/c4f976234bf6d4737bc8c02a81192f045c307b72cf39c9e5c5a2d78927f6/psutil-7.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d4a113425c037300de3ac8b331637293da9be9713855c4fc9d2d97436d7259d", size = 293625, upload-time = "2025-09-17T20:15:04.492Z" }, + { url = "https://files.pythonhosted.org/packages/79/87/157c8e7959ec39ced1b11cc93c730c4fb7f9d408569a6c59dbd92ceb35db/psutil-7.1.0-cp37-abi3-win32.whl", hash = "sha256:09ad740870c8d219ed8daae0ad3b726d3bf9a028a198e7f3080f6a1888b99bca", size = 244812, upload-time = "2025-09-17T20:15:07.462Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e9/b44c4f697276a7a95b8e94d0e320a7bf7f3318521b23de69035540b39838/psutil-7.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:57f5e987c36d3146c0dd2528cd42151cf96cd359b9d67cfff836995cc5df9a3d", size = 247965, upload-time = "2025-09-17T20:15:09.673Z" }, + { url = "https://files.pythonhosted.org/packages/26/65/1070a6e3c036f39142c2820c4b52e9243246fcfc3f96239ac84472ba361e/psutil-7.1.0-cp37-abi3-win_arm64.whl", hash = "sha256:6937cb68133e7c97b6cc9649a570c9a18ba0efebed46d8c5dae4c07fa1b67a07", size = 244971, upload-time = "2025-09-17T20:15:12.262Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -1785,6 +2069,7 @@ wheels = [ [[package]] name = "pyarrow" +<<<<<<< HEAD version = "22.0.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/30/53/04a7fdc63e6056116c9ddc8b43bc28c12cdd181b85cbeadb79278475f3ae/pyarrow-22.0.0.tar.gz", hash = "sha256:3d600dc583260d845c7d8a6db540339dd883081925da2bd1c5cb808f720b3cd9", size = 1151151, upload-time = "2025-10-24T12:30:00.762Z" } @@ -1796,6 +2081,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/bb/d4/74ac9f7a54cfde12ee42734ea25d5a3c9a45db78f9def949307a92720d37/pyarrow-22.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c3200cb41cdbc65156e5f8c908d739b0dfed57e890329413da2748d1a2cd1a4e", size = 47990906, upload-time = "2025-10-24T10:05:58.254Z" }, { url = "https://files.pythonhosted.org/packages/2e/71/fedf2499bf7a95062eafc989ace56572f3343432570e1c54e6599d5b88da/pyarrow-22.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ac93252226cf288753d8b46280f4edf3433bf9508b6977f8dd8526b521a1bbb9", size = 50306783, upload-time = "2025-10-24T10:06:08.08Z" }, { url = "https://files.pythonhosted.org/packages/68/ed/b202abd5a5b78f519722f3d29063dda03c114711093c1995a33b8e2e0f4b/pyarrow-22.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:44729980b6c50a5f2bfcc2668d36c569ce17f8b17bccaf470c4313dcbbf13c9d", size = 27972883, upload-time = "2025-10-24T10:06:14.204Z" }, +======= +version = "21.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ef/c2/ea068b8f00905c06329a3dfcd40d0fcc2b7d0f2e355bdb25b65e0a0e4cd4/pyarrow-21.0.0.tar.gz", hash = "sha256:5051f2dccf0e283ff56335760cbc8622cf52264d67e359d5569541ac11b6d5bc", size = 1133487, upload-time = "2025-07-18T00:57:31.761Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/d4/d4f817b21aacc30195cf6a46ba041dd1be827efa4a623cc8bf39a1c2a0c0/pyarrow-21.0.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:3a302f0e0963db37e0a24a70c56cf91a4faa0bca51c23812279ca2e23481fccd", size = 31160305, upload-time = "2025-07-18T00:55:35.373Z" }, + { url = "https://files.pythonhosted.org/packages/a2/9c/dcd38ce6e4b4d9a19e1d36914cb8e2b1da4e6003dd075474c4cfcdfe0601/pyarrow-21.0.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:b6b27cf01e243871390474a211a7922bfbe3bda21e39bc9160daf0da3fe48876", size = 32684264, upload-time = "2025-07-18T00:55:39.303Z" }, + { url = "https://files.pythonhosted.org/packages/4f/74/2a2d9f8d7a59b639523454bec12dba35ae3d0a07d8ab529dc0809f74b23c/pyarrow-21.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:e72a8ec6b868e258a2cd2672d91f2860ad532d590ce94cdf7d5e7ec674ccf03d", size = 41108099, upload-time = "2025-07-18T00:55:42.889Z" }, + { url = "https://files.pythonhosted.org/packages/ad/90/2660332eeb31303c13b653ea566a9918484b6e4d6b9d2d46879a33ab0622/pyarrow-21.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b7ae0bbdc8c6674259b25bef5d2a1d6af5d39d7200c819cf99e07f7dfef1c51e", size = 42829529, upload-time = "2025-07-18T00:55:47.069Z" }, + { url = "https://files.pythonhosted.org/packages/33/27/1a93a25c92717f6aa0fca06eb4700860577d016cd3ae51aad0e0488ac899/pyarrow-21.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:58c30a1729f82d201627c173d91bd431db88ea74dcaa3885855bc6203e433b82", size = 43367883, upload-time = "2025-07-18T00:55:53.069Z" }, + { url = "https://files.pythonhosted.org/packages/05/d9/4d09d919f35d599bc05c6950095e358c3e15148ead26292dfca1fb659b0c/pyarrow-21.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:072116f65604b822a7f22945a7a6e581cfa28e3454fdcc6939d4ff6090126623", size = 45133802, upload-time = "2025-07-18T00:55:57.714Z" }, + { url = "https://files.pythonhosted.org/packages/71/30/f3795b6e192c3ab881325ffe172e526499eb3780e306a15103a2764916a2/pyarrow-21.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:cf56ec8b0a5c8c9d7021d6fd754e688104f9ebebf1bf4449613c9531f5346a18", size = 26203175, upload-time = "2025-07-18T00:56:01.364Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -1809,7 +2107,11 @@ wheels = [ [[package]] name = "pydantic" +<<<<<<< HEAD version = "2.12.4" +======= +version = "2.11.9" +>>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -1817,9 +2119,15 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] +<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/96/ad/a17bc283d7d81837c061c49e3eaa27a45991759a1b7eae1031921c6bd924/pydantic-2.12.4.tar.gz", hash = "sha256:0f8cb9555000a4b5b617f66bfd2566264c4984b27589d3b845685983e8ea85ac", size = 821038, upload-time = "2025-11-05T10:50:08.59Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/82/2f/e68750da9b04856e2a7ec56fc6f034a5a79775e9b9a81882252789873798/pydantic-2.12.4-py3-none-any.whl", hash = "sha256:92d3d202a745d46f9be6df459ac5a064fdaa3c1c4cd8adcfa332ccf3c05f871e", size = 463400, upload-time = "2025-11-05T10:50:06.732Z" }, +======= +sdist = { url = "https://files.pythonhosted.org/packages/ff/5d/09a551ba512d7ca404d785072700d3f6727a02f6f3c24ecfd081c7cf0aa8/pydantic-2.11.9.tar.gz", hash = "sha256:6b8ffda597a14812a7975c90b82a8a2e777d9257aba3453f973acd3c032a18e2", size = 788495, upload-time = "2025-09-13T11:26:39.325Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3e/d3/108f2006987c58e76691d5ae5d200dd3e0f532cb4e5fa3560751c3a1feba/pydantic-2.11.9-py3-none-any.whl", hash = "sha256:c42dd626f5cfc1c6950ce6205ea58c93efa406da65f479dcb4029d5934857da2", size = 444855, upload-time = "2025-09-13T11:26:36.909Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -1911,15 +2219,25 @@ wheels = [ [[package]] name = "python-socketio" +<<<<<<< HEAD version = "5.14.3" +======= +version = "5.14.0" +>>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "bidict" }, { name = "python-engineio" }, ] +<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/c0/3f/02f5970c82285bd015ec433078bfc3275580b03715ed6024607dbe0f1966/python_socketio-5.14.3.tar.gz", hash = "sha256:cd8da5e0666e741b4be19e07882e880f57a4751d1645f92c2bc746c95f23b1eb", size = 124266, upload-time = "2025-10-29T09:42:53.749Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/c0/1a/b393a06aa6f2f6ab4a9c5c160a62d488b17d6da5cf93a67bc13a6e3239cd/python_socketio-5.14.3-py3-none-any.whl", hash = "sha256:a5208c1bbf45a8d6328d01ed67e3fa52ec8b186fd3ea44cfcfcbd120f0c71fbe", size = 79010, upload-time = "2025-10-29T09:42:52.098Z" }, +======= +sdist = { url = "https://files.pythonhosted.org/packages/ec/bf/bbc41facdb33a7f440a39f213e59202032106b42df4667a32ef4c9ffe604/python_socketio-5.14.0.tar.gz", hash = "sha256:d057737f658b3948392ff452a5c865c5ccc969859c37cf095a73393ce755f98e", size = 122099, upload-time = "2025-09-30T19:30:40.902Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ee/8d/f41abde5846c456b33f25e7fa71d8b8ad78785bb812ef0f2393cda2caaf2/python_socketio-5.14.0-py3-none-any.whl", hash = "sha256:7de5ad8a55efc33e17897f6cf91d20168d3d259f98c38d38e2940af83136d6f8", size = 78438, upload-time = "2025-09-30T19:30:39.134Z" }, +>>>>>>> 8387c31 (uv sync) ] [package.optional-dependencies] @@ -1930,7 +2248,11 @@ client = [ [[package]] name = "pytorch-lightning" +<<<<<<< HEAD version = "2.5.6" +======= +version = "2.5.5" +>>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "fsspec", extra = ["http"] }, @@ -1942,9 +2264,15 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] +<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/0a/1f/94a441d30779e1ffa5f7dc2ac5fa374c142d8b96c347a49a30226264124e/pytorch_lightning-2.5.6.tar.gz", hash = "sha256:c428faaceef74be50b870814d0d7e9f9c6ee748b8769a2afd3366bc69daf3a0f", size = 642830, upload-time = "2025-11-05T20:53:04.871Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/17/e4/32ed2f33c1b634f7c2895369222f4f8cb345044f4642bbff718e7dd1e0b7/pytorch_lightning-2.5.6-py3-none-any.whl", hash = "sha256:037bad1e2fd94d5eb6c5144f045fd4c1070c3d38fc9c14d9f3774a3a9be54dff", size = 831555, upload-time = "2025-11-05T20:53:03.316Z" }, +======= +sdist = { url = "https://files.pythonhosted.org/packages/16/78/bce84aab9a5b3b2e9d087d4f1a6be9b481adbfaac4903bc9daaaf09d49a3/pytorch_lightning-2.5.5.tar.gz", hash = "sha256:d6fc8173d1d6e49abfd16855ea05d2eb2415e68593f33d43e59028ecb4e64087", size = 643703, upload-time = "2025-09-05T16:01:18.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/f6/99a5c66478f469598dee25b0e29b302b5bddd4e03ed0da79608ac964056e/pytorch_lightning-2.5.5-py3-none-any.whl", hash = "sha256:0b533991df2353c0c6ea9ca10a7d0728b73631fd61f5a15511b19bee2aef8af0", size = 832431, upload-time = "2025-09-05T16:01:16.234Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -1957,12 +2285,31 @@ wheels = [ ] [[package]] +<<<<<<< HEAD name = "pywinpty" version = "3.0.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f3/bb/a7cc2967c5c4eceb6cc49cfe39447d4bfc56e6c865e7c2249b6eb978935f/pywinpty-3.0.2.tar.gz", hash = "sha256:1505cc4cb248af42cb6285a65c9c2086ee9e7e574078ee60933d5d7fa86fb004", size = 30669, upload-time = "2025-10-03T21:16:29.205Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/02/4e/1098484e042c9485f56f16eb2b69b43b874bd526044ee401512234cf9e04/pywinpty-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:99fdd9b455f0ad6419aba6731a7a0d2f88ced83c3c94a80ff9533d95fa8d8a9e", size = 2050391, upload-time = "2025-10-03T21:19:01.642Z" }, +======= +name = "pywin32" +version = "311" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/ab/01ea1943d4eba0f850c3c61e78e8dd59757ff815ff3ccd0a84de5f541f42/pywin32-311-cp312-cp312-win32.whl", hash = "sha256:750ec6e621af2b948540032557b10a2d43b0cee2ae9758c54154d711cc852d31", size = 8706543, upload-time = "2025-07-14T20:13:20.765Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a8/a0e8d07d4d051ec7502cd58b291ec98dcc0c3fff027caad0470b72cfcc2f/pywin32-311-cp312-cp312-win_amd64.whl", hash = "sha256:b8c095edad5c211ff31c05223658e71bf7116daa0ecf3ad85f3201ea3190d067", size = 9495040, upload-time = "2025-07-14T20:13:22.543Z" }, + { url = "https://files.pythonhosted.org/packages/ba/3a/2ae996277b4b50f17d61f0603efd8253cb2d79cc7ae159468007b586396d/pywin32-311-cp312-cp312-win_arm64.whl", hash = "sha256:e286f46a9a39c4a18b319c28f59b61de793654af2f395c102b4f819e584b5852", size = 8710102, upload-time = "2025-07-14T20:13:24.682Z" }, +] + +[[package]] +name = "pywinpty" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/06/df/429cc505dc5f77ab0612c4b60bca2e3dcc81f6c321844ee017d6dc0f4a95/pywinpty-3.0.0.tar.gz", hash = "sha256:68f70e68a9f0766ffdea3fc500351cb7b9b012bcb8239a411f7ff0fc8f86dcb1", size = 28551, upload-time = "2025-08-12T20:33:46.506Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/d9/bd2249815c305ef8f879b326db1fe1effc8e5f22bd88e522b4b55231aa6f/pywinpty-3.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:1e0c4b01e5b03b1531d7c5d0e044b8c66dd0288c6d2b661820849f2a8d91aec3", size = 2051564, upload-time = "2025-08-12T20:37:09.128Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -2020,6 +2367,7 @@ wheels = [ [[package]] name = "regex" +<<<<<<< HEAD version = "2025.11.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/cc/a9/546676f25e573a4cf00fe8e119b78a37b6a8fe2dc95cda877b30889c9c45/regex-2025.11.3.tar.gz", hash = "sha256:1fedc720f9bb2494ce31a58a1631f9c82df6a09b49c19517ea5cc280b4541e01", size = 414669, upload-time = "2025-11-03T21:34:22.089Z" } @@ -2038,6 +2386,26 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/59/9b/7c29be7903c318488983e7d97abcf8ebd3830e4c956c4c540005fcfb0462/regex-2025.11.3-cp312-cp312-win32.whl", hash = "sha256:3839967cf4dc4b985e1570fd8d91078f0c519f30491c60f9ac42a8db039be204", size = 266194, upload-time = "2025-11-03T21:31:51.53Z" }, { url = "https://files.pythonhosted.org/packages/1a/67/3b92df89f179d7c367be654ab5626ae311cb28f7d5c237b6bb976cd5fbbb/regex-2025.11.3-cp312-cp312-win_amd64.whl", hash = "sha256:e721d1b46e25c481dc5ded6f4b3f66c897c58d2e8cfdf77bbced84339108b0b9", size = 277069, upload-time = "2025-11-03T21:31:53.151Z" }, { url = "https://files.pythonhosted.org/packages/d7/55/85ba4c066fe5094d35b249c3ce8df0ba623cfd35afb22d6764f23a52a1c5/regex-2025.11.3-cp312-cp312-win_arm64.whl", hash = "sha256:64350685ff08b1d3a6fff33f45a9ca183dc1d58bbfe4981604e70ec9801bbc26", size = 270330, upload-time = "2025-11-03T21:31:54.514Z" }, +======= +version = "2025.9.18" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/49/d3/eaa0d28aba6ad1827ad1e716d9a93e1ba963ada61887498297d3da715133/regex-2025.9.18.tar.gz", hash = "sha256:c5ba23274c61c6fef447ba6a39333297d0c247f53059dba0bca415cac511edc4", size = 400917, upload-time = "2025-09-19T00:38:35.79Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b0/99/05859d87a66ae7098222d65748f11ef7f2dff51bfd7482a4e2256c90d72b/regex-2025.9.18-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:436e1b31d7efd4dcd52091d076482031c611dde58bf9c46ca6d0a26e33053a7e", size = 486335, upload-time = "2025-09-19T00:36:03.661Z" }, + { url = "https://files.pythonhosted.org/packages/97/7e/d43d4e8b978890932cf7b0957fce58c5b08c66f32698f695b0c2c24a48bf/regex-2025.9.18-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c190af81e5576b9c5fdc708f781a52ff20f8b96386c6e2e0557a78402b029f4a", size = 289720, upload-time = "2025-09-19T00:36:05.471Z" }, + { url = "https://files.pythonhosted.org/packages/bb/3b/ff80886089eb5dcf7e0d2040d9aaed539e25a94300403814bb24cc775058/regex-2025.9.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e4121f1ce2b2b5eec4b397cc1b277686e577e658d8f5870b7eb2d726bd2300ab", size = 287257, upload-time = "2025-09-19T00:36:07.072Z" }, + { url = "https://files.pythonhosted.org/packages/ee/66/243edf49dd8720cba8d5245dd4d6adcb03a1defab7238598c0c97cf549b8/regex-2025.9.18-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:300e25dbbf8299d87205e821a201057f2ef9aa3deb29caa01cd2cac669e508d5", size = 797463, upload-time = "2025-09-19T00:36:08.399Z" }, + { url = "https://files.pythonhosted.org/packages/df/71/c9d25a1142c70432e68bb03211d4a82299cd1c1fbc41db9409a394374ef5/regex-2025.9.18-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7b47fcf9f5316c0bdaf449e879407e1b9937a23c3b369135ca94ebc8d74b1742", size = 862670, upload-time = "2025-09-19T00:36:10.101Z" }, + { url = "https://files.pythonhosted.org/packages/f8/8f/329b1efc3a64375a294e3a92d43372bf1a351aa418e83c21f2f01cf6ec41/regex-2025.9.18-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:57a161bd3acaa4b513220b49949b07e252165e6b6dc910ee7617a37ff4f5b425", size = 910881, upload-time = "2025-09-19T00:36:12.223Z" }, + { url = "https://files.pythonhosted.org/packages/35/9e/a91b50332a9750519320ed30ec378b74c996f6befe282cfa6bb6cea7e9fd/regex-2025.9.18-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f130c3a7845ba42de42f380fff3c8aebe89a810747d91bcf56d40a069f15352", size = 802011, upload-time = "2025-09-19T00:36:13.901Z" }, + { url = "https://files.pythonhosted.org/packages/a4/1d/6be3b8d7856b6e0d7ee7f942f437d0a76e0d5622983abbb6d21e21ab9a17/regex-2025.9.18-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5f96fa342b6f54dcba928dd452e8d8cb9f0d63e711d1721cd765bb9f73bb048d", size = 786668, upload-time = "2025-09-19T00:36:15.391Z" }, + { url = "https://files.pythonhosted.org/packages/cb/ce/4a60e53df58bd157c5156a1736d3636f9910bdcc271d067b32b7fcd0c3a8/regex-2025.9.18-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0f0d676522d68c207828dcd01fb6f214f63f238c283d9f01d85fc664c7c85b56", size = 856578, upload-time = "2025-09-19T00:36:16.845Z" }, + { url = "https://files.pythonhosted.org/packages/86/e8/162c91bfe7217253afccde112868afb239f94703de6580fb235058d506a6/regex-2025.9.18-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:40532bff8a1a0621e7903ae57fce88feb2e8a9a9116d341701302c9302aef06e", size = 849017, upload-time = "2025-09-19T00:36:18.597Z" }, + { url = "https://files.pythonhosted.org/packages/35/34/42b165bc45289646ea0959a1bc7531733e90b47c56a72067adfe6b3251f6/regex-2025.9.18-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:039f11b618ce8d71a1c364fdee37da1012f5a3e79b1b2819a9f389cd82fd6282", size = 788150, upload-time = "2025-09-19T00:36:20.464Z" }, + { url = "https://files.pythonhosted.org/packages/79/5d/cdd13b1f3c53afa7191593a7ad2ee24092a5a46417725ffff7f64be8342d/regex-2025.9.18-cp312-cp312-win32.whl", hash = "sha256:e1dd06f981eb226edf87c55d523131ade7285137fbde837c34dc9d1bf309f459", size = 264536, upload-time = "2025-09-19T00:36:21.922Z" }, + { url = "https://files.pythonhosted.org/packages/e0/f5/4a7770c9a522e7d2dc1fa3ffc83ab2ab33b0b22b447e62cffef186805302/regex-2025.9.18-cp312-cp312-win_amd64.whl", hash = "sha256:3d86b5247bf25fa3715e385aa9ff272c307e0636ce0c9595f64568b41f0a9c77", size = 275501, upload-time = "2025-09-19T00:36:23.4Z" }, + { url = "https://files.pythonhosted.org/packages/df/05/9ce3e110e70d225ecbed455b966003a3afda5e58e8aec2964042363a18f4/regex-2025.9.18-cp312-cp312-win_arm64.whl", hash = "sha256:032720248cbeeae6444c269b78cb15664458b7bb9ed02401d3da59fe4d68c3a5", size = 268601, upload-time = "2025-09-19T00:36:25.092Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -2103,6 +2471,7 @@ wheels = [ [[package]] name = "rpds-py" +<<<<<<< HEAD version = "0.28.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/48/dc/95f074d43452b3ef5d06276696ece4b3b5d696e7c9ad7173c54b1390cd70/rpds_py-0.28.0.tar.gz", hash = "sha256:abd4df20485a0983e2ca334a216249b6186d6e3c1627e106651943dbdb791aea", size = 27419, upload-time = "2025-10-22T22:24:29.327Z" } @@ -2122,6 +2491,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7d/89/33e675dccff11a06d4d85dbb4d1865f878d5020cbb69b2c1e7b2d3f82562/rpds_py-0.28.0-cp312-cp312-win32.whl", hash = "sha256:d15431e334fba488b081d47f30f091e5d03c18527c325386091f31718952fe08", size = 216954, upload-time = "2025-10-22T22:22:24.105Z" }, { url = "https://files.pythonhosted.org/packages/af/36/45f6ebb3210887e8ee6dbf1bc710ae8400bb417ce165aaf3024b8360d999/rpds_py-0.28.0-cp312-cp312-win_amd64.whl", hash = "sha256:a410542d61fc54710f750d3764380b53bf09e8c4edbf2f9141a82aa774a04f7c", size = 227844, upload-time = "2025-10-22T22:22:25.551Z" }, { url = "https://files.pythonhosted.org/packages/57/91/f3fb250d7e73de71080f9a221d19bd6a1c1eb0d12a1ea26513f6c1052ad6/rpds_py-0.28.0-cp312-cp312-win_arm64.whl", hash = "sha256:1f0cfd1c69e2d14f8c892b893997fa9a60d890a0c8a603e88dca4955f26d1edd", size = 217624, upload-time = "2025-10-22T22:22:26.914Z" }, +======= +version = "0.27.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e9/dd/2c0cbe774744272b0ae725f44032c77bdcab6e8bcf544bffa3b6e70c8dba/rpds_py-0.27.1.tar.gz", hash = "sha256:26a1c73171d10b7acccbded82bf6a586ab8203601e565badc74bbbf8bc5a10f8", size = 27479, upload-time = "2025-08-27T12:16:36.024Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/fe/38de28dee5df58b8198c743fe2bea0c785c6d40941b9950bac4cdb71a014/rpds_py-0.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ae2775c1973e3c30316892737b91f9283f9908e3cc7625b9331271eaaed7dc90", size = 361887, upload-time = "2025-08-27T12:13:10.233Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/4b6c7eedc7dd90986bf0fab6ea2a091ec11c01b15f8ba0a14d3f80450468/rpds_py-0.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2643400120f55c8a96f7c9d858f7be0c88d383cd4653ae2cf0d0c88f668073e5", size = 345795, upload-time = "2025-08-27T12:13:11.65Z" }, + { url = "https://files.pythonhosted.org/packages/6f/0e/e650e1b81922847a09cca820237b0edee69416a01268b7754d506ade11ad/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16323f674c089b0360674a4abd28d5042947d54ba620f72514d69be4ff64845e", size = 385121, upload-time = "2025-08-27T12:13:13.008Z" }, + { url = "https://files.pythonhosted.org/packages/1b/ea/b306067a712988e2bff00dcc7c8f31d26c29b6d5931b461aa4b60a013e33/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9a1f4814b65eacac94a00fc9a526e3fdafd78e439469644032032d0d63de4881", size = 398976, upload-time = "2025-08-27T12:13:14.368Z" }, + { url = "https://files.pythonhosted.org/packages/2c/0a/26dc43c8840cb8fe239fe12dbc8d8de40f2365e838f3d395835dde72f0e5/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ba32c16b064267b22f1850a34051121d423b6f7338a12b9459550eb2096e7ec", size = 525953, upload-time = "2025-08-27T12:13:15.774Z" }, + { url = "https://files.pythonhosted.org/packages/22/14/c85e8127b573aaf3a0cbd7fbb8c9c99e735a4a02180c84da2a463b766e9e/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5c20f33fd10485b80f65e800bbe5f6785af510b9f4056c5a3c612ebc83ba6cb", size = 407915, upload-time = "2025-08-27T12:13:17.379Z" }, + { url = "https://files.pythonhosted.org/packages/ed/7b/8f4fee9ba1fb5ec856eb22d725a4efa3deb47f769597c809e03578b0f9d9/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:466bfe65bd932da36ff279ddd92de56b042f2266d752719beb97b08526268ec5", size = 386883, upload-time = "2025-08-27T12:13:18.704Z" }, + { url = "https://files.pythonhosted.org/packages/86/47/28fa6d60f8b74fcdceba81b272f8d9836ac0340570f68f5df6b41838547b/rpds_py-0.27.1-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:41e532bbdcb57c92ba3be62c42e9f096431b4cf478da9bc3bc6ce5c38ab7ba7a", size = 405699, upload-time = "2025-08-27T12:13:20.089Z" }, + { url = "https://files.pythonhosted.org/packages/d0/fd/c5987b5e054548df56953a21fe2ebed51fc1ec7c8f24fd41c067b68c4a0a/rpds_py-0.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f149826d742b406579466283769a8ea448eed82a789af0ed17b0cd5770433444", size = 423713, upload-time = "2025-08-27T12:13:21.436Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ba/3c4978b54a73ed19a7d74531be37a8bcc542d917c770e14d372b8daea186/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:80c60cfb5310677bd67cb1e85a1e8eb52e12529545441b43e6f14d90b878775a", size = 562324, upload-time = "2025-08-27T12:13:22.789Z" }, + { url = "https://files.pythonhosted.org/packages/b5/6c/6943a91768fec16db09a42b08644b960cff540c66aab89b74be6d4a144ba/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7ee6521b9baf06085f62ba9c7a3e5becffbc32480d2f1b351559c001c38ce4c1", size = 593646, upload-time = "2025-08-27T12:13:24.122Z" }, + { url = "https://files.pythonhosted.org/packages/11/73/9d7a8f4be5f4396f011a6bb7a19fe26303a0dac9064462f5651ced2f572f/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a512c8263249a9d68cac08b05dd59d2b3f2061d99b322813cbcc14c3c7421998", size = 558137, upload-time = "2025-08-27T12:13:25.557Z" }, + { url = "https://files.pythonhosted.org/packages/6e/96/6772cbfa0e2485bcceef8071de7821f81aeac8bb45fbfd5542a3e8108165/rpds_py-0.27.1-cp312-cp312-win32.whl", hash = "sha256:819064fa048ba01b6dadc5116f3ac48610435ac9a0058bbde98e569f9e785c39", size = 221343, upload-time = "2025-08-27T12:13:26.967Z" }, + { url = "https://files.pythonhosted.org/packages/67/b6/c82f0faa9af1c6a64669f73a17ee0eeef25aff30bb9a1c318509efe45d84/rpds_py-0.27.1-cp312-cp312-win_amd64.whl", hash = "sha256:d9199717881f13c32c4046a15f024971a3b78ad4ea029e8da6b86e5aa9cf4594", size = 232497, upload-time = "2025-08-27T12:13:28.326Z" }, + { url = "https://files.pythonhosted.org/packages/e1/96/2817b44bd2ed11aebacc9251da03689d56109b9aba5e311297b6902136e2/rpds_py-0.27.1-cp312-cp312-win_arm64.whl", hash = "sha256:33aa65b97826a0e885ef6e278fbd934e98cdcfed80b63946025f01e2f5b29502", size = 222790, upload-time = "2025-08-27T12:13:29.71Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -2173,15 +2563,25 @@ wheels = [ [[package]] name = "sentry-sdk" +<<<<<<< HEAD version = "2.43.0" +======= +version = "2.39.0" +>>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "urllib3" }, ] +<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/b3/18/09875b4323b03ca9025bae7e6539797b27e4fc032998a466b4b9c3d24653/sentry_sdk-2.43.0.tar.gz", hash = "sha256:52ed6e251c5d2c084224d73efee56b007ef5c2d408a4a071270e82131d336e20", size = 368953, upload-time = "2025-10-29T11:26:08.156Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/69/31/8228fa962f7fd8814d634e4ebece8780e2cdcfbdf0cd2e14d4a6861a7cd5/sentry_sdk-2.43.0-py2.py3-none-any.whl", hash = "sha256:4aacafcf1756ef066d359ae35030881917160ba7f6fc3ae11e0e58b09edc2d5d", size = 400997, upload-time = "2025-10-29T11:26:05.77Z" }, +======= +sdist = { url = "https://files.pythonhosted.org/packages/4c/72/43294fa4bdd75c51610b5104a3ff834459ba653abb415150aa7826a249dd/sentry_sdk-2.39.0.tar.gz", hash = "sha256:8c185854d111f47f329ab6bc35993f28f7a6b7114db64aa426b326998cfa14e9", size = 348556, upload-time = "2025-09-25T09:15:39.064Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dd/44/4356cc64246ba7b2b920f7c97a85c3c52748e213e250b512ee8152eb559d/sentry_sdk-2.39.0-py2.py3-none-any.whl", hash = "sha256:ba655ca5e57b41569b18e2a5552cb3375209760a5d332cdd87c6c3f28f729602", size = 370851, upload-time = "2025-09-25T09:15:36.35Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -2483,7 +2883,11 @@ wheels = [ [[package]] name = "transformers" +<<<<<<< HEAD version = "4.57.1" +======= +version = "4.56.2" +>>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "filelock" }, @@ -2497,9 +2901,15 @@ dependencies = [ { name = "tokenizers" }, { name = "tqdm" }, ] +<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/d6/68/a39307bcc4116a30b2106f2e689130a48de8bd8a1e635b5e1030e46fcd9e/transformers-4.57.1.tar.gz", hash = "sha256:f06c837959196c75039809636cd964b959f6604b75b8eeec6fdfc0440b89cc55", size = 10142511, upload-time = "2025-10-14T15:39:26.18Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/71/d3/c16c3b3cf7655a67db1144da94b021c200ac1303f82428f2beef6c2e72bb/transformers-4.57.1-py3-none-any.whl", hash = "sha256:b10d05da8fa67dc41644dbbf9bc45a44cb86ae33da6f9295f5fbf5b7890bd267", size = 11990925, upload-time = "2025-10-14T15:39:23.085Z" }, +======= +sdist = { url = "https://files.pythonhosted.org/packages/e5/82/0bcfddd134cdf53440becb5e738257cc3cf34cf229d63b57bfd288e6579f/transformers-4.56.2.tar.gz", hash = "sha256:5e7c623e2d7494105c726dd10f6f90c2c99a55ebe86eef7233765abd0cb1c529", size = 9844296, upload-time = "2025-09-19T15:16:26.778Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/26/2591b48412bde75e33bfd292034103ffe41743cacd03120e3242516cd143/transformers-4.56.2-py3-none-any.whl", hash = "sha256:79c03d0e85b26cb573c109ff9eafa96f3c8d4febfd8a0774e8bba32702dd6dde", size = 11608055, upload-time = "2025-09-19T15:16:23.736Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -2515,6 +2925,12 @@ sdist = { url = "https://files.pythonhosted.org/packages/42/c2/65f13aec253100e19 name = "triton" version = "3.5.0" source = { registry = "https://pypi.org/simple" } +<<<<<<< HEAD +======= +dependencies = [ + { name = "setuptools" }, +] +>>>>>>> 8387c31 (uv sync) wheels = [ { url = "https://files.pythonhosted.org/packages/f5/3a/e991574f3102147b642e49637e0281e9bb7c4ba254edb2bab78247c85e01/triton-3.5.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9e71db82261c4ffa3921cd050cd5faa18322d2d405c30eb56084afaff3b0833", size = 170476535, upload-time = "2025-10-13T16:38:05.18Z" }, ] @@ -2533,7 +2949,11 @@ wheels = [ [[package]] name = "typer" +<<<<<<< HEAD version = "0.20.0" +======= +version = "0.19.2" +>>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -2541,9 +2961,15 @@ dependencies = [ { name = "shellingham" }, { name = "typing-extensions" }, ] +<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/8f/28/7c85c8032b91dbe79725b6f17d2fffc595dff06a35c7a30a37bef73a1ab4/typer-0.20.0.tar.gz", hash = "sha256:1aaf6494031793e4876fb0bacfa6a912b551cf43c1e63c800df8b1a866720c37", size = 106492, upload-time = "2025-10-20T17:03:49.445Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/78/64/7713ffe4b5983314e9d436a90d5bd4f63b6054e2aca783a3cfc44cb95bbf/typer-0.20.0-py3-none-any.whl", hash = "sha256:5b463df6793ec1dca6213a3cf4c0f03bc6e322ac5e16e13ddd622a889489784a", size = 47028, upload-time = "2025-10-20T17:03:47.617Z" }, +======= +sdist = { url = "https://files.pythonhosted.org/packages/21/ca/950278884e2ca20547ff3eb109478c6baf6b8cf219318e6bc4f666fad8e8/typer-0.19.2.tar.gz", hash = "sha256:9ad824308ded0ad06cc716434705f691d4ee0bfd0fb081839d2e426860e7fdca", size = 104755, upload-time = "2025-09-23T09:47:48.256Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/22/35617eee79080a5d071d0f14ad698d325ee6b3bf824fc0467c03b30e7fa8/typer-0.19.2-py3-none-any.whl", hash = "sha256:755e7e19670ffad8283db353267cb81ef252f595aa6834a0d1ca9312d9326cb9", size = 46748, upload-time = "2025-09-23T09:47:46.777Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -2553,6 +2979,18 @@ source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/52/68/943c3aeaf14624712a0357c4a67814dba5cea36d194f5c764dad7959a00c/types-certifi-2021.10.8.3.tar.gz", hash = "sha256:72cf7798d165bc0b76e1c10dd1ea3097c7063c42c21d664523b928e88b554a4f", size = 2095, upload-time = "2022-06-09T15:19:05.244Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b5/63/2463d89481e811f007b0e1cd0a91e52e141b47f9de724d20db7b861dcfec/types_certifi-2021.10.8.3-py3-none-any.whl", hash = "sha256:b2d1e325e69f71f7c78e5943d410e650b4707bb0ef32e4ddf3da37f54176e88a", size = 2136, upload-time = "2022-06-09T15:19:03.127Z" }, +<<<<<<< HEAD +======= +] + +[[package]] +name = "types-python-dateutil" +version = "2.9.0.20250822" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0c/0a/775f8551665992204c756be326f3575abba58c4a3a52eef9909ef4536428/types_python_dateutil-2.9.0.20250822.tar.gz", hash = "sha256:84c92c34bd8e68b117bff742bc00b692a1e8531262d4507b33afcc9f7716cd53", size = 16084, upload-time = "2025-08-22T03:02:00.613Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/d9/a29dfa84363e88b053bf85a8b7f212a04f0d7343a4d24933baa45c06e08b/types_python_dateutil-2.9.0.20250822-py3-none-any.whl", hash = "sha256:849d52b737e10a6dc6621d2bd7940ec7c65fcb69e6aa2882acf4e56b2b508ddc", size = 17892, upload-time = "2025-08-22T03:01:59.436Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -2636,7 +3074,11 @@ wheels = [ [[package]] name = "wandb" +<<<<<<< HEAD version = "0.22.3" +======= +version = "0.22.1" +>>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -2650,6 +3092,7 @@ dependencies = [ { name = "sentry-sdk" }, { name = "typing-extensions" }, ] +<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/c1/d1/6b70f365ed86bd69debba8ad55dec8606fc21006e7ca703a5a091bd3b719/wandb-0.22.3.tar.gz", hash = "sha256:04468a8ab2769a46f5e384c9c4ada5da0dced005ca689a8424e4b8b5cb2a0291", size = 44337368, upload-time = "2025-10-28T23:59:10.275Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/23/02/87fb60f587ec249f784a40bd91c30de1b2b24d691ee72675d5b66c3d0728/wandb-0.22.3-py3-none-macosx_12_0_arm64.whl", hash = "sha256:81b3b6e405f38342b0a080898b7d00c5b9375432f5ba358942a09e65cdcfe781", size = 18758047, upload-time = "2025-10-28T23:58:46.56Z" }, @@ -2661,6 +3104,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/da/91/1decaf1a6ac2017481c782e0fad7f90bc9ae4057f3d76d478cb6527f3dd3/wandb-0.22.3-py3-none-win32.whl", hash = "sha256:09ca1edfe0fd6dc30447d368acddb825668e60ee705c98594a6bbfd30d34d47e", size = 19160297, upload-time = "2025-10-28T23:59:01.536Z" }, { url = "https://files.pythonhosted.org/packages/4c/ba/3b092634279994b0c79fe05220532822be09f3a353ae95c54e7142769db8/wandb-0.22.3-py3-none-win_amd64.whl", hash = "sha256:55403bf93872c9978433d101324f51e43e78c70c809bf6d06ca7b2760e39f497", size = 19160300, upload-time = "2025-10-28T23:59:04.06Z" }, { url = "https://files.pythonhosted.org/packages/7f/80/4662fce9eebcc8c71f5083e9152ccaf7d43d4ca9c446e1422f9aa784a51c/wandb-0.22.3-py3-none-win_arm64.whl", hash = "sha256:49f66b05882abfa53816cc8d01b3c2435a89c5a090176802fa6928b5979d34d9", size = 17461959, upload-time = "2025-10-28T23:59:07.059Z" }, +======= +sdist = { url = "https://files.pythonhosted.org/packages/ac/6f/be255b13157cab6c6670594171f59f67bd8a89f20d1978dc4eb892e2de27/wandb-0.22.1.tar.gz", hash = "sha256:6a1d668ecd6bd6531a73f6f7cfec0a93a08ef578c16ccf7167168c52cbf8cb12", size = 40246806, upload-time = "2025-09-29T17:15:55.207Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/73/de1d62301ef5d084160221637f34a821b7ed90b0769698b7b420686608ab/wandb-0.22.1-py3-none-macosx_12_0_arm64.whl", hash = "sha256:d862d0d28919556a5c32977138449812a2d127853e20b0deb39a5ab17700230f", size = 18370574, upload-time = "2025-09-29T17:15:18.236Z" }, + { url = "https://files.pythonhosted.org/packages/42/0e/4f60d9c7f1fa9d249dcbe70c6bad1573a9cfc070d00c3d8dbd62f715938d/wandb-0.22.1-py3-none-macosx_12_0_x86_64.whl", hash = "sha256:ce57213de331717270020f7e07b098a0ea37646550b63758eabf8cb05eeb066f", size = 19392851, upload-time = "2025-09-29T17:15:22.093Z" }, + { url = "https://files.pythonhosted.org/packages/c6/8b/757ede4a581eece5e72ade51fd4b43cfedbd3e39b85fe29d0198bc98131b/wandb-0.22.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5a0ac652c23bf88e12bf0c04e911ff4f95696ac60a3612d81e54f1f8d89f3c5", size = 18171463, upload-time = "2025-09-29T17:15:24.588Z" }, + { url = "https://files.pythonhosted.org/packages/a2/e6/275d60292183d4de89fc9053887192f978fd8612e55c8f7719aa5c81bbd1/wandb-0.22.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dc14dd06938c282900dd9f72cbaaed45368b0c6b9bc2ffd1f45d07eeb13095b", size = 19585538, upload-time = "2025-09-29T17:15:28.432Z" }, + { url = "https://files.pythonhosted.org/packages/a8/5c/4199abb92d06de6ebd63ee33551ba0de6d91a814ac42e372dec6d8009ea0/wandb-0.22.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1b2d2b9d8d1ea8aea3c2cbf9de7696105432886ba9845c50e7cc71613aa6c8ef", size = 18210525, upload-time = "2025-09-29T17:15:33.459Z" }, + { url = "https://files.pythonhosted.org/packages/0d/00/a7719c048115825861a31435fa911887c9949b20096dbc7307e11b3c981b/wandb-0.22.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:051906d7f22bdf8c07c8837ffc6d9ae357d61dcd74cfb7d29fd0243e03da8f4a", size = 19680055, upload-time = "2025-09-29T17:15:38.521Z" }, + { url = "https://files.pythonhosted.org/packages/6f/5d/e6270557a315211e880c1efa9c1cab577f945d81168bc1c1187fd483f1bb/wandb-0.22.1-py3-none-win32.whl", hash = "sha256:b2df59bd70771329f27171f55d25d5557731bb0674d60db4735c173a8fb8076d", size = 18769036, upload-time = "2025-09-29T17:15:43.19Z" }, + { url = "https://files.pythonhosted.org/packages/92/fe/34cdfd491ea6c89495794f361102b727b922adcc4f3eedb47c8aa16984c3/wandb-0.22.1-py3-none-win_amd64.whl", hash = "sha256:c1b442e6de805d78743321200a27099517509f9e4aa2e6d330211a4809f932d7", size = 18769038, upload-time = "2025-09-29T17:15:46.977Z" }, + { url = "https://files.pythonhosted.org/packages/1e/9e/fe95f5d48ff10215b7d7e67dc998cba3f660027829fac2a67c79ce89e985/wandb-0.22.1-py3-none-win_arm64.whl", hash = "sha256:52758008c9ef9e7201113af08d6015322a699ebe3497a6e6fc885b39f5652b4d", size = 17077774, upload-time = "2025-09-29T17:15:50.588Z" }, +>>>>>>> 8387c31 (uv sync) ] [[package]] @@ -2769,13 +3225,18 @@ wheels = [ [[package]] name = "yarl" +<<<<<<< HEAD version = "1.22.0" +======= +version = "1.20.1" +>>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "multidict" }, { name = "propcache" }, ] +<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/57/63/0c6ebca57330cd313f6102b16dd57ffaf3ec4c83403dcb45dbd15c6f3ea1/yarl-1.22.0.tar.gz", hash = "sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71", size = 187169, upload-time = "2025-10-06T14:12:55.963Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/75/ff/46736024fee3429b80a165a732e38e5d5a238721e634ab41b040d49f8738/yarl-1.22.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e340382d1afa5d32b892b3ff062436d592ec3d692aeea3bef3a5cfe11bbf8c6f", size = 142000, upload-time = "2025-10-06T14:09:44.631Z" }, @@ -2795,4 +3256,26 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c8/9a/6ad1a9b37c2f72874f93e691b2e7ecb6137fb2b899983125db4204e47575/yarl-1.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:8884d8b332a5e9b88e23f60bb166890009429391864c685e17bd73a9eda9105c", size = 87213, upload-time = "2025-10-06T14:10:11.369Z" }, { url = "https://files.pythonhosted.org/packages/44/c5/c21b562d1680a77634d748e30c653c3ca918beb35555cff24986fff54598/yarl-1.22.0-cp312-cp312-win_arm64.whl", hash = "sha256:ea70f61a47f3cc93bdf8b2f368ed359ef02a01ca6393916bc8ff877427181e74", size = 81330, upload-time = "2025-10-06T14:10:13.112Z" }, { url = "https://files.pythonhosted.org/packages/73/ae/b48f95715333080afb75a4504487cbe142cae1268afc482d06692d605ae6/yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff", size = 46814, upload-time = "2025-10-06T14:12:53.872Z" }, +======= +sdist = { url = "https://files.pythonhosted.org/packages/3c/fb/efaa23fa4e45537b827620f04cf8f3cd658b76642205162e072703a5b963/yarl-1.20.1.tar.gz", hash = "sha256:d017a4997ee50c91fd5466cef416231bb82177b93b029906cefc542ce14c35ac", size = 186428, upload-time = "2025-06-10T00:46:09.923Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/9a/cb7fad7d73c69f296eda6815e4a2c7ed53fc70c2f136479a91c8e5fbdb6d/yarl-1.20.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdcc4cd244e58593a4379fe60fdee5ac0331f8eb70320a24d591a3be197b94a9", size = 133667, upload-time = "2025-06-10T00:43:44.369Z" }, + { url = "https://files.pythonhosted.org/packages/67/38/688577a1cb1e656e3971fb66a3492501c5a5df56d99722e57c98249e5b8a/yarl-1.20.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b29a2c385a5f5b9c7d9347e5812b6f7ab267193c62d282a540b4fc528c8a9d2a", size = 91025, upload-time = "2025-06-10T00:43:46.295Z" }, + { url = "https://files.pythonhosted.org/packages/50/ec/72991ae51febeb11a42813fc259f0d4c8e0507f2b74b5514618d8b640365/yarl-1.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1112ae8154186dfe2de4732197f59c05a83dc814849a5ced892b708033f40dc2", size = 89709, upload-time = "2025-06-10T00:43:48.22Z" }, + { url = "https://files.pythonhosted.org/packages/99/da/4d798025490e89426e9f976702e5f9482005c548c579bdae792a4c37769e/yarl-1.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90bbd29c4fe234233f7fa2b9b121fb63c321830e5d05b45153a2ca68f7d310ee", size = 352287, upload-time = "2025-06-10T00:43:49.924Z" }, + { url = "https://files.pythonhosted.org/packages/1a/26/54a15c6a567aac1c61b18aa0f4b8aa2e285a52d547d1be8bf48abe2b3991/yarl-1.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:680e19c7ce3710ac4cd964e90dad99bf9b5029372ba0c7cbfcd55e54d90ea819", size = 345429, upload-time = "2025-06-10T00:43:51.7Z" }, + { url = "https://files.pythonhosted.org/packages/d6/95/9dcf2386cb875b234353b93ec43e40219e14900e046bf6ac118f94b1e353/yarl-1.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a979218c1fdb4246a05efc2cc23859d47c89af463a90b99b7c56094daf25a16", size = 365429, upload-time = "2025-06-10T00:43:53.494Z" }, + { url = "https://files.pythonhosted.org/packages/91/b2/33a8750f6a4bc224242a635f5f2cff6d6ad5ba651f6edcccf721992c21a0/yarl-1.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255b468adf57b4a7b65d8aad5b5138dce6a0752c139965711bdcb81bc370e1b6", size = 363862, upload-time = "2025-06-10T00:43:55.766Z" }, + { url = "https://files.pythonhosted.org/packages/98/28/3ab7acc5b51f4434b181b0cee8f1f4b77a65919700a355fb3617f9488874/yarl-1.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a97d67108e79cfe22e2b430d80d7571ae57d19f17cda8bb967057ca8a7bf5bfd", size = 355616, upload-time = "2025-06-10T00:43:58.056Z" }, + { url = "https://files.pythonhosted.org/packages/36/a3/f666894aa947a371724ec7cd2e5daa78ee8a777b21509b4252dd7bd15e29/yarl-1.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8570d998db4ddbfb9a590b185a0a33dbf8aafb831d07a5257b4ec9948df9cb0a", size = 339954, upload-time = "2025-06-10T00:43:59.773Z" }, + { url = "https://files.pythonhosted.org/packages/f1/81/5f466427e09773c04219d3450d7a1256138a010b6c9f0af2d48565e9ad13/yarl-1.20.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:97c75596019baae7c71ccf1d8cc4738bc08134060d0adfcbe5642f778d1dca38", size = 365575, upload-time = "2025-06-10T00:44:02.051Z" }, + { url = "https://files.pythonhosted.org/packages/2e/e3/e4b0ad8403e97e6c9972dd587388940a032f030ebec196ab81a3b8e94d31/yarl-1.20.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1c48912653e63aef91ff988c5432832692ac5a1d8f0fb8a33091520b5bbe19ef", size = 365061, upload-time = "2025-06-10T00:44:04.196Z" }, + { url = "https://files.pythonhosted.org/packages/ac/99/b8a142e79eb86c926f9f06452eb13ecb1bb5713bd01dc0038faf5452e544/yarl-1.20.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4c3ae28f3ae1563c50f3d37f064ddb1511ecc1d5584e88c6b7c63cf7702a6d5f", size = 364142, upload-time = "2025-06-10T00:44:06.527Z" }, + { url = "https://files.pythonhosted.org/packages/34/f2/08ed34a4a506d82a1a3e5bab99ccd930a040f9b6449e9fd050320e45845c/yarl-1.20.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c5e9642f27036283550f5f57dc6156c51084b458570b9d0d96100c8bebb186a8", size = 381894, upload-time = "2025-06-10T00:44:08.379Z" }, + { url = "https://files.pythonhosted.org/packages/92/f8/9a3fbf0968eac704f681726eff595dce9b49c8a25cd92bf83df209668285/yarl-1.20.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2c26b0c49220d5799f7b22c6838409ee9bc58ee5c95361a4d7831f03cc225b5a", size = 383378, upload-time = "2025-06-10T00:44:10.51Z" }, + { url = "https://files.pythonhosted.org/packages/af/85/9363f77bdfa1e4d690957cd39d192c4cacd1c58965df0470a4905253b54f/yarl-1.20.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:564ab3d517e3d01c408c67f2e5247aad4019dcf1969982aba3974b4093279004", size = 374069, upload-time = "2025-06-10T00:44:12.834Z" }, + { url = "https://files.pythonhosted.org/packages/35/99/9918c8739ba271dcd935400cff8b32e3cd319eaf02fcd023d5dcd487a7c8/yarl-1.20.1-cp312-cp312-win32.whl", hash = "sha256:daea0d313868da1cf2fac6b2d3a25c6e3a9e879483244be38c8e6a41f1d876a5", size = 81249, upload-time = "2025-06-10T00:44:14.731Z" }, + { url = "https://files.pythonhosted.org/packages/eb/83/5d9092950565481b413b31a23e75dd3418ff0a277d6e0abf3729d4d1ce25/yarl-1.20.1-cp312-cp312-win_amd64.whl", hash = "sha256:48ea7d7f9be0487339828a4de0360d7ce0efc06524a48e1810f945c45b813698", size = 86710, upload-time = "2025-06-10T00:44:16.716Z" }, + { url = "https://files.pythonhosted.org/packages/b4/2d/2345fce04cfd4bee161bf1e7d9cdc702e3e16109021035dbb24db654a622/yarl-1.20.1-py3-none-any.whl", hash = "sha256:83b8eb083fe4683c6115795d9fc1cfaf2cbbefb19b3a1cb68f6527460f483a77", size = 46542, upload-time = "2025-06-10T00:46:07.521Z" }, +>>>>>>> 8387c31 (uv sync) ] From 6a1f21547af5a0e80e16065187dbdb9660aeee17 Mon Sep 17 00:00:00 2001 From: jiito Date: Wed, 1 Oct 2025 11:39:12 -0700 Subject: [PATCH 16/99] add example config with cb, save model intermediately --- config/default_circuit-tracer.yaml | 165 +++++++++++++++++++++++ crosslayer_transcoder/utils/callbacks.py | 15 ++- 2 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 config/default_circuit-tracer.yaml diff --git a/config/default_circuit-tracer.yaml b/config/default_circuit-tracer.yaml new file mode 100644 index 0000000..c963404 --- /dev/null +++ b/config/default_circuit-tracer.yaml @@ -0,0 +1,165 @@ +# Default configuration for CrossLayer Transcoder training +# This file uses Lightning CLI's automatic class construction + +seed_everything: 42 + +trainer: + # max_steps is number of gradient updates. If using gradient accumulation, this is not the number of batches. + max_steps: 100_000 + val_check_interval: 1_000 + limit_val_batches: 1 + enable_checkpointing: false # We use custom end-of-training checkpoint + num_sanity_val_steps: 0 # Can't run replacement model before standardizers are initialized + precision: "16-mixed" + accelerator: "gpu" + devices: [0] # [0] means cuda:0 + accumulate_grad_batches: 1 + logger: # WandB logger is recommended but other loggers are supported as well + class_path: lightning.pytorch.loggers.WandbLogger + init_args: + project: "clt" + name: "jumprelu" + save_dir: "./wandb" + callbacks: + - class_path: crosslayer_transcoder.utils.callbacks.EndOfTrainingCheckpointCallback + init_args: + checkpoint_dir: "checkpoints" + - class_path: crosslayer_transcoder.utils.callbacks.CircuitTracerCallback + init_args: + save_dir: "/experiments/checkpoints" + +model: + class_path: crosslayer_transcoder.model.clt_lightning.JumpReLUCrossLayerTranscoderModule + init_args: + model: + class_path: crosslayer_transcoder.model.clt.CrossLayerTranscoder + init_args: + encoder: + class_path: crosslayer_transcoder.model.clt.Encoder + init_args: + d_acts: 768 + d_features: 10_000 + n_layers: 12 + + decoder: + class_path: crosslayer_transcoder.model.clt.CrosslayerDecoder + init_args: + d_acts: 768 + d_features: 10_000 + n_layers: 12 + + nonlinearity: + class_path: crosslayer_transcoder.model.jumprelu.JumpReLU + init_args: + theta: 0.03 + bandwidth: 0.01 + n_layers: 12 + d_features: 10_000 + + input_standardizer: + class_path: crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer + init_args: + n_layers: 12 + activation_dim: 768 + + output_standardizer: + class_path: crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer + init_args: + n_layers: 12 + activation_dim: 768 + + # Pre-constructed replacement model + replacement_model: + class_path: crosslayer_transcoder.metrics.replacement_model_accuracy.ReplacementModelAccuracy + init_args: + model_name: "openai-community/gpt2" + device_map: "cuda:0" # should match trainer.devices + loader_batch_size: 2 + + # Pre-constructed dead features metric + dead_features: + class_path: crosslayer_transcoder.metrics.dead_features.DeadFeatures + init_args: + n_features: 10_000 + n_layers: 12 + return_per_layer: true + return_log_freqs: true + return_neuron_indices: true + + + # Training parameters + learning_rate: 1e-4 + compile: true # if using torch.compile + lr_decay_step: 80_000 # lr is scaled by lr_decay_factor after this many steps + lr_decay_factor: 0.1 + + lambda_sparsity: 0.0007 # sparsity loss weight + c_sparsity: 1 # sparsity loss coefficient + use_tanh: true # use tanh nonlinearity in the JumpReLU + pre_actv_loss: 1e-6 # pre-activation loss weight + + # Dead features computation settings + compute_dead_features: true + compute_dead_features_every: 500 + +data: + class_path: crosslayer_transcoder.data.datamodule.ActivationDataModule + init_args: + # Buffer settings + buffer_size: 1_000_000 # number of activations to store in the buffer + n_in_out: 2 # number of input and output layers + n_layers: 12 # number of layers in the model + activation_dim: 768 # dimension of the activations + dtype: "float16" # dtype of the activations + max_batch_size: 50000 # maximum batch size for the data loader + + # Model settings for activation generation + model_name: "openai-community/gpt2" + model_dtype: "float32" + + # Dataset settings + dataset_name: "Skylion007/openwebtext" + dataset_split: "train" + max_sequence_length: 1024 + + # Generation settings + generation_batch_size: 10 + refresh_interval: 0.1 # time (s) between shell logs updates + + # Memory settings + shared_memory_name: "activation_buffer" + timeout_seconds: 30 + + # File paths + init_file: null # path to file with shuffled activations to initialize the buffer fast + # if null, activations are generated and training starts when the buffer is at least minimum_fill_threshold full + + # DataLoader settings + batch_size: 1000 + num_workers: 10 + prefetch_factor: 2 + shuffle: true + persistent_workers: true + pin_memory: true + + minimum_fill_threshold: 0.2 # Only provide activations when buffer is at least 20% full + # to maintain sufficient shuffling + + use_shared_memory: true + + # Device configuration + device_map: "cuda:0" # "cpu", "auto", "cuda:0", "cuda:0,1,2,3" + deployment_policy: "gpu_only" # "cpu_only", "gpu_only", or "dynamic" + # dynamic will use CPU and only GPU if the buffer is almost empty to refill fast. Use this if you use a single GPU and have a beefy CPU. + + # WandB logging configuration for data generation + wandb_logging: + enabled: true # Enable WandB logging for data generation + project: "clt" # WandB project (should match trainer logger) + group: null # Group name (null = auto-generated from training run) + run_name: "data-generator-jumprelu" # Run name suffix + tags: ["data-generation"] # Tags for the data generation run + save_dir: "./wandb" # Directory for WandB files + log_interval: 5.0 # Logging interval in seconds + +ckpt_path: null \ No newline at end of file diff --git a/crosslayer_transcoder/utils/callbacks.py b/crosslayer_transcoder/utils/callbacks.py index bdfb6d0..e407558 100644 --- a/crosslayer_transcoder/utils/callbacks.py +++ b/crosslayer_transcoder/utils/callbacks.py @@ -67,5 +67,18 @@ def __init__(self, save_dir: str = "clt_module"): super().__init__() self.save_dir = Path(save_dir) + def _convert_model(self, pl_module): + convert_model_to_circuit_tracer(pl_module, self.save_dir.as_posix()) + logger.info(f"Circuit-tracer model saved to {self.save_dir.as_posix()}") + + def on_train_start(self, trainer, pl_module): + self.save_dir.mkdir(parents=True, exist_ok=True) + logger.info(f"Saving circuit-tracer model to {self.save_dir.as_posix()}") + + self._convert_model(pl_module) + + def on_train_batch_end(self, trainer, pl_module, outputs, batch, batch_idx): + self._convert_model(pl_module) + def on_train_end(self, trainer, pl_module): - convert_model_to_circuit_tracer(pl_module, self.save_dir) + self._convert_model(pl_module) From d0e70becab8ad44655b7e59d26c63b5f1d732d0f Mon Sep 17 00:00:00 2001 From: jiito Date: Wed, 1 Oct 2025 13:18:28 -0700 Subject: [PATCH 17/99] add TODO --- crosslayer_transcoder/utils/convert_to_circuit_tracer.py | 1 + 1 file changed, 1 insertion(+) diff --git a/crosslayer_transcoder/utils/convert_to_circuit_tracer.py b/crosslayer_transcoder/utils/convert_to_circuit_tracer.py index 9509f93..f7601c2 100644 --- a/crosslayer_transcoder/utils/convert_to_circuit_tracer.py +++ b/crosslayer_transcoder/utils/convert_to_circuit_tracer.py @@ -41,6 +41,7 @@ def save_decoder_dict(decoder_dict: dict, path: str): def convert_model_to_circuit_tracer( lightning_module: CLTModule, save_dir: str, + # TODO: check the hooks feature_input_hook: str = "blocks.{layer}.hook_resid_pre", feature_output_hook: str = "blocks.{layer}.hook_mlp_out", ): From 6f1f45b9dad700f908b67076b81099c4cc5c8392 Mon Sep 17 00:00:00 2001 From: jiito Date: Wed, 1 Oct 2025 13:27:48 -0700 Subject: [PATCH 18/99] add non-linearity --- .../utils/convert_to_circuit_tracer.py | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/crosslayer_transcoder/utils/convert_to_circuit_tracer.py b/crosslayer_transcoder/utils/convert_to_circuit_tracer.py index f7601c2..55f9834 100644 --- a/crosslayer_transcoder/utils/convert_to_circuit_tracer.py +++ b/crosslayer_transcoder/utils/convert_to_circuit_tracer.py @@ -1,11 +1,12 @@ # simple file to convert the lightning model to a circuit-tracer model +import logging import os from pathlib import Path from typing import List, Union -from huggingface_hub import upload_folder import torch import yaml +from huggingface_hub import upload_folder from safetensors.torch import save_file from crosslayer_transcoder.model.clt import ( @@ -18,6 +19,9 @@ TopKCrossLayerTranscoderModule, ) +logger = logging.getLogger(__name__) + + CLTModule = Union[ CrossLayerTranscoderModule, JumpReLUCrossLayerTranscoderModule, @@ -51,6 +55,7 @@ def convert_model_to_circuit_tracer( encoder = lightning_module.model.encoder decoder = lightning_module.model.decoder + nonlinearity = lightning_module.model.nonlinearity n_layers = encoder.n_layers d_acts = encoder.d_acts # -> d_model d_features = encoder.d_features # -> d_transcoder @@ -71,7 +76,11 @@ def convert_model_to_circuit_tracer( if hasattr(decoder, "b") else torch.zeros(d_acts) ), - # TODO: add non-lin params like threshold + f"threshold_{source_layer}": ( + nonlinearity.theta.cpu() + if hasattr(nonlinearity, "theta") + else torch.zeros(d_features) + ), } # TODO: check names @@ -113,21 +122,21 @@ def upload_to_hub(save_dir: str, repo_id: str, repo_type: str = "model"): if __name__ == "__main__": - from crosslayer_transcoder.model.clt_lightning import CrossLayerTranscoderModule + from crosslayer_transcoder.metrics.dead_features import DeadFeatures + from crosslayer_transcoder.metrics.replacement_model_accuracy import ( + ReplacementModelAccuracy, + ) from crosslayer_transcoder.model.clt import ( + CrosslayerDecoder, CrossLayerTranscoder, Encoder, - CrosslayerDecoder, ) + from crosslayer_transcoder.model.clt_lightning import CrossLayerTranscoderModule from crosslayer_transcoder.model.jumprelu import JumpReLU from crosslayer_transcoder.model.standardize import ( DimensionwiseInputStandardizer, DimensionwiseOutputStandardizer, ) - from crosslayer_transcoder.metrics.replacement_model_accuracy import ( - ReplacementModelAccuracy, - ) - from crosslayer_transcoder.metrics.dead_features import DeadFeatures # Create components based on default.yaml config encoder = Encoder(d_acts=768, d_features=10_000, n_layers=12) From e5844e735d8805a56f6ee67fe587425533ac9cd2 Mon Sep 17 00:00:00 2001 From: jiito Date: Wed, 1 Oct 2025 13:30:36 -0700 Subject: [PATCH 19/99] refactor: move to test and util file --- .../utils/convert_to_circuit_tracer.py | 92 ------------------- crosslayer_transcoder/utils/hf.py | 5 + tests/test_convert_to_circuit_tracer.py | 69 ++++++++++++++ 3 files changed, 74 insertions(+), 92 deletions(-) create mode 100644 crosslayer_transcoder/utils/hf.py create mode 100644 tests/test_convert_to_circuit_tracer.py diff --git a/crosslayer_transcoder/utils/convert_to_circuit_tracer.py b/crosslayer_transcoder/utils/convert_to_circuit_tracer.py index 55f9834..e186432 100644 --- a/crosslayer_transcoder/utils/convert_to_circuit_tracer.py +++ b/crosslayer_transcoder/utils/convert_to_circuit_tracer.py @@ -1,17 +1,14 @@ # simple file to convert the lightning model to a circuit-tracer model import logging -import os from pathlib import Path from typing import List, Union import torch import yaml -from huggingface_hub import upload_folder from safetensors.torch import save_file from crosslayer_transcoder.model.clt import ( CrosslayerDecoder, - Encoder, ) from crosslayer_transcoder.model.clt_lightning import ( CrossLayerTranscoderModule, @@ -21,7 +18,6 @@ logger = logging.getLogger(__name__) - CLTModule = Union[ CrossLayerTranscoderModule, JumpReLUCrossLayerTranscoderModule, @@ -112,91 +108,3 @@ def convert_model_to_circuit_tracer( with open(save_path / "config.yaml", "w") as f: yaml.dump(config, f, default_flow_style=False) - - -def upload_to_hub(save_dir: str, repo_id: str, repo_type: str = "model"): - from huggingface_hub import upload_folder - - print(f"Uploading {save_dir} to {repo_id} ({repo_type})") - upload_folder(folder_path=save_dir, repo_id=repo_id, repo_type=repo_type) - - -if __name__ == "__main__": - from crosslayer_transcoder.metrics.dead_features import DeadFeatures - from crosslayer_transcoder.metrics.replacement_model_accuracy import ( - ReplacementModelAccuracy, - ) - from crosslayer_transcoder.model.clt import ( - CrosslayerDecoder, - CrossLayerTranscoder, - Encoder, - ) - from crosslayer_transcoder.model.clt_lightning import CrossLayerTranscoderModule - from crosslayer_transcoder.model.jumprelu import JumpReLU - from crosslayer_transcoder.model.standardize import ( - DimensionwiseInputStandardizer, - DimensionwiseOutputStandardizer, - ) - - # Create components based on default.yaml config - encoder = Encoder(d_acts=768, d_features=10_000, n_layers=12) - - decoder = CrosslayerDecoder(d_acts=768, d_features=10_000, n_layers=12) - - nonlinearity = JumpReLU(theta=0.03, bandwidth=0.01, n_layers=12, d_features=10_000) - - input_standardizer = DimensionwiseInputStandardizer(n_layers=12, activation_dim=768) - - output_standardizer = DimensionwiseOutputStandardizer( - n_layers=12, activation_dim=768 - ) - - model = CrossLayerTranscoder( - encoder=encoder, - decoder=decoder, - nonlinearity=nonlinearity, - input_standardizer=input_standardizer, - output_standardizer=output_standardizer, - ) - - # replacement_model = ReplacementModelAccuracy( - # model_name="openai-community/gpt2", device_map="mps", loader_batch_size=2 - # ) - - dead_features = DeadFeatures( - n_features=10_000, - n_layers=12, - return_per_layer=True, - return_log_freqs=True, - return_neuron_indices=True, - ) - - clt_module = CrossLayerTranscoderModule( - model=model, - # replacement_model=replacement_model, - dead_features=dead_features, - learning_rate=1e-4, - compile=True, - lr_decay_step=80_000, - lr_decay_factor=0.1, - compute_dead_features=True, - compute_dead_features_every=500, - ) - - convert_model_to_circuit_tracer(clt_module, "clt_module") - - upload_folder( - folder_path="clt_module", repo_id="jiito/clt_test_gpt2_zero", repo_type="model" - ) - upload_folder( - folder_path="clt_module/encoder", - path_in_repo="encoder", - repo_id="jiito/clt_test_gpt2_zero", - repo_type="model", - ) - upload_folder( - folder_path="clt_module/decoder", - path_in_repo="decoder", - repo_id="jiito/clt_test_gpt2_zero", - repo_type="model", - ) diff --git a/crosslayer_transcoder/utils/hf.py b/crosslayer_transcoder/utils/hf.py new file mode 100644 index 0000000..89e4127 --- /dev/null +++ b/crosslayer_transcoder/utils/hf.py @@ -0,0 +1,5 @@ +def upload_to_hub(save_dir: str, repo_id: str, repo_type: str = "model"): + from huggingface_hub import upload_folder + + print(f"Uploading {save_dir} to {repo_id} ({repo_type})") + upload_folder(folder_path=save_dir, repo_id=repo_id, repo_type=repo_type) diff --git a/tests/test_convert_to_circuit_tracer.py b/tests/test_convert_to_circuit_tracer.py new file mode 100644 index 0000000..0055733 --- /dev/null +++ b/tests/test_convert_to_circuit_tracer.py @@ -0,0 +1,69 @@ +from crosslayer_transcoder.utils.convert_to_circuit_tracer import ( + convert_model_to_circuit_tracer, +) + + +def test_convert_to_circuit_tracer(): + from crosslayer_transcoder.metrics.dead_features import DeadFeatures + from crosslayer_transcoder.model.clt import ( + CrosslayerDecoder, + CrossLayerTranscoder, + Encoder, + ) + from crosslayer_transcoder.model.clt_lightning import CrossLayerTranscoderModule + from crosslayer_transcoder.model.jumprelu import JumpReLU + from crosslayer_transcoder.model.standardize import ( + DimensionwiseInputStandardizer, + DimensionwiseOutputStandardizer, + ) + + # Create components based on default.yaml config + encoder = Encoder(d_acts=768, d_features=10_000, n_layers=12) + + decoder = CrosslayerDecoder(d_acts=768, d_features=10_000, n_layers=12) + + nonlinearity = JumpReLU(theta=0.03, bandwidth=0.01, n_layers=12, d_features=10_000) + + input_standardizer = DimensionwiseInputStandardizer(n_layers=12, activation_dim=768) + + output_standardizer = DimensionwiseOutputStandardizer( + n_layers=12, activation_dim=768 + ) + + model = CrossLayerTranscoder( + encoder=encoder, + decoder=decoder, + nonlinearity=nonlinearity, + input_standardizer=input_standardizer, + output_standardizer=output_standardizer, + ) + + # replacement_model = ReplacementModelAccuracy( + # model_name="openai-community/gpt2", device_map="mps", loader_batch_size=2 + # ) + + dead_features = DeadFeatures( + n_features=10_000, + n_layers=12, + return_per_layer=True, + return_log_freqs=True, + return_neuron_indices=True, + ) + + clt_module = CrossLayerTranscoderModule( + model=model, + # replacement_model=replacement_model, + dead_features=dead_features, + learning_rate=1e-4, + compile=True, + lr_decay_step=80_000, + lr_decay_factor=0.1, + compute_dead_features=True, + compute_dead_features_every=500, + ) + + convert_model_to_circuit_tracer(clt_module, "clt_module") + + +if __name__ == "__main__": + test_convert_to_circuit_tracer() From 7b383c32e242bd54558b4c2586711663f616fb02 Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 2 Oct 2025 16:42:40 -0700 Subject: [PATCH 20/99] add upload to hf callback --- config/default_circuit-tracer.yaml | 5 +++++ crosslayer_transcoder/utils/callbacks.py | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/config/default_circuit-tracer.yaml b/config/default_circuit-tracer.yaml index c963404..ca15bd1 100644 --- a/config/default_circuit-tracer.yaml +++ b/config/default_circuit-tracer.yaml @@ -27,6 +27,11 @@ trainer: - class_path: crosslayer_transcoder.utils.callbacks.CircuitTracerCallback init_args: save_dir: "/experiments/checkpoints" + - class_path: crosslayer_transcoder.utils.callbacks.HuggingFaceCallback + init_args: + repo_id: "jiito/clt_test_gpt2_zero" + repo_type: "model" + save_dir: "/experiments/checkpoints" model: class_path: crosslayer_transcoder.model.clt_lightning.JumpReLUCrossLayerTranscoderModule diff --git a/crosslayer_transcoder/utils/callbacks.py b/crosslayer_transcoder/utils/callbacks.py index e407558..d850d1f 100644 --- a/crosslayer_transcoder/utils/callbacks.py +++ b/crosslayer_transcoder/utils/callbacks.py @@ -16,6 +16,7 @@ from crosslayer_transcoder.utils.convert_to_circuit_tracer import ( convert_model_to_circuit_tracer, ) +from crosslayer_transcoder.utils.hf import upload_to_hub logger = logging.getLogger(__name__) @@ -82,3 +83,18 @@ def on_train_batch_end(self, trainer, pl_module, outputs, batch, batch_idx): def on_train_end(self, trainer, pl_module): self._convert_model(pl_module) + + +class HuggingFaceCallback(L.Callback): + """Callback to upload the model to Hugging Face.""" + + def __init__( + self, repo_id: str, repo_type: str = "model", save_dir: str = "clt_module" + ): + super().__init__() + self.repo_id = repo_id + self.repo_type = repo_type + self.save_dir = Path(save_dir) + + def on_train_end(self, trainer, pl_module): + upload_to_hub(self.save_dir.as_posix(), self.repo_id, self.repo_type) From 2617e5831dacd908db0d2b0dc86e6c8997b291ef Mon Sep 17 00:00:00 2001 From: jiito Date: Mon, 13 Oct 2025 08:04:11 -0700 Subject: [PATCH 21/99] debug config --- config/debug.yaml | 148 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 config/debug.yaml diff --git a/config/debug.yaml b/config/debug.yaml new file mode 100644 index 0000000..ee5083b --- /dev/null +++ b/config/debug.yaml @@ -0,0 +1,148 @@ +# Debug configuration for CrossLayer Transcoder training +# This file uses Lightning CLI's automatic class construction + +seed_everything: 42 + +trainer: + max_steps: 20 + val_check_interval: 2 + limit_val_batches: 1 + enable_checkpointing: false # We use custom end-of-training checkpoint + num_sanity_val_steps: 0 # Can't run replacement model before standardizers are initialized + precision: "16-mixed" + accelerator: "gpu" + devices: [0] # [0] means cuda:0 + accumulate_grad_batches: 1 + logger: # WandB logger is recommended but other loggers are supported as well + class_path: lightning.pytorch.loggers.WandbLogger + init_args: + project: "clt" + name: "debug-jumprelu" + save_dir: "./wandb" + callbacks: + - class_path: crosslayer_transcoder.utils.callbacks.EndOfTrainingCheckpointCallback + init_args: + checkpoint_dir: "checkpoints_debug" + +model: + class_path: crosslayer_transcoder.model.clt_lightning.JumpReLUCrossLayerTranscoderModule + init_args: + model: + class_path: crosslayer_transcoder.model.clt.CrossLayerTranscoder + init_args: + encoder: + class_path: crosslayer_transcoder.model.clt.Encoder + init_args: + d_acts: 16 + d_features: 48 + n_layers: 2 + + decoder: + class_path: crosslayer_transcoder.model.clt.CrosslayerDecoder + init_args: + d_acts: 16 + d_features: 48 + n_layers: 2 + + nonlinearity: + class_path: crosslayer_transcoder.model.jumprelu.JumpReLU + init_args: + theta: 0.03 + bandwidth: 0.01 + n_layers: 2 + d_features: 48 + + input_standardizer: + class_path: crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer + init_args: + n_layers: 2 + activation_dim: 16 + + output_standardizer: + class_path: crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer + init_args: + n_layers: 2 + activation_dim: 16 + + # Pre-constructed replacement model + replacement_model: + class_path: crosslayer_transcoder.metrics.replacement_model_accuracy.ReplacementModelAccuracy + init_args: + model_name: "openai-community/gpt2" + device_map: "cuda:0" # should match trainer.devices + loader_batch_size: 2 + + # Pre-constructed dead features metric + dead_features: + class_path: crosslayer_transcoder.metrics.dead_features.DeadFeatures + init_args: + n_features: 48 + n_layers: 2 + return_per_layer: true + return_log_freqs: true + return_neuron_indices: true + + + # Training parameters + learning_rate: 1e-4 + compile: true # if using torch.compile + lr_decay_step: 80_000 # lr is scaled by lr_decay_factor after this many steps + lr_decay_factor: 0.1 + + compute_dead_features: true + compute_dead_features_every: 2 + +data: + class_path: crosslayer_transcoder.data.datamodule.ActivationDataModule + init_args: + buffer_size: 200 + n_in_out: 2 + n_layers: 2 + activation_dim: 16 + dtype: "float16" + max_batch_size: 50 + + model_name: "openai-community/gpt2" + model_dtype: "float32" + + # Dataset settings + dataset_name: "Skylion007/openwebtext" + dataset_split: "train" + max_sequence_length: 128 + + generation_batch_size: 2 + refresh_interval: 0.05 + + shared_memory_name: "activation_buffer_debug" + timeout_seconds: 10 + + init_file: null + + batch_size: 8 + num_workers: 0 + prefetch_factor: 2 + shuffle: true + persistent_workers: false + pin_memory: false + + minimum_fill_threshold: 0.1 + use_shared_memory: false + + use_shared_memory: true + + # Device configuration + device_map: "cuda:0" # "cpu", "auto", "cuda:0", "cuda:0,1,2,3" + deployment_policy: "gpu_only" # "cpu_only", "gpu_only", or "dynamic" + # dynamic will use CPU and only GPU if the buffer is almost empty to refill fast. Use this if you use a single GPU and have a beefy CPU. + + # WandB logging configuration for data generation + wandb_logging: + enabled: false + project: "clt" + group: null + run_name: "data-generator-debug-jumprelu" + tags: ["data-generation", "debug"] + save_dir: "./wandb" + log_interval: 5.0 + +ckpt_path: null \ No newline at end of file From f03aab0d3c0f3aca24e78658f6fcba0d81d2d919 Mon Sep 17 00:00:00 2001 From: jiito Date: Mon, 13 Oct 2025 08:20:51 -0700 Subject: [PATCH 22/99] refactor: change to abc converters --- .../utils/convert_to_circuit_tracer.py | 110 ------------------ .../utils/converters/circuit_tracer.py | 80 +++++++++++++ .../utils/model_converter.py | 27 +++++ 3 files changed, 107 insertions(+), 110 deletions(-) delete mode 100644 crosslayer_transcoder/utils/convert_to_circuit_tracer.py create mode 100644 crosslayer_transcoder/utils/converters/circuit_tracer.py create mode 100644 crosslayer_transcoder/utils/model_converter.py diff --git a/crosslayer_transcoder/utils/convert_to_circuit_tracer.py b/crosslayer_transcoder/utils/convert_to_circuit_tracer.py deleted file mode 100644 index e186432..0000000 --- a/crosslayer_transcoder/utils/convert_to_circuit_tracer.py +++ /dev/null @@ -1,110 +0,0 @@ -# simple file to convert the lightning model to a circuit-tracer model -import logging -from pathlib import Path -from typing import List, Union - -import torch -import yaml -from safetensors.torch import save_file - -from crosslayer_transcoder.model.clt import ( - CrosslayerDecoder, -) -from crosslayer_transcoder.model.clt_lightning import ( - CrossLayerTranscoderModule, - JumpReLUCrossLayerTranscoderModule, - TopKCrossLayerTranscoderModule, -) - -logger = logging.getLogger(__name__) - -CLTModule = Union[ - CrossLayerTranscoderModule, - JumpReLUCrossLayerTranscoderModule, - TopKCrossLayerTranscoderModule, -] - - -def add_decoder_bias(d: List[dict], decoder: CrosslayerDecoder): - for i in range(decoder.n_layers): - d[i][f"b_dec_{i}"] = ( - decoder.b[i].cpu() if hasattr(decoder, "b") else torch.zeros(decoder.d_acts) - ) - return d - - -def save_decoder_dict(decoder_dict: dict, path: str): - for key, value in decoder_dict.items(): - save_file({key: value}, f"{path}/{key}.safetensors") - - -def convert_model_to_circuit_tracer( - lightning_module: CLTModule, - save_dir: str, - # TODO: check the hooks - feature_input_hook: str = "blocks.{layer}.hook_resid_pre", - feature_output_hook: str = "blocks.{layer}.hook_mlp_out", -): - # convert the lightning model to the circuit-tracer compatible shape - save_path = Path(save_dir) - save_path.mkdir(parents=True, exist_ok=True) - - encoder = lightning_module.model.encoder - decoder = lightning_module.model.decoder - nonlinearity = lightning_module.model.nonlinearity - n_layers = encoder.n_layers - d_acts = encoder.d_acts # -> d_model - d_features = encoder.d_features # -> d_transcoder - - for source_layer in range(encoder.n_layers): - # encoder - layer_encoder_dict = { - f"W_enc_{source_layer}": encoder.W[source_layer] - .T.contiguous() - .cpu(), # Transpose! - f"b_enc_{source_layer}": ( - encoder.b[source_layer].cpu() - if hasattr(encoder, "b") - else torch.zeros(encoder.d_features) - ), - f"b_dec_{source_layer}": ( - decoder.b[source_layer].cpu() - if hasattr(decoder, "b") - else torch.zeros(d_acts) - ), - f"threshold_{source_layer}": ( - nonlinearity.theta.cpu() - if hasattr(nonlinearity, "theta") - else torch.zeros(d_features) - ), - } - - # TODO: check names - save_file(layer_encoder_dict, f"{save_path}/W_enc_{source_layer}.safetensors") - - # decoder - output_dec_i = torch.zeros([d_features, n_layers - source_layer, d_acts]) - - for k in range(source_layer, n_layers): - # get decoder mat for layer i --> k - decoder_w_k = decoder.get_parameter(f"W_{k}") - dec_i_k = decoder_w_k[source_layer, ...] - assert dec_i_k.shape == ( - d_features, - d_acts, - ) - output_dec_i[:, k - source_layer, ...] = dec_i_k.cpu() - - decoder_dict = {f"W_dec_{source_layer}": output_dec_i} - - save_file(decoder_dict, f"{save_path}/W_dec_{source_layer}.safetensors") - - # Create config - config = { - "model_kind": "cross_layer_transcoder", - "feature_input_hook": feature_input_hook, - "feature_output_hook": feature_output_hook, - } - - with open(save_path / "config.yaml", "w") as f: - yaml.dump(config, f, default_flow_style=False) diff --git a/crosslayer_transcoder/utils/converters/circuit_tracer.py b/crosslayer_transcoder/utils/converters/circuit_tracer.py new file mode 100644 index 0000000..4069f96 --- /dev/null +++ b/crosslayer_transcoder/utils/converters/circuit_tracer.py @@ -0,0 +1,80 @@ +from crosslayer_transcoder.utils.model_converter import CLTModule, ModelConverter +import torch +import yaml +from safetensors.torch import save_file + + +class CircuitTracerConverter(ModelConverter): + def __init__( + self, + save_dir: str, + feature_input_hook: str = "blocks.{layer}.hook_resid_pre", + feature_output_hook: str = "blocks.{layer}.hook_mlp_out", + ): + self.save_dir = save_dir + self.feature_input_hook = feature_input_hook + self.feature_output_hook = feature_output_hook + + self.save_dir.mkdir(parents=True, exist_ok=True) + + def convert(self, model: CLTModule) -> CLTModule: + encoder = model.model.encoder + decoder = model.model.decoder + nonlinearity = model.model.nonlinearity + n_layers = encoder.n_layers + d_acts = encoder.d_acts # -> d_model + d_features = encoder.d_features # -> d_transcoder + + for source_layer in range(encoder.n_layers): + # encoder + layer_encoder_dict = { + f"W_enc_{source_layer}": encoder.W[source_layer] + .T.contiguous() + .cpu(), # Transpose! + f"b_enc_{source_layer}": ( + encoder.b[source_layer].cpu() + if hasattr(encoder, "b") + else torch.zeros(encoder.d_features) + ), + f"b_dec_{source_layer}": ( + decoder.b[source_layer].cpu() + if hasattr(decoder, "b") + else torch.zeros(d_acts) + ), + f"threshold_{source_layer}": ( + nonlinearity.theta.cpu() + if hasattr(nonlinearity, "theta") + else torch.zeros(d_features) + ), + } + # TODO: check names + save_file( + layer_encoder_dict, f"{self.save_dir}/W_enc_{source_layer}.safetensors" + ) + + # decoder + output_dec_i = torch.zeros([d_features, n_layers - source_layer, d_acts]) + + for k in range(source_layer, n_layers): + # get decoder mat for layer i --> k + decoder_w_k = decoder.get_parameter(f"W_{k}") + dec_i_k = decoder_w_k[source_layer, ...] + assert dec_i_k.shape == ( + d_features, + d_acts, + ) + output_dec_i[:, k - source_layer, ...] = dec_i_k.cpu() + + decoder_dict = {f"W_dec_{source_layer}": output_dec_i} + + save_file(decoder_dict, f"{self.save_dir}/W_dec_{source_layer}.safetensors") + + # Create config + config = { + "model_kind": "cross_layer_transcoder", + "feature_input_hook": self.feature_input_hook, + "feature_output_hook": self.feature_output_hook, + } + + with open(self.save_dir / "config.yaml", "w") as f: + yaml.dump(config, f, default_flow_style=False) diff --git a/crosslayer_transcoder/utils/model_converter.py b/crosslayer_transcoder/utils/model_converter.py new file mode 100644 index 0000000..3cd2bb6 --- /dev/null +++ b/crosslayer_transcoder/utils/model_converter.py @@ -0,0 +1,27 @@ +from abc import ABC, abstractmethod +from typing import Union + +import lightning as L + +from crosslayer_transcoder.model.clt_lightning import ( + CrossLayerTranscoderModule, + JumpReLUCrossLayerTranscoderModule, + TopKCrossLayerTranscoderModule, +) + +CLTModule = Union[ + CrossLayerTranscoderModule, + JumpReLUCrossLayerTranscoderModule, + TopKCrossLayerTranscoderModule, +] + + +class ModelConverter(ABC): + def __init__( + self, + ): + pass + + @abstractmethod + def convert(self, model: CLTModule) -> CLTModule: + pass From af7fa38bc0dcb48f82fcffa9f2475aaf7b9081df Mon Sep 17 00:00:00 2001 From: jiito Date: Mon, 13 Oct 2025 08:22:39 -0700 Subject: [PATCH 23/99] update test --- tests/test_convert_to_circuit_tracer.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/tests/test_convert_to_circuit_tracer.py b/tests/test_convert_to_circuit_tracer.py index 0055733..0cfa1ef 100644 --- a/tests/test_convert_to_circuit_tracer.py +++ b/tests/test_convert_to_circuit_tracer.py @@ -1,9 +1,7 @@ -from crosslayer_transcoder.utils.convert_to_circuit_tracer import ( - convert_model_to_circuit_tracer, -) +from crosslayer_transcoder.utils.converters.circuit_tracer import CircuitTracerConverter -def test_convert_to_circuit_tracer(): +def test_circuit_tracer_converter(): from crosslayer_transcoder.metrics.dead_features import DeadFeatures from crosslayer_transcoder.model.clt import ( CrosslayerDecoder, @@ -38,10 +36,6 @@ def test_convert_to_circuit_tracer(): output_standardizer=output_standardizer, ) - # replacement_model = ReplacementModelAccuracy( - # model_name="openai-community/gpt2", device_map="mps", loader_batch_size=2 - # ) - dead_features = DeadFeatures( n_features=10_000, n_layers=12, @@ -52,7 +46,6 @@ def test_convert_to_circuit_tracer(): clt_module = CrossLayerTranscoderModule( model=model, - # replacement_model=replacement_model, dead_features=dead_features, learning_rate=1e-4, compile=True, @@ -62,8 +55,13 @@ def test_convert_to_circuit_tracer(): compute_dead_features_every=500, ) - convert_model_to_circuit_tracer(clt_module, "clt_module") + # Use the new CircuitTracerConverter directly + import pathlib + + save_dir = pathlib.Path("clt_module") + converter = CircuitTracerConverter(save_dir=save_dir) + converter.convert(clt_module) if __name__ == "__main__": - test_convert_to_circuit_tracer() + test_circuit_tracer_converter() From a0feda06bd3c183e8415da5254480c72ff618d72 Mon Sep 17 00:00:00 2001 From: jiito Date: Mon, 13 Oct 2025 14:21:53 -0700 Subject: [PATCH 24/99] feat: first pass at standardization folding --- crosslayer_transcoder/model/clt_lightning.py | 88 ++++++++++++++----- crosslayer_transcoder/model/standardize.py | 2 +- .../circuit_tracer.py | 30 +++++-- 3 files changed, 93 insertions(+), 27 deletions(-) rename crosslayer_transcoder/utils/{converters => model_converters}/circuit_tracer.py (72%) diff --git a/crosslayer_transcoder/model/clt_lightning.py b/crosslayer_transcoder/model/clt_lightning.py index b95fb44..39a874a 100644 --- a/crosslayer_transcoder/model/clt_lightning.py +++ b/crosslayer_transcoder/model/clt_lightning.py @@ -14,8 +14,14 @@ import wandb from crosslayer_transcoder.metrics.dead_features import DeadFeatures -from crosslayer_transcoder.metrics.replacement_model_accuracy import ReplacementModelAccuracy -from crosslayer_transcoder.model.clt import CrosslayerDecoder, CrossLayerTranscoder, Decoder +from crosslayer_transcoder.metrics.replacement_model_accuracy import ( + ReplacementModelAccuracy, +) +from crosslayer_transcoder.model.clt import ( + CrosslayerDecoder, + CrossLayerTranscoder, + Decoder, +) from crosslayer_transcoder.model.jumprelu import JumpReLU from crosslayer_transcoder.model.topk import BatchTopK @@ -49,7 +55,9 @@ def __init__( ): super().__init__(*args, **kwargs) - self.save_hyperparameters(ignore=["model", "replacement_model", "dead_features"]) + self.save_hyperparameters( + ignore=["model", "replacement_model", "dead_features"] + ) # torch.cuda.memory._record_memory_history(max_entries=100_000) # Store pre-constructed modules @@ -77,13 +85,16 @@ def __init__( self.beta2 = beta2 self.log_metrics_every = log_metrics_every - assert ( - self.model.encoder.n_layers == self.model.decoder.n_layers - ), "Encoder and decoder must have the same number of layers" + assert self.model.encoder.n_layers == self.model.decoder.n_layers, ( + "Encoder and decoder must have the same number of layers" + ) self.register_buffer( "last_active", - torch.zeros((self.model.encoder.n_layers, self.model.encoder.d_features), dtype=torch.long), + torch.zeros( + (self.model.encoder.n_layers, self.model.encoder.d_features), + dtype=torch.long, + ), ) def configure_model(self): @@ -107,7 +118,9 @@ def configure_model(self): } parallelize_module(self, tp_mesh, plan) - def forward(self, acts_norm: Float[torch.Tensor, "batch_size n_layers d_acts"]) -> Tuple[ + def forward( + self, acts_norm: Float[torch.Tensor, "batch_size n_layers d_acts"] + ) -> Tuple[ Float[torch.Tensor, "batch_size n_layers d_features"], # pre_actvs Float[torch.Tensor, "batch_size n_layers d_features"], # features Float[torch.Tensor, "batch_size n_layers d_acts"], # recons_norm @@ -130,13 +143,18 @@ def log_training_metrics(self, features, recons_norm, recons, mlp_out, batch_idx ss_err = (mlp_out_norm - recons_norm) ** 2 ss_err = ss_err.sum(dim=0) - ss_total = ((mlp_out_norm - mlp_out_norm.mean(dim=0, keepdim=True)) ** 2).sum(dim=0) + ss_total = ((mlp_out_norm - mlp_out_norm.mean(dim=0, keepdim=True)) ** 2).sum( + dim=0 + ) fvu = (ss_err / ss_total).mean() # (n_layers, d_model) self.log("metrics/fraction_of_variance_unexplained", fvu) fvu_per_layer = (ss_err / ss_total).mean(dim=-1) assert fvu_per_layer.shape == (self.model.encoder.n_layers,) for layer in range(self.model.encoder.n_layers): - self.log(f"layers/fraction_of_variance_unexplained/layer_{layer}", fvu_per_layer[layer]) + self.log( + f"layers/fraction_of_variance_unexplained/layer_{layer}", + fvu_per_layer[layer], + ) # number of tokens seen if not hasattr(self, "tokens_seen"): @@ -171,7 +189,8 @@ def log_training_metrics(self, features, recons_norm, recons, mlp_out, batch_idx self.log("metrics/recons_standardized_std", recons_norm.std()) self.log( "metrics/L0_avg_per_layer", - torch.count_nonzero(active_features) / (features.shape[0] * features.shape[1]), + torch.count_nonzero(active_features) + / (features.shape[0] * features.shape[1]), ) # Magnitude of feature activations - memory efficient version @@ -197,7 +216,9 @@ def log_training_metrics(self, features, recons_norm, recons, mlp_out, batch_idx # Log L0 table per layer if batch_idx % 500 == 1: - l0_per_layer = torch.count_nonzero(active_features, dim=(0, 2)) / features.shape[0] + l0_per_layer = ( + torch.count_nonzero(active_features, dim=(0, 2)) / features.shape[0] + ) if self.logger and isinstance(self.logger.experiment, wandb.wandb_run.Run): table = wandb.Table( @@ -205,7 +226,11 @@ def log_training_metrics(self, features, recons_norm, recons, mlp_out, batch_idx columns=["layer", "L0"], ) self.logger.experiment.log( - {"layers/L0_per_layer": wandb.plot.bar(table, "layer", "L0", title="L0 per Layer")}, + { + "layers/L0_per_layer": wandb.plot.bar( + table, "layer", "L0", title="L0 per Layer" + ) + }, step=self.global_step, ) @@ -234,7 +259,11 @@ def log_training_metrics(self, features, recons_norm, recons, mlp_out, batch_idx ): for layer in range(dead_log_freqs.shape[0]): self.logger.experiment.log( - {f"layers/log_feature_density/layer_{layer}": dead_log_freqs[layer]}, + { + f"layers/log_feature_density/layer_{layer}": dead_log_freqs[ + layer + ] + }, step=self.global_step, ) self.logger.experiment.log( @@ -304,11 +333,17 @@ def configure_optimizers(self): if self.optimizer == "adam": optimizer = torch.optim.Adam( - self.parameters(), lr=self.learning_rate, betas=(self.beta1, self.beta2), fused=True + self.parameters(), + lr=self.learning_rate, + betas=(self.beta1, self.beta2), + fused=True, ) elif self.optimizer == "adamw": optimizer = torch.optim.AdamW( - self.parameters(), lr=self.learning_rate, betas=(self.beta1, self.beta2), fused=True + self.parameters(), + lr=self.learning_rate, + betas=(self.beta1, self.beta2), + fused=True, ) else: raise ValueError(f"Optimizer {self.optimizer} not supported") @@ -398,7 +433,9 @@ def training_step(self, batch, batch_idx): if isinstance(self.model.decoder, CrosslayerDecoder): dec_norms = torch.zeros_like(features[:1]) for l in range(self.model.decoder.n_layers): - W = self.model.decoder.get_parameter(f"W_{l}") # (from_layer, d_features, d_acts) + W = self.model.decoder.get_parameter( + f"W_{l}" + ) # (from_layer, d_features, d_acts) dec_norms[:, : l + 1] = dec_norms[:, : l + 1] + (W**2).sum(dim=-1) dec_norms = dec_norms.sqrt() @@ -406,11 +443,17 @@ def training_step(self, batch, batch_idx): dec_norms = torch.sqrt((self.model.decoder.W**2).sum(dim=-1)) weighted_features = features * dec_norms * self.c - self.log("model/weighted_features_mean", weighted_features.detach().mean().cpu()) + self.log( + "model/weighted_features_mean", weighted_features.detach().mean().cpu() + ) if self.use_tanh: - weighted_features = torch.tanh(weighted_features) # (batch_size, n_layers, d_features) - sparsity = self.current_sparsity_penalty() * weighted_features.sum(dim=[1, 2]).mean() + weighted_features = torch.tanh( + weighted_features + ) # (batch_size, n_layers, d_features) + sparsity = ( + self.current_sparsity_penalty() * weighted_features.sum(dim=[1, 2]).mean() + ) self.log("training/sparsity_loss", sparsity) # Compute Pre-activation Loss @@ -462,7 +505,10 @@ def __init__( self.aux_loss_scale = aux_loss_scale self.register_buffer( "last_active", - torch.zeros((self.model.encoder.n_layers, self.model.encoder.d_features), dtype=torch.long), + torch.zeros( + (self.model.encoder.n_layers, self.model.encoder.d_features), + dtype=torch.long, + ), ) def training_step(self, batch, batch_idx): diff --git a/crosslayer_transcoder/model/standardize.py b/crosslayer_transcoder/model/standardize.py index 45b1b63..571a031 100644 --- a/crosslayer_transcoder/model/standardize.py +++ b/crosslayer_transcoder/model/standardize.py @@ -35,7 +35,7 @@ def __init__(self, n_layers, activation_dim): def initialize_from_batch( self, batch: Float[torch.Tensor, "batch_size io n_layers actv_dim"] ): - batch = batch[:, 0] + batch = batch[:, 0] # input self.mean.data = batch.mean(dim=0) self.std.data = batch.std(dim=0) self.std.data.clamp_(min=1e-8) diff --git a/crosslayer_transcoder/utils/converters/circuit_tracer.py b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py similarity index 72% rename from crosslayer_transcoder/utils/converters/circuit_tracer.py rename to crosslayer_transcoder/utils/model_converters/circuit_tracer.py index 4069f96..60a1987 100644 --- a/crosslayer_transcoder/utils/converters/circuit_tracer.py +++ b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py @@ -1,3 +1,4 @@ +from einops import einsum from crosslayer_transcoder.utils.model_converter import CLTModule, ModelConverter import torch import yaml @@ -19,25 +20,40 @@ def __init__( def convert(self, model: CLTModule) -> CLTModule: encoder = model.model.encoder + input_standardizer = model.model.input_standardizer + output_standardizer = model.model.output_standardizer decoder = model.model.decoder nonlinearity = model.model.nonlinearity n_layers = encoder.n_layers d_acts = encoder.d_acts # -> d_model d_features = encoder.d_features # -> d_transcoder + # fold in the input standardization + W_enc_folded = encoder.W / input_standardizer.std + b_enc_folded = encoder.b - ( + einsum( + input_standardizer.mean, + W_enc_folded, + "n_layers actv_dim, n_layers actv_dim d_features -> n_layers d_features", + ) + ) + + # TODO: check/assert shapes + b_dec_folded = decoder.b * output_standardizer.std + output_standardizer.mean + + # encoder for source_layer in range(encoder.n_layers): - # encoder layer_encoder_dict = { - f"W_enc_{source_layer}": encoder.W[source_layer] + f"W_enc_{source_layer}": W_enc_folded[source_layer] .T.contiguous() .cpu(), # Transpose! f"b_enc_{source_layer}": ( - encoder.b[source_layer].cpu() + b_enc_folded[source_layer].cpu() if hasattr(encoder, "b") else torch.zeros(encoder.d_features) ), f"b_dec_{source_layer}": ( - decoder.b[source_layer].cpu() + b_dec_folded[source_layer].cpu() if hasattr(decoder, "b") else torch.zeros(d_acts) ), @@ -57,14 +73,18 @@ def convert(self, model: CLTModule) -> CLTModule: for k in range(source_layer, n_layers): # get decoder mat for layer i --> k + decoder_w_k = decoder.get_parameter(f"W_{k}") - dec_i_k = decoder_w_k[source_layer, ...] + # TODO: check shapes + decoder_w_k_folded = decoder_w_k * output_standardizer.std + dec_i_k = decoder_w_k_folded[source_layer, ...] assert dec_i_k.shape == ( d_features, d_acts, ) output_dec_i[:, k - source_layer, ...] = dec_i_k.cpu() + # TODO: fold in the output standardization decoder_dict = {f"W_dec_{source_layer}": output_dec_i} save_file(decoder_dict, f"{self.save_dir}/W_dec_{source_layer}.safetensors") From 12ab5c8ed68160d282308e83997e7164cd4bea65 Mon Sep 17 00:00:00 2001 From: jiito Date: Tue, 14 Oct 2025 09:16:12 -0700 Subject: [PATCH 25/99] debug+circuit-tracer config --- config/debug_circuit-tracer.yaml | 169 +++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 config/debug_circuit-tracer.yaml diff --git a/config/debug_circuit-tracer.yaml b/config/debug_circuit-tracer.yaml new file mode 100644 index 0000000..daf6c48 --- /dev/null +++ b/config/debug_circuit-tracer.yaml @@ -0,0 +1,169 @@ +# Debug configuration for CrossLayer Transcoder training with compatibility for `circuit-tracer` + +seed_everything: 42 + +trainer: + # max_steps is number of gradient updates. If using gradient accumulation, this is not the number of batches. + max_steps: 20 + val_check_interval: 2 + limit_val_batches: 1 + enable_checkpointing: false # We use custom end-of-training checkpoint + num_sanity_val_steps: 0 # Can't run replacement model before standardizers are initialized + precision: "16-mixed" + accelerator: "gpu" + devices: [0] # [0] means cuda:0 + accumulate_grad_batches: 1 + logger: # WandB logger is recommended but other loggers are supported as well + class_path: lightning.pytorch.loggers.WandbLogger + init_args: + project: "clt" + name: "jumprelu" + save_dir: "./wandb" + callbacks: + - class_path: crosslayer_transcoder.utils.callbacks.EndOfTrainingCheckpointCallback + init_args: + checkpoint_dir: "checkpoints" + - class_path: crosslayer_transcoder.utils.callbacks.CircuitTracerCallback + init_args: + save_dir: "/experiments/checkpoints" + - class_path: crosslayer_transcoder.utils.callbacks.HuggingFaceCallback + init_args: + repo_id: "jiito/clt_test_gpt2_zero" + repo_type: "model" + save_dir: "/experiments/checkpoints" + +model: + class_path: crosslayer_transcoder.model.clt_lightning.JumpReLUCrossLayerTranscoderModule + init_args: + model: + class_path: crosslayer_transcoder.model.clt.CrossLayerTranscoder + init_args: + encoder: + class_path: crosslayer_transcoder.model.clt.Encoder + init_args: + d_acts: 768 + d_features: 48 + n_layers: 2 + + decoder: + class_path: crosslayer_transcoder.model.clt.CrosslayerDecoder + init_args: + d_acts: 768 + d_features: 48 + n_layers: 2 + + nonlinearity: + class_path: crosslayer_transcoder.model.jumprelu.JumpReLU + init_args: + theta: 0.03 + bandwidth: 0.01 + n_layers: 2 + d_features: 48 + + input_standardizer: + class_path: crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer + init_args: + n_layers: 2 + activation_dim: 768 + + output_standardizer: + class_path: crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer + init_args: + n_layers: 2 + activation_dim: 768 + + # Pre-constructed replacement model + replacement_model: + class_path: crosslayer_transcoder.metrics.replacement_model_accuracy.ReplacementModelAccuracy + init_args: + model_name: "openai-community/gpt2" + device_map: "cuda:0" # should match trainer.devices + loader_batch_size: 2 + + # Pre-constructed dead features metric + dead_features: + class_path: crosslayer_transcoder.metrics.dead_features.DeadFeatures + init_args: + n_features: 48 + n_layers: 2 + return_per_layer: true + return_log_freqs: true + return_neuron_indices: true + + + # Training parameters + learning_rate: 1e-4 + compile: true # if using torch.compile + lr_decay_step: 80_000 # lr is scaled by lr_decay_factor after this many steps + lr_decay_factor: 0.1 + + lambda_sparsity: 0.0007 # sparsity loss weight + c_sparsity: 1 # sparsity loss coefficient + use_tanh: true # use tanh nonlinearity in the JumpReLU + pre_actv_loss: 1e-6 # pre-activation loss weight + + # Dead features computation settings + compute_dead_features: true + compute_dead_features_every: 2 + +data: + class_path: crosslayer_transcoder.data.datamodule.ActivationDataModule + init_args: + # Buffer settings + buffer_size: 200 # number of activations to store in the buffer + n_in_out: 2 # number of input and output layers + n_layers: 2 # number of layers in the model + activation_dim: 768 # dimension of the activations + dtype: "float16" # dtype of the activations + max_batch_size: 50 # maximum batch size for the data loader + + # Model settings for activation generation + model_name: "openai-community/gpt2" + model_dtype: "float32" + + # Dataset settings + dataset_name: "roneneldan/TinyStories" + dataset_split: "train" + max_sequence_length: 128 + + # Generation settings + generation_batch_size: 2 + refresh_interval: 0.05 # time (s) between shell logs updates + + # Memory settings + shared_memory_name: "activation_buffer_debug" + timeout_seconds: 10 + + # File paths + init_file: null # path to file with shuffled activations to initialize the buffer fast + # if null, activations are generated and training starts when the buffer is at least minimum_fill_threshold full + + # DataLoader settings + batch_size: 8 + num_workers: 0 + prefetch_factor: 2 + shuffle: true + persistent_workers: false + pin_memory: false + + minimum_fill_threshold: 0.1 # Only provide activations when buffer is at least 10% full + # to maintain sufficient shuffling + + use_shared_memory: true + + # Device configuration + device_map: "cuda:0" # "cpu", "auto", "cuda:0", "cuda:0,1,2,3" + deployment_policy: "gpu_only" # "cpu_only", "gpu_only", or "dynamic" + # dynamic will use CPU and only GPU if the buffer is almost empty to refill fast. Use this if you use a single GPU and have a beefy CPU. + + # WandB logging configuration for data generation + wandb_logging: + enabled: false # Enable WandB logging for data generation + project: "clt" # WandB project (should match trainer logger) + group: null # Group name (null = auto-generated from training run) + run_name: "data-generator-debug-jumprelu" # Run name suffix + tags: ["data-generation", "debug"] # Tags for the data generation run + save_dir: "./wandb" # Directory for WandB files + log_interval: 5.0 # Logging interval in seconds + +ckpt_path: null \ No newline at end of file From 8fc62841e3281305b3357c8d1d3977a95bc5e97d Mon Sep 17 00:00:00 2001 From: jiito Date: Tue, 14 Oct 2025 09:32:33 -0700 Subject: [PATCH 26/99] fix: shapes of standardization --- crosslayer_transcoder/utils/callbacks.py | 11 ++++-- .../utils/model_converters/circuit_tracer.py | 39 ++++++++++++------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/crosslayer_transcoder/utils/callbacks.py b/crosslayer_transcoder/utils/callbacks.py index d850d1f..79d9261 100644 --- a/crosslayer_transcoder/utils/callbacks.py +++ b/crosslayer_transcoder/utils/callbacks.py @@ -13,10 +13,10 @@ tensorboard_trace_handler, ) -from crosslayer_transcoder.utils.convert_to_circuit_tracer import ( - convert_model_to_circuit_tracer, -) from crosslayer_transcoder.utils.hf import upload_to_hub +from crosslayer_transcoder.utils.model_converters.circuit_tracer import ( + CircuitTracerConverter, +) logger = logging.getLogger(__name__) @@ -69,7 +69,10 @@ def __init__(self, save_dir: str = "clt_module"): self.save_dir = Path(save_dir) def _convert_model(self, pl_module): - convert_model_to_circuit_tracer(pl_module, self.save_dir.as_posix()) + circuit_tracer_converter = CircuitTracerConverter( + save_dir=self.save_dir.as_posix() + ) + circuit_tracer_converter.convert(pl_module) logger.info(f"Circuit-tracer model saved to {self.save_dir.as_posix()}") def on_train_start(self, trainer, pl_module): diff --git a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py index 60a1987..6dcfa34 100644 --- a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py +++ b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py @@ -3,6 +3,7 @@ import torch import yaml from safetensors.torch import save_file +from pathlib import Path class CircuitTracerConverter(ModelConverter): @@ -12,7 +13,7 @@ def __init__( feature_input_hook: str = "blocks.{layer}.hook_resid_pre", feature_output_hook: str = "blocks.{layer}.hook_mlp_out", ): - self.save_dir = save_dir + self.save_dir = Path(save_dir) self.feature_input_hook = feature_input_hook self.feature_output_hook = feature_output_hook @@ -29,17 +30,25 @@ def convert(self, model: CLTModule) -> CLTModule: d_features = encoder.d_features # -> d_transcoder # fold in the input standardization - W_enc_folded = encoder.W / input_standardizer.std - b_enc_folded = encoder.b - ( - einsum( - input_standardizer.mean, - W_enc_folded, - "n_layers actv_dim, n_layers actv_dim d_features -> n_layers d_features", + assert encoder.W.shape == (n_layers, d_acts, d_features) + assert input_standardizer.std.shape == (n_layers, d_acts) + W_enc_folded = encoder.W.float() / input_standardizer.std.unsqueeze(-1) + + # TODO: check if bias is present + if hasattr(encoder, "b"): + b_enc_folded = encoder.b - ( + einsum( + input_standardizer.mean.float(), + W_enc_folded.float(), + "n_layers actv_dim, n_layers actv_dim d_features -> n_layers d_features", + ) ) - ) # TODO: check/assert shapes - b_dec_folded = decoder.b * output_standardizer.std + output_standardizer.mean + b_dec_folded = ( + decoder.b.float() * output_standardizer.std.float() + + output_standardizer.mean.float() + ) # encoder for source_layer in range(encoder.n_layers): @@ -73,10 +82,15 @@ def convert(self, model: CLTModule) -> CLTModule: for k in range(source_layer, n_layers): # get decoder mat for layer i --> k - decoder_w_k = decoder.get_parameter(f"W_{k}") - # TODO: check shapes - decoder_w_k_folded = decoder_w_k * output_standardizer.std + + # [n_layers, d_features, d_acts] * [n_layers, d_acts] + # NOTE: we want to multiply every feature by the activation std + assert output_standardizer.std.shape == (n_layers, d_acts) + assert decoder_w_k.shape == (n_layers, d_features, d_acts) + decoder_w_k_folded = ( + decoder_w_k.float() * output_standardizer.std.unsqueeze(1).float() + ) dec_i_k = decoder_w_k_folded[source_layer, ...] assert dec_i_k.shape == ( d_features, @@ -84,7 +98,6 @@ def convert(self, model: CLTModule) -> CLTModule: ) output_dec_i[:, k - source_layer, ...] = dec_i_k.cpu() - # TODO: fold in the output standardization decoder_dict = {f"W_dec_{source_layer}": output_dec_i} save_file(decoder_dict, f"{self.save_dir}/W_dec_{source_layer}.safetensors") From c64955f1c719641e7fb477dbd70b10e61ccafc6b Mon Sep 17 00:00:00 2001 From: jiito Date: Wed, 15 Oct 2025 06:38:12 -0700 Subject: [PATCH 27/99] update config --- config/debug_circuit-tracer.yaml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/config/debug_circuit-tracer.yaml b/config/debug_circuit-tracer.yaml index daf6c48..b6c61ab 100644 --- a/config/debug_circuit-tracer.yaml +++ b/config/debug_circuit-tracer.yaml @@ -4,7 +4,7 @@ seed_everything: 42 trainer: # max_steps is number of gradient updates. If using gradient accumulation, this is not the number of batches. - max_steps: 20 + max_steps: 2 val_check_interval: 2 limit_val_batches: 1 enable_checkpointing: false # We use custom end-of-training checkpoint @@ -43,33 +43,33 @@ model: init_args: d_acts: 768 d_features: 48 - n_layers: 2 + n_layers: 12 decoder: class_path: crosslayer_transcoder.model.clt.CrosslayerDecoder init_args: d_acts: 768 d_features: 48 - n_layers: 2 + n_layers: 12 nonlinearity: class_path: crosslayer_transcoder.model.jumprelu.JumpReLU init_args: theta: 0.03 bandwidth: 0.01 - n_layers: 2 + n_layers: 12 d_features: 48 input_standardizer: class_path: crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer init_args: - n_layers: 2 + n_layers: 12 activation_dim: 768 output_standardizer: class_path: crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer init_args: - n_layers: 2 + n_layers: 12 activation_dim: 768 # Pre-constructed replacement model @@ -85,7 +85,7 @@ model: class_path: crosslayer_transcoder.metrics.dead_features.DeadFeatures init_args: n_features: 48 - n_layers: 2 + n_layers: 12 return_per_layer: true return_log_freqs: true return_neuron_indices: true @@ -93,7 +93,7 @@ model: # Training parameters learning_rate: 1e-4 - compile: true # if using torch.compile + compile: false # if using torch.compile lr_decay_step: 80_000 # lr is scaled by lr_decay_factor after this many steps lr_decay_factor: 0.1 @@ -110,9 +110,9 @@ data: class_path: crosslayer_transcoder.data.datamodule.ActivationDataModule init_args: # Buffer settings - buffer_size: 200 # number of activations to store in the buffer + buffer_size: 10 # number of activations to store in the buffer n_in_out: 2 # number of input and output layers - n_layers: 2 # number of layers in the model + n_layers: 12 # number of layers in the model activation_dim: 768 # dimension of the activations dtype: "float16" # dtype of the activations max_batch_size: 50 # maximum batch size for the data loader @@ -124,7 +124,7 @@ data: # Dataset settings dataset_name: "roneneldan/TinyStories" dataset_split: "train" - max_sequence_length: 128 + max_sequence_length: 2048 # Generation settings generation_batch_size: 2 @@ -152,8 +152,8 @@ data: use_shared_memory: true # Device configuration - device_map: "cuda:0" # "cpu", "auto", "cuda:0", "cuda:0,1,2,3" - deployment_policy: "gpu_only" # "cpu_only", "gpu_only", or "dynamic" + device_map: "auto" # "cpu", "auto", "cuda:0", "cuda:0,1,2,3" + deployment_policy: "dynamic" # "cpu_only", "gpu_only", or "dynamic" # dynamic will use CPU and only GPU if the buffer is almost empty to refill fast. Use this if you use a single GPU and have a beefy CPU. # WandB logging configuration for data generation From 890a60c2d3be1afe3fcd3ad815648bc426d256fa Mon Sep 17 00:00:00 2001 From: jiito Date: Fri, 17 Oct 2025 10:32:05 -0700 Subject: [PATCH 28/99] initial failing test case with float --- crosslayer_transcoder/utils/model_converters/circuit_tracer.py | 1 - 1 file changed, 1 deletion(-) diff --git a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py index 6dcfa34..88226f9 100644 --- a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py +++ b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py @@ -34,7 +34,6 @@ def convert(self, model: CLTModule) -> CLTModule: assert input_standardizer.std.shape == (n_layers, d_acts) W_enc_folded = encoder.W.float() / input_standardizer.std.unsqueeze(-1) - # TODO: check if bias is present if hasattr(encoder, "b"): b_enc_folded = encoder.b - ( einsum( From 459acd701e899fe3cded4f68bfa9297ec18967fe Mon Sep 17 00:00:00 2001 From: jiito Date: Fri, 17 Oct 2025 11:45:26 -0700 Subject: [PATCH 29/99] fix: numerical stability --- tests/test_standarization_folding.py | 44 ++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/test_standarization_folding.py b/tests/test_standarization_folding.py index 8136775..01e346a 100644 --- a/tests/test_standarization_folding.py +++ b/tests/test_standarization_folding.py @@ -66,6 +66,50 @@ def test_math_sanity_check(): assert_allclose(lhs, rhs) +def test_math_sanity_check(): + batch_size, d_acts, d_feats, n_layers = 100, 768, 32, 12 + torch.manual_seed(42) + dtype = torch.float64 + batch = torch.randn((batch_size, 2, n_layers, d_acts), dtype=dtype) + encoder = Encoder(d_acts=d_acts, d_features=d_feats, n_layers=n_layers).to(dtype) + + input_std = DimensionwiseInputStandardizer( + n_layers=n_layers, activation_dim=d_acts + ).to(dtype) + input_std.initialize_from_batch(batch=batch) + + resid = batch[:, 0] + W = encoder.W + b = encoder.b + mean, std = input_std.mean, input_std.std + + W_div_std = W / std.unsqueeze(-1) + + lhs = ( + einsum( + (resid - mean) / std, + W, + "batch n_layers d_acts, n_layers d_acts d_features -> batch n_layers d_features", + ) + + b + ) + rhs = ( + einsum( + resid, + W_div_std, + "batch n_layers d_acts, n_layers d_acts d_features -> batch n_layers d_features", + ) + + b + - einsum( + mean, + W_div_std, + "n_layers d_acts, n_layers d_acts d_features -> n_layers d_features", + ) + ) + + assert torch.allclose(lhs, rhs, rtol=1e-7, atol=1e-9) + + def test_encoder_standarization_folding(): encoder = Encoder(d_acts=D_ACTS, d_features=D_FEATS, n_layers=N_LAYERS).to(DTYPE) input_std = DimensionwiseInputStandardizer( From 74a80ea3dea8358b1eed6e00e2904b3f7f6c929f Mon Sep 17 00:00:00 2001 From: jiito Date: Fri, 17 Oct 2025 12:51:05 -0700 Subject: [PATCH 30/99] add const, rm comments --- tests/test_standarization_folding.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/tests/test_standarization_folding.py b/tests/test_standarization_folding.py index 01e346a..1937b1b 100644 --- a/tests/test_standarization_folding.py +++ b/tests/test_standarization_folding.py @@ -67,18 +67,14 @@ def test_math_sanity_check(): def test_math_sanity_check(): - batch_size, d_acts, d_feats, n_layers = 100, 768, 32, 12 - torch.manual_seed(42) - dtype = torch.float64 - batch = torch.randn((batch_size, 2, n_layers, d_acts), dtype=dtype) - encoder = Encoder(d_acts=d_acts, d_features=d_feats, n_layers=n_layers).to(dtype) + encoder = Encoder(d_acts=D_ACTS, d_features=D_FEATS, n_layers=N_LAYERS).to(DTYPE) input_std = DimensionwiseInputStandardizer( - n_layers=n_layers, activation_dim=d_acts - ).to(dtype) - input_std.initialize_from_batch(batch=batch) + n_layers=N_LAYERS, activation_dim=D_ACTS + ).to(DTYPE) + input_std.initialize_from_batch(batch=BATCH) - resid = batch[:, 0] + resid = BATCH[:, 0] W = encoder.W b = encoder.b mean, std = input_std.mean, input_std.std @@ -107,7 +103,7 @@ def test_math_sanity_check(): ) ) - assert torch.allclose(lhs, rhs, rtol=1e-7, atol=1e-9) + assert_allclose(lhs, rhs) def test_encoder_standarization_folding(): From 3a76fb77a7d62c3144178353da19455e76a788b1 Mon Sep 17 00:00:00 2001 From: jiito Date: Fri, 17 Oct 2025 13:49:11 -0700 Subject: [PATCH 31/99] refactor: use standardizer method in conversion --- .../utils/model_converters/circuit_tracer.py | 32 ++++--------------- 1 file changed, 7 insertions(+), 25 deletions(-) diff --git a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py index 88226f9..e40b9e8 100644 --- a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py +++ b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py @@ -29,26 +29,12 @@ def convert(self, model: CLTModule) -> CLTModule: d_acts = encoder.d_acts # -> d_model d_features = encoder.d_features # -> d_transcoder - # fold in the input standardization - assert encoder.W.shape == (n_layers, d_acts, d_features) - assert input_standardizer.std.shape == (n_layers, d_acts) - W_enc_folded = encoder.W.float() / input_standardizer.std.unsqueeze(-1) - - if hasattr(encoder, "b"): - b_enc_folded = encoder.b - ( - einsum( - input_standardizer.mean.float(), - W_enc_folded.float(), - "n_layers actv_dim, n_layers actv_dim d_features -> n_layers d_features", - ) - ) - - # TODO: check/assert shapes - b_dec_folded = ( - decoder.b.float() * output_standardizer.std.float() - + output_standardizer.mean.float() + W_enc_folded, b_enc_folded = input_standardizer.fold_in_encoder( + encoder.W.float(), encoder.b.float() ) + b_dec_folded = output_standardizer.fold_in_decoder_bias(decoder.b.float()) + # encoder for source_layer in range(encoder.n_layers): layer_encoder_dict = { @@ -71,7 +57,6 @@ def convert(self, model: CLTModule) -> CLTModule: else torch.zeros(d_features) ), } - # TODO: check names save_file( layer_encoder_dict, f"{self.save_dir}/W_enc_{source_layer}.safetensors" ) @@ -83,12 +68,9 @@ def convert(self, model: CLTModule) -> CLTModule: # get decoder mat for layer i --> k decoder_w_k = decoder.get_parameter(f"W_{k}") - # [n_layers, d_features, d_acts] * [n_layers, d_acts] - # NOTE: we want to multiply every feature by the activation std - assert output_standardizer.std.shape == (n_layers, d_acts) - assert decoder_w_k.shape == (n_layers, d_features, d_acts) - decoder_w_k_folded = ( - decoder_w_k.float() * output_standardizer.std.unsqueeze(1).float() + # fold in output standardization for decoder weights using standardizer method + decoder_w_k_folded = output_standardizer.fold_in_decoder_weights_layer( + decoder_w_k.float(), k ) dec_i_k = decoder_w_k_folded[source_layer, ...] assert dec_i_k.shape == ( From c19536bb6bb45a034c41e6415117546cbc68c016 Mon Sep 17 00:00:00 2001 From: jiito Date: Fri, 17 Oct 2025 13:54:50 -0700 Subject: [PATCH 32/99] cleanup comments --- .../utils/model_converters/circuit_tracer.py | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py index e40b9e8..4a85ea0 100644 --- a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py +++ b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py @@ -1,9 +1,10 @@ -from einops import einsum -from crosslayer_transcoder.utils.model_converter import CLTModule, ModelConverter +from pathlib import Path + import torch import yaml from safetensors.torch import save_file -from pathlib import Path + +from crosslayer_transcoder.utils.model_converter import CLTModule, ModelConverter class CircuitTracerConverter(ModelConverter): @@ -26,8 +27,8 @@ def convert(self, model: CLTModule) -> CLTModule: decoder = model.model.decoder nonlinearity = model.model.nonlinearity n_layers = encoder.n_layers - d_acts = encoder.d_acts # -> d_model - d_features = encoder.d_features # -> d_transcoder + d_acts = encoder.d_acts # -> circuit-tracer.d_model + d_features = encoder.d_features # -> circuit-tracer.d_transcoder W_enc_folded, b_enc_folded = input_standardizer.fold_in_encoder( encoder.W.float(), encoder.b.float() @@ -41,16 +42,8 @@ def convert(self, model: CLTModule) -> CLTModule: f"W_enc_{source_layer}": W_enc_folded[source_layer] .T.contiguous() .cpu(), # Transpose! - f"b_enc_{source_layer}": ( - b_enc_folded[source_layer].cpu() - if hasattr(encoder, "b") - else torch.zeros(encoder.d_features) - ), - f"b_dec_{source_layer}": ( - b_dec_folded[source_layer].cpu() - if hasattr(decoder, "b") - else torch.zeros(d_acts) - ), + f"b_enc_{source_layer}": (b_enc_folded[source_layer].cpu()), + f"b_dec_{source_layer}": (b_dec_folded[source_layer].cpu()), f"threshold_{source_layer}": ( nonlinearity.theta.cpu() if hasattr(nonlinearity, "theta") @@ -61,7 +54,6 @@ def convert(self, model: CLTModule) -> CLTModule: layer_encoder_dict, f"{self.save_dir}/W_enc_{source_layer}.safetensors" ) - # decoder output_dec_i = torch.zeros([d_features, n_layers - source_layer, d_acts]) for k in range(source_layer, n_layers): @@ -83,7 +75,6 @@ def convert(self, model: CLTModule) -> CLTModule: save_file(decoder_dict, f"{self.save_dir}/W_dec_{source_layer}.safetensors") - # Create config config = { "model_kind": "cross_layer_transcoder", "feature_input_hook": self.feature_input_hook, From c97a2402c13c72fe18c01c00a436ff695525ad01 Mon Sep 17 00:00:00 2001 From: jiito Date: Tue, 4 Nov 2025 11:52:46 -0500 Subject: [PATCH 33/99] rm ckpt loading test --- .../modal/test_ckpt_loading.py | 125 ------------------ 1 file changed, 125 deletions(-) delete mode 100644 crosslayer_transcoder/modal/test_ckpt_loading.py diff --git a/crosslayer_transcoder/modal/test_ckpt_loading.py b/crosslayer_transcoder/modal/test_ckpt_loading.py deleted file mode 100644 index ae6e745..0000000 --- a/crosslayer_transcoder/modal/test_ckpt_loading.py +++ /dev/null @@ -1,125 +0,0 @@ -import psutil -import torch -from rich.console import Console - -from crosslayer_transcoder.modal.app import CHECKPOINTS_PATH, app, volumes - -console = Console() - - -def get_memory_usage(): - """Get current memory usage statistics""" - process = psutil.Process() - memory_info = process.memory_info() - - stats = { - "cpu_memory_mb": memory_info.rss / 1024 / 1024, - "cpu_memory_percent": process.memory_percent(), - } - - if torch.cuda.is_available(): - stats.update( - { - "gpu_memory_allocated_mb": torch.cuda.memory_allocated() / 1024 / 1024, - "gpu_memory_reserved_mb": torch.cuda.memory_reserved() / 1024 / 1024, - "gpu_memory_max_allocated_mb": torch.cuda.max_memory_allocated() - / 1024 - / 1024, - } - ) - - return stats - - -def log_memory_usage(stage: str): - """Log memory usage with a descriptive stage label""" - stats = get_memory_usage() - console.print(f"[bold blue]{stage}[/bold blue]") - console.print( - f" CPU Memory: {stats['cpu_memory_mb']:.1f} MB ({stats['cpu_memory_percent']:.1f}%)" - ) - - if torch.cuda.is_available(): - console.print( - f" GPU Memory Allocated: {stats['gpu_memory_allocated_mb']:.1f} MB" - ) - console.print( - f" GPU Memory Reserved: {stats['gpu_memory_reserved_mb']:.1f} MB" - ) - console.print( - f" GPU Memory Max: {stats['gpu_memory_max_allocated_mb']:.1f} MB" - ) - - -@app.function(gpu="a10g", volumes=volumes) -def load_ckpt_lightning(ckpt_path): - from crosslayer_transcoder.model.clt_lightning import ( - JumpReLUCrossLayerTranscoderModule, - ) - from crosslayer_transcoder.model.clt import CrossLayerTranscoder - from crosslayer_transcoder.model.clt import Encoder - from crosslayer_transcoder.model.clt import CrosslayerDecoder - from crosslayer_transcoder.model.standardize import DimensionwiseInputStandardizer - from crosslayer_transcoder.model.standardize import DimensionwiseOutputStandardizer - from crosslayer_transcoder.model.jumprelu import JumpReLU - from crosslayer_transcoder.metrics.replacement_model_accuracy import ( - ReplacementModelAccuracy, - ) - from crosslayer_transcoder.metrics.dead_features import DeadFeatures - - console.print("[bold yellow]Loading model from checkpoint...[/bold yellow]") - - log_memory_usage("Initial memory usage") - - encoder = Encoder( - d_acts=768, - d_features=10_000, - n_layers=12, - ) - decoder = CrosslayerDecoder( - d_acts=768, - d_features=10_000, - n_layers=12, - ) - - input_standardizer = DimensionwiseInputStandardizer( - n_layers=12, - activation_dim=768, - ) - output_standardizer = DimensionwiseOutputStandardizer( - n_layers=12, - activation_dim=768, - ) - nonlinearity = JumpReLU(theta=0.03, bandwidth=0.01, n_layers=12, d_features=10_000) - - clt = CrossLayerTranscoder( - encoder=encoder, - decoder=decoder, - input_standardizer=input_standardizer, - output_standardizer=output_standardizer, - nonlinearity=nonlinearity, - ) - - log_memory_usage("After model creation") - - model = JumpReLUCrossLayerTranscoderModule.load_from_checkpoint( - ckpt_path, - model=clt, - replacement_model=None, - dead_features=None, - ) - model.eval() - - log_memory_usage("After checkpoint loading") - - console.print("[bold green]✓ Model loaded successfully![/bold green]") - return - - -@app.local_entrypoint() -def main(): - experiment = "34f20c70" - console.print( - f"[bold cyan]Starting checkpoint loading test for experiment:[/bold cyan] {experiment}" - ) - load_ckpt_lightning.remote(f"{CHECKPOINTS_PATH}/{experiment}/last.ckpt") From 663f5d2acf374b7746d75b5bd251e7a1903ca30f Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 6 Nov 2025 13:29:18 -0500 Subject: [PATCH 34/99] remove debug configs --- config/debug.yaml | 148 ------------------------- config/debug_circuit-tracer.yaml | 169 ---------------------------- config/default_circuit-tracer.yaml | 170 ----------------------------- 3 files changed, 487 deletions(-) delete mode 100644 config/debug.yaml delete mode 100644 config/debug_circuit-tracer.yaml delete mode 100644 config/default_circuit-tracer.yaml diff --git a/config/debug.yaml b/config/debug.yaml deleted file mode 100644 index ee5083b..0000000 --- a/config/debug.yaml +++ /dev/null @@ -1,148 +0,0 @@ -# Debug configuration for CrossLayer Transcoder training -# This file uses Lightning CLI's automatic class construction - -seed_everything: 42 - -trainer: - max_steps: 20 - val_check_interval: 2 - limit_val_batches: 1 - enable_checkpointing: false # We use custom end-of-training checkpoint - num_sanity_val_steps: 0 # Can't run replacement model before standardizers are initialized - precision: "16-mixed" - accelerator: "gpu" - devices: [0] # [0] means cuda:0 - accumulate_grad_batches: 1 - logger: # WandB logger is recommended but other loggers are supported as well - class_path: lightning.pytorch.loggers.WandbLogger - init_args: - project: "clt" - name: "debug-jumprelu" - save_dir: "./wandb" - callbacks: - - class_path: crosslayer_transcoder.utils.callbacks.EndOfTrainingCheckpointCallback - init_args: - checkpoint_dir: "checkpoints_debug" - -model: - class_path: crosslayer_transcoder.model.clt_lightning.JumpReLUCrossLayerTranscoderModule - init_args: - model: - class_path: crosslayer_transcoder.model.clt.CrossLayerTranscoder - init_args: - encoder: - class_path: crosslayer_transcoder.model.clt.Encoder - init_args: - d_acts: 16 - d_features: 48 - n_layers: 2 - - decoder: - class_path: crosslayer_transcoder.model.clt.CrosslayerDecoder - init_args: - d_acts: 16 - d_features: 48 - n_layers: 2 - - nonlinearity: - class_path: crosslayer_transcoder.model.jumprelu.JumpReLU - init_args: - theta: 0.03 - bandwidth: 0.01 - n_layers: 2 - d_features: 48 - - input_standardizer: - class_path: crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer - init_args: - n_layers: 2 - activation_dim: 16 - - output_standardizer: - class_path: crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer - init_args: - n_layers: 2 - activation_dim: 16 - - # Pre-constructed replacement model - replacement_model: - class_path: crosslayer_transcoder.metrics.replacement_model_accuracy.ReplacementModelAccuracy - init_args: - model_name: "openai-community/gpt2" - device_map: "cuda:0" # should match trainer.devices - loader_batch_size: 2 - - # Pre-constructed dead features metric - dead_features: - class_path: crosslayer_transcoder.metrics.dead_features.DeadFeatures - init_args: - n_features: 48 - n_layers: 2 - return_per_layer: true - return_log_freqs: true - return_neuron_indices: true - - - # Training parameters - learning_rate: 1e-4 - compile: true # if using torch.compile - lr_decay_step: 80_000 # lr is scaled by lr_decay_factor after this many steps - lr_decay_factor: 0.1 - - compute_dead_features: true - compute_dead_features_every: 2 - -data: - class_path: crosslayer_transcoder.data.datamodule.ActivationDataModule - init_args: - buffer_size: 200 - n_in_out: 2 - n_layers: 2 - activation_dim: 16 - dtype: "float16" - max_batch_size: 50 - - model_name: "openai-community/gpt2" - model_dtype: "float32" - - # Dataset settings - dataset_name: "Skylion007/openwebtext" - dataset_split: "train" - max_sequence_length: 128 - - generation_batch_size: 2 - refresh_interval: 0.05 - - shared_memory_name: "activation_buffer_debug" - timeout_seconds: 10 - - init_file: null - - batch_size: 8 - num_workers: 0 - prefetch_factor: 2 - shuffle: true - persistent_workers: false - pin_memory: false - - minimum_fill_threshold: 0.1 - use_shared_memory: false - - use_shared_memory: true - - # Device configuration - device_map: "cuda:0" # "cpu", "auto", "cuda:0", "cuda:0,1,2,3" - deployment_policy: "gpu_only" # "cpu_only", "gpu_only", or "dynamic" - # dynamic will use CPU and only GPU if the buffer is almost empty to refill fast. Use this if you use a single GPU and have a beefy CPU. - - # WandB logging configuration for data generation - wandb_logging: - enabled: false - project: "clt" - group: null - run_name: "data-generator-debug-jumprelu" - tags: ["data-generation", "debug"] - save_dir: "./wandb" - log_interval: 5.0 - -ckpt_path: null \ No newline at end of file diff --git a/config/debug_circuit-tracer.yaml b/config/debug_circuit-tracer.yaml deleted file mode 100644 index b6c61ab..0000000 --- a/config/debug_circuit-tracer.yaml +++ /dev/null @@ -1,169 +0,0 @@ -# Debug configuration for CrossLayer Transcoder training with compatibility for `circuit-tracer` - -seed_everything: 42 - -trainer: - # max_steps is number of gradient updates. If using gradient accumulation, this is not the number of batches. - max_steps: 2 - val_check_interval: 2 - limit_val_batches: 1 - enable_checkpointing: false # We use custom end-of-training checkpoint - num_sanity_val_steps: 0 # Can't run replacement model before standardizers are initialized - precision: "16-mixed" - accelerator: "gpu" - devices: [0] # [0] means cuda:0 - accumulate_grad_batches: 1 - logger: # WandB logger is recommended but other loggers are supported as well - class_path: lightning.pytorch.loggers.WandbLogger - init_args: - project: "clt" - name: "jumprelu" - save_dir: "./wandb" - callbacks: - - class_path: crosslayer_transcoder.utils.callbacks.EndOfTrainingCheckpointCallback - init_args: - checkpoint_dir: "checkpoints" - - class_path: crosslayer_transcoder.utils.callbacks.CircuitTracerCallback - init_args: - save_dir: "/experiments/checkpoints" - - class_path: crosslayer_transcoder.utils.callbacks.HuggingFaceCallback - init_args: - repo_id: "jiito/clt_test_gpt2_zero" - repo_type: "model" - save_dir: "/experiments/checkpoints" - -model: - class_path: crosslayer_transcoder.model.clt_lightning.JumpReLUCrossLayerTranscoderModule - init_args: - model: - class_path: crosslayer_transcoder.model.clt.CrossLayerTranscoder - init_args: - encoder: - class_path: crosslayer_transcoder.model.clt.Encoder - init_args: - d_acts: 768 - d_features: 48 - n_layers: 12 - - decoder: - class_path: crosslayer_transcoder.model.clt.CrosslayerDecoder - init_args: - d_acts: 768 - d_features: 48 - n_layers: 12 - - nonlinearity: - class_path: crosslayer_transcoder.model.jumprelu.JumpReLU - init_args: - theta: 0.03 - bandwidth: 0.01 - n_layers: 12 - d_features: 48 - - input_standardizer: - class_path: crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer - init_args: - n_layers: 12 - activation_dim: 768 - - output_standardizer: - class_path: crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer - init_args: - n_layers: 12 - activation_dim: 768 - - # Pre-constructed replacement model - replacement_model: - class_path: crosslayer_transcoder.metrics.replacement_model_accuracy.ReplacementModelAccuracy - init_args: - model_name: "openai-community/gpt2" - device_map: "cuda:0" # should match trainer.devices - loader_batch_size: 2 - - # Pre-constructed dead features metric - dead_features: - class_path: crosslayer_transcoder.metrics.dead_features.DeadFeatures - init_args: - n_features: 48 - n_layers: 12 - return_per_layer: true - return_log_freqs: true - return_neuron_indices: true - - - # Training parameters - learning_rate: 1e-4 - compile: false # if using torch.compile - lr_decay_step: 80_000 # lr is scaled by lr_decay_factor after this many steps - lr_decay_factor: 0.1 - - lambda_sparsity: 0.0007 # sparsity loss weight - c_sparsity: 1 # sparsity loss coefficient - use_tanh: true # use tanh nonlinearity in the JumpReLU - pre_actv_loss: 1e-6 # pre-activation loss weight - - # Dead features computation settings - compute_dead_features: true - compute_dead_features_every: 2 - -data: - class_path: crosslayer_transcoder.data.datamodule.ActivationDataModule - init_args: - # Buffer settings - buffer_size: 10 # number of activations to store in the buffer - n_in_out: 2 # number of input and output layers - n_layers: 12 # number of layers in the model - activation_dim: 768 # dimension of the activations - dtype: "float16" # dtype of the activations - max_batch_size: 50 # maximum batch size for the data loader - - # Model settings for activation generation - model_name: "openai-community/gpt2" - model_dtype: "float32" - - # Dataset settings - dataset_name: "roneneldan/TinyStories" - dataset_split: "train" - max_sequence_length: 2048 - - # Generation settings - generation_batch_size: 2 - refresh_interval: 0.05 # time (s) between shell logs updates - - # Memory settings - shared_memory_name: "activation_buffer_debug" - timeout_seconds: 10 - - # File paths - init_file: null # path to file with shuffled activations to initialize the buffer fast - # if null, activations are generated and training starts when the buffer is at least minimum_fill_threshold full - - # DataLoader settings - batch_size: 8 - num_workers: 0 - prefetch_factor: 2 - shuffle: true - persistent_workers: false - pin_memory: false - - minimum_fill_threshold: 0.1 # Only provide activations when buffer is at least 10% full - # to maintain sufficient shuffling - - use_shared_memory: true - - # Device configuration - device_map: "auto" # "cpu", "auto", "cuda:0", "cuda:0,1,2,3" - deployment_policy: "dynamic" # "cpu_only", "gpu_only", or "dynamic" - # dynamic will use CPU and only GPU if the buffer is almost empty to refill fast. Use this if you use a single GPU and have a beefy CPU. - - # WandB logging configuration for data generation - wandb_logging: - enabled: false # Enable WandB logging for data generation - project: "clt" # WandB project (should match trainer logger) - group: null # Group name (null = auto-generated from training run) - run_name: "data-generator-debug-jumprelu" # Run name suffix - tags: ["data-generation", "debug"] # Tags for the data generation run - save_dir: "./wandb" # Directory for WandB files - log_interval: 5.0 # Logging interval in seconds - -ckpt_path: null \ No newline at end of file diff --git a/config/default_circuit-tracer.yaml b/config/default_circuit-tracer.yaml deleted file mode 100644 index ca15bd1..0000000 --- a/config/default_circuit-tracer.yaml +++ /dev/null @@ -1,170 +0,0 @@ -# Default configuration for CrossLayer Transcoder training -# This file uses Lightning CLI's automatic class construction - -seed_everything: 42 - -trainer: - # max_steps is number of gradient updates. If using gradient accumulation, this is not the number of batches. - max_steps: 100_000 - val_check_interval: 1_000 - limit_val_batches: 1 - enable_checkpointing: false # We use custom end-of-training checkpoint - num_sanity_val_steps: 0 # Can't run replacement model before standardizers are initialized - precision: "16-mixed" - accelerator: "gpu" - devices: [0] # [0] means cuda:0 - accumulate_grad_batches: 1 - logger: # WandB logger is recommended but other loggers are supported as well - class_path: lightning.pytorch.loggers.WandbLogger - init_args: - project: "clt" - name: "jumprelu" - save_dir: "./wandb" - callbacks: - - class_path: crosslayer_transcoder.utils.callbacks.EndOfTrainingCheckpointCallback - init_args: - checkpoint_dir: "checkpoints" - - class_path: crosslayer_transcoder.utils.callbacks.CircuitTracerCallback - init_args: - save_dir: "/experiments/checkpoints" - - class_path: crosslayer_transcoder.utils.callbacks.HuggingFaceCallback - init_args: - repo_id: "jiito/clt_test_gpt2_zero" - repo_type: "model" - save_dir: "/experiments/checkpoints" - -model: - class_path: crosslayer_transcoder.model.clt_lightning.JumpReLUCrossLayerTranscoderModule - init_args: - model: - class_path: crosslayer_transcoder.model.clt.CrossLayerTranscoder - init_args: - encoder: - class_path: crosslayer_transcoder.model.clt.Encoder - init_args: - d_acts: 768 - d_features: 10_000 - n_layers: 12 - - decoder: - class_path: crosslayer_transcoder.model.clt.CrosslayerDecoder - init_args: - d_acts: 768 - d_features: 10_000 - n_layers: 12 - - nonlinearity: - class_path: crosslayer_transcoder.model.jumprelu.JumpReLU - init_args: - theta: 0.03 - bandwidth: 0.01 - n_layers: 12 - d_features: 10_000 - - input_standardizer: - class_path: crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer - init_args: - n_layers: 12 - activation_dim: 768 - - output_standardizer: - class_path: crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer - init_args: - n_layers: 12 - activation_dim: 768 - - # Pre-constructed replacement model - replacement_model: - class_path: crosslayer_transcoder.metrics.replacement_model_accuracy.ReplacementModelAccuracy - init_args: - model_name: "openai-community/gpt2" - device_map: "cuda:0" # should match trainer.devices - loader_batch_size: 2 - - # Pre-constructed dead features metric - dead_features: - class_path: crosslayer_transcoder.metrics.dead_features.DeadFeatures - init_args: - n_features: 10_000 - n_layers: 12 - return_per_layer: true - return_log_freqs: true - return_neuron_indices: true - - - # Training parameters - learning_rate: 1e-4 - compile: true # if using torch.compile - lr_decay_step: 80_000 # lr is scaled by lr_decay_factor after this many steps - lr_decay_factor: 0.1 - - lambda_sparsity: 0.0007 # sparsity loss weight - c_sparsity: 1 # sparsity loss coefficient - use_tanh: true # use tanh nonlinearity in the JumpReLU - pre_actv_loss: 1e-6 # pre-activation loss weight - - # Dead features computation settings - compute_dead_features: true - compute_dead_features_every: 500 - -data: - class_path: crosslayer_transcoder.data.datamodule.ActivationDataModule - init_args: - # Buffer settings - buffer_size: 1_000_000 # number of activations to store in the buffer - n_in_out: 2 # number of input and output layers - n_layers: 12 # number of layers in the model - activation_dim: 768 # dimension of the activations - dtype: "float16" # dtype of the activations - max_batch_size: 50000 # maximum batch size for the data loader - - # Model settings for activation generation - model_name: "openai-community/gpt2" - model_dtype: "float32" - - # Dataset settings - dataset_name: "Skylion007/openwebtext" - dataset_split: "train" - max_sequence_length: 1024 - - # Generation settings - generation_batch_size: 10 - refresh_interval: 0.1 # time (s) between shell logs updates - - # Memory settings - shared_memory_name: "activation_buffer" - timeout_seconds: 30 - - # File paths - init_file: null # path to file with shuffled activations to initialize the buffer fast - # if null, activations are generated and training starts when the buffer is at least minimum_fill_threshold full - - # DataLoader settings - batch_size: 1000 - num_workers: 10 - prefetch_factor: 2 - shuffle: true - persistent_workers: true - pin_memory: true - - minimum_fill_threshold: 0.2 # Only provide activations when buffer is at least 20% full - # to maintain sufficient shuffling - - use_shared_memory: true - - # Device configuration - device_map: "cuda:0" # "cpu", "auto", "cuda:0", "cuda:0,1,2,3" - deployment_policy: "gpu_only" # "cpu_only", "gpu_only", or "dynamic" - # dynamic will use CPU and only GPU if the buffer is almost empty to refill fast. Use this if you use a single GPU and have a beefy CPU. - - # WandB logging configuration for data generation - wandb_logging: - enabled: true # Enable WandB logging for data generation - project: "clt" # WandB project (should match trainer logger) - group: null # Group name (null = auto-generated from training run) - run_name: "data-generator-jumprelu" # Run name suffix - tags: ["data-generation"] # Tags for the data generation run - save_dir: "./wandb" # Directory for WandB files - log_interval: 5.0 # Logging interval in seconds - -ckpt_path: null \ No newline at end of file From 9d8ea2b6b1f9b1350c1f69c8b01326e476e80c43 Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 6 Nov 2025 13:29:52 -0500 Subject: [PATCH 35/99] remove main.py changes --- crosslayer_transcoder/main.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crosslayer_transcoder/main.py b/crosslayer_transcoder/main.py index d7b09d4..2afce89 100755 --- a/crosslayer_transcoder/main.py +++ b/crosslayer_transcoder/main.py @@ -27,7 +27,7 @@ def add_arguments_to_parser(self, parser): ) -def main(*args): +def main(): """Main entry point for training.""" # Set up wandb directories os.environ.setdefault("WANDB_DIR", f"{os.getcwd()}/wandb") @@ -45,7 +45,6 @@ def main(*args): "prog": "CrossLayer Transcoder Training", "description": "Train CrossLayer Transcoder models for neural network interpretability", }, - args=args, ) From a3e60453ea53980def0b14e26fb9e367e661e496 Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 6 Nov 2025 13:30:17 -0500 Subject: [PATCH 36/99] remove modal changes --- crosslayer_transcoder/modal/app.py | 59 ----------------------------- crosslayer_transcoder/modal/main.py | 26 ------------- 2 files changed, 85 deletions(-) delete mode 100644 crosslayer_transcoder/modal/app.py delete mode 100644 crosslayer_transcoder/modal/main.py diff --git a/crosslayer_transcoder/modal/app.py b/crosslayer_transcoder/modal/app.py deleted file mode 100644 index 7f0122f..0000000 --- a/crosslayer_transcoder/modal/app.py +++ /dev/null @@ -1,59 +0,0 @@ -import modal -from pathlib import Path -import logging - -volume = modal.Volume.from_name("clt-checkpoints", create_if_missing=True) -cache_volume = modal.Volume.from_name("cache", create_if_missing=True) - -cache_volume_path = Path("/hf") -volume_path = Path("/experiments") -HF_HOME_PATH = cache_volume_path -ACTIVATIONS_PATH = volume_path / "activations" -CHECKPOINTS_PATH = volume_path / "checkpoints" -WANDB_PATH = volume_path / "wandb" - -volumes = {volume_path: volume, cache_volume_path: cache_volume} - -image = ( - modal.Image.debian_slim(python_version="3.12") - .pip_install( - "torch>=2.8.0", - "nnsight==0.5.0.dev7", - "datasets==3.6.0", - "h5py>=3.13.0", - "einops>=0.8.1", - "jaxtyping>=0.3.2", - "lightning>=2.5.1", - "wandb>=0.19.11", - "transformers>=4.46.0", - "numpy>=1.24.0", - "jsonargparse[signatures]>=4.27.7", - "huggingface_hub[hf_transfer]", - ) - .env({"HF_HUB_ENABLE_HF_TRANSFER": "1", "HF_HOME": HF_HOME_PATH.as_posix()}) - .add_local_python_source("crosslayer_transcoder", "tests") - .add_local_dir("config", "/config") -) - -wandb_secret = modal.Secret.from_name("wandb-secret") - -retries = modal.Retries(initial_delay=0.0, max_retries=3) - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - -app = modal.App("clt-trainer", image=image) - - -def volume_commit(volume): - def inner(func): - def wrapper(*args, **kwargs): - logger.info("Committing volume") - result = func(*args, **kwargs) - volume.commit() - logger.info("Volume committed") - return result - - return wrapper - - return inner diff --git a/crosslayer_transcoder/modal/main.py b/crosslayer_transcoder/modal/main.py deleted file mode 100644 index 0a24028..0000000 --- a/crosslayer_transcoder/modal/main.py +++ /dev/null @@ -1,26 +0,0 @@ -import os -import sys -from crosslayer_transcoder.modal.app import app, volumes, wandb_secret, retries -from crosslayer_transcoder.main import main as lightning_cli_main - - -@app.function( - gpu="A100-40GB", - volumes=volumes, - secrets=[wandb_secret], - timeout=60 * 60 * 24, - retries=retries, -) -def train(*args, **kwargs): - # TODO: try resuming from checkpoint - - # NOTE: clear sysargv to allow command-line arg parsing from lightning - if len(sys.argv) > 1: - sys.argv[1:] = [] - - lightning_cli_main(*args) - - -@app.local_entrypoint() -def main(*args): - train.remote(*args) From 06c9f4c60781e3dc40c0d2fbbc443b193c5da052 Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 6 Nov 2025 13:31:27 -0500 Subject: [PATCH 37/99] restore lightning file --- crosslayer_transcoder/model/clt_lightning.py | 88 +++++--------------- 1 file changed, 21 insertions(+), 67 deletions(-) diff --git a/crosslayer_transcoder/model/clt_lightning.py b/crosslayer_transcoder/model/clt_lightning.py index 39a874a..b95fb44 100644 --- a/crosslayer_transcoder/model/clt_lightning.py +++ b/crosslayer_transcoder/model/clt_lightning.py @@ -14,14 +14,8 @@ import wandb from crosslayer_transcoder.metrics.dead_features import DeadFeatures -from crosslayer_transcoder.metrics.replacement_model_accuracy import ( - ReplacementModelAccuracy, -) -from crosslayer_transcoder.model.clt import ( - CrosslayerDecoder, - CrossLayerTranscoder, - Decoder, -) +from crosslayer_transcoder.metrics.replacement_model_accuracy import ReplacementModelAccuracy +from crosslayer_transcoder.model.clt import CrosslayerDecoder, CrossLayerTranscoder, Decoder from crosslayer_transcoder.model.jumprelu import JumpReLU from crosslayer_transcoder.model.topk import BatchTopK @@ -55,9 +49,7 @@ def __init__( ): super().__init__(*args, **kwargs) - self.save_hyperparameters( - ignore=["model", "replacement_model", "dead_features"] - ) + self.save_hyperparameters(ignore=["model", "replacement_model", "dead_features"]) # torch.cuda.memory._record_memory_history(max_entries=100_000) # Store pre-constructed modules @@ -85,16 +77,13 @@ def __init__( self.beta2 = beta2 self.log_metrics_every = log_metrics_every - assert self.model.encoder.n_layers == self.model.decoder.n_layers, ( - "Encoder and decoder must have the same number of layers" - ) + assert ( + self.model.encoder.n_layers == self.model.decoder.n_layers + ), "Encoder and decoder must have the same number of layers" self.register_buffer( "last_active", - torch.zeros( - (self.model.encoder.n_layers, self.model.encoder.d_features), - dtype=torch.long, - ), + torch.zeros((self.model.encoder.n_layers, self.model.encoder.d_features), dtype=torch.long), ) def configure_model(self): @@ -118,9 +107,7 @@ def configure_model(self): } parallelize_module(self, tp_mesh, plan) - def forward( - self, acts_norm: Float[torch.Tensor, "batch_size n_layers d_acts"] - ) -> Tuple[ + def forward(self, acts_norm: Float[torch.Tensor, "batch_size n_layers d_acts"]) -> Tuple[ Float[torch.Tensor, "batch_size n_layers d_features"], # pre_actvs Float[torch.Tensor, "batch_size n_layers d_features"], # features Float[torch.Tensor, "batch_size n_layers d_acts"], # recons_norm @@ -143,18 +130,13 @@ def log_training_metrics(self, features, recons_norm, recons, mlp_out, batch_idx ss_err = (mlp_out_norm - recons_norm) ** 2 ss_err = ss_err.sum(dim=0) - ss_total = ((mlp_out_norm - mlp_out_norm.mean(dim=0, keepdim=True)) ** 2).sum( - dim=0 - ) + ss_total = ((mlp_out_norm - mlp_out_norm.mean(dim=0, keepdim=True)) ** 2).sum(dim=0) fvu = (ss_err / ss_total).mean() # (n_layers, d_model) self.log("metrics/fraction_of_variance_unexplained", fvu) fvu_per_layer = (ss_err / ss_total).mean(dim=-1) assert fvu_per_layer.shape == (self.model.encoder.n_layers,) for layer in range(self.model.encoder.n_layers): - self.log( - f"layers/fraction_of_variance_unexplained/layer_{layer}", - fvu_per_layer[layer], - ) + self.log(f"layers/fraction_of_variance_unexplained/layer_{layer}", fvu_per_layer[layer]) # number of tokens seen if not hasattr(self, "tokens_seen"): @@ -189,8 +171,7 @@ def log_training_metrics(self, features, recons_norm, recons, mlp_out, batch_idx self.log("metrics/recons_standardized_std", recons_norm.std()) self.log( "metrics/L0_avg_per_layer", - torch.count_nonzero(active_features) - / (features.shape[0] * features.shape[1]), + torch.count_nonzero(active_features) / (features.shape[0] * features.shape[1]), ) # Magnitude of feature activations - memory efficient version @@ -216,9 +197,7 @@ def log_training_metrics(self, features, recons_norm, recons, mlp_out, batch_idx # Log L0 table per layer if batch_idx % 500 == 1: - l0_per_layer = ( - torch.count_nonzero(active_features, dim=(0, 2)) / features.shape[0] - ) + l0_per_layer = torch.count_nonzero(active_features, dim=(0, 2)) / features.shape[0] if self.logger and isinstance(self.logger.experiment, wandb.wandb_run.Run): table = wandb.Table( @@ -226,11 +205,7 @@ def log_training_metrics(self, features, recons_norm, recons, mlp_out, batch_idx columns=["layer", "L0"], ) self.logger.experiment.log( - { - "layers/L0_per_layer": wandb.plot.bar( - table, "layer", "L0", title="L0 per Layer" - ) - }, + {"layers/L0_per_layer": wandb.plot.bar(table, "layer", "L0", title="L0 per Layer")}, step=self.global_step, ) @@ -259,11 +234,7 @@ def log_training_metrics(self, features, recons_norm, recons, mlp_out, batch_idx ): for layer in range(dead_log_freqs.shape[0]): self.logger.experiment.log( - { - f"layers/log_feature_density/layer_{layer}": dead_log_freqs[ - layer - ] - }, + {f"layers/log_feature_density/layer_{layer}": dead_log_freqs[layer]}, step=self.global_step, ) self.logger.experiment.log( @@ -333,17 +304,11 @@ def configure_optimizers(self): if self.optimizer == "adam": optimizer = torch.optim.Adam( - self.parameters(), - lr=self.learning_rate, - betas=(self.beta1, self.beta2), - fused=True, + self.parameters(), lr=self.learning_rate, betas=(self.beta1, self.beta2), fused=True ) elif self.optimizer == "adamw": optimizer = torch.optim.AdamW( - self.parameters(), - lr=self.learning_rate, - betas=(self.beta1, self.beta2), - fused=True, + self.parameters(), lr=self.learning_rate, betas=(self.beta1, self.beta2), fused=True ) else: raise ValueError(f"Optimizer {self.optimizer} not supported") @@ -433,9 +398,7 @@ def training_step(self, batch, batch_idx): if isinstance(self.model.decoder, CrosslayerDecoder): dec_norms = torch.zeros_like(features[:1]) for l in range(self.model.decoder.n_layers): - W = self.model.decoder.get_parameter( - f"W_{l}" - ) # (from_layer, d_features, d_acts) + W = self.model.decoder.get_parameter(f"W_{l}") # (from_layer, d_features, d_acts) dec_norms[:, : l + 1] = dec_norms[:, : l + 1] + (W**2).sum(dim=-1) dec_norms = dec_norms.sqrt() @@ -443,17 +406,11 @@ def training_step(self, batch, batch_idx): dec_norms = torch.sqrt((self.model.decoder.W**2).sum(dim=-1)) weighted_features = features * dec_norms * self.c - self.log( - "model/weighted_features_mean", weighted_features.detach().mean().cpu() - ) + self.log("model/weighted_features_mean", weighted_features.detach().mean().cpu()) if self.use_tanh: - weighted_features = torch.tanh( - weighted_features - ) # (batch_size, n_layers, d_features) - sparsity = ( - self.current_sparsity_penalty() * weighted_features.sum(dim=[1, 2]).mean() - ) + weighted_features = torch.tanh(weighted_features) # (batch_size, n_layers, d_features) + sparsity = self.current_sparsity_penalty() * weighted_features.sum(dim=[1, 2]).mean() self.log("training/sparsity_loss", sparsity) # Compute Pre-activation Loss @@ -505,10 +462,7 @@ def __init__( self.aux_loss_scale = aux_loss_scale self.register_buffer( "last_active", - torch.zeros( - (self.model.encoder.n_layers, self.model.encoder.d_features), - dtype=torch.long, - ), + torch.zeros((self.model.encoder.n_layers, self.model.encoder.d_features), dtype=torch.long), ) def training_step(self, batch, batch_idx): From 9158094abb44751b7beb98b008759ffd8dbf2de4 Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 6 Nov 2025 13:46:12 -0500 Subject: [PATCH 38/99] make conversion callback more general --- crosslayer_transcoder/utils/callbacks.py | 43 ++++++++++++------------ 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/crosslayer_transcoder/utils/callbacks.py b/crosslayer_transcoder/utils/callbacks.py index 79d9261..953e15b 100644 --- a/crosslayer_transcoder/utils/callbacks.py +++ b/crosslayer_transcoder/utils/callbacks.py @@ -2,9 +2,11 @@ Simple Lightning callbacks for CrossLayer Transcoder training. """ +from ast import List import logging from pathlib import Path +from huggingface_hub import upload_folder import lightning as L from torch.profiler import ( ProfilerActivity, @@ -13,7 +15,6 @@ tensorboard_trace_handler, ) -from crosslayer_transcoder.utils.hf import upload_to_hub from crosslayer_transcoder.utils.model_converters.circuit_tracer import ( CircuitTracerConverter, ) @@ -61,31 +62,27 @@ def on_train_end(self, trainer, pl_module): trainer.save_checkpoint(checkpoint_path) -class CircuitTracerCallback(L.Callback): +class ModelConversionCallback(L.Callback): """Callback to convert the model to a circuit-tracer model.""" - def __init__(self, save_dir: str = "clt_module"): + def __init__( + self, save_dir: str = "clt_module", kinds: List[str] = ["circuit_tracer"] + ): super().__init__() self.save_dir = Path(save_dir) + self.kinds = kinds + self.converters = { + "circuit_tracer": CircuitTracerConverter, + } def _convert_model(self, pl_module): - circuit_tracer_converter = CircuitTracerConverter( - save_dir=self.save_dir.as_posix() - ) - circuit_tracer_converter.convert(pl_module) - logger.info(f"Circuit-tracer model saved to {self.save_dir.as_posix()}") - - def on_train_start(self, trainer, pl_module): - self.save_dir.mkdir(parents=True, exist_ok=True) - logger.info(f"Saving circuit-tracer model to {self.save_dir.as_posix()}") - - self._convert_model(pl_module) - - def on_train_batch_end(self, trainer, pl_module, outputs, batch, batch_idx): - self._convert_model(pl_module) - - def on_train_end(self, trainer, pl_module): - self._convert_model(pl_module) + for kind in self.kinds: + converter = self.converters[kind](save_dir=self.save_dir.as_posix()) + # NOTE: conversion also does the saving + converter.convert(pl_module) + logger.info( + f"{kind} model converted and saved to {self.save_dir.as_posix()}" + ) class HuggingFaceCallback(L.Callback): @@ -100,4 +97,8 @@ def __init__( self.save_dir = Path(save_dir) def on_train_end(self, trainer, pl_module): - upload_to_hub(self.save_dir.as_posix(), self.repo_id, self.repo_type) + upload_folder( + folder_path=self.save_dir.as_posix(), + repo_id=self.repo_id, + repo_type=self.repo_type, + ) From 26c8d4f2e62dc0ede44bcbdacf234ea44a873aa9 Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 6 Nov 2025 13:46:28 -0500 Subject: [PATCH 39/99] add circuit-tracer debug config --- config/circuit-tracer.yaml | 166 +++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 config/circuit-tracer.yaml diff --git a/config/circuit-tracer.yaml b/config/circuit-tracer.yaml new file mode 100644 index 0000000..7162203 --- /dev/null +++ b/config/circuit-tracer.yaml @@ -0,0 +1,166 @@ +# Default configuration for CrossLayer Transcoder training +# This file uses Lightning CLI's automatic class construction + +seed_everything: 42 + +trainer: + # max_steps is number of gradient updates. If using gradient accumulation, this is not the number of batches. + max_steps: 100 + val_check_interval: 10 + limit_val_batches: 1 + enable_checkpointing: false # We use custom end-of-training checkpoint + num_sanity_val_steps: 0 # Can't run replacement model before standardizers are initialized + precision: "16-mixed" + accelerator: "gpu" + devices: [0] # [0] means cuda:0 + accumulate_grad_batches: 1 + logger: # WandB logger is recommended but other loggers are supported as well + class_path: lightning.pytorch.loggers.WandbLogger + init_args: + project: "clt" + name: "circuit-tracer" + save_dir: "./wandb" + callbacks: + - class_path: crosslayer_transcoder.utils.callbacks.EndOfTrainingCheckpointCallback + init_args: + checkpoint_dir: "checkpoints" + - class_path: crosslayer_transcoder.utils.callbacks.ModelConversionCallback + init_args: + save_dir: "clt_module" + kinds: ["circuit_tracer"] + +model: + class_path: crosslayer_transcoder.model.clt_lightning.JumpReLUCrossLayerTranscoderModule + init_args: + model: + class_path: crosslayer_transcoder.model.clt.CrossLayerTranscoder + init_args: + encoder: + class_path: crosslayer_transcoder.model.clt.Encoder + init_args: + d_acts: 768 + d_features: 10_000 + n_layers: 12 + + decoder: + class_path: crosslayer_transcoder.model.clt.CrosslayerDecoder + init_args: + d_acts: 768 + d_features: 10_000 + n_layers: 12 + + nonlinearity: + class_path: crosslayer_transcoder.model.jumprelu.JumpReLU + init_args: + theta: 0.03 + bandwidth: 0.01 + n_layers: 12 + d_features: 10_000 + + input_standardizer: + class_path: crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer + init_args: + n_layers: 12 + activation_dim: 768 + + output_standardizer: + class_path: crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer + init_args: + n_layers: 12 + activation_dim: 768 + + # Pre-constructed replacement model + replacement_model: + class_path: crosslayer_transcoder.metrics.replacement_model_accuracy.ReplacementModelAccuracy + init_args: + model_name: "openai-community/gpt2" + device_map: "cuda:0" # should match trainer.devices + loader_batch_size: 2 + + # Pre-constructed dead features metric + dead_features: + class_path: crosslayer_transcoder.metrics.dead_features.DeadFeatures + init_args: + n_features: 10_000 + n_layers: 12 + return_per_layer: true + return_log_freqs: true + return_neuron_indices: true + + + # Training parameters + learning_rate: 1e-4 + compile: true # if using torch.compile + lr_decay_step: 80_000 # lr is scaled by lr_decay_factor after this many steps + lr_decay_factor: 0.1 + + lambda_sparsity: 0.0007 # sparsity loss weight + c_sparsity: 1 # sparsity loss coefficient + use_tanh: true # use tanh nonlinearity in the JumpReLU + pre_actv_loss: 1e-6 # pre-activation loss weight + + # Dead features computation settings + compute_dead_features: true + compute_dead_features_every: 50 + +data: + class_path: crosslayer_transcoder.data.datamodule.ActivationDataModule + init_args: + # Buffer settings + buffer_size: 1_000 # number of activations to store in the buffer + n_in_out: 2 # number of input and output layers + n_layers: 12 # number of layers in the model + activation_dim: 768 # dimension of the activations + dtype: "float16" # dtype of the activations + max_batch_size: 500 # maximum batch size for the data loader + + # Model settings for activation generation + model_name: "openai-community/gpt2" + model_dtype: "float32" + + # Dataset settings + dataset_name: "Skylion007/openwebtext" + dataset_split: "train" + max_sequence_length: 1024 + + # Generation settings + generation_batch_size: 10 + refresh_interval: 0.1 # time (s) between shell logs updates + + # Memory settings + shared_memory_name: "activation_buffer" + timeout_seconds: 30 + + # File paths + init_file: null # path to file with shuffled activations to initialize the buffer fast + # if null, activations are generated and training starts when the buffer is at least minimum_fill_threshold full + + # DataLoader settings + batch_size: 1000 + num_workers: 10 + prefetch_factor: 2 + shuffle: true + persistent_workers: true + pin_memory: true + + minimum_fill_threshold: 0.2 # Only provide activations when buffer is at least 20% full + # to maintain sufficient shuffling + + use_shared_memory: true + + # Device configuration + device_map: "cuda:0" # "cpu", "auto", "cuda:0", "cuda:0,1,2,3" + deployment_policy: "gpu_only" # "cpu_only", "gpu_only", or "dynamic" + # dynamic will use CPU and only GPU if the buffer is almost empty to refill fast. Use this if you use a single GPU and have a beefy CPU. + + # WandB logging configuration for data generation + wandb_logging: + enabled: true # Enable WandB logging for data generation + project: "clt" # WandB project (should match trainer logger) + group: null # Group name (null = auto-generated from training run) + run_name: "data-generator-jumprelu" # Run name suffix + tags: ["data-generation"] # Tags for the data generation run + save_dir: "./wandb" # Directory for WandB files + log_interval: 5.0 # Logging interval in seconds + +ckpt_path: null \ No newline at end of file From cfb163148c5c67d211350f4a60ee0e71ec4422a5 Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 6 Nov 2025 13:46:36 -0500 Subject: [PATCH 40/99] cleanup unused methods --- crosslayer_transcoder/utils/hf.py | 5 ----- crosslayer_transcoder/utils/model_converter.py | 5 ----- 2 files changed, 10 deletions(-) delete mode 100644 crosslayer_transcoder/utils/hf.py diff --git a/crosslayer_transcoder/utils/hf.py b/crosslayer_transcoder/utils/hf.py deleted file mode 100644 index 89e4127..0000000 --- a/crosslayer_transcoder/utils/hf.py +++ /dev/null @@ -1,5 +0,0 @@ -def upload_to_hub(save_dir: str, repo_id: str, repo_type: str = "model"): - from huggingface_hub import upload_folder - - print(f"Uploading {save_dir} to {repo_id} ({repo_type})") - upload_folder(folder_path=save_dir, repo_id=repo_id, repo_type=repo_type) diff --git a/crosslayer_transcoder/utils/model_converter.py b/crosslayer_transcoder/utils/model_converter.py index 3cd2bb6..741e15a 100644 --- a/crosslayer_transcoder/utils/model_converter.py +++ b/crosslayer_transcoder/utils/model_converter.py @@ -17,11 +17,6 @@ class ModelConverter(ABC): - def __init__( - self, - ): - pass - @abstractmethod def convert(self, model: CLTModule) -> CLTModule: pass From 9d1594a03e0c9b7f9c4bdf9e8593c0aa47576d81 Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 6 Nov 2025 19:06:42 +0000 Subject: [PATCH 41/99] fix: circuit tracer installation --- pyproject.toml | 6 +- uv.lock | 516 +------------------------------------------------ 2 files changed, 11 insertions(+), 511 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9100228..3f80dc2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,6 +24,7 @@ dependencies = [ "numpy>=1.24.0", "jsonargparse[signatures]>=4.27.7", "modal>=1.1.4", + "circuit-tracer@git+https://github.com/safety-research/circuit-tracer.git@main" ] [project.optional-dependencies] @@ -34,8 +35,6 @@ dev = [ "circuit-tracer" ] -[tool.uv.sources] -circuit-tracer = { path = "../circuit-tracer", editable = true } [project.scripts] clt = "crosslayer_transcoder.main:main" @@ -47,5 +46,8 @@ dev-dependencies = [ "pytest>=8.4.1", ] +[tool.hatch.metadata] +allow-direct-references=true + [tool.black] line-length = 110 diff --git a/uv.lock b/uv.lock index c06e756..7e56af8 100644 --- a/uv.lock +++ b/uv.lock @@ -8,11 +8,7 @@ resolution-markers = [ [[package]] name = "accelerate" -<<<<<<< HEAD version = "1.11.0" -======= -version = "1.10.1" ->>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "huggingface-hub" }, @@ -23,15 +19,9 @@ dependencies = [ { name = "safetensors" }, { name = "torch" }, ] -<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/23/60/2757c4f03a8705dbf80b1268b03881927878dca5ed07d74f733fb6c219e0/accelerate-1.11.0.tar.gz", hash = "sha256:bb1caf2597b4cd632b917b5000c591d10730bb024a79746f1ee205bba80bd229", size = 393715, upload-time = "2025-10-20T14:42:25.025Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/77/85/85951bc0f9843e2c10baaa1b6657227056095de08f4d1eea7d8b423a6832/accelerate-1.11.0-py3-none-any.whl", hash = "sha256:a628fa6beb069b8e549460fc449135d5bd8d73e7a11fd09f0bc9fc4ace7f06f1", size = 375777, upload-time = "2025-10-20T14:42:23.256Z" }, -======= -sdist = { url = "https://files.pythonhosted.org/packages/b1/72/ff3961c19ee395c3d30ac630ee77bfb0e1b46b87edc504d4f83bb4a89705/accelerate-1.10.1.tar.gz", hash = "sha256:3dea89e433420e4bfac0369cae7e36dcd6a56adfcfd38cdda145c6225eab5df8", size = 392446, upload-time = "2025-08-25T13:57:06.21Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5f/a0/d9ef19f780f319c21ee90ecfef4431cbeeca95bec7f14071785c17b6029b/accelerate-1.10.1-py3-none-any.whl", hash = "sha256:3621cff60b9a27ce798857ece05e2b9f56fcc71631cfb31ccf71f0359c311f11", size = 374909, upload-time = "2025-08-25T13:57:04.55Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -45,11 +35,7 @@ wheels = [ [[package]] name = "aiohttp" -<<<<<<< HEAD version = "3.13.2" -======= -version = "3.12.15" ->>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, @@ -60,7 +46,6 @@ dependencies = [ { name = "propcache" }, { name = "yarl" }, ] -<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/1c/ce/3b83ebba6b3207a7135e5fcaba49706f8a4b6008153b4e30540c982fae26/aiohttp-3.13.2.tar.gz", hash = "sha256:40176a52c186aefef6eb3cad2cdd30cd06e3afbe88fe8ab2af9c0b90f228daca", size = 7837994, upload-time = "2025-10-28T20:59:39.937Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/29/9b/01f00e9856d0a73260e86dd8ed0c2234a466c5c1712ce1c281548df39777/aiohttp-3.13.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b1e56bab2e12b2b9ed300218c351ee2a3d8c8fdab5b1ec6193e11a817767e47b", size = 737623, upload-time = "2025-10-28T20:56:30.797Z" }, @@ -80,27 +65,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ba/e4/19ce547b58ab2a385e5f0b8aa3db38674785085abcf79b6e0edd1632b12f/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ff15c147b2ad66da1f2cbb0622313f2242d8e6e8f9b79b5206c84523a4473248", size = 1719512, upload-time = "2025-10-28T20:56:56.428Z" }, { url = "https://files.pythonhosted.org/packages/70/30/6355a737fed29dcb6dfdd48682d5790cb5eab050f7b4e01f49b121d3acad/aiohttp-3.13.2-cp312-cp312-win32.whl", hash = "sha256:27e569eb9d9e95dbd55c0fc3ec3a9335defbf1d8bc1d20171a49f3c4c607b93e", size = 426690, upload-time = "2025-10-28T20:56:58.736Z" }, { url = "https://files.pythonhosted.org/packages/0a/0d/b10ac09069973d112de6ef980c1f6bb31cb7dcd0bc363acbdad58f927873/aiohttp-3.13.2-cp312-cp312-win_amd64.whl", hash = "sha256:8709a0f05d59a71f33fd05c17fc11fcb8c30140506e13c2f5e8ee1b8964e1b45", size = 453465, upload-time = "2025-10-28T20:57:00.795Z" }, -======= -sdist = { url = "https://files.pythonhosted.org/packages/9b/e7/d92a237d8802ca88483906c388f7c201bbe96cd80a165ffd0ac2f6a8d59f/aiohttp-3.12.15.tar.gz", hash = "sha256:4fc61385e9c98d72fcdf47e6dd81833f47b2f77c114c29cd64a361be57a763a2", size = 7823716, upload-time = "2025-07-29T05:52:32.215Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/63/97/77cb2450d9b35f517d6cf506256bf4f5bda3f93a66b4ad64ba7fc917899c/aiohttp-3.12.15-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:802d3868f5776e28f7bf69d349c26fc0efadb81676d0afa88ed00d98a26340b7", size = 702333, upload-time = "2025-07-29T05:50:46.507Z" }, - { url = "https://files.pythonhosted.org/packages/83/6d/0544e6b08b748682c30b9f65640d006e51f90763b41d7c546693bc22900d/aiohttp-3.12.15-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2800614cd560287be05e33a679638e586a2d7401f4ddf99e304d98878c29444", size = 476948, upload-time = "2025-07-29T05:50:48.067Z" }, - { url = "https://files.pythonhosted.org/packages/3a/1d/c8c40e611e5094330284b1aea8a4b02ca0858f8458614fa35754cab42b9c/aiohttp-3.12.15-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8466151554b593909d30a0a125d638b4e5f3836e5aecde85b66b80ded1cb5b0d", size = 469787, upload-time = "2025-07-29T05:50:49.669Z" }, - { url = "https://files.pythonhosted.org/packages/38/7d/b76438e70319796bfff717f325d97ce2e9310f752a267bfdf5192ac6082b/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e5a495cb1be69dae4b08f35a6c4579c539e9b5706f606632102c0f855bcba7c", size = 1716590, upload-time = "2025-07-29T05:50:51.368Z" }, - { url = "https://files.pythonhosted.org/packages/79/b1/60370d70cdf8b269ee1444b390cbd72ce514f0d1cd1a715821c784d272c9/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6404dfc8cdde35c69aaa489bb3542fb86ef215fc70277c892be8af540e5e21c0", size = 1699241, upload-time = "2025-07-29T05:50:53.628Z" }, - { url = "https://files.pythonhosted.org/packages/a3/2b/4968a7b8792437ebc12186db31523f541943e99bda8f30335c482bea6879/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3ead1c00f8521a5c9070fcb88f02967b1d8a0544e6d85c253f6968b785e1a2ab", size = 1754335, upload-time = "2025-07-29T05:50:55.394Z" }, - { url = "https://files.pythonhosted.org/packages/fb/c1/49524ed553f9a0bec1a11fac09e790f49ff669bcd14164f9fab608831c4d/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6990ef617f14450bc6b34941dba4f12d5613cbf4e33805932f853fbd1cf18bfb", size = 1800491, upload-time = "2025-07-29T05:50:57.202Z" }, - { url = "https://files.pythonhosted.org/packages/de/5e/3bf5acea47a96a28c121b167f5ef659cf71208b19e52a88cdfa5c37f1fcc/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd736ed420f4db2b8148b52b46b88ed038d0354255f9a73196b7bbce3ea97545", size = 1719929, upload-time = "2025-07-29T05:50:59.192Z" }, - { url = "https://files.pythonhosted.org/packages/39/94/8ae30b806835bcd1cba799ba35347dee6961a11bd507db634516210e91d8/aiohttp-3.12.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c5092ce14361a73086b90c6efb3948ffa5be2f5b6fbcf52e8d8c8b8848bb97c", size = 1635733, upload-time = "2025-07-29T05:51:01.394Z" }, - { url = "https://files.pythonhosted.org/packages/7a/46/06cdef71dd03acd9da7f51ab3a9107318aee12ad38d273f654e4f981583a/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:aaa2234bb60c4dbf82893e934d8ee8dea30446f0647e024074237a56a08c01bd", size = 1696790, upload-time = "2025-07-29T05:51:03.657Z" }, - { url = "https://files.pythonhosted.org/packages/02/90/6b4cfaaf92ed98d0ec4d173e78b99b4b1a7551250be8937d9d67ecb356b4/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6d86a2fbdd14192e2f234a92d3b494dd4457e683ba07e5905a0b3ee25389ac9f", size = 1718245, upload-time = "2025-07-29T05:51:05.911Z" }, - { url = "https://files.pythonhosted.org/packages/2e/e6/2593751670fa06f080a846f37f112cbe6f873ba510d070136a6ed46117c6/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a041e7e2612041a6ddf1c6a33b883be6a421247c7afd47e885969ee4cc58bd8d", size = 1658899, upload-time = "2025-07-29T05:51:07.753Z" }, - { url = "https://files.pythonhosted.org/packages/8f/28/c15bacbdb8b8eb5bf39b10680d129ea7410b859e379b03190f02fa104ffd/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5015082477abeafad7203757ae44299a610e89ee82a1503e3d4184e6bafdd519", size = 1738459, upload-time = "2025-07-29T05:51:09.56Z" }, - { url = "https://files.pythonhosted.org/packages/00/de/c269cbc4faa01fb10f143b1670633a8ddd5b2e1ffd0548f7aa49cb5c70e2/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:56822ff5ddfd1b745534e658faba944012346184fbfe732e0d6134b744516eea", size = 1766434, upload-time = "2025-07-29T05:51:11.423Z" }, - { url = "https://files.pythonhosted.org/packages/52/b0/4ff3abd81aa7d929b27d2e1403722a65fc87b763e3a97b3a2a494bfc63bc/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b2acbbfff69019d9014508c4ba0401822e8bae5a5fdc3b6814285b71231b60f3", size = 1726045, upload-time = "2025-07-29T05:51:13.689Z" }, - { url = "https://files.pythonhosted.org/packages/71/16/949225a6a2dd6efcbd855fbd90cf476052e648fb011aa538e3b15b89a57a/aiohttp-3.12.15-cp312-cp312-win32.whl", hash = "sha256:d849b0901b50f2185874b9a232f38e26b9b3d4810095a7572eacea939132d4e1", size = 423591, upload-time = "2025-07-29T05:51:15.452Z" }, - { url = "https://files.pythonhosted.org/packages/2b/d8/fa65d2a349fe938b76d309db1a56a75c4fb8cc7b17a398b698488a939903/aiohttp-3.12.15-cp312-cp312-win_amd64.whl", hash = "sha256:b390ef5f62bb508a9d67cb3bba9b8356e23b3996da7062f1a57ce1a79d2b3d34", size = 450266, upload-time = "2025-07-29T05:51:17.239Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -297,7 +261,6 @@ css = [ ] [[package]] -<<<<<<< HEAD name = "cbor2" version = "5.7.1" source = { registry = "https://pypi.org/simple" } @@ -321,14 +284,6 @@ source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/4c/5b/b6ce21586237c77ce67d01dc5507039d444b630dd76611bbca2d8e5dcd91/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43", size = 164519, upload-time = "2025-10-05T04:12:15.808Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e4/37/af0d2ef3967ac0d6113837b44a4f0bfe1328c2b9763bd5b1744520e5cfed/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", size = 163286, upload-time = "2025-10-05T04:12:14.03Z" }, -======= -name = "certifi" -version = "2025.8.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/dc/67/960ebe6bf230a96cda2e0abcf73af550ec4f090005363542f0765df162e0/certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407", size = 162386, upload-time = "2025-08-03T03:07:47.08Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5", size = 161216, upload-time = "2025-08-03T03:07:45.777Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -356,7 +311,6 @@ wheels = [ [[package]] name = "charset-normalizer" -<<<<<<< HEAD version = "3.4.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } @@ -378,30 +332,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" }, { url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" }, { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, -======= -version = "3.4.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/83/2d/5fd176ceb9b2fc619e63405525573493ca23441330fcdaee6bef9460e924/charset_normalizer-3.4.3.tar.gz", hash = "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14", size = 122371, upload-time = "2025-08-09T07:57:28.46Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/5e/14c94999e418d9b87682734589404a25854d5f5d0408df68bc15b6ff54bb/charset_normalizer-3.4.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1", size = 205655, upload-time = "2025-08-09T07:56:08.475Z" }, - { url = "https://files.pythonhosted.org/packages/7d/a8/c6ec5d389672521f644505a257f50544c074cf5fc292d5390331cd6fc9c3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884", size = 146223, upload-time = "2025-08-09T07:56:09.708Z" }, - { url = "https://files.pythonhosted.org/packages/fc/eb/a2ffb08547f4e1e5415fb69eb7db25932c52a52bed371429648db4d84fb1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018", size = 159366, upload-time = "2025-08-09T07:56:11.326Z" }, - { url = "https://files.pythonhosted.org/packages/82/10/0fd19f20c624b278dddaf83b8464dcddc2456cb4b02bb902a6da126b87a1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392", size = 157104, upload-time = "2025-08-09T07:56:13.014Z" }, - { url = "https://files.pythonhosted.org/packages/16/ab/0233c3231af734f5dfcf0844aa9582d5a1466c985bbed6cedab85af9bfe3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f", size = 151830, upload-time = "2025-08-09T07:56:14.428Z" }, - { url = "https://files.pythonhosted.org/packages/ae/02/e29e22b4e02839a0e4a06557b1999d0a47db3567e82989b5bb21f3fbbd9f/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154", size = 148854, upload-time = "2025-08-09T07:56:16.051Z" }, - { url = "https://files.pythonhosted.org/packages/05/6b/e2539a0a4be302b481e8cafb5af8792da8093b486885a1ae4d15d452bcec/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491", size = 160670, upload-time = "2025-08-09T07:56:17.314Z" }, - { url = "https://files.pythonhosted.org/packages/31/e7/883ee5676a2ef217a40ce0bffcc3d0dfbf9e64cbcfbdf822c52981c3304b/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93", size = 158501, upload-time = "2025-08-09T07:56:18.641Z" }, - { url = "https://files.pythonhosted.org/packages/c1/35/6525b21aa0db614cf8b5792d232021dca3df7f90a1944db934efa5d20bb1/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f", size = 153173, upload-time = "2025-08-09T07:56:20.289Z" }, - { url = "https://files.pythonhosted.org/packages/50/ee/f4704bad8201de513fdc8aac1cabc87e38c5818c93857140e06e772b5892/charset_normalizer-3.4.3-cp312-cp312-win32.whl", hash = "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37", size = 99822, upload-time = "2025-08-09T07:56:21.551Z" }, - { url = "https://files.pythonhosted.org/packages/39/f5/3b3836ca6064d0992c58c7561c6b6eee1b3892e9665d650c803bd5614522/charset_normalizer-3.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc", size = 107543, upload-time = "2025-08-09T07:56:23.115Z" }, - { url = "https://files.pythonhosted.org/packages/8a/1f/f041989e93b001bc4e44bb1669ccdcf54d3f00e628229a85b08d330615c5/charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", size = 53175, upload-time = "2025-08-09T07:57:26.864Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] name = "circuit-tracer" version = "0.1.0" -source = { editable = "../circuit-tracer" } +source = { git = "https://github.com/safety-research/circuit-tracer.git?rev=main#a1ca600d0f3eeb4da7982a122b822882bae18ade" } dependencies = [ { name = "einops" }, { name = "huggingface-hub" }, @@ -417,27 +353,6 @@ dependencies = [ { name = "transformers" }, ] -[package.metadata] -requires-dist = [ - { name = "einops", specifier = ">=0.8.0" }, - { name = "huggingface-hub", specifier = ">=0.26.0" }, - { name = "ipykernel", specifier = ">=6.29.5" }, - { name = "ipython", marker = "extra == 'dev'", specifier = ">=8.37.0" }, - { name = "ipywidgets", specifier = ">=8.1.7" }, - { name = "numpy", specifier = ">=1.24.0" }, - { name = "pydantic", specifier = ">=2.0.0" }, - { name = "pyright", marker = "extra == 'dev'", specifier = ">=1.1.403" }, - { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.0.0" }, - { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.12.7" }, - { name = "safetensors", specifier = ">=0.5.0" }, - { name = "tokenizers", specifier = ">=0.21.0" }, - { name = "torch", specifier = ">=2.0.0" }, - { name = "tqdm", specifier = ">=4.60.0" }, - { name = "transformer-lens", specifier = ">=2.16.0" }, - { name = "transformers", specifier = ">=4.50.0" }, -] -provides-extras = ["dev"] - [[package]] name = "click" version = "8.3.0" @@ -473,6 +388,7 @@ name = "crosslayer-transcoder" version = "0.1.0" source = { editable = "." } dependencies = [ + { name = "circuit-tracer" }, { name = "datasets" }, { name = "einops" }, { name = "h5py" }, @@ -504,7 +420,8 @@ dev = [ [package.metadata] requires-dist = [ - { name = "circuit-tracer", marker = "extra == 'dev'", editable = "../circuit-tracer" }, + { name = "circuit-tracer", git = "https://github.com/safety-research/circuit-tracer.git?rev=main" }, + { name = "circuit-tracer", marker = "extra == 'dev'" }, { name = "datasets", specifier = ">=3.6.0" }, { name = "einops", specifier = ">=0.8.1" }, { name = "h5py", specifier = ">=3.13.0" }, @@ -532,11 +449,7 @@ dev = [ [[package]] name = "datasets" -<<<<<<< HEAD version = "4.4.1" -======= -version = "4.1.1" ->>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "dill" }, @@ -554,15 +467,9 @@ dependencies = [ { name = "tqdm" }, { name = "xxhash" }, ] -<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/93/bf/0dae295d6d1ba0b1a200a9dd216838464b5bbd05da01407cb1330b377445/datasets-4.4.1.tar.gz", hash = "sha256:80322699aa8c0bbbdb7caa87906da689c3c2e29523cff698775c67f28fdab1fc", size = 585341, upload-time = "2025-11-05T16:00:38.162Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/3b/5e/6f8d874366788ad5d549e9ba258037d974dda6e004843be1bda794571701/datasets-4.4.1-py3-none-any.whl", hash = "sha256:c1163de5211e42546079ab355cc0250c7e6db16eb209ac5ac6252f801f596c44", size = 511591, upload-time = "2025-11-05T16:00:36.365Z" }, -======= -sdist = { url = "https://files.pythonhosted.org/packages/91/a4/73f8e6ef52c535e1d20d5b2ca83bfe6de399d8b8b8a61ccc8d63d60735aa/datasets-4.1.1.tar.gz", hash = "sha256:7d8d5ba8b12861d2c44bfff9c83484ebfafff1ff553371e5901a8d3aab5450e2", size = 579324, upload-time = "2025-09-18T13:14:27.108Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/c8/09012ac195a0aab58755800d2efdc0e7d5905053509f12cb5d136c911cda/datasets-4.1.1-py3-none-any.whl", hash = "sha256:62e4f6899a36be9ec74a7e759a6951253cc85b3fcfa0a759b0efa8353b149dac", size = 503623, upload-time = "2025-09-18T13:14:25.111Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -652,19 +559,11 @@ wheels = [ [[package]] name = "filelock" -<<<<<<< HEAD version = "3.20.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/58/46/0028a82567109b5ef6e4d2a1f04a583fb513e6cf9527fcdd09afd817deeb/filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4", size = 18922, upload-time = "2025-10-08T18:03:50.056Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" }, -======= -version = "3.19.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/40/bb/0ab3e58d22305b6f5440629d20683af28959bf793d98d11950e305c1c326/filelock-3.19.1.tar.gz", hash = "sha256:66eda1888b0171c998b35be2bcc0f6d75c388a7ce20c3f3f37aa8e96c2dddf58", size = 17687, upload-time = "2025-08-14T16:56:03.016Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/42/14/42b2651a2f46b022ccd948bca9f2d5af0fd8929c4eec235b8d6d844fbe67/filelock-3.19.1-py3-none-any.whl", hash = "sha256:d38e30481def20772f5baf097c122c3babc4fcdb7e14e57049eb9d88c6dc017d", size = 15988, upload-time = "2025-08-14T16:56:01.633Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -678,7 +577,6 @@ wheels = [ [[package]] name = "frozenlist" -<<<<<<< HEAD version = "1.8.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875, upload-time = "2025-10-06T05:38:17.865Z" } @@ -700,47 +598,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b8/af/38e51a553dd66eb064cdf193841f16f077585d4d28394c2fa6235cb41765/frozenlist-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746", size = 44591, upload-time = "2025-10-06T05:36:24.958Z" }, { url = "https://files.pythonhosted.org/packages/a7/06/1dc65480ab147339fecc70797e9c2f69d9cea9cf38934ce08df070fdb9cb/frozenlist-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd", size = 40102, upload-time = "2025-10-06T05:36:26.333Z" }, { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, -======= -version = "1.7.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/79/b1/b64018016eeb087db503b038296fd782586432b9c077fc5c7839e9cb6ef6/frozenlist-1.7.0.tar.gz", hash = "sha256:2e310d81923c2437ea8670467121cc3e9b0f76d3043cc1d2331d56c7fb7a3a8f", size = 45078, upload-time = "2025-06-09T23:02:35.538Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/a2/c8131383f1e66adad5f6ecfcce383d584ca94055a34d683bbb24ac5f2f1c/frozenlist-1.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3dbf9952c4bb0e90e98aec1bd992b3318685005702656bc6f67c1a32b76787f2", size = 81424, upload-time = "2025-06-09T23:00:42.24Z" }, - { url = "https://files.pythonhosted.org/packages/4c/9d/02754159955088cb52567337d1113f945b9e444c4960771ea90eb73de8db/frozenlist-1.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1f5906d3359300b8a9bb194239491122e6cf1444c2efb88865426f170c262cdb", size = 47952, upload-time = "2025-06-09T23:00:43.481Z" }, - { url = "https://files.pythonhosted.org/packages/01/7a/0046ef1bd6699b40acd2067ed6d6670b4db2f425c56980fa21c982c2a9db/frozenlist-1.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3dabd5a8f84573c8d10d8859a50ea2dec01eea372031929871368c09fa103478", size = 46688, upload-time = "2025-06-09T23:00:44.793Z" }, - { url = "https://files.pythonhosted.org/packages/d6/a2/a910bafe29c86997363fb4c02069df4ff0b5bc39d33c5198b4e9dd42d8f8/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa57daa5917f1738064f302bf2626281a1cb01920c32f711fbc7bc36111058a8", size = 243084, upload-time = "2025-06-09T23:00:46.125Z" }, - { url = "https://files.pythonhosted.org/packages/64/3e/5036af9d5031374c64c387469bfcc3af537fc0f5b1187d83a1cf6fab1639/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c193dda2b6d49f4c4398962810fa7d7c78f032bf45572b3e04dd5249dff27e08", size = 233524, upload-time = "2025-06-09T23:00:47.73Z" }, - { url = "https://files.pythonhosted.org/packages/06/39/6a17b7c107a2887e781a48ecf20ad20f1c39d94b2a548c83615b5b879f28/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe2b675cf0aaa6d61bf8fbffd3c274b3c9b7b1623beb3809df8a81399a4a9c4", size = 248493, upload-time = "2025-06-09T23:00:49.742Z" }, - { url = "https://files.pythonhosted.org/packages/be/00/711d1337c7327d88c44d91dd0f556a1c47fb99afc060ae0ef66b4d24793d/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8fc5d5cda37f62b262405cf9652cf0856839c4be8ee41be0afe8858f17f4c94b", size = 244116, upload-time = "2025-06-09T23:00:51.352Z" }, - { url = "https://files.pythonhosted.org/packages/24/fe/74e6ec0639c115df13d5850e75722750adabdc7de24e37e05a40527ca539/frozenlist-1.7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0d5ce521d1dd7d620198829b87ea002956e4319002ef0bc8d3e6d045cb4646e", size = 224557, upload-time = "2025-06-09T23:00:52.855Z" }, - { url = "https://files.pythonhosted.org/packages/8d/db/48421f62a6f77c553575201e89048e97198046b793f4a089c79a6e3268bd/frozenlist-1.7.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:488d0a7d6a0008ca0db273c542098a0fa9e7dfaa7e57f70acef43f32b3f69dca", size = 241820, upload-time = "2025-06-09T23:00:54.43Z" }, - { url = "https://files.pythonhosted.org/packages/1d/fa/cb4a76bea23047c8462976ea7b7a2bf53997a0ca171302deae9d6dd12096/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:15a7eaba63983d22c54d255b854e8108e7e5f3e89f647fc854bd77a237e767df", size = 236542, upload-time = "2025-06-09T23:00:56.409Z" }, - { url = "https://files.pythonhosted.org/packages/5d/32/476a4b5cfaa0ec94d3f808f193301debff2ea42288a099afe60757ef6282/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1eaa7e9c6d15df825bf255649e05bd8a74b04a4d2baa1ae46d9c2d00b2ca2cb5", size = 249350, upload-time = "2025-06-09T23:00:58.468Z" }, - { url = "https://files.pythonhosted.org/packages/8d/ba/9a28042f84a6bf8ea5dbc81cfff8eaef18d78b2a1ad9d51c7bc5b029ad16/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4389e06714cfa9d47ab87f784a7c5be91d3934cd6e9a7b85beef808297cc025", size = 225093, upload-time = "2025-06-09T23:01:00.015Z" }, - { url = "https://files.pythonhosted.org/packages/bc/29/3a32959e68f9cf000b04e79ba574527c17e8842e38c91d68214a37455786/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:73bd45e1488c40b63fe5a7df892baf9e2a4d4bb6409a2b3b78ac1c6236178e01", size = 245482, upload-time = "2025-06-09T23:01:01.474Z" }, - { url = "https://files.pythonhosted.org/packages/80/e8/edf2f9e00da553f07f5fa165325cfc302dead715cab6ac8336a5f3d0adc2/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:99886d98e1643269760e5fe0df31e5ae7050788dd288947f7f007209b8c33f08", size = 249590, upload-time = "2025-06-09T23:01:02.961Z" }, - { url = "https://files.pythonhosted.org/packages/1c/80/9a0eb48b944050f94cc51ee1c413eb14a39543cc4f760ed12657a5a3c45a/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:290a172aae5a4c278c6da8a96222e6337744cd9c77313efe33d5670b9f65fc43", size = 237785, upload-time = "2025-06-09T23:01:05.095Z" }, - { url = "https://files.pythonhosted.org/packages/f3/74/87601e0fb0369b7a2baf404ea921769c53b7ae00dee7dcfe5162c8c6dbf0/frozenlist-1.7.0-cp312-cp312-win32.whl", hash = "sha256:426c7bc70e07cfebc178bc4c2bf2d861d720c4fff172181eeb4a4c41d4ca2ad3", size = 39487, upload-time = "2025-06-09T23:01:06.54Z" }, - { url = "https://files.pythonhosted.org/packages/0b/15/c026e9a9fc17585a9d461f65d8593d281fedf55fbf7eb53f16c6df2392f9/frozenlist-1.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:563b72efe5da92e02eb68c59cb37205457c977aa7a449ed1b37e6939e5c47c6a", size = 43874, upload-time = "2025-06-09T23:01:07.752Z" }, - { url = "https://files.pythonhosted.org/packages/ee/45/b82e3c16be2182bff01179db177fe144d58b5dc787a7d4492c6ed8b9317f/frozenlist-1.7.0-py3-none-any.whl", hash = "sha256:9a5af342e34f7e97caf8c995864c7a396418ae2859cc6fdf1b1073020d516a7e", size = 13106, upload-time = "2025-06-09T23:02:34.204Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] name = "fsspec" -<<<<<<< HEAD version = "2025.10.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/24/7f/2747c0d332b9acfa75dc84447a066fdf812b5a6b8d30472b74d309bfe8cb/fsspec-2025.10.0.tar.gz", hash = "sha256:b6789427626f068f9a83ca4e8a3cc050850b6c0f71f99ddb4f542b8266a26a59", size = 309285, upload-time = "2025-10-30T14:58:44.036Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/eb/02/a6b21098b1d5d6249b7c5ab69dde30108a71e4e819d4a9778f1de1d5b70d/fsspec-2025.10.0-py3-none-any.whl", hash = "sha256:7c7712353ae7d875407f97715f0e1ffcc21e33d5b24556cb1e090ae9409ec61d", size = 200966, upload-time = "2025-10-30T14:58:42.53Z" }, -======= -version = "2025.9.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/de/e0/bab50af11c2d75c9c4a2a26a5254573c0bd97cea152254401510950486fa/fsspec-2025.9.0.tar.gz", hash = "sha256:19fd429483d25d28b65ec68f9f4adc16c17ea2c7c7bf54ec61360d478fb19c19", size = 304847, upload-time = "2025-09-02T19:10:49.215Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/47/71/70db47e4f6ce3e5c37a607355f80da8860a33226be640226ac52cb05ef2e/fsspec-2025.9.0-py3-none-any.whl", hash = "sha256:530dc2a2af60a414a832059574df4a6e10cce927f6f4a78209390fe38955cfb7", size = 199289, upload-time = "2025-09-02T19:10:47.708Z" }, ->>>>>>> 8387c31 (uv sync) ] [package.optional-dependencies] @@ -828,7 +694,6 @@ wheels = [ [[package]] name = "hf-xet" -<<<<<<< HEAD version = "1.2.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/5e/6e/0f11bacf08a67f7fb5ee09740f2ca54163863b07b70d579356e9222ce5d8/hf_xet-1.2.0.tar.gz", hash = "sha256:a8c27070ca547293b6890c4bf389f713f80e8c478631432962bb7f4bc0bd7d7f", size = 506020, upload-time = "2025-10-24T19:04:32.129Z" } @@ -840,19 +705,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0b/dd/7ac658d54b9fb7999a0ccb07ad863b413cbaf5cf172f48ebcd9497ec7263/hf_xet-1.2.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:4c1428c9ae73ec0939410ec73023c4f842927f39db09b063b9482dac5a3bb737", size = 3413812, upload-time = "2025-10-24T19:04:24.585Z" }, { url = "https://files.pythonhosted.org/packages/92/68/89ac4e5b12a9ff6286a12174c8538a5930e2ed662091dd2572bbe0a18c8a/hf_xet-1.2.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a55558084c16b09b5ed32ab9ed38421e2d87cf3f1f89815764d1177081b99865", size = 3508920, upload-time = "2025-10-24T19:04:26.927Z" }, { url = "https://files.pythonhosted.org/packages/cb/44/870d44b30e1dcfb6a65932e3e1506c103a8a5aea9103c337e7a53180322c/hf_xet-1.2.0-cp37-abi3-win_amd64.whl", hash = "sha256:e6584a52253f72c9f52f9e549d5895ca7a471608495c4ecaa6cc73dba2b24d69", size = 2905735, upload-time = "2025-10-24T19:04:35.928Z" }, -======= -version = "1.1.10" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/74/31/feeddfce1748c4a233ec1aa5b7396161c07ae1aa9b7bdbc9a72c3c7dd768/hf_xet-1.1.10.tar.gz", hash = "sha256:408aef343800a2102374a883f283ff29068055c111f003ff840733d3b715bb97", size = 487910, upload-time = "2025-09-12T20:10:27.12Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f7/a2/343e6d05de96908366bdc0081f2d8607d61200be2ac802769c4284cc65bd/hf_xet-1.1.10-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:686083aca1a6669bc85c21c0563551cbcdaa5cf7876a91f3d074a030b577231d", size = 2761466, upload-time = "2025-09-12T20:10:22.836Z" }, - { url = "https://files.pythonhosted.org/packages/31/f9/6215f948ac8f17566ee27af6430ea72045e0418ce757260248b483f4183b/hf_xet-1.1.10-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:71081925383b66b24eedff3013f8e6bbd41215c3338be4b94ba75fd75b21513b", size = 2623807, upload-time = "2025-09-12T20:10:21.118Z" }, - { url = "https://files.pythonhosted.org/packages/15/07/86397573efefff941e100367bbda0b21496ffcdb34db7ab51912994c32a2/hf_xet-1.1.10-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b6bceb6361c80c1cc42b5a7b4e3efd90e64630bcf11224dcac50ef30a47e435", size = 3186960, upload-time = "2025-09-12T20:10:19.336Z" }, - { url = "https://files.pythonhosted.org/packages/01/a7/0b2e242b918cc30e1f91980f3c4b026ff2eedaf1e2ad96933bca164b2869/hf_xet-1.1.10-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:eae7c1fc8a664e54753ffc235e11427ca61f4b0477d757cc4eb9ae374b69f09c", size = 3087167, upload-time = "2025-09-12T20:10:17.255Z" }, - { url = "https://files.pythonhosted.org/packages/4a/25/3e32ab61cc7145b11eee9d745988e2f0f4fafda81b25980eebf97d8cff15/hf_xet-1.1.10-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0a0005fd08f002180f7a12d4e13b22be277725bc23ed0529f8add5c7a6309c06", size = 3248612, upload-time = "2025-09-12T20:10:24.093Z" }, - { url = "https://files.pythonhosted.org/packages/2c/3d/ab7109e607ed321afaa690f557a9ada6d6d164ec852fd6bf9979665dc3d6/hf_xet-1.1.10-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f900481cf6e362a6c549c61ff77468bd59d6dd082f3170a36acfef2eb6a6793f", size = 3353360, upload-time = "2025-09-12T20:10:25.563Z" }, - { url = "https://files.pythonhosted.org/packages/ee/0e/471f0a21db36e71a2f1752767ad77e92d8cde24e974e03d662931b1305ec/hf_xet-1.1.10-cp37-abi3-win_amd64.whl", hash = "sha256:5f54b19cc347c13235ae7ee98b330c26dd65ef1df47e5316ffb1e87713ca7045", size = 2804691, upload-time = "2025-09-12T20:10:28.433Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -894,11 +746,7 @@ wheels = [ [[package]] name = "huggingface-hub" -<<<<<<< HEAD version = "0.36.0" -======= -version = "0.35.3" ->>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "filelock" }, @@ -910,15 +758,9 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] -<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/98/63/4910c5fa9128fdadf6a9c5ac138e8b1b6cee4ca44bf7915bbfbce4e355ee/huggingface_hub-0.36.0.tar.gz", hash = "sha256:47b3f0e2539c39bf5cde015d63b72ec49baff67b6931c3d97f3f84532e2b8d25", size = 463358, upload-time = "2025-10-23T12:12:01.413Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/cb/bd/1a875e0d592d447cbc02805fd3fe0f497714d6a2583f59d14fa9ebad96eb/huggingface_hub-0.36.0-py3-none-any.whl", hash = "sha256:7bcc9ad17d5b3f07b57c78e79d527102d08313caa278a641993acddcb894548d", size = 566094, upload-time = "2025-10-23T12:11:59.557Z" }, -======= -sdist = { url = "https://files.pythonhosted.org/packages/10/7e/a0a97de7c73671863ca6b3f61fa12518caf35db37825e43d63a70956738c/huggingface_hub-0.35.3.tar.gz", hash = "sha256:350932eaa5cc6a4747efae85126ee220e4ef1b54e29d31c3b45c5612ddf0b32a", size = 461798, upload-time = "2025-09-29T14:29:58.625Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/31/a0/651f93d154cb72323358bf2bbae3e642bdb5d2f1bfc874d096f7cb159fa0/huggingface_hub-0.35.3-py3-none-any.whl", hash = "sha256:0e3a01829c19d86d03793e4577816fe3bdfc1602ac62c7fb220d593d351224ba", size = 564262, upload-time = "2025-09-29T14:29:55.813Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -959,11 +801,7 @@ wheels = [ [[package]] name = "ipykernel" -<<<<<<< HEAD -version = "7.1.0" -======= -version = "6.30.1" ->>>>>>> 8387c31 (uv sync) +version = "6.31.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "appnope", marker = "sys_platform == 'darwin'" }, @@ -980,24 +818,14 @@ dependencies = [ { name = "tornado" }, { name = "traitlets" }, ] -<<<<<<< HEAD -sdist = { url = "https://files.pythonhosted.org/packages/b9/a4/4948be6eb88628505b83a1f2f40d90254cab66abf2043b3c40fa07dfce0f/ipykernel-7.1.0.tar.gz", hash = "sha256:58a3fc88533d5930c3546dc7eac66c6d288acde4f801e2001e65edc5dc9cf0db", size = 174579, upload-time = "2025-10-27T09:46:39.471Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a3/17/20c2552266728ceba271967b87919664ecc0e33efca29c3efc6baf88c5f9/ipykernel-7.1.0-py3-none-any.whl", hash = "sha256:763b5ec6c5b7776f6a8d7ce09b267693b4e5ce75cb50ae696aaefb3c85e1ea4c", size = 117968, upload-time = "2025-10-27T09:46:37.805Z" }, -======= -sdist = { url = "https://files.pythonhosted.org/packages/bb/76/11082e338e0daadc89c8ff866185de11daf67d181901038f9e139d109761/ipykernel-6.30.1.tar.gz", hash = "sha256:6abb270161896402e76b91394fcdce5d1be5d45f456671e5080572f8505be39b", size = 166260, upload-time = "2025-08-04T15:47:35.018Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a5/1d/d5ba6edbfe6fae4c3105bca3a9c889563cc752c7f2de45e333164c7f4846/ipykernel-6.31.0.tar.gz", hash = "sha256:2372ce8bc1ff4f34e58cafed3a0feb2194b91fc7cad0fc72e79e47b45ee9e8f6", size = 167493, upload-time = "2025-10-20T11:42:39.948Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fc/c7/b445faca8deb954fe536abebff4ece5b097b923de482b26e78448c89d1dd/ipykernel-6.30.1-py3-none-any.whl", hash = "sha256:aa6b9fb93dca949069d8b85b6c79b2518e32ac583ae9c7d37c51d119e18b3fb4", size = 117484, upload-time = "2025-08-04T15:47:32.622Z" }, ->>>>>>> 8387c31 (uv sync) + { url = "https://files.pythonhosted.org/packages/f6/d8/502954a4ec0efcf264f99b65b41c3c54e65a647d9f0d6f62cd02227d242c/ipykernel-6.31.0-py3-none-any.whl", hash = "sha256:abe5386f6ced727a70e0eb0cf1da801fa7c5fa6ff82147747d5a0406cd8c94af", size = 117003, upload-time = "2025-10-20T11:42:37.502Z" }, ] [[package]] name = "ipython" -<<<<<<< HEAD version = "9.7.0" -======= -version = "9.6.0" ->>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -1011,15 +839,9 @@ dependencies = [ { name = "stack-data" }, { name = "traitlets" }, ] -<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/29/e6/48c74d54039241a456add616464ea28c6ebf782e4110d419411b83dae06f/ipython-9.7.0.tar.gz", hash = "sha256:5f6de88c905a566c6a9d6c400a8fed54a638e1f7543d17aae2551133216b1e4e", size = 4422115, upload-time = "2025-11-05T12:18:54.646Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/05/aa/62893d6a591d337aa59dcc4c6f6c842f1fe20cd72c8c5c1f980255243252/ipython-9.7.0-py3-none-any.whl", hash = "sha256:bce8ac85eb9521adc94e1845b4c03d88365fd6ac2f4908ec4ed1eb1b0a065f9f", size = 618911, upload-time = "2025-11-05T12:18:52.484Z" }, -======= -sdist = { url = "https://files.pythonhosted.org/packages/2a/34/29b18c62e39ee2f7a6a3bba7efd952729d8aadd45ca17efc34453b717665/ipython-9.6.0.tar.gz", hash = "sha256:5603d6d5d356378be5043e69441a072b50a5b33b4503428c77b04cb8ce7bc731", size = 4396932, upload-time = "2025-09-29T10:55:53.948Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/48/c5/d5e07995077e48220269c28a221e168c91123ad5ceee44d548f54a057fc0/ipython-9.6.0-py3-none-any.whl", hash = "sha256:5f77efafc886d2f023442479b8149e7d86547ad0a979e9da9f045d252f648196", size = 616170, upload-time = "2025-09-29T10:55:47.676Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -1109,24 +931,14 @@ wheels = [ [[package]] name = "jsonargparse" -<<<<<<< HEAD version = "4.42.0" -======= -version = "4.41.0" ->>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyyaml" }, ] -<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/32/ef/6bcc6d88e401af6d1c05c6a3f3955ebeae538711f1199e25c53326c921e5/jsonargparse-4.42.0.tar.gz", hash = "sha256:170551344f06500091ca6732bf93726c5aa79f4f2632a7f2a18d7a897ae2c5c1", size = 212273, upload-time = "2025-10-14T05:23:43.15Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/0b/a1/3f06c00dc217baaa273b08022c00bc6c71d619c4d03325179b8fec80d90f/jsonargparse-4.42.0-py3-none-any.whl", hash = "sha256:d112bdaab22918ff5a8fb2d6036596f8527961922fd972b6e50afc6340514a28", size = 235760, upload-time = "2025-10-14T05:23:40.849Z" }, -======= -sdist = { url = "https://files.pythonhosted.org/packages/44/86/60032fb5623df8d938d31f733e4b3385c40791d85d0fae3dfb4e3be10c42/jsonargparse-4.41.0.tar.gz", hash = "sha256:ba1806bf0ed0ad1975e403dffb18b3a755fee3bfe4e7b36d8cce2f297b552b5f", size = 206634, upload-time = "2025-09-04T03:46:34.715Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/62/fc/6ac1943f22f3d2e14703335d64a7d68496f0480c82a3077cde44b2c55ef5/jsonargparse-4.41.0-py3-none-any.whl", hash = "sha256:cd49b6a2fea723ee4d80f9df034f51af226128a7f166be8755d6acdeb3e077a7", size = 228528, upload-time = "2025-09-04T03:46:32.668Z" }, ->>>>>>> 8387c31 (uv sync) ] [package.optional-dependencies] @@ -1288,11 +1100,7 @@ wheels = [ [[package]] name = "jupyterlab" -<<<<<<< HEAD version = "4.4.10" -======= -version = "4.4.9" ->>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "async-lru" }, @@ -1309,15 +1117,9 @@ dependencies = [ { name = "tornado" }, { name = "traitlets" }, ] -<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/6a/5d/75c42a48ff5fc826a7dff3fe4004cda47c54f9d981c351efacfbc9139d3c/jupyterlab-4.4.10.tar.gz", hash = "sha256:521c017508af4e1d6d9d8a9d90f47a11c61197ad63b2178342489de42540a615", size = 22969303, upload-time = "2025-10-22T14:50:58.768Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/f7/46/1eaa5db8d54a594bdade67afbcae42e9a2da676628be3eb39f36dcff6390/jupyterlab-4.4.10-py3-none-any.whl", hash = "sha256:65939ab4c8dcd0c42185c2d0d1a9d60b254dc8c46fc4fdb286b63c51e9358e07", size = 12293385, upload-time = "2025-10-22T14:50:54.075Z" }, -======= -sdist = { url = "https://files.pythonhosted.org/packages/45/b2/7dad2d0049a904d17c070226a4f78f81905f93bfe09503722d210ccf9335/jupyterlab-4.4.9.tar.gz", hash = "sha256:ea55aca8269909016d5fde2dc09b97128bc931230183fe7e2920ede5154ad9c2", size = 22966654, upload-time = "2025-09-26T17:28:20.158Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1f/fd/ac0979ebd1b1975c266c99b96930b0a66609c3f6e5d76979ca6eb3073896/jupyterlab-4.4.9-py3-none-any.whl", hash = "sha256:394c902827350c017430a8370b9f40c03c098773084bc53930145c146d3d2cb2", size = 12292552, upload-time = "2025-09-26T17:28:15.663Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -1365,22 +1167,9 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl", hash = "sha256:c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12", size = 113151, upload-time = "2025-10-27T18:25:54.882Z" }, ] -[[package]] -name = "lark" -version = "1.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1d/37/a13baf0135f348af608c667633cbe5d13aa2c5c15a56ae9ad3e6cba45ae3/lark-1.3.0.tar.gz", hash = "sha256:9a3839d0ca5e1faf7cfa3460e420e859b66bcbde05b634e73c369c8244c5fa48", size = 259551, upload-time = "2025-09-22T13:45:05.072Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a8/3e/1c6b43277de64fc3c0333b0e72ab7b52ddaaea205210d60d9b9f83c3d0c7/lark-1.3.0-py3-none-any.whl", hash = "sha256:80661f261fb2584a9828a097a2432efd575af27d20be0fd35d17f0fe37253831", size = 113002, upload-time = "2025-09-22T13:45:03.747Z" }, -] - [[package]] name = "lightning" -<<<<<<< HEAD version = "2.5.6" -======= -version = "2.5.5" ->>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "fsspec", extra = ["http"] }, @@ -1393,15 +1182,9 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] -<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/e9/da/289e17b2d4631b885771ce10ab7fe19c6c0ab2b1208d1dda418818ffbbfd/lightning-2.5.6.tar.gz", hash = "sha256:57b6abe87080895bc237fb7f36b7b4abaa2793760cbca00e3907e56607e0ed27", size = 640106, upload-time = "2025-11-05T20:53:06.823Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/23/dc/d7804f13928b6a81a0e948cfecbf0071e8cc74e3f341c704e23e75e504ad/lightning-2.5.6-py3-none-any.whl", hash = "sha256:25bb2053078c2efc57c082fda89dfbd975dfa76beb08def191947c2b571a8c8a", size = 827915, upload-time = "2025-11-05T20:53:03.169Z" }, -======= -sdist = { url = "https://files.pythonhosted.org/packages/0f/dd/86bb3bebadcdbc6e6e5a63657f0a03f74cd065b5ea965896679f76fec0b4/lightning-2.5.5.tar.gz", hash = "sha256:4d3d66c5b1481364a7e6a1ce8ddde1777a04fa740a3145ec218a9941aed7dd30", size = 640770, upload-time = "2025-09-05T16:01:21.026Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2e/d0/4b4fbafc3b18df91207a6e46782d9fd1905f9f45cb2c3b8dfbb239aef781/lightning-2.5.5-py3-none-any.whl", hash = "sha256:69eb248beadd7b600bf48eff00a0ec8af171ec7a678d23787c4aedf12e225e8f", size = 828490, upload-time = "2025-09-05T16:01:17.845Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -1515,7 +1298,6 @@ wheels = [ [[package]] name = "multidict" -<<<<<<< HEAD version = "6.7.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/80/1e/5492c365f222f907de1039b91f922b93fa4f764c713ee858d235495d8f50/multidict-6.7.0.tar.gz", hash = "sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5", size = 101834, upload-time = "2025-10-06T14:52:30.657Z" } @@ -1539,31 +1321,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/46/e2/348cd32faad84eaf1d20cce80e2bb0ef8d312c55bca1f7fa9865e7770aaf/multidict-6.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:92abb658ef2d7ef22ac9f8bb88e8b6c3e571671534e029359b6d9e845923eb1b", size = 46073, upload-time = "2025-10-06T14:49:50.28Z" }, { url = "https://files.pythonhosted.org/packages/25/ec/aad2613c1910dce907480e0c3aa306905830f25df2e54ccc9dea450cb5aa/multidict-6.7.0-cp312-cp312-win_arm64.whl", hash = "sha256:490dab541a6a642ce1a9d61a4781656b346a55c13038f0b1244653828e3a83ec", size = 43226, upload-time = "2025-10-06T14:49:52.304Z" }, { url = "https://files.pythonhosted.org/packages/b7/da/7d22601b625e241d4f23ef1ebff8acfc60da633c9e7e7922e24d10f592b3/multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3", size = 12317, upload-time = "2025-10-06T14:52:29.272Z" }, -======= -version = "6.6.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/69/7f/0652e6ed47ab288e3756ea9c0df8b14950781184d4bd7883f4d87dd41245/multidict-6.6.4.tar.gz", hash = "sha256:d2d4e4787672911b48350df02ed3fa3fffdc2f2e8ca06dd6afdf34189b76a9dd", size = 101843, upload-time = "2025-08-11T12:08:48.217Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/05/f6/512ffd8fd8b37fb2680e5ac35d788f1d71bbaf37789d21a820bdc441e565/multidict-6.6.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0ffb87be160942d56d7b87b0fdf098e81ed565add09eaa1294268c7f3caac4c8", size = 76516, upload-time = "2025-08-11T12:06:53.393Z" }, - { url = "https://files.pythonhosted.org/packages/99/58/45c3e75deb8855c36bd66cc1658007589662ba584dbf423d01df478dd1c5/multidict-6.6.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d191de6cbab2aff5de6c5723101705fd044b3e4c7cfd587a1929b5028b9714b3", size = 45394, upload-time = "2025-08-11T12:06:54.555Z" }, - { url = "https://files.pythonhosted.org/packages/fd/ca/e8c4472a93a26e4507c0b8e1f0762c0d8a32de1328ef72fd704ef9cc5447/multidict-6.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:38a0956dd92d918ad5feff3db8fcb4a5eb7dba114da917e1a88475619781b57b", size = 43591, upload-time = "2025-08-11T12:06:55.672Z" }, - { url = "https://files.pythonhosted.org/packages/05/51/edf414f4df058574a7265034d04c935aa84a89e79ce90fcf4df211f47b16/multidict-6.6.4-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:6865f6d3b7900ae020b495d599fcf3765653bc927951c1abb959017f81ae8287", size = 237215, upload-time = "2025-08-11T12:06:57.213Z" }, - { url = "https://files.pythonhosted.org/packages/c8/45/8b3d6dbad8cf3252553cc41abea09ad527b33ce47a5e199072620b296902/multidict-6.6.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a2088c126b6f72db6c9212ad827d0ba088c01d951cee25e758c450da732c138", size = 258299, upload-time = "2025-08-11T12:06:58.946Z" }, - { url = "https://files.pythonhosted.org/packages/3c/e8/8ca2e9a9f5a435fc6db40438a55730a4bf4956b554e487fa1b9ae920f825/multidict-6.6.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0f37bed7319b848097085d7d48116f545985db988e2256b2e6f00563a3416ee6", size = 242357, upload-time = "2025-08-11T12:07:00.301Z" }, - { url = "https://files.pythonhosted.org/packages/0f/84/80c77c99df05a75c28490b2af8f7cba2a12621186e0a8b0865d8e745c104/multidict-6.6.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:01368e3c94032ba6ca0b78e7ccb099643466cf24f8dc8eefcfdc0571d56e58f9", size = 268369, upload-time = "2025-08-11T12:07:01.638Z" }, - { url = "https://files.pythonhosted.org/packages/0d/e9/920bfa46c27b05fb3e1ad85121fd49f441492dca2449c5bcfe42e4565d8a/multidict-6.6.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8fe323540c255db0bffee79ad7f048c909f2ab0edb87a597e1c17da6a54e493c", size = 269341, upload-time = "2025-08-11T12:07:02.943Z" }, - { url = "https://files.pythonhosted.org/packages/af/65/753a2d8b05daf496f4a9c367fe844e90a1b2cac78e2be2c844200d10cc4c/multidict-6.6.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8eb3025f17b0a4c3cd08cda49acf312a19ad6e8a4edd9dbd591e6506d999402", size = 256100, upload-time = "2025-08-11T12:07:04.564Z" }, - { url = "https://files.pythonhosted.org/packages/09/54/655be13ae324212bf0bc15d665a4e34844f34c206f78801be42f7a0a8aaa/multidict-6.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bbc14f0365534d35a06970d6a83478b249752e922d662dc24d489af1aa0d1be7", size = 253584, upload-time = "2025-08-11T12:07:05.914Z" }, - { url = "https://files.pythonhosted.org/packages/5c/74/ab2039ecc05264b5cec73eb018ce417af3ebb384ae9c0e9ed42cb33f8151/multidict-6.6.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:75aa52fba2d96bf972e85451b99d8e19cc37ce26fd016f6d4aa60da9ab2b005f", size = 251018, upload-time = "2025-08-11T12:07:08.301Z" }, - { url = "https://files.pythonhosted.org/packages/af/0a/ccbb244ac848e56c6427f2392741c06302bbfba49c0042f1eb3c5b606497/multidict-6.6.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4fefd4a815e362d4f011919d97d7b4a1e566f1dde83dc4ad8cfb5b41de1df68d", size = 251477, upload-time = "2025-08-11T12:07:10.248Z" }, - { url = "https://files.pythonhosted.org/packages/0e/b0/0ed49bba775b135937f52fe13922bc64a7eaf0a3ead84a36e8e4e446e096/multidict-6.6.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:db9801fe021f59a5b375ab778973127ca0ac52429a26e2fd86aa9508f4d26eb7", size = 263575, upload-time = "2025-08-11T12:07:11.928Z" }, - { url = "https://files.pythonhosted.org/packages/3e/d9/7fb85a85e14de2e44dfb6a24f03c41e2af8697a6df83daddb0e9b7569f73/multidict-6.6.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a650629970fa21ac1fb06ba25dabfc5b8a2054fcbf6ae97c758aa956b8dba802", size = 259649, upload-time = "2025-08-11T12:07:13.244Z" }, - { url = "https://files.pythonhosted.org/packages/03/9e/b3a459bcf9b6e74fa461a5222a10ff9b544cb1cd52fd482fb1b75ecda2a2/multidict-6.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:452ff5da78d4720d7516a3a2abd804957532dd69296cb77319c193e3ffb87e24", size = 251505, upload-time = "2025-08-11T12:07:14.57Z" }, - { url = "https://files.pythonhosted.org/packages/86/a2/8022f78f041dfe6d71e364001a5cf987c30edfc83c8a5fb7a3f0974cff39/multidict-6.6.4-cp312-cp312-win32.whl", hash = "sha256:8c2fcb12136530ed19572bbba61b407f655e3953ba669b96a35036a11a485793", size = 41888, upload-time = "2025-08-11T12:07:15.904Z" }, - { url = "https://files.pythonhosted.org/packages/c7/eb/d88b1780d43a56db2cba24289fa744a9d216c1a8546a0dc3956563fd53ea/multidict-6.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:047d9425860a8c9544fed1b9584f0c8bcd31bcde9568b047c5e567a1025ecd6e", size = 46072, upload-time = "2025-08-11T12:07:17.045Z" }, - { url = "https://files.pythonhosted.org/packages/9f/16/b929320bf5750e2d9d4931835a4c638a19d2494a5b519caaaa7492ebe105/multidict-6.6.4-cp312-cp312-win_arm64.whl", hash = "sha256:14754eb72feaa1e8ae528468f24250dd997b8e2188c3d2f593f9eba259e4b364", size = 43222, upload-time = "2025-08-11T12:07:18.328Z" }, - { url = "https://files.pythonhosted.org/packages/fd/69/b547032297c7e63ba2af494edba695d781af8a0c6e89e4d06cf848b21d80/multidict-6.6.4-py3-none-any.whl", hash = "sha256:27d8f8e125c07cb954e54d75d04905a9bba8a439c1d84aca94949d4d03d8601c", size = 12313, upload-time = "2025-08-11T12:08:46.891Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -1899,19 +1656,11 @@ wheels = [ [[package]] name = "platformdirs" -<<<<<<< HEAD version = "4.5.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/61/33/9611380c2bdb1225fdef633e2a9610622310fed35ab11dac9620972ee088/platformdirs-4.5.0.tar.gz", hash = "sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312", size = 21632, upload-time = "2025-10-08T17:44:48.791Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl", hash = "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3", size = 18651, upload-time = "2025-10-08T17:44:47.223Z" }, -======= -version = "4.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/23/e8/21db9c9987b0e728855bd57bff6984f67952bea55d6f75e055c46b5383e8/platformdirs-4.4.0.tar.gz", hash = "sha256:ca753cf4d81dc309bc67b0ea38fd15dc97bc30ce419a7f58d13eb3bf14c4febf", size = 21634, upload-time = "2025-08-26T14:32:04.268Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/40/4b/2028861e724d3bd36227adfa20d3fd24c3fc6d52032f4a93c133be5d17ce/platformdirs-4.4.0-py3-none-any.whl", hash = "sha256:abd01743f24e5287cd7a5db3752faf1a2d65353f38ec26d98e25a6db65958c85", size = 18654, upload-time = "2025-08-26T14:32:02.735Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -1946,7 +1695,6 @@ wheels = [ [[package]] name = "propcache" -<<<<<<< HEAD version = "0.4.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/9e/da/e9fc233cf63743258bff22b3dfa7ea5baef7b5bc324af47a0ad89b8ffc6f/propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", size = 46442, upload-time = "2025-10-08T19:49:02.291Z" } @@ -1967,34 +1715,10 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/09/d19cff2a5aaac632ec8fc03737b223597b1e347416934c1b3a7df079784c/propcache-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db", size = 41655, upload-time = "2025-10-08T19:47:04.973Z" }, { url = "https://files.pythonhosted.org/packages/68/ab/6b5c191bb5de08036a8c697b265d4ca76148efb10fa162f14af14fb5f076/propcache-0.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1", size = 37789, upload-time = "2025-10-08T19:47:06.077Z" }, { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" }, -======= -version = "0.3.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a6/16/43264e4a779dd8588c21a70f0709665ee8f611211bdd2c87d952cfa7c776/propcache-0.3.2.tar.gz", hash = "sha256:20d7d62e4e7ef05f221e0db2856b979540686342e7dd9973b815599c7057e168", size = 44139, upload-time = "2025-06-09T22:56:06.081Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a8/42/9ca01b0a6f48e81615dca4765a8f1dd2c057e0540f6116a27dc5ee01dfb6/propcache-0.3.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8de106b6c84506b31c27168582cd3cb3000a6412c16df14a8628e5871ff83c10", size = 73674, upload-time = "2025-06-09T22:54:30.551Z" }, - { url = "https://files.pythonhosted.org/packages/af/6e/21293133beb550f9c901bbece755d582bfaf2176bee4774000bd4dd41884/propcache-0.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:28710b0d3975117239c76600ea351934ac7b5ff56e60953474342608dbbb6154", size = 43570, upload-time = "2025-06-09T22:54:32.296Z" }, - { url = "https://files.pythonhosted.org/packages/0c/c8/0393a0a3a2b8760eb3bde3c147f62b20044f0ddac81e9d6ed7318ec0d852/propcache-0.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce26862344bdf836650ed2487c3d724b00fbfec4233a1013f597b78c1cb73615", size = 43094, upload-time = "2025-06-09T22:54:33.929Z" }, - { url = "https://files.pythonhosted.org/packages/37/2c/489afe311a690399d04a3e03b069225670c1d489eb7b044a566511c1c498/propcache-0.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bca54bd347a253af2cf4544bbec232ab982f4868de0dd684246b67a51bc6b1db", size = 226958, upload-time = "2025-06-09T22:54:35.186Z" }, - { url = "https://files.pythonhosted.org/packages/9d/ca/63b520d2f3d418c968bf596839ae26cf7f87bead026b6192d4da6a08c467/propcache-0.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55780d5e9a2ddc59711d727226bb1ba83a22dd32f64ee15594b9392b1f544eb1", size = 234894, upload-time = "2025-06-09T22:54:36.708Z" }, - { url = "https://files.pythonhosted.org/packages/11/60/1d0ed6fff455a028d678df30cc28dcee7af77fa2b0e6962ce1df95c9a2a9/propcache-0.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:035e631be25d6975ed87ab23153db6a73426a48db688070d925aa27e996fe93c", size = 233672, upload-time = "2025-06-09T22:54:38.062Z" }, - { url = "https://files.pythonhosted.org/packages/37/7c/54fd5301ef38505ab235d98827207176a5c9b2aa61939b10a460ca53e123/propcache-0.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee6f22b6eaa39297c751d0e80c0d3a454f112f5c6481214fcf4c092074cecd67", size = 224395, upload-time = "2025-06-09T22:54:39.634Z" }, - { url = "https://files.pythonhosted.org/packages/ee/1a/89a40e0846f5de05fdc6779883bf46ba980e6df4d2ff8fb02643de126592/propcache-0.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ca3aee1aa955438c4dba34fc20a9f390e4c79967257d830f137bd5a8a32ed3b", size = 212510, upload-time = "2025-06-09T22:54:41.565Z" }, - { url = "https://files.pythonhosted.org/packages/5e/33/ca98368586c9566a6b8d5ef66e30484f8da84c0aac3f2d9aec6d31a11bd5/propcache-0.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7a4f30862869fa2b68380d677cc1c5fcf1e0f2b9ea0cf665812895c75d0ca3b8", size = 222949, upload-time = "2025-06-09T22:54:43.038Z" }, - { url = "https://files.pythonhosted.org/packages/ba/11/ace870d0aafe443b33b2f0b7efdb872b7c3abd505bfb4890716ad7865e9d/propcache-0.3.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b77ec3c257d7816d9f3700013639db7491a434644c906a2578a11daf13176251", size = 217258, upload-time = "2025-06-09T22:54:44.376Z" }, - { url = "https://files.pythonhosted.org/packages/5b/d2/86fd6f7adffcfc74b42c10a6b7db721d1d9ca1055c45d39a1a8f2a740a21/propcache-0.3.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:cab90ac9d3f14b2d5050928483d3d3b8fb6b4018893fc75710e6aa361ecb2474", size = 213036, upload-time = "2025-06-09T22:54:46.243Z" }, - { url = "https://files.pythonhosted.org/packages/07/94/2d7d1e328f45ff34a0a284cf5a2847013701e24c2a53117e7c280a4316b3/propcache-0.3.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0b504d29f3c47cf6b9e936c1852246c83d450e8e063d50562115a6be6d3a2535", size = 227684, upload-time = "2025-06-09T22:54:47.63Z" }, - { url = "https://files.pythonhosted.org/packages/b7/05/37ae63a0087677e90b1d14710e532ff104d44bc1efa3b3970fff99b891dc/propcache-0.3.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:ce2ac2675a6aa41ddb2a0c9cbff53780a617ac3d43e620f8fd77ba1c84dcfc06", size = 234562, upload-time = "2025-06-09T22:54:48.982Z" }, - { url = "https://files.pythonhosted.org/packages/a4/7c/3f539fcae630408d0bd8bf3208b9a647ccad10976eda62402a80adf8fc34/propcache-0.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:62b4239611205294cc433845b914131b2a1f03500ff3c1ed093ed216b82621e1", size = 222142, upload-time = "2025-06-09T22:54:50.424Z" }, - { url = "https://files.pythonhosted.org/packages/7c/d2/34b9eac8c35f79f8a962546b3e97e9d4b990c420ee66ac8255d5d9611648/propcache-0.3.2-cp312-cp312-win32.whl", hash = "sha256:df4a81b9b53449ebc90cc4deefb052c1dd934ba85012aa912c7ea7b7e38b60c1", size = 37711, upload-time = "2025-06-09T22:54:52.072Z" }, - { url = "https://files.pythonhosted.org/packages/19/61/d582be5d226cf79071681d1b46b848d6cb03d7b70af7063e33a2787eaa03/propcache-0.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7046e79b989d7fe457bb755844019e10f693752d169076138abf17f31380800c", size = 41479, upload-time = "2025-06-09T22:54:53.234Z" }, - { url = "https://files.pythonhosted.org/packages/cc/35/cc0aaecf278bb4575b8555f2b137de5ab821595ddae9da9d3cd1da4072c7/propcache-0.3.2-py3-none-any.whl", hash = "sha256:98f1ec44fb675f5052cccc8e609c46ed23a35a1cfd18545ad4e29002d858a43f", size = 12663, upload-time = "2025-06-09T22:56:04.484Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] name = "protobuf" -<<<<<<< HEAD version = "6.33.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/19/ff/64a6c8f420818bb873713988ca5492cba3a7946be57e027ac63495157d97/protobuf-6.33.0.tar.gz", hash = "sha256:140303d5c8d2037730c548f8c7b93b20bb1dc301be280c378b82b8894589c954", size = 443463, upload-time = "2025-10-15T20:39:52.159Z" } @@ -2006,23 +1730,10 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e6/eb/2a981a13e35cda8b75b5585aaffae2eb904f8f351bdd3870769692acbd8a/protobuf-6.33.0-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:e0a1715e4f27355afd9570f3ea369735afc853a6c3951a6afe1f80d8569ad298", size = 339159, upload-time = "2025-10-15T20:39:46.186Z" }, { url = "https://files.pythonhosted.org/packages/21/51/0b1cbad62074439b867b4e04cc09b93f6699d78fd191bed2bbb44562e077/protobuf-6.33.0-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:35be49fd3f4fefa4e6e2aacc35e8b837d6703c37a2168a55ac21e9b1bc7559ef", size = 323172, upload-time = "2025-10-15T20:39:47.465Z" }, { url = "https://files.pythonhosted.org/packages/07/d1/0a28c21707807c6aacd5dc9c3704b2aa1effbf37adebd8caeaf68b17a636/protobuf-6.33.0-py3-none-any.whl", hash = "sha256:25c9e1963c6734448ea2d308cfa610e692b801304ba0908d7bfa564ac5132995", size = 170477, upload-time = "2025-10-15T20:39:51.311Z" }, -======= -version = "6.32.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fa/a4/cc17347aa2897568beece2e674674359f911d6fe21b0b8d6268cd42727ac/protobuf-6.32.1.tar.gz", hash = "sha256:ee2469e4a021474ab9baafea6cd070e5bf27c7d29433504ddea1a4ee5850f68d", size = 440635, upload-time = "2025-09-11T21:38:42.935Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c0/98/645183ea03ab3995d29086b8bf4f7562ebd3d10c9a4b14ee3f20d47cfe50/protobuf-6.32.1-cp310-abi3-win32.whl", hash = "sha256:a8a32a84bc9f2aad712041b8b366190f71dde248926da517bde9e832e4412085", size = 424411, upload-time = "2025-09-11T21:38:27.427Z" }, - { url = "https://files.pythonhosted.org/packages/8c/f3/6f58f841f6ebafe076cebeae33fc336e900619d34b1c93e4b5c97a81fdfa/protobuf-6.32.1-cp310-abi3-win_amd64.whl", hash = "sha256:b00a7d8c25fa471f16bc8153d0e53d6c9e827f0953f3c09aaa4331c718cae5e1", size = 435738, upload-time = "2025-09-11T21:38:30.959Z" }, - { url = "https://files.pythonhosted.org/packages/10/56/a8a3f4e7190837139e68c7002ec749190a163af3e330f65d90309145a210/protobuf-6.32.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d8c7e6eb619ffdf105ee4ab76af5a68b60a9d0f66da3ea12d1640e6d8dab7281", size = 426454, upload-time = "2025-09-11T21:38:34.076Z" }, - { url = "https://files.pythonhosted.org/packages/3f/be/8dd0a927c559b37d7a6c8ab79034fd167dcc1f851595f2e641ad62be8643/protobuf-6.32.1-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:2f5b80a49e1eb7b86d85fcd23fe92df154b9730a725c3b38c4e43b9d77018bf4", size = 322874, upload-time = "2025-09-11T21:38:35.509Z" }, - { url = "https://files.pythonhosted.org/packages/5c/f6/88d77011b605ef979aace37b7703e4eefad066f7e84d935e5a696515c2dd/protobuf-6.32.1-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:b1864818300c297265c83a4982fd3169f97122c299f56a56e2445c3698d34710", size = 322013, upload-time = "2025-09-11T21:38:37.017Z" }, - { url = "https://files.pythonhosted.org/packages/97/b7/15cc7d93443d6c6a84626ae3258a91f4c6ac8c0edd5df35ea7658f71b79c/protobuf-6.32.1-py3-none-any.whl", hash = "sha256:2601b779fc7d32a866c6b4404f9d42a3f67c5b9f3f15b4db3cccabe06b95c346", size = 169289, upload-time = "2025-09-11T21:38:41.234Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] name = "psutil" -<<<<<<< HEAD version = "7.1.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/e1/88/bdd0a41e5857d5d703287598cbf08dad90aed56774ea52ae071bae9071b6/psutil-7.1.3.tar.gz", hash = "sha256:6c86281738d77335af7aec228328e944b30930899ea760ecf33a4dba66be5e74", size = 489059, upload-time = "2025-11-02T12:25:54.619Z" } @@ -2033,20 +1744,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e0/95/992c8816a74016eb095e73585d747e0a8ea21a061ed3689474fabb29a395/psutil-7.1.3-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:56d974e02ca2c8eb4812c3f76c30e28836fffc311d55d979f1465c1feeb2b68b", size = 264635, upload-time = "2025-11-02T12:26:31.74Z" }, { url = "https://files.pythonhosted.org/packages/55/4c/c3ed1a622b6ae2fd3c945a366e64eb35247a31e4db16cf5095e269e8eb3c/psutil-7.1.3-cp37-abi3-win_amd64.whl", hash = "sha256:f39c2c19fe824b47484b96f9692932248a54c43799a84282cfe58d05a6449efd", size = 247633, upload-time = "2025-11-02T12:26:33.887Z" }, { url = "https://files.pythonhosted.org/packages/c9/ad/33b2ccec09bf96c2b2ef3f9a6f66baac8253d7565d8839e024a6b905d45d/psutil-7.1.3-cp37-abi3-win_arm64.whl", hash = "sha256:bd0d69cee829226a761e92f28140bec9a5ee9d5b4fb4b0cc589068dbfff559b1", size = 244608, upload-time = "2025-11-02T12:26:36.136Z" }, -======= -version = "7.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b3/31/4723d756b59344b643542936e37a31d1d3204bcdc42a7daa8ee9eb06fb50/psutil-7.1.0.tar.gz", hash = "sha256:655708b3c069387c8b77b072fc429a57d0e214221d01c0a772df7dfedcb3bcd2", size = 497660, upload-time = "2025-09-17T20:14:52.902Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/46/62/ce4051019ee20ce0ed74432dd73a5bb087a6704284a470bb8adff69a0932/psutil-7.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:76168cef4397494250e9f4e73eb3752b146de1dd950040b29186d0cce1d5ca13", size = 245242, upload-time = "2025-09-17T20:14:56.126Z" }, - { url = "https://files.pythonhosted.org/packages/38/61/f76959fba841bf5b61123fbf4b650886dc4094c6858008b5bf73d9057216/psutil-7.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:5d007560c8c372efdff9e4579c2846d71de737e4605f611437255e81efcca2c5", size = 246682, upload-time = "2025-09-17T20:14:58.25Z" }, - { url = "https://files.pythonhosted.org/packages/88/7a/37c99d2e77ec30d63398ffa6a660450b8a62517cabe44b3e9bae97696e8d/psutil-7.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22e4454970b32472ce7deaa45d045b34d3648ce478e26a04c7e858a0a6e75ff3", size = 287994, upload-time = "2025-09-17T20:14:59.901Z" }, - { url = "https://files.pythonhosted.org/packages/9d/de/04c8c61232f7244aa0a4b9a9fbd63a89d5aeaf94b2fc9d1d16e2faa5cbb0/psutil-7.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c70e113920d51e89f212dd7be06219a9b88014e63a4cec69b684c327bc474e3", size = 291163, upload-time = "2025-09-17T20:15:01.481Z" }, - { url = "https://files.pythonhosted.org/packages/f4/58/c4f976234bf6d4737bc8c02a81192f045c307b72cf39c9e5c5a2d78927f6/psutil-7.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d4a113425c037300de3ac8b331637293da9be9713855c4fc9d2d97436d7259d", size = 293625, upload-time = "2025-09-17T20:15:04.492Z" }, - { url = "https://files.pythonhosted.org/packages/79/87/157c8e7959ec39ced1b11cc93c730c4fb7f9d408569a6c59dbd92ceb35db/psutil-7.1.0-cp37-abi3-win32.whl", hash = "sha256:09ad740870c8d219ed8daae0ad3b726d3bf9a028a198e7f3080f6a1888b99bca", size = 244812, upload-time = "2025-09-17T20:15:07.462Z" }, - { url = "https://files.pythonhosted.org/packages/bf/e9/b44c4f697276a7a95b8e94d0e320a7bf7f3318521b23de69035540b39838/psutil-7.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:57f5e987c36d3146c0dd2528cd42151cf96cd359b9d67cfff836995cc5df9a3d", size = 247965, upload-time = "2025-09-17T20:15:09.673Z" }, - { url = "https://files.pythonhosted.org/packages/26/65/1070a6e3c036f39142c2820c4b52e9243246fcfc3f96239ac84472ba361e/psutil-7.1.0-cp37-abi3-win_arm64.whl", hash = "sha256:6937cb68133e7c97b6cc9649a570c9a18ba0efebed46d8c5dae4c07fa1b67a07", size = 244971, upload-time = "2025-09-17T20:15:12.262Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -2069,7 +1766,6 @@ wheels = [ [[package]] name = "pyarrow" -<<<<<<< HEAD version = "22.0.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/30/53/04a7fdc63e6056116c9ddc8b43bc28c12cdd181b85cbeadb79278475f3ae/pyarrow-22.0.0.tar.gz", hash = "sha256:3d600dc583260d845c7d8a6db540339dd883081925da2bd1c5cb808f720b3cd9", size = 1151151, upload-time = "2025-10-24T12:30:00.762Z" } @@ -2081,19 +1777,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/bb/d4/74ac9f7a54cfde12ee42734ea25d5a3c9a45db78f9def949307a92720d37/pyarrow-22.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c3200cb41cdbc65156e5f8c908d739b0dfed57e890329413da2748d1a2cd1a4e", size = 47990906, upload-time = "2025-10-24T10:05:58.254Z" }, { url = "https://files.pythonhosted.org/packages/2e/71/fedf2499bf7a95062eafc989ace56572f3343432570e1c54e6599d5b88da/pyarrow-22.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ac93252226cf288753d8b46280f4edf3433bf9508b6977f8dd8526b521a1bbb9", size = 50306783, upload-time = "2025-10-24T10:06:08.08Z" }, { url = "https://files.pythonhosted.org/packages/68/ed/b202abd5a5b78f519722f3d29063dda03c114711093c1995a33b8e2e0f4b/pyarrow-22.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:44729980b6c50a5f2bfcc2668d36c569ce17f8b17bccaf470c4313dcbbf13c9d", size = 27972883, upload-time = "2025-10-24T10:06:14.204Z" }, -======= -version = "21.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ef/c2/ea068b8f00905c06329a3dfcd40d0fcc2b7d0f2e355bdb25b65e0a0e4cd4/pyarrow-21.0.0.tar.gz", hash = "sha256:5051f2dccf0e283ff56335760cbc8622cf52264d67e359d5569541ac11b6d5bc", size = 1133487, upload-time = "2025-07-18T00:57:31.761Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ca/d4/d4f817b21aacc30195cf6a46ba041dd1be827efa4a623cc8bf39a1c2a0c0/pyarrow-21.0.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:3a302f0e0963db37e0a24a70c56cf91a4faa0bca51c23812279ca2e23481fccd", size = 31160305, upload-time = "2025-07-18T00:55:35.373Z" }, - { url = "https://files.pythonhosted.org/packages/a2/9c/dcd38ce6e4b4d9a19e1d36914cb8e2b1da4e6003dd075474c4cfcdfe0601/pyarrow-21.0.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:b6b27cf01e243871390474a211a7922bfbe3bda21e39bc9160daf0da3fe48876", size = 32684264, upload-time = "2025-07-18T00:55:39.303Z" }, - { url = "https://files.pythonhosted.org/packages/4f/74/2a2d9f8d7a59b639523454bec12dba35ae3d0a07d8ab529dc0809f74b23c/pyarrow-21.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:e72a8ec6b868e258a2cd2672d91f2860ad532d590ce94cdf7d5e7ec674ccf03d", size = 41108099, upload-time = "2025-07-18T00:55:42.889Z" }, - { url = "https://files.pythonhosted.org/packages/ad/90/2660332eeb31303c13b653ea566a9918484b6e4d6b9d2d46879a33ab0622/pyarrow-21.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b7ae0bbdc8c6674259b25bef5d2a1d6af5d39d7200c819cf99e07f7dfef1c51e", size = 42829529, upload-time = "2025-07-18T00:55:47.069Z" }, - { url = "https://files.pythonhosted.org/packages/33/27/1a93a25c92717f6aa0fca06eb4700860577d016cd3ae51aad0e0488ac899/pyarrow-21.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:58c30a1729f82d201627c173d91bd431db88ea74dcaa3885855bc6203e433b82", size = 43367883, upload-time = "2025-07-18T00:55:53.069Z" }, - { url = "https://files.pythonhosted.org/packages/05/d9/4d09d919f35d599bc05c6950095e358c3e15148ead26292dfca1fb659b0c/pyarrow-21.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:072116f65604b822a7f22945a7a6e581cfa28e3454fdcc6939d4ff6090126623", size = 45133802, upload-time = "2025-07-18T00:55:57.714Z" }, - { url = "https://files.pythonhosted.org/packages/71/30/f3795b6e192c3ab881325ffe172e526499eb3780e306a15103a2764916a2/pyarrow-21.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:cf56ec8b0a5c8c9d7021d6fd754e688104f9ebebf1bf4449613c9531f5346a18", size = 26203175, upload-time = "2025-07-18T00:56:01.364Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -2107,11 +1790,7 @@ wheels = [ [[package]] name = "pydantic" -<<<<<<< HEAD version = "2.12.4" -======= -version = "2.11.9" ->>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -2119,15 +1798,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/96/ad/a17bc283d7d81837c061c49e3eaa27a45991759a1b7eae1031921c6bd924/pydantic-2.12.4.tar.gz", hash = "sha256:0f8cb9555000a4b5b617f66bfd2566264c4984b27589d3b845685983e8ea85ac", size = 821038, upload-time = "2025-11-05T10:50:08.59Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/82/2f/e68750da9b04856e2a7ec56fc6f034a5a79775e9b9a81882252789873798/pydantic-2.12.4-py3-none-any.whl", hash = "sha256:92d3d202a745d46f9be6df459ac5a064fdaa3c1c4cd8adcfa332ccf3c05f871e", size = 463400, upload-time = "2025-11-05T10:50:06.732Z" }, -======= -sdist = { url = "https://files.pythonhosted.org/packages/ff/5d/09a551ba512d7ca404d785072700d3f6727a02f6f3c24ecfd081c7cf0aa8/pydantic-2.11.9.tar.gz", hash = "sha256:6b8ffda597a14812a7975c90b82a8a2e777d9257aba3453f973acd3c032a18e2", size = 788495, upload-time = "2025-09-13T11:26:39.325Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3e/d3/108f2006987c58e76691d5ae5d200dd3e0f532cb4e5fa3560751c3a1feba/pydantic-2.11.9-py3-none-any.whl", hash = "sha256:c42dd626f5cfc1c6950ce6205ea58c93efa406da65f479dcb4029d5934857da2", size = 444855, upload-time = "2025-09-13T11:26:36.909Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -2219,25 +1892,15 @@ wheels = [ [[package]] name = "python-socketio" -<<<<<<< HEAD version = "5.14.3" -======= -version = "5.14.0" ->>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "bidict" }, { name = "python-engineio" }, ] -<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/c0/3f/02f5970c82285bd015ec433078bfc3275580b03715ed6024607dbe0f1966/python_socketio-5.14.3.tar.gz", hash = "sha256:cd8da5e0666e741b4be19e07882e880f57a4751d1645f92c2bc746c95f23b1eb", size = 124266, upload-time = "2025-10-29T09:42:53.749Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/c0/1a/b393a06aa6f2f6ab4a9c5c160a62d488b17d6da5cf93a67bc13a6e3239cd/python_socketio-5.14.3-py3-none-any.whl", hash = "sha256:a5208c1bbf45a8d6328d01ed67e3fa52ec8b186fd3ea44cfcfcbd120f0c71fbe", size = 79010, upload-time = "2025-10-29T09:42:52.098Z" }, -======= -sdist = { url = "https://files.pythonhosted.org/packages/ec/bf/bbc41facdb33a7f440a39f213e59202032106b42df4667a32ef4c9ffe604/python_socketio-5.14.0.tar.gz", hash = "sha256:d057737f658b3948392ff452a5c865c5ccc969859c37cf095a73393ce755f98e", size = 122099, upload-time = "2025-09-30T19:30:40.902Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ee/8d/f41abde5846c456b33f25e7fa71d8b8ad78785bb812ef0f2393cda2caaf2/python_socketio-5.14.0-py3-none-any.whl", hash = "sha256:7de5ad8a55efc33e17897f6cf91d20168d3d259f98c38d38e2940af83136d6f8", size = 78438, upload-time = "2025-09-30T19:30:39.134Z" }, ->>>>>>> 8387c31 (uv sync) ] [package.optional-dependencies] @@ -2248,11 +1911,7 @@ client = [ [[package]] name = "pytorch-lightning" -<<<<<<< HEAD version = "2.5.6" -======= -version = "2.5.5" ->>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "fsspec", extra = ["http"] }, @@ -2264,15 +1923,9 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] -<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/0a/1f/94a441d30779e1ffa5f7dc2ac5fa374c142d8b96c347a49a30226264124e/pytorch_lightning-2.5.6.tar.gz", hash = "sha256:c428faaceef74be50b870814d0d7e9f9c6ee748b8769a2afd3366bc69daf3a0f", size = 642830, upload-time = "2025-11-05T20:53:04.871Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/17/e4/32ed2f33c1b634f7c2895369222f4f8cb345044f4642bbff718e7dd1e0b7/pytorch_lightning-2.5.6-py3-none-any.whl", hash = "sha256:037bad1e2fd94d5eb6c5144f045fd4c1070c3d38fc9c14d9f3774a3a9be54dff", size = 831555, upload-time = "2025-11-05T20:53:03.316Z" }, -======= -sdist = { url = "https://files.pythonhosted.org/packages/16/78/bce84aab9a5b3b2e9d087d4f1a6be9b481adbfaac4903bc9daaaf09d49a3/pytorch_lightning-2.5.5.tar.gz", hash = "sha256:d6fc8173d1d6e49abfd16855ea05d2eb2415e68593f33d43e59028ecb4e64087", size = 643703, upload-time = "2025-09-05T16:01:18.313Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/f6/99a5c66478f469598dee25b0e29b302b5bddd4e03ed0da79608ac964056e/pytorch_lightning-2.5.5-py3-none-any.whl", hash = "sha256:0b533991df2353c0c6ea9ca10a7d0728b73631fd61f5a15511b19bee2aef8af0", size = 832431, upload-time = "2025-09-05T16:01:16.234Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -2285,31 +1938,12 @@ wheels = [ ] [[package]] -<<<<<<< HEAD name = "pywinpty" version = "3.0.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f3/bb/a7cc2967c5c4eceb6cc49cfe39447d4bfc56e6c865e7c2249b6eb978935f/pywinpty-3.0.2.tar.gz", hash = "sha256:1505cc4cb248af42cb6285a65c9c2086ee9e7e574078ee60933d5d7fa86fb004", size = 30669, upload-time = "2025-10-03T21:16:29.205Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/02/4e/1098484e042c9485f56f16eb2b69b43b874bd526044ee401512234cf9e04/pywinpty-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:99fdd9b455f0ad6419aba6731a7a0d2f88ced83c3c94a80ff9533d95fa8d8a9e", size = 2050391, upload-time = "2025-10-03T21:19:01.642Z" }, -======= -name = "pywin32" -version = "311" -source = { registry = "https://pypi.org/simple" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/ab/01ea1943d4eba0f850c3c61e78e8dd59757ff815ff3ccd0a84de5f541f42/pywin32-311-cp312-cp312-win32.whl", hash = "sha256:750ec6e621af2b948540032557b10a2d43b0cee2ae9758c54154d711cc852d31", size = 8706543, upload-time = "2025-07-14T20:13:20.765Z" }, - { url = "https://files.pythonhosted.org/packages/d1/a8/a0e8d07d4d051ec7502cd58b291ec98dcc0c3fff027caad0470b72cfcc2f/pywin32-311-cp312-cp312-win_amd64.whl", hash = "sha256:b8c095edad5c211ff31c05223658e71bf7116daa0ecf3ad85f3201ea3190d067", size = 9495040, upload-time = "2025-07-14T20:13:22.543Z" }, - { url = "https://files.pythonhosted.org/packages/ba/3a/2ae996277b4b50f17d61f0603efd8253cb2d79cc7ae159468007b586396d/pywin32-311-cp312-cp312-win_arm64.whl", hash = "sha256:e286f46a9a39c4a18b319c28f59b61de793654af2f395c102b4f819e584b5852", size = 8710102, upload-time = "2025-07-14T20:13:24.682Z" }, -] - -[[package]] -name = "pywinpty" -version = "3.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/06/df/429cc505dc5f77ab0612c4b60bca2e3dcc81f6c321844ee017d6dc0f4a95/pywinpty-3.0.0.tar.gz", hash = "sha256:68f70e68a9f0766ffdea3fc500351cb7b9b012bcb8239a411f7ff0fc8f86dcb1", size = 28551, upload-time = "2025-08-12T20:33:46.506Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/76/d9/bd2249815c305ef8f879b326db1fe1effc8e5f22bd88e522b4b55231aa6f/pywinpty-3.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:1e0c4b01e5b03b1531d7c5d0e044b8c66dd0288c6d2b661820849f2a8d91aec3", size = 2051564, upload-time = "2025-08-12T20:37:09.128Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -2367,7 +2001,6 @@ wheels = [ [[package]] name = "regex" -<<<<<<< HEAD version = "2025.11.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/cc/a9/546676f25e573a4cf00fe8e119b78a37b6a8fe2dc95cda877b30889c9c45/regex-2025.11.3.tar.gz", hash = "sha256:1fedc720f9bb2494ce31a58a1631f9c82df6a09b49c19517ea5cc280b4541e01", size = 414669, upload-time = "2025-11-03T21:34:22.089Z" } @@ -2386,26 +2019,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/59/9b/7c29be7903c318488983e7d97abcf8ebd3830e4c956c4c540005fcfb0462/regex-2025.11.3-cp312-cp312-win32.whl", hash = "sha256:3839967cf4dc4b985e1570fd8d91078f0c519f30491c60f9ac42a8db039be204", size = 266194, upload-time = "2025-11-03T21:31:51.53Z" }, { url = "https://files.pythonhosted.org/packages/1a/67/3b92df89f179d7c367be654ab5626ae311cb28f7d5c237b6bb976cd5fbbb/regex-2025.11.3-cp312-cp312-win_amd64.whl", hash = "sha256:e721d1b46e25c481dc5ded6f4b3f66c897c58d2e8cfdf77bbced84339108b0b9", size = 277069, upload-time = "2025-11-03T21:31:53.151Z" }, { url = "https://files.pythonhosted.org/packages/d7/55/85ba4c066fe5094d35b249c3ce8df0ba623cfd35afb22d6764f23a52a1c5/regex-2025.11.3-cp312-cp312-win_arm64.whl", hash = "sha256:64350685ff08b1d3a6fff33f45a9ca183dc1d58bbfe4981604e70ec9801bbc26", size = 270330, upload-time = "2025-11-03T21:31:54.514Z" }, -======= -version = "2025.9.18" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/49/d3/eaa0d28aba6ad1827ad1e716d9a93e1ba963ada61887498297d3da715133/regex-2025.9.18.tar.gz", hash = "sha256:c5ba23274c61c6fef447ba6a39333297d0c247f53059dba0bca415cac511edc4", size = 400917, upload-time = "2025-09-19T00:38:35.79Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b0/99/05859d87a66ae7098222d65748f11ef7f2dff51bfd7482a4e2256c90d72b/regex-2025.9.18-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:436e1b31d7efd4dcd52091d076482031c611dde58bf9c46ca6d0a26e33053a7e", size = 486335, upload-time = "2025-09-19T00:36:03.661Z" }, - { url = "https://files.pythonhosted.org/packages/97/7e/d43d4e8b978890932cf7b0957fce58c5b08c66f32698f695b0c2c24a48bf/regex-2025.9.18-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c190af81e5576b9c5fdc708f781a52ff20f8b96386c6e2e0557a78402b029f4a", size = 289720, upload-time = "2025-09-19T00:36:05.471Z" }, - { url = "https://files.pythonhosted.org/packages/bb/3b/ff80886089eb5dcf7e0d2040d9aaed539e25a94300403814bb24cc775058/regex-2025.9.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e4121f1ce2b2b5eec4b397cc1b277686e577e658d8f5870b7eb2d726bd2300ab", size = 287257, upload-time = "2025-09-19T00:36:07.072Z" }, - { url = "https://files.pythonhosted.org/packages/ee/66/243edf49dd8720cba8d5245dd4d6adcb03a1defab7238598c0c97cf549b8/regex-2025.9.18-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:300e25dbbf8299d87205e821a201057f2ef9aa3deb29caa01cd2cac669e508d5", size = 797463, upload-time = "2025-09-19T00:36:08.399Z" }, - { url = "https://files.pythonhosted.org/packages/df/71/c9d25a1142c70432e68bb03211d4a82299cd1c1fbc41db9409a394374ef5/regex-2025.9.18-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7b47fcf9f5316c0bdaf449e879407e1b9937a23c3b369135ca94ebc8d74b1742", size = 862670, upload-time = "2025-09-19T00:36:10.101Z" }, - { url = "https://files.pythonhosted.org/packages/f8/8f/329b1efc3a64375a294e3a92d43372bf1a351aa418e83c21f2f01cf6ec41/regex-2025.9.18-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:57a161bd3acaa4b513220b49949b07e252165e6b6dc910ee7617a37ff4f5b425", size = 910881, upload-time = "2025-09-19T00:36:12.223Z" }, - { url = "https://files.pythonhosted.org/packages/35/9e/a91b50332a9750519320ed30ec378b74c996f6befe282cfa6bb6cea7e9fd/regex-2025.9.18-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f130c3a7845ba42de42f380fff3c8aebe89a810747d91bcf56d40a069f15352", size = 802011, upload-time = "2025-09-19T00:36:13.901Z" }, - { url = "https://files.pythonhosted.org/packages/a4/1d/6be3b8d7856b6e0d7ee7f942f437d0a76e0d5622983abbb6d21e21ab9a17/regex-2025.9.18-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5f96fa342b6f54dcba928dd452e8d8cb9f0d63e711d1721cd765bb9f73bb048d", size = 786668, upload-time = "2025-09-19T00:36:15.391Z" }, - { url = "https://files.pythonhosted.org/packages/cb/ce/4a60e53df58bd157c5156a1736d3636f9910bdcc271d067b32b7fcd0c3a8/regex-2025.9.18-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0f0d676522d68c207828dcd01fb6f214f63f238c283d9f01d85fc664c7c85b56", size = 856578, upload-time = "2025-09-19T00:36:16.845Z" }, - { url = "https://files.pythonhosted.org/packages/86/e8/162c91bfe7217253afccde112868afb239f94703de6580fb235058d506a6/regex-2025.9.18-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:40532bff8a1a0621e7903ae57fce88feb2e8a9a9116d341701302c9302aef06e", size = 849017, upload-time = "2025-09-19T00:36:18.597Z" }, - { url = "https://files.pythonhosted.org/packages/35/34/42b165bc45289646ea0959a1bc7531733e90b47c56a72067adfe6b3251f6/regex-2025.9.18-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:039f11b618ce8d71a1c364fdee37da1012f5a3e79b1b2819a9f389cd82fd6282", size = 788150, upload-time = "2025-09-19T00:36:20.464Z" }, - { url = "https://files.pythonhosted.org/packages/79/5d/cdd13b1f3c53afa7191593a7ad2ee24092a5a46417725ffff7f64be8342d/regex-2025.9.18-cp312-cp312-win32.whl", hash = "sha256:e1dd06f981eb226edf87c55d523131ade7285137fbde837c34dc9d1bf309f459", size = 264536, upload-time = "2025-09-19T00:36:21.922Z" }, - { url = "https://files.pythonhosted.org/packages/e0/f5/4a7770c9a522e7d2dc1fa3ffc83ab2ab33b0b22b447e62cffef186805302/regex-2025.9.18-cp312-cp312-win_amd64.whl", hash = "sha256:3d86b5247bf25fa3715e385aa9ff272c307e0636ce0c9595f64568b41f0a9c77", size = 275501, upload-time = "2025-09-19T00:36:23.4Z" }, - { url = "https://files.pythonhosted.org/packages/df/05/9ce3e110e70d225ecbed455b966003a3afda5e58e8aec2964042363a18f4/regex-2025.9.18-cp312-cp312-win_arm64.whl", hash = "sha256:032720248cbeeae6444c269b78cb15664458b7bb9ed02401d3da59fe4d68c3a5", size = 268601, upload-time = "2025-09-19T00:36:25.092Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -2471,7 +2084,6 @@ wheels = [ [[package]] name = "rpds-py" -<<<<<<< HEAD version = "0.28.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/48/dc/95f074d43452b3ef5d06276696ece4b3b5d696e7c9ad7173c54b1390cd70/rpds_py-0.28.0.tar.gz", hash = "sha256:abd4df20485a0983e2ca334a216249b6186d6e3c1627e106651943dbdb791aea", size = 27419, upload-time = "2025-10-22T22:24:29.327Z" } @@ -2491,27 +2103,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7d/89/33e675dccff11a06d4d85dbb4d1865f878d5020cbb69b2c1e7b2d3f82562/rpds_py-0.28.0-cp312-cp312-win32.whl", hash = "sha256:d15431e334fba488b081d47f30f091e5d03c18527c325386091f31718952fe08", size = 216954, upload-time = "2025-10-22T22:22:24.105Z" }, { url = "https://files.pythonhosted.org/packages/af/36/45f6ebb3210887e8ee6dbf1bc710ae8400bb417ce165aaf3024b8360d999/rpds_py-0.28.0-cp312-cp312-win_amd64.whl", hash = "sha256:a410542d61fc54710f750d3764380b53bf09e8c4edbf2f9141a82aa774a04f7c", size = 227844, upload-time = "2025-10-22T22:22:25.551Z" }, { url = "https://files.pythonhosted.org/packages/57/91/f3fb250d7e73de71080f9a221d19bd6a1c1eb0d12a1ea26513f6c1052ad6/rpds_py-0.28.0-cp312-cp312-win_arm64.whl", hash = "sha256:1f0cfd1c69e2d14f8c892b893997fa9a60d890a0c8a603e88dca4955f26d1edd", size = 217624, upload-time = "2025-10-22T22:22:26.914Z" }, -======= -version = "0.27.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e9/dd/2c0cbe774744272b0ae725f44032c77bdcab6e8bcf544bffa3b6e70c8dba/rpds_py-0.27.1.tar.gz", hash = "sha256:26a1c73171d10b7acccbded82bf6a586ab8203601e565badc74bbbf8bc5a10f8", size = 27479, upload-time = "2025-08-27T12:16:36.024Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bd/fe/38de28dee5df58b8198c743fe2bea0c785c6d40941b9950bac4cdb71a014/rpds_py-0.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ae2775c1973e3c30316892737b91f9283f9908e3cc7625b9331271eaaed7dc90", size = 361887, upload-time = "2025-08-27T12:13:10.233Z" }, - { url = "https://files.pythonhosted.org/packages/7c/9a/4b6c7eedc7dd90986bf0fab6ea2a091ec11c01b15f8ba0a14d3f80450468/rpds_py-0.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2643400120f55c8a96f7c9d858f7be0c88d383cd4653ae2cf0d0c88f668073e5", size = 345795, upload-time = "2025-08-27T12:13:11.65Z" }, - { url = "https://files.pythonhosted.org/packages/6f/0e/e650e1b81922847a09cca820237b0edee69416a01268b7754d506ade11ad/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16323f674c089b0360674a4abd28d5042947d54ba620f72514d69be4ff64845e", size = 385121, upload-time = "2025-08-27T12:13:13.008Z" }, - { url = "https://files.pythonhosted.org/packages/1b/ea/b306067a712988e2bff00dcc7c8f31d26c29b6d5931b461aa4b60a013e33/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9a1f4814b65eacac94a00fc9a526e3fdafd78e439469644032032d0d63de4881", size = 398976, upload-time = "2025-08-27T12:13:14.368Z" }, - { url = "https://files.pythonhosted.org/packages/2c/0a/26dc43c8840cb8fe239fe12dbc8d8de40f2365e838f3d395835dde72f0e5/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ba32c16b064267b22f1850a34051121d423b6f7338a12b9459550eb2096e7ec", size = 525953, upload-time = "2025-08-27T12:13:15.774Z" }, - { url = "https://files.pythonhosted.org/packages/22/14/c85e8127b573aaf3a0cbd7fbb8c9c99e735a4a02180c84da2a463b766e9e/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5c20f33fd10485b80f65e800bbe5f6785af510b9f4056c5a3c612ebc83ba6cb", size = 407915, upload-time = "2025-08-27T12:13:17.379Z" }, - { url = "https://files.pythonhosted.org/packages/ed/7b/8f4fee9ba1fb5ec856eb22d725a4efa3deb47f769597c809e03578b0f9d9/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:466bfe65bd932da36ff279ddd92de56b042f2266d752719beb97b08526268ec5", size = 386883, upload-time = "2025-08-27T12:13:18.704Z" }, - { url = "https://files.pythonhosted.org/packages/86/47/28fa6d60f8b74fcdceba81b272f8d9836ac0340570f68f5df6b41838547b/rpds_py-0.27.1-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:41e532bbdcb57c92ba3be62c42e9f096431b4cf478da9bc3bc6ce5c38ab7ba7a", size = 405699, upload-time = "2025-08-27T12:13:20.089Z" }, - { url = "https://files.pythonhosted.org/packages/d0/fd/c5987b5e054548df56953a21fe2ebed51fc1ec7c8f24fd41c067b68c4a0a/rpds_py-0.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f149826d742b406579466283769a8ea448eed82a789af0ed17b0cd5770433444", size = 423713, upload-time = "2025-08-27T12:13:21.436Z" }, - { url = "https://files.pythonhosted.org/packages/ac/ba/3c4978b54a73ed19a7d74531be37a8bcc542d917c770e14d372b8daea186/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:80c60cfb5310677bd67cb1e85a1e8eb52e12529545441b43e6f14d90b878775a", size = 562324, upload-time = "2025-08-27T12:13:22.789Z" }, - { url = "https://files.pythonhosted.org/packages/b5/6c/6943a91768fec16db09a42b08644b960cff540c66aab89b74be6d4a144ba/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7ee6521b9baf06085f62ba9c7a3e5becffbc32480d2f1b351559c001c38ce4c1", size = 593646, upload-time = "2025-08-27T12:13:24.122Z" }, - { url = "https://files.pythonhosted.org/packages/11/73/9d7a8f4be5f4396f011a6bb7a19fe26303a0dac9064462f5651ced2f572f/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a512c8263249a9d68cac08b05dd59d2b3f2061d99b322813cbcc14c3c7421998", size = 558137, upload-time = "2025-08-27T12:13:25.557Z" }, - { url = "https://files.pythonhosted.org/packages/6e/96/6772cbfa0e2485bcceef8071de7821f81aeac8bb45fbfd5542a3e8108165/rpds_py-0.27.1-cp312-cp312-win32.whl", hash = "sha256:819064fa048ba01b6dadc5116f3ac48610435ac9a0058bbde98e569f9e785c39", size = 221343, upload-time = "2025-08-27T12:13:26.967Z" }, - { url = "https://files.pythonhosted.org/packages/67/b6/c82f0faa9af1c6a64669f73a17ee0eeef25aff30bb9a1c318509efe45d84/rpds_py-0.27.1-cp312-cp312-win_amd64.whl", hash = "sha256:d9199717881f13c32c4046a15f024971a3b78ad4ea029e8da6b86e5aa9cf4594", size = 232497, upload-time = "2025-08-27T12:13:28.326Z" }, - { url = "https://files.pythonhosted.org/packages/e1/96/2817b44bd2ed11aebacc9251da03689d56109b9aba5e311297b6902136e2/rpds_py-0.27.1-cp312-cp312-win_arm64.whl", hash = "sha256:33aa65b97826a0e885ef6e278fbd934e98cdcfed80b63946025f01e2f5b29502", size = 222790, upload-time = "2025-08-27T12:13:29.71Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -2563,25 +2154,15 @@ wheels = [ [[package]] name = "sentry-sdk" -<<<<<<< HEAD version = "2.43.0" -======= -version = "2.39.0" ->>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "urllib3" }, ] -<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/b3/18/09875b4323b03ca9025bae7e6539797b27e4fc032998a466b4b9c3d24653/sentry_sdk-2.43.0.tar.gz", hash = "sha256:52ed6e251c5d2c084224d73efee56b007ef5c2d408a4a071270e82131d336e20", size = 368953, upload-time = "2025-10-29T11:26:08.156Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/69/31/8228fa962f7fd8814d634e4ebece8780e2cdcfbdf0cd2e14d4a6861a7cd5/sentry_sdk-2.43.0-py2.py3-none-any.whl", hash = "sha256:4aacafcf1756ef066d359ae35030881917160ba7f6fc3ae11e0e58b09edc2d5d", size = 400997, upload-time = "2025-10-29T11:26:05.77Z" }, -======= -sdist = { url = "https://files.pythonhosted.org/packages/4c/72/43294fa4bdd75c51610b5104a3ff834459ba653abb415150aa7826a249dd/sentry_sdk-2.39.0.tar.gz", hash = "sha256:8c185854d111f47f329ab6bc35993f28f7a6b7114db64aa426b326998cfa14e9", size = 348556, upload-time = "2025-09-25T09:15:39.064Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/dd/44/4356cc64246ba7b2b920f7c97a85c3c52748e213e250b512ee8152eb559d/sentry_sdk-2.39.0-py2.py3-none-any.whl", hash = "sha256:ba655ca5e57b41569b18e2a5552cb3375209760a5d332cdd87c6c3f28f729602", size = 370851, upload-time = "2025-09-25T09:15:36.35Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -2883,11 +2464,7 @@ wheels = [ [[package]] name = "transformers" -<<<<<<< HEAD version = "4.57.1" -======= -version = "4.56.2" ->>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "filelock" }, @@ -2901,15 +2478,9 @@ dependencies = [ { name = "tokenizers" }, { name = "tqdm" }, ] -<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/d6/68/a39307bcc4116a30b2106f2e689130a48de8bd8a1e635b5e1030e46fcd9e/transformers-4.57.1.tar.gz", hash = "sha256:f06c837959196c75039809636cd964b959f6604b75b8eeec6fdfc0440b89cc55", size = 10142511, upload-time = "2025-10-14T15:39:26.18Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/71/d3/c16c3b3cf7655a67db1144da94b021c200ac1303f82428f2beef6c2e72bb/transformers-4.57.1-py3-none-any.whl", hash = "sha256:b10d05da8fa67dc41644dbbf9bc45a44cb86ae33da6f9295f5fbf5b7890bd267", size = 11990925, upload-time = "2025-10-14T15:39:23.085Z" }, -======= -sdist = { url = "https://files.pythonhosted.org/packages/e5/82/0bcfddd134cdf53440becb5e738257cc3cf34cf229d63b57bfd288e6579f/transformers-4.56.2.tar.gz", hash = "sha256:5e7c623e2d7494105c726dd10f6f90c2c99a55ebe86eef7233765abd0cb1c529", size = 9844296, upload-time = "2025-09-19T15:16:26.778Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/70/26/2591b48412bde75e33bfd292034103ffe41743cacd03120e3242516cd143/transformers-4.56.2-py3-none-any.whl", hash = "sha256:79c03d0e85b26cb573c109ff9eafa96f3c8d4febfd8a0774e8bba32702dd6dde", size = 11608055, upload-time = "2025-09-19T15:16:23.736Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -2925,12 +2496,6 @@ sdist = { url = "https://files.pythonhosted.org/packages/42/c2/65f13aec253100e19 name = "triton" version = "3.5.0" source = { registry = "https://pypi.org/simple" } -<<<<<<< HEAD -======= -dependencies = [ - { name = "setuptools" }, -] ->>>>>>> 8387c31 (uv sync) wheels = [ { url = "https://files.pythonhosted.org/packages/f5/3a/e991574f3102147b642e49637e0281e9bb7c4ba254edb2bab78247c85e01/triton-3.5.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9e71db82261c4ffa3921cd050cd5faa18322d2d405c30eb56084afaff3b0833", size = 170476535, upload-time = "2025-10-13T16:38:05.18Z" }, ] @@ -2949,11 +2514,7 @@ wheels = [ [[package]] name = "typer" -<<<<<<< HEAD version = "0.20.0" -======= -version = "0.19.2" ->>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -2961,15 +2522,9 @@ dependencies = [ { name = "shellingham" }, { name = "typing-extensions" }, ] -<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/8f/28/7c85c8032b91dbe79725b6f17d2fffc595dff06a35c7a30a37bef73a1ab4/typer-0.20.0.tar.gz", hash = "sha256:1aaf6494031793e4876fb0bacfa6a912b551cf43c1e63c800df8b1a866720c37", size = 106492, upload-time = "2025-10-20T17:03:49.445Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/78/64/7713ffe4b5983314e9d436a90d5bd4f63b6054e2aca783a3cfc44cb95bbf/typer-0.20.0-py3-none-any.whl", hash = "sha256:5b463df6793ec1dca6213a3cf4c0f03bc6e322ac5e16e13ddd622a889489784a", size = 47028, upload-time = "2025-10-20T17:03:47.617Z" }, -======= -sdist = { url = "https://files.pythonhosted.org/packages/21/ca/950278884e2ca20547ff3eb109478c6baf6b8cf219318e6bc4f666fad8e8/typer-0.19.2.tar.gz", hash = "sha256:9ad824308ded0ad06cc716434705f691d4ee0bfd0fb081839d2e426860e7fdca", size = 104755, upload-time = "2025-09-23T09:47:48.256Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/00/22/35617eee79080a5d071d0f14ad698d325ee6b3bf824fc0467c03b30e7fa8/typer-0.19.2-py3-none-any.whl", hash = "sha256:755e7e19670ffad8283db353267cb81ef252f595aa6834a0d1ca9312d9326cb9", size = 46748, upload-time = "2025-09-23T09:47:46.777Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -2979,18 +2534,6 @@ source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/52/68/943c3aeaf14624712a0357c4a67814dba5cea36d194f5c764dad7959a00c/types-certifi-2021.10.8.3.tar.gz", hash = "sha256:72cf7798d165bc0b76e1c10dd1ea3097c7063c42c21d664523b928e88b554a4f", size = 2095, upload-time = "2022-06-09T15:19:05.244Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b5/63/2463d89481e811f007b0e1cd0a91e52e141b47f9de724d20db7b861dcfec/types_certifi-2021.10.8.3-py3-none-any.whl", hash = "sha256:b2d1e325e69f71f7c78e5943d410e650b4707bb0ef32e4ddf3da37f54176e88a", size = 2136, upload-time = "2022-06-09T15:19:03.127Z" }, -<<<<<<< HEAD -======= -] - -[[package]] -name = "types-python-dateutil" -version = "2.9.0.20250822" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0c/0a/775f8551665992204c756be326f3575abba58c4a3a52eef9909ef4536428/types_python_dateutil-2.9.0.20250822.tar.gz", hash = "sha256:84c92c34bd8e68b117bff742bc00b692a1e8531262d4507b33afcc9f7716cd53", size = 16084, upload-time = "2025-08-22T03:02:00.613Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ab/d9/a29dfa84363e88b053bf85a8b7f212a04f0d7343a4d24933baa45c06e08b/types_python_dateutil-2.9.0.20250822-py3-none-any.whl", hash = "sha256:849d52b737e10a6dc6621d2bd7940ec7c65fcb69e6aa2882acf4e56b2b508ddc", size = 17892, upload-time = "2025-08-22T03:01:59.436Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -3074,11 +2617,7 @@ wheels = [ [[package]] name = "wandb" -<<<<<<< HEAD version = "0.22.3" -======= -version = "0.22.1" ->>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -3092,7 +2631,6 @@ dependencies = [ { name = "sentry-sdk" }, { name = "typing-extensions" }, ] -<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/c1/d1/6b70f365ed86bd69debba8ad55dec8606fc21006e7ca703a5a091bd3b719/wandb-0.22.3.tar.gz", hash = "sha256:04468a8ab2769a46f5e384c9c4ada5da0dced005ca689a8424e4b8b5cb2a0291", size = 44337368, upload-time = "2025-10-28T23:59:10.275Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/23/02/87fb60f587ec249f784a40bd91c30de1b2b24d691ee72675d5b66c3d0728/wandb-0.22.3-py3-none-macosx_12_0_arm64.whl", hash = "sha256:81b3b6e405f38342b0a080898b7d00c5b9375432f5ba358942a09e65cdcfe781", size = 18758047, upload-time = "2025-10-28T23:58:46.56Z" }, @@ -3104,19 +2642,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/da/91/1decaf1a6ac2017481c782e0fad7f90bc9ae4057f3d76d478cb6527f3dd3/wandb-0.22.3-py3-none-win32.whl", hash = "sha256:09ca1edfe0fd6dc30447d368acddb825668e60ee705c98594a6bbfd30d34d47e", size = 19160297, upload-time = "2025-10-28T23:59:01.536Z" }, { url = "https://files.pythonhosted.org/packages/4c/ba/3b092634279994b0c79fe05220532822be09f3a353ae95c54e7142769db8/wandb-0.22.3-py3-none-win_amd64.whl", hash = "sha256:55403bf93872c9978433d101324f51e43e78c70c809bf6d06ca7b2760e39f497", size = 19160300, upload-time = "2025-10-28T23:59:04.06Z" }, { url = "https://files.pythonhosted.org/packages/7f/80/4662fce9eebcc8c71f5083e9152ccaf7d43d4ca9c446e1422f9aa784a51c/wandb-0.22.3-py3-none-win_arm64.whl", hash = "sha256:49f66b05882abfa53816cc8d01b3c2435a89c5a090176802fa6928b5979d34d9", size = 17461959, upload-time = "2025-10-28T23:59:07.059Z" }, -======= -sdist = { url = "https://files.pythonhosted.org/packages/ac/6f/be255b13157cab6c6670594171f59f67bd8a89f20d1978dc4eb892e2de27/wandb-0.22.1.tar.gz", hash = "sha256:6a1d668ecd6bd6531a73f6f7cfec0a93a08ef578c16ccf7167168c52cbf8cb12", size = 40246806, upload-time = "2025-09-29T17:15:55.207Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/76/73/de1d62301ef5d084160221637f34a821b7ed90b0769698b7b420686608ab/wandb-0.22.1-py3-none-macosx_12_0_arm64.whl", hash = "sha256:d862d0d28919556a5c32977138449812a2d127853e20b0deb39a5ab17700230f", size = 18370574, upload-time = "2025-09-29T17:15:18.236Z" }, - { url = "https://files.pythonhosted.org/packages/42/0e/4f60d9c7f1fa9d249dcbe70c6bad1573a9cfc070d00c3d8dbd62f715938d/wandb-0.22.1-py3-none-macosx_12_0_x86_64.whl", hash = "sha256:ce57213de331717270020f7e07b098a0ea37646550b63758eabf8cb05eeb066f", size = 19392851, upload-time = "2025-09-29T17:15:22.093Z" }, - { url = "https://files.pythonhosted.org/packages/c6/8b/757ede4a581eece5e72ade51fd4b43cfedbd3e39b85fe29d0198bc98131b/wandb-0.22.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5a0ac652c23bf88e12bf0c04e911ff4f95696ac60a3612d81e54f1f8d89f3c5", size = 18171463, upload-time = "2025-09-29T17:15:24.588Z" }, - { url = "https://files.pythonhosted.org/packages/a2/e6/275d60292183d4de89fc9053887192f978fd8612e55c8f7719aa5c81bbd1/wandb-0.22.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dc14dd06938c282900dd9f72cbaaed45368b0c6b9bc2ffd1f45d07eeb13095b", size = 19585538, upload-time = "2025-09-29T17:15:28.432Z" }, - { url = "https://files.pythonhosted.org/packages/a8/5c/4199abb92d06de6ebd63ee33551ba0de6d91a814ac42e372dec6d8009ea0/wandb-0.22.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1b2d2b9d8d1ea8aea3c2cbf9de7696105432886ba9845c50e7cc71613aa6c8ef", size = 18210525, upload-time = "2025-09-29T17:15:33.459Z" }, - { url = "https://files.pythonhosted.org/packages/0d/00/a7719c048115825861a31435fa911887c9949b20096dbc7307e11b3c981b/wandb-0.22.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:051906d7f22bdf8c07c8837ffc6d9ae357d61dcd74cfb7d29fd0243e03da8f4a", size = 19680055, upload-time = "2025-09-29T17:15:38.521Z" }, - { url = "https://files.pythonhosted.org/packages/6f/5d/e6270557a315211e880c1efa9c1cab577f945d81168bc1c1187fd483f1bb/wandb-0.22.1-py3-none-win32.whl", hash = "sha256:b2df59bd70771329f27171f55d25d5557731bb0674d60db4735c173a8fb8076d", size = 18769036, upload-time = "2025-09-29T17:15:43.19Z" }, - { url = "https://files.pythonhosted.org/packages/92/fe/34cdfd491ea6c89495794f361102b727b922adcc4f3eedb47c8aa16984c3/wandb-0.22.1-py3-none-win_amd64.whl", hash = "sha256:c1b442e6de805d78743321200a27099517509f9e4aa2e6d330211a4809f932d7", size = 18769038, upload-time = "2025-09-29T17:15:46.977Z" }, - { url = "https://files.pythonhosted.org/packages/1e/9e/fe95f5d48ff10215b7d7e67dc998cba3f660027829fac2a67c79ce89e985/wandb-0.22.1-py3-none-win_arm64.whl", hash = "sha256:52758008c9ef9e7201113af08d6015322a699ebe3497a6e6fc885b39f5652b4d", size = 17077774, upload-time = "2025-09-29T17:15:50.588Z" }, ->>>>>>> 8387c31 (uv sync) ] [[package]] @@ -3225,18 +2750,13 @@ wheels = [ [[package]] name = "yarl" -<<<<<<< HEAD version = "1.22.0" -======= -version = "1.20.1" ->>>>>>> 8387c31 (uv sync) source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "multidict" }, { name = "propcache" }, ] -<<<<<<< HEAD sdist = { url = "https://files.pythonhosted.org/packages/57/63/0c6ebca57330cd313f6102b16dd57ffaf3ec4c83403dcb45dbd15c6f3ea1/yarl-1.22.0.tar.gz", hash = "sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71", size = 187169, upload-time = "2025-10-06T14:12:55.963Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/75/ff/46736024fee3429b80a165a732e38e5d5a238721e634ab41b040d49f8738/yarl-1.22.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e340382d1afa5d32b892b3ff062436d592ec3d692aeea3bef3a5cfe11bbf8c6f", size = 142000, upload-time = "2025-10-06T14:09:44.631Z" }, @@ -3256,26 +2776,4 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c8/9a/6ad1a9b37c2f72874f93e691b2e7ecb6137fb2b899983125db4204e47575/yarl-1.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:8884d8b332a5e9b88e23f60bb166890009429391864c685e17bd73a9eda9105c", size = 87213, upload-time = "2025-10-06T14:10:11.369Z" }, { url = "https://files.pythonhosted.org/packages/44/c5/c21b562d1680a77634d748e30c653c3ca918beb35555cff24986fff54598/yarl-1.22.0-cp312-cp312-win_arm64.whl", hash = "sha256:ea70f61a47f3cc93bdf8b2f368ed359ef02a01ca6393916bc8ff877427181e74", size = 81330, upload-time = "2025-10-06T14:10:13.112Z" }, { url = "https://files.pythonhosted.org/packages/73/ae/b48f95715333080afb75a4504487cbe142cae1268afc482d06692d605ae6/yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff", size = 46814, upload-time = "2025-10-06T14:12:53.872Z" }, -======= -sdist = { url = "https://files.pythonhosted.org/packages/3c/fb/efaa23fa4e45537b827620f04cf8f3cd658b76642205162e072703a5b963/yarl-1.20.1.tar.gz", hash = "sha256:d017a4997ee50c91fd5466cef416231bb82177b93b029906cefc542ce14c35ac", size = 186428, upload-time = "2025-06-10T00:46:09.923Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5f/9a/cb7fad7d73c69f296eda6815e4a2c7ed53fc70c2f136479a91c8e5fbdb6d/yarl-1.20.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdcc4cd244e58593a4379fe60fdee5ac0331f8eb70320a24d591a3be197b94a9", size = 133667, upload-time = "2025-06-10T00:43:44.369Z" }, - { url = "https://files.pythonhosted.org/packages/67/38/688577a1cb1e656e3971fb66a3492501c5a5df56d99722e57c98249e5b8a/yarl-1.20.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b29a2c385a5f5b9c7d9347e5812b6f7ab267193c62d282a540b4fc528c8a9d2a", size = 91025, upload-time = "2025-06-10T00:43:46.295Z" }, - { url = "https://files.pythonhosted.org/packages/50/ec/72991ae51febeb11a42813fc259f0d4c8e0507f2b74b5514618d8b640365/yarl-1.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1112ae8154186dfe2de4732197f59c05a83dc814849a5ced892b708033f40dc2", size = 89709, upload-time = "2025-06-10T00:43:48.22Z" }, - { url = "https://files.pythonhosted.org/packages/99/da/4d798025490e89426e9f976702e5f9482005c548c579bdae792a4c37769e/yarl-1.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90bbd29c4fe234233f7fa2b9b121fb63c321830e5d05b45153a2ca68f7d310ee", size = 352287, upload-time = "2025-06-10T00:43:49.924Z" }, - { url = "https://files.pythonhosted.org/packages/1a/26/54a15c6a567aac1c61b18aa0f4b8aa2e285a52d547d1be8bf48abe2b3991/yarl-1.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:680e19c7ce3710ac4cd964e90dad99bf9b5029372ba0c7cbfcd55e54d90ea819", size = 345429, upload-time = "2025-06-10T00:43:51.7Z" }, - { url = "https://files.pythonhosted.org/packages/d6/95/9dcf2386cb875b234353b93ec43e40219e14900e046bf6ac118f94b1e353/yarl-1.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a979218c1fdb4246a05efc2cc23859d47c89af463a90b99b7c56094daf25a16", size = 365429, upload-time = "2025-06-10T00:43:53.494Z" }, - { url = "https://files.pythonhosted.org/packages/91/b2/33a8750f6a4bc224242a635f5f2cff6d6ad5ba651f6edcccf721992c21a0/yarl-1.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255b468adf57b4a7b65d8aad5b5138dce6a0752c139965711bdcb81bc370e1b6", size = 363862, upload-time = "2025-06-10T00:43:55.766Z" }, - { url = "https://files.pythonhosted.org/packages/98/28/3ab7acc5b51f4434b181b0cee8f1f4b77a65919700a355fb3617f9488874/yarl-1.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a97d67108e79cfe22e2b430d80d7571ae57d19f17cda8bb967057ca8a7bf5bfd", size = 355616, upload-time = "2025-06-10T00:43:58.056Z" }, - { url = "https://files.pythonhosted.org/packages/36/a3/f666894aa947a371724ec7cd2e5daa78ee8a777b21509b4252dd7bd15e29/yarl-1.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8570d998db4ddbfb9a590b185a0a33dbf8aafb831d07a5257b4ec9948df9cb0a", size = 339954, upload-time = "2025-06-10T00:43:59.773Z" }, - { url = "https://files.pythonhosted.org/packages/f1/81/5f466427e09773c04219d3450d7a1256138a010b6c9f0af2d48565e9ad13/yarl-1.20.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:97c75596019baae7c71ccf1d8cc4738bc08134060d0adfcbe5642f778d1dca38", size = 365575, upload-time = "2025-06-10T00:44:02.051Z" }, - { url = "https://files.pythonhosted.org/packages/2e/e3/e4b0ad8403e97e6c9972dd587388940a032f030ebec196ab81a3b8e94d31/yarl-1.20.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1c48912653e63aef91ff988c5432832692ac5a1d8f0fb8a33091520b5bbe19ef", size = 365061, upload-time = "2025-06-10T00:44:04.196Z" }, - { url = "https://files.pythonhosted.org/packages/ac/99/b8a142e79eb86c926f9f06452eb13ecb1bb5713bd01dc0038faf5452e544/yarl-1.20.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4c3ae28f3ae1563c50f3d37f064ddb1511ecc1d5584e88c6b7c63cf7702a6d5f", size = 364142, upload-time = "2025-06-10T00:44:06.527Z" }, - { url = "https://files.pythonhosted.org/packages/34/f2/08ed34a4a506d82a1a3e5bab99ccd930a040f9b6449e9fd050320e45845c/yarl-1.20.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c5e9642f27036283550f5f57dc6156c51084b458570b9d0d96100c8bebb186a8", size = 381894, upload-time = "2025-06-10T00:44:08.379Z" }, - { url = "https://files.pythonhosted.org/packages/92/f8/9a3fbf0968eac704f681726eff595dce9b49c8a25cd92bf83df209668285/yarl-1.20.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2c26b0c49220d5799f7b22c6838409ee9bc58ee5c95361a4d7831f03cc225b5a", size = 383378, upload-time = "2025-06-10T00:44:10.51Z" }, - { url = "https://files.pythonhosted.org/packages/af/85/9363f77bdfa1e4d690957cd39d192c4cacd1c58965df0470a4905253b54f/yarl-1.20.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:564ab3d517e3d01c408c67f2e5247aad4019dcf1969982aba3974b4093279004", size = 374069, upload-time = "2025-06-10T00:44:12.834Z" }, - { url = "https://files.pythonhosted.org/packages/35/99/9918c8739ba271dcd935400cff8b32e3cd319eaf02fcd023d5dcd487a7c8/yarl-1.20.1-cp312-cp312-win32.whl", hash = "sha256:daea0d313868da1cf2fac6b2d3a25c6e3a9e879483244be38c8e6a41f1d876a5", size = 81249, upload-time = "2025-06-10T00:44:14.731Z" }, - { url = "https://files.pythonhosted.org/packages/eb/83/5d9092950565481b413b31a23e75dd3418ff0a277d6e0abf3729d4d1ce25/yarl-1.20.1-cp312-cp312-win_amd64.whl", hash = "sha256:48ea7d7f9be0487339828a4de0360d7ce0efc06524a48e1810f945c45b813698", size = 86710, upload-time = "2025-06-10T00:44:16.716Z" }, - { url = "https://files.pythonhosted.org/packages/b4/2d/2345fce04cfd4bee161bf1e7d9cdc702e3e16109021035dbb24db654a622/yarl-1.20.1-py3-none-any.whl", hash = "sha256:83b8eb083fe4683c6115795d9fc1cfaf2cbbefb19b3a1cb68f6527460f483a77", size = 46542, upload-time = "2025-06-10T00:46:07.521Z" }, ->>>>>>> 8387c31 (uv sync) ] From 1ee4eb43eb13e694e57f26711ed061d322a068aa Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 6 Nov 2025 21:05:43 +0000 Subject: [PATCH 42/99] downgrade datasets --- pyproject.toml | 5 ++-- uv.lock | 70 +++++++++++++++++++++++++++++++++----------------- 2 files changed, 49 insertions(+), 26 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 3f80dc2..67f93cf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ requires-python = ">=3.12,<3.13" dependencies = [ "torch>=2.8.0", "nnsight==0.5.0.dev7", - "datasets>=3.6.0", + "datasets==3.6.0", "h5py>=3.13.0", "einops>=0.8.1", "jaxtyping>=0.3.2", @@ -24,7 +24,8 @@ dependencies = [ "numpy>=1.24.0", "jsonargparse[signatures]>=4.27.7", "modal>=1.1.4", - "circuit-tracer@git+https://github.com/safety-research/circuit-tracer.git@main" + "circuit-tracer@git+https://github.com/safety-research/circuit-tracer.git@main", + "hf-transfer>=0.1.9", ] [project.optional-dependencies] diff --git a/uv.lock b/uv.lock index 7e56af8..8dd4d48 100644 --- a/uv.lock +++ b/uv.lock @@ -392,6 +392,7 @@ dependencies = [ { name = "datasets" }, { name = "einops" }, { name = "h5py" }, + { name = "hf-transfer" }, { name = "jaxtyping" }, { name = "jsonargparse", extra = ["signatures"] }, { name = "lightning" }, @@ -422,9 +423,10 @@ dev = [ requires-dist = [ { name = "circuit-tracer", git = "https://github.com/safety-research/circuit-tracer.git?rev=main" }, { name = "circuit-tracer", marker = "extra == 'dev'" }, - { name = "datasets", specifier = ">=3.6.0" }, + { name = "datasets", specifier = "==3.6.0" }, { name = "einops", specifier = ">=0.8.1" }, { name = "h5py", specifier = ">=3.13.0" }, + { name = "hf-transfer", specifier = ">=0.1.9" }, { name = "ipykernel", marker = "extra == 'dev'", specifier = ">=6.29.5" }, { name = "jaxtyping", specifier = ">=0.3.2" }, { name = "jsonargparse", extras = ["signatures"], specifier = ">=4.27.7" }, @@ -449,13 +451,12 @@ dev = [ [[package]] name = "datasets" -version = "4.4.1" +version = "3.6.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "dill" }, { name = "filelock" }, { name = "fsspec", extra = ["http"] }, - { name = "httpx" }, { name = "huggingface-hub" }, { name = "multiprocess" }, { name = "numpy" }, @@ -467,9 +468,9 @@ dependencies = [ { name = "tqdm" }, { name = "xxhash" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/93/bf/0dae295d6d1ba0b1a200a9dd216838464b5bbd05da01407cb1330b377445/datasets-4.4.1.tar.gz", hash = "sha256:80322699aa8c0bbbdb7caa87906da689c3c2e29523cff698775c67f28fdab1fc", size = 585341, upload-time = "2025-11-05T16:00:38.162Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1a/89/d3d6fef58a488f8569c82fd293ab7cbd4250244d67f425dcae64c63800ea/datasets-3.6.0.tar.gz", hash = "sha256:1b2bf43b19776e2787e181cfd329cb0ca1a358ea014780c3581e0f276375e041", size = 569336, upload-time = "2025-05-07T15:15:02.659Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3b/5e/6f8d874366788ad5d549e9ba258037d974dda6e004843be1bda794571701/datasets-4.4.1-py3-none-any.whl", hash = "sha256:c1163de5211e42546079ab355cc0250c7e6db16eb209ac5ac6252f801f596c44", size = 511591, upload-time = "2025-11-05T16:00:36.365Z" }, + { url = "https://files.pythonhosted.org/packages/20/34/a08b0ee99715eaba118cbe19a71f7b5e2425c2718ef96007c325944a1152/datasets-3.6.0-py3-none-any.whl", hash = "sha256:25000c4a2c0873a710df127d08a202a06eab7bf42441a6bc278b499c2f72cd1b", size = 491546, upload-time = "2025-05-07T15:14:59.742Z" }, ] [[package]] @@ -505,11 +506,11 @@ wheels = [ [[package]] name = "dill" -version = "0.4.0" +version = "0.3.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/12/80/630b4b88364e9a8c8c5797f4602d0f76ef820909ee32f0bacb9f90654042/dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0", size = 186976, upload-time = "2025-04-16T00:41:48.867Z" } +sdist = { url = "https://files.pythonhosted.org/packages/17/4d/ac7ffa80c69ea1df30a8aa11b3578692a5118e7cd1aa157e3ef73b092d15/dill-0.3.8.tar.gz", hash = "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca", size = 184847, upload-time = "2024-01-27T23:42:16.145Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049", size = 119668, upload-time = "2025-04-16T00:41:47.671Z" }, + { url = "https://files.pythonhosted.org/packages/c9/7a/cef76fd8438a42f96db64ddaa85280485a9c395e7df3db8158cfec1eee34/dill-0.3.8-py3-none-any.whl", hash = "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7", size = 116252, upload-time = "2024-01-27T23:42:14.239Z" }, ] [[package]] @@ -602,11 +603,11 @@ wheels = [ [[package]] name = "fsspec" -version = "2025.10.0" +version = "2025.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/24/7f/2747c0d332b9acfa75dc84447a066fdf812b5a6b8d30472b74d309bfe8cb/fsspec-2025.10.0.tar.gz", hash = "sha256:b6789427626f068f9a83ca4e8a3cc050850b6c0f71f99ddb4f542b8266a26a59", size = 309285, upload-time = "2025-10-30T14:58:44.036Z" } +sdist = { url = "https://files.pythonhosted.org/packages/34/f4/5721faf47b8c499e776bc34c6a8fc17efdf7fdef0b00f398128bc5dcb4ac/fsspec-2025.3.0.tar.gz", hash = "sha256:a935fd1ea872591f2b5148907d103488fc523295e6c64b835cfad8c3eca44972", size = 298491, upload-time = "2025-03-07T21:47:56.461Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/eb/02/a6b21098b1d5d6249b7c5ab69dde30108a71e4e819d4a9778f1de1d5b70d/fsspec-2025.10.0-py3-none-any.whl", hash = "sha256:7c7712353ae7d875407f97715f0e1ffcc21e33d5b24556cb1e090ae9409ec61d", size = 200966, upload-time = "2025-10-30T14:58:42.53Z" }, + { url = "https://files.pythonhosted.org/packages/56/53/eb690efa8513166adef3e0669afd31e95ffde69fb3c52ec2ac7223ed6018/fsspec-2025.3.0-py3-none-any.whl", hash = "sha256:efb87af3efa9103f94ca91a7f8cb7a4df91af9f74fc106c9c7ea0efd7277c1b3", size = 193615, upload-time = "2025-03-07T21:47:54.809Z" }, ] [package.optional-dependencies] @@ -692,6 +693,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/09/a8/2d02b10a66747c54446e932171dd89b8b4126c0111b440e6bc05a7c852ec/h5py-3.15.1-cp312-cp312-win_arm64.whl", hash = "sha256:61d5a58a9851e01ee61c932bbbb1c98fe20aba0a5674776600fb9a361c0aa652", size = 2458214, upload-time = "2025-10-16T10:34:35.733Z" }, ] +[[package]] +name = "hf-transfer" +version = "0.1.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1a/eb/8fc64f40388c29ce8ce3b2b180a089d4d6b25b1d0d232d016704cb852104/hf_transfer-0.1.9.tar.gz", hash = "sha256:035572865dab29d17e783fbf1e84cf1cb24f3fcf8f1b17db1cfc7fdf139f02bf", size = 25201, upload-time = "2025-01-07T10:05:12.947Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/f5/461d2e5f307e5048289b1168d5c642ae3bb2504e88dff1a38b92ed990a21/hf_transfer-0.1.9-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:e66acf91df4a8b72f60223059df3003062a5ae111757187ed1a06750a30e911b", size = 1393046, upload-time = "2025-01-07T10:04:51.003Z" }, + { url = "https://files.pythonhosted.org/packages/41/ba/8d9fd9f1083525edfcb389c93738c802f3559cb749324090d7109c8bf4c2/hf_transfer-0.1.9-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:8669dbcc7a3e2e8d61d42cd24da9c50d57770bd74b445c65123291ca842a7e7a", size = 1348126, upload-time = "2025-01-07T10:04:45.712Z" }, + { url = "https://files.pythonhosted.org/packages/8e/a2/cd7885bc9959421065a6fae0fe67b6c55becdeda4e69b873e52976f9a9f0/hf_transfer-0.1.9-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8fd0167c4407a3bc4cdd0307e65ada2294ec04f1813d8a69a5243e379b22e9d8", size = 3728604, upload-time = "2025-01-07T10:04:14.173Z" }, + { url = "https://files.pythonhosted.org/packages/f6/2e/a072cf196edfeda3310c9a5ade0a0fdd785e6154b3ce24fc738c818da2a7/hf_transfer-0.1.9-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ee8b10afedcb75f71091bcc197c526a6ebf5c58bbbadb34fdeee6160f55f619f", size = 3064995, upload-time = "2025-01-07T10:04:18.663Z" }, + { url = "https://files.pythonhosted.org/packages/c2/84/aec9ef4c0fab93c1ea2b1badff38c78b4b2f86f0555b26d2051dbc920cde/hf_transfer-0.1.9-cp38-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5828057e313de59300dd1abb489444bc452efe3f479d3c55b31a8f680936ba42", size = 3580908, upload-time = "2025-01-07T10:04:32.834Z" }, + { url = "https://files.pythonhosted.org/packages/29/63/b560d39651a56603d64f1a0212d0472a44cbd965db2fa62b99d99cb981bf/hf_transfer-0.1.9-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc6bd19e1cc177c66bdef15ef8636ad3bde79d5a4f608c158021153b4573509d", size = 3400839, upload-time = "2025-01-07T10:04:26.122Z" }, + { url = "https://files.pythonhosted.org/packages/d6/d8/f87ea6f42456254b48915970ed98e993110521e9263472840174d32c880d/hf_transfer-0.1.9-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdca9bfb89e6f8f281890cc61a8aff2d3cecaff7e1a4d275574d96ca70098557", size = 3552664, upload-time = "2025-01-07T10:04:40.123Z" }, + { url = "https://files.pythonhosted.org/packages/d6/56/1267c39b65fc8f4e2113b36297320f102718bf5799b544a6cbe22013aa1d/hf_transfer-0.1.9-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:89a23f58b7b7effbc047b8ca286f131b17728c99a9f972723323003ffd1bb916", size = 4073732, upload-time = "2025-01-07T10:04:55.624Z" }, + { url = "https://files.pythonhosted.org/packages/82/1a/9c748befbe3decf7cb415e34f8a0c3789a0a9c55910dea73d581e48c0ce5/hf_transfer-0.1.9-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:dc7fff1345980d6c0ebb92c811d24afa4b98b3e07ed070c8e38cc91fd80478c5", size = 3390096, upload-time = "2025-01-07T10:04:59.98Z" }, + { url = "https://files.pythonhosted.org/packages/72/85/4c03da147b6b4b7cb12e074d3d44eee28604a387ed0eaf7eaaead5069c57/hf_transfer-0.1.9-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:1a6bd16c667ebe89a069ca163060127a794fa3a3525292c900b8c8cc47985b0d", size = 3664743, upload-time = "2025-01-07T10:05:05.416Z" }, + { url = "https://files.pythonhosted.org/packages/e7/6e/e597b04f753f1b09e6893075d53a82a30c13855cbaa791402695b01e369f/hf_transfer-0.1.9-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d2fde99d502093ade3ab1b53f80da18480e9902aa960dab7f74fb1b9e5bc5746", size = 3695243, upload-time = "2025-01-07T10:05:11.411Z" }, + { url = "https://files.pythonhosted.org/packages/09/89/d4e234727a26b2546c8fb70a276cd924260d60135f2165bf8b9ed67bb9a4/hf_transfer-0.1.9-cp38-abi3-win32.whl", hash = "sha256:435cc3cdc8524ce57b074032b8fd76eed70a4224d2091232fa6a8cef8fd6803e", size = 1086605, upload-time = "2025-01-07T10:05:18.873Z" }, + { url = "https://files.pythonhosted.org/packages/a1/14/f1e15b851d1c2af5b0b1a82bf8eb10bda2da62d98180220ba6fd8879bb5b/hf_transfer-0.1.9-cp38-abi3-win_amd64.whl", hash = "sha256:16f208fc678911c37e11aa7b586bc66a37d02e636208f18b6bc53d29b5df40ad", size = 1160240, upload-time = "2025-01-07T10:05:14.324Z" }, +] + [[package]] name = "hf-xet" version = "1.2.0" @@ -1325,18 +1347,18 @@ wheels = [ [[package]] name = "multiprocess" -version = "0.70.18" +version = "0.70.16" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "dill" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/72/fd/2ae3826f5be24c6ed87266bc4e59c46ea5b059a103f3d7e7eb76a52aeecb/multiprocess-0.70.18.tar.gz", hash = "sha256:f9597128e6b3e67b23956da07cf3d2e5cba79e2f4e0fba8d7903636663ec6d0d", size = 1798503, upload-time = "2025-04-17T03:11:27.742Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b5/ae/04f39c5d0d0def03247c2893d6f2b83c136bf3320a2154d7b8858f2ba72d/multiprocess-0.70.16.tar.gz", hash = "sha256:161af703d4652a0e1410be6abccecde4a7ddffd19341be0a7011b94aeb171ac1", size = 1772603, upload-time = "2024-01-28T18:52:34.85Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ba/d8/0cba6cf51a1a31f20471fbc823a716170c73012ddc4fb85d706630ed6e8f/multiprocess-0.70.18-py310-none-any.whl", hash = "sha256:60c194974c31784019c1f459d984e8f33ee48f10fcf42c309ba97b30d9bd53ea", size = 134948, upload-time = "2025-04-17T03:11:20.223Z" }, - { url = "https://files.pythonhosted.org/packages/4b/88/9039f2fed1012ef584751d4ceff9ab4a51e5ae264898f0b7cbf44340a859/multiprocess-0.70.18-py311-none-any.whl", hash = "sha256:5aa6eef98e691281b3ad923be2832bf1c55dd2c859acd73e5ec53a66aae06a1d", size = 144462, upload-time = "2025-04-17T03:11:21.657Z" }, - { url = "https://files.pythonhosted.org/packages/bf/b6/5f922792be93b82ec6b5f270bbb1ef031fd0622847070bbcf9da816502cc/multiprocess-0.70.18-py312-none-any.whl", hash = "sha256:9b78f8e5024b573730bfb654783a13800c2c0f2dfc0c25e70b40d184d64adaa2", size = 150287, upload-time = "2025-04-17T03:11:22.69Z" }, - { url = "https://files.pythonhosted.org/packages/3b/c3/ca84c19bd14cdfc21c388fdcebf08b86a7a470ebc9f5c3c084fc2dbc50f7/multiprocess-0.70.18-py38-none-any.whl", hash = "sha256:dbf705e52a154fe5e90fb17b38f02556169557c2dd8bb084f2e06c2784d8279b", size = 132636, upload-time = "2025-04-17T03:11:24.936Z" }, - { url = "https://files.pythonhosted.org/packages/6c/28/dd72947e59a6a8c856448a5e74da6201cb5502ddff644fbc790e4bd40b9a/multiprocess-0.70.18-py39-none-any.whl", hash = "sha256:e78ca805a72b1b810c690b6b4cc32579eba34f403094bbbae962b7b5bf9dfcb8", size = 133478, upload-time = "2025-04-17T03:11:26.253Z" }, + { url = "https://files.pythonhosted.org/packages/bc/f7/7ec7fddc92e50714ea3745631f79bd9c96424cb2702632521028e57d3a36/multiprocess-0.70.16-py310-none-any.whl", hash = "sha256:c4a9944c67bd49f823687463660a2d6daae94c289adff97e0f9d696ba6371d02", size = 134824, upload-time = "2024-01-28T18:52:26.062Z" }, + { url = "https://files.pythonhosted.org/packages/50/15/b56e50e8debaf439f44befec5b2af11db85f6e0f344c3113ae0be0593a91/multiprocess-0.70.16-py311-none-any.whl", hash = "sha256:af4cabb0dac72abfb1e794fa7855c325fd2b55a10a44628a3c1ad3311c04127a", size = 143519, upload-time = "2024-01-28T18:52:28.115Z" }, + { url = "https://files.pythonhosted.org/packages/0a/7d/a988f258104dcd2ccf1ed40fdc97e26c4ac351eeaf81d76e266c52d84e2f/multiprocess-0.70.16-py312-none-any.whl", hash = "sha256:fc0544c531920dde3b00c29863377f87e1632601092ea2daca74e4beb40faa2e", size = 146741, upload-time = "2024-01-28T18:52:29.395Z" }, + { url = "https://files.pythonhosted.org/packages/ea/89/38df130f2c799090c978b366cfdf5b96d08de5b29a4a293df7f7429fa50b/multiprocess-0.70.16-py38-none-any.whl", hash = "sha256:a71d82033454891091a226dfc319d0cfa8019a4e888ef9ca910372a446de4435", size = 132628, upload-time = "2024-01-28T18:52:30.853Z" }, + { url = "https://files.pythonhosted.org/packages/da/d9/f7f9379981e39b8c2511c9e0326d212accacb82f12fbfdc1aa2ce2a7b2b6/multiprocess-0.70.16-py39-none-any.whl", hash = "sha256:a0bafd3ae1b732eac64be2e72038231c1ba97724b60b09400d68f229fcc2fbf3", size = 133351, upload-time = "2024-01-28T18:52:31.981Z" }, ] [[package]] @@ -1497,7 +1519,7 @@ name = "nvidia-cudnn-cu12" version = "9.10.2.21" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas-cu12" }, + { name = "nvidia-cublas-cu12", marker = "sys_platform == 'linux'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/ba/51/e123d997aa098c61d029f76663dedbfb9bc8dcf8c60cbd6adbe42f76d049/nvidia_cudnn_cu12-9.10.2.21-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:949452be657fa16687d0930933f032835951ef0892b37d2d53824d1a84dc97a8", size = 706758467, upload-time = "2025-06-06T21:54:08.597Z" }, @@ -1508,7 +1530,7 @@ name = "nvidia-cufft-cu12" version = "11.3.3.83" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink-cu12" }, + { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/1f/13/ee4e00f30e676b66ae65b4f08cb5bcbb8392c03f54f2d5413ea99a5d1c80/nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d2dd21ec0b88cf61b62e6b43564355e5222e4a3fb394cac0db101f2dd0d4f74", size = 193118695, upload-time = "2025-03-07T01:45:27.821Z" }, @@ -1535,9 +1557,9 @@ name = "nvidia-cusolver-cu12" version = "11.7.3.90" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas-cu12" }, - { name = "nvidia-cusparse-cu12" }, - { name = "nvidia-nvjitlink-cu12" }, + { name = "nvidia-cublas-cu12", marker = "sys_platform == 'linux'" }, + { name = "nvidia-cusparse-cu12", marker = "sys_platform == 'linux'" }, + { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/85/48/9a13d2975803e8cf2777d5ed57b87a0b6ca2cc795f9a4f59796a910bfb80/nvidia_cusolver_cu12-11.7.3.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:4376c11ad263152bd50ea295c05370360776f8c3427b30991df774f9fb26c450", size = 267506905, upload-time = "2025-03-07T01:47:16.273Z" }, @@ -1548,7 +1570,7 @@ name = "nvidia-cusparse-cu12" version = "12.5.8.93" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink-cu12" }, + { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/c2/f5/e1854cb2f2bcd4280c44736c93550cc300ff4b8c95ebe370d0aa7d2b473d/nvidia_cusparse_cu12-12.5.8.93-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ec05d76bbbd8b61b06a80e1eaf8cf4959c3d4ce8e711b65ebd0443bb0ebb13b", size = 288216466, upload-time = "2025-03-07T01:48:13.779Z" }, From 61801e5fe5845e3b48da3ddbe6bdf9fd718cf404 Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 6 Nov 2025 21:06:49 +0000 Subject: [PATCH 43/99] fix callback params --- config/circuit-tracer.yaml | 12 +++++------- crosslayer_transcoder/utils/callbacks.py | 7 ++++--- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/config/circuit-tracer.yaml b/config/circuit-tracer.yaml index 7162203..a83a2c3 100644 --- a/config/circuit-tracer.yaml +++ b/config/circuit-tracer.yaml @@ -21,13 +21,11 @@ trainer: name: "circuit-tracer" save_dir: "./wandb" callbacks: - - class_path: crosslayer_transcoder.utils.callbacks.EndOfTrainingCheckpointCallback - init_args: - checkpoint_dir: "checkpoints" - - class_path: crosslayer_transcoder.utils.callbacks.ModelConversionCallback - init_args: - save_dir: "clt_module" - kinds: ["circuit_tracer"] + class_path: crosslayer_transcoder.utils.callbacks.ModelConversionCallback + init_args: + save_dir: "clt_module" + kinds: + - "circuit_tracer" model: class_path: crosslayer_transcoder.model.clt_lightning.JumpReLUCrossLayerTranscoderModule diff --git a/crosslayer_transcoder/utils/callbacks.py b/crosslayer_transcoder/utils/callbacks.py index 953e15b..6aab2eb 100644 --- a/crosslayer_transcoder/utils/callbacks.py +++ b/crosslayer_transcoder/utils/callbacks.py @@ -65,9 +65,7 @@ def on_train_end(self, trainer, pl_module): class ModelConversionCallback(L.Callback): """Callback to convert the model to a circuit-tracer model.""" - def __init__( - self, save_dir: str = "clt_module", kinds: List[str] = ["circuit_tracer"] - ): + def __init__(self, save_dir: str = "clt_module", kinds=["circuit_tracer"]): super().__init__() self.save_dir = Path(save_dir) self.kinds = kinds @@ -84,6 +82,9 @@ def _convert_model(self, pl_module): f"{kind} model converted and saved to {self.save_dir.as_posix()}" ) + def on_test_end(self, trainer, pl_module): + self._convert_model(pl_module) + class HuggingFaceCallback(L.Callback): """Callback to upload the model to Hugging Face.""" From 0e6d1c5c709108b56113c3328d4f09654a89f95f Mon Sep 17 00:00:00 2001 From: jiito Date: Sat, 8 Nov 2025 11:01:22 -0500 Subject: [PATCH 44/99] rm math sanity check test --- tests/test_standardization_folding.py | 40 --------------------------- 1 file changed, 40 deletions(-) diff --git a/tests/test_standardization_folding.py b/tests/test_standardization_folding.py index 1937b1b..8136775 100644 --- a/tests/test_standardization_folding.py +++ b/tests/test_standardization_folding.py @@ -66,46 +66,6 @@ def test_math_sanity_check(): assert_allclose(lhs, rhs) -def test_math_sanity_check(): - encoder = Encoder(d_acts=D_ACTS, d_features=D_FEATS, n_layers=N_LAYERS).to(DTYPE) - - input_std = DimensionwiseInputStandardizer( - n_layers=N_LAYERS, activation_dim=D_ACTS - ).to(DTYPE) - input_std.initialize_from_batch(batch=BATCH) - - resid = BATCH[:, 0] - W = encoder.W - b = encoder.b - mean, std = input_std.mean, input_std.std - - W_div_std = W / std.unsqueeze(-1) - - lhs = ( - einsum( - (resid - mean) / std, - W, - "batch n_layers d_acts, n_layers d_acts d_features -> batch n_layers d_features", - ) - + b - ) - rhs = ( - einsum( - resid, - W_div_std, - "batch n_layers d_acts, n_layers d_acts d_features -> batch n_layers d_features", - ) - + b - - einsum( - mean, - W_div_std, - "n_layers d_acts, n_layers d_acts d_features -> n_layers d_features", - ) - ) - - assert_allclose(lhs, rhs) - - def test_encoder_standarization_folding(): encoder = Encoder(d_acts=D_ACTS, d_features=D_FEATS, n_layers=N_LAYERS).to(DTYPE) input_std = DimensionwiseInputStandardizer( From ba74a533c70453be5e0bb9f7cec8e23397c391fb Mon Sep 17 00:00:00 2001 From: jiito Date: Sat, 8 Nov 2025 11:23:06 -0500 Subject: [PATCH 45/99] change to train batch end --- crosslayer_transcoder/utils/callbacks.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crosslayer_transcoder/utils/callbacks.py b/crosslayer_transcoder/utils/callbacks.py index 6aab2eb..0015799 100644 --- a/crosslayer_transcoder/utils/callbacks.py +++ b/crosslayer_transcoder/utils/callbacks.py @@ -82,7 +82,8 @@ def _convert_model(self, pl_module): f"{kind} model converted and saved to {self.save_dir.as_posix()}" ) - def on_test_end(self, trainer, pl_module): + # TODO: for testing, just turn on the train batch end + def on_train_batch_end(self, trainer, pl_module): self._convert_model(pl_module) From cbd9d3af05886fc5b229901fbeb9597377445446 Mon Sep 17 00:00:00 2001 From: jiito Date: Sat, 8 Nov 2025 11:23:18 -0500 Subject: [PATCH 46/99] cleanup + todos --- crosslayer_transcoder/utils/model_converter.py | 2 -- tests/test_circuit_tracer_integration.py | 2 ++ tests/test_convert_to_circuit_tracer.py | 9 +++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/crosslayer_transcoder/utils/model_converter.py b/crosslayer_transcoder/utils/model_converter.py index 741e15a..e60ddcf 100644 --- a/crosslayer_transcoder/utils/model_converter.py +++ b/crosslayer_transcoder/utils/model_converter.py @@ -1,8 +1,6 @@ from abc import ABC, abstractmethod from typing import Union -import lightning as L - from crosslayer_transcoder.model.clt_lightning import ( CrossLayerTranscoderModule, JumpReLUCrossLayerTranscoderModule, diff --git a/tests/test_circuit_tracer_integration.py b/tests/test_circuit_tracer_integration.py index cb7e4a8..26af500 100644 --- a/tests/test_circuit_tracer_integration.py +++ b/tests/test_circuit_tracer_integration.py @@ -1,6 +1,8 @@ from circuit_tracer.utils.hf_utils import load_transcoder_from_hub import torch +# TODO: try the conversion and then try uploading + def validate_upload(repo_id: str): """Verify uploaded model loads correctly.""" diff --git a/tests/test_convert_to_circuit_tracer.py b/tests/test_convert_to_circuit_tracer.py index 0cfa1ef..c0dcd90 100644 --- a/tests/test_convert_to_circuit_tracer.py +++ b/tests/test_convert_to_circuit_tracer.py @@ -1,4 +1,7 @@ -from crosslayer_transcoder.utils.converters.circuit_tracer import CircuitTracerConverter +from crosslayer_transcoder.utils.model_converters.circuit_tracer import ( + CircuitTracerConverter, +) +import pathlib def test_circuit_tracer_converter(): @@ -15,6 +18,7 @@ def test_circuit_tracer_converter(): DimensionwiseOutputStandardizer, ) + # TODO: find a better way to build the clt_module # Create components based on default.yaml config encoder = Encoder(d_acts=768, d_features=10_000, n_layers=12) @@ -55,9 +59,6 @@ def test_circuit_tracer_converter(): compute_dead_features_every=500, ) - # Use the new CircuitTracerConverter directly - import pathlib - save_dir = pathlib.Path("clt_module") converter = CircuitTracerConverter(save_dir=save_dir) converter.convert(clt_module) From 9bf31ce31003d874fea4868e32ebc347385490bd Mon Sep 17 00:00:00 2001 From: jiito Date: Sat, 8 Nov 2025 17:14:40 +0000 Subject: [PATCH 47/99] basic checkpoint loading + test --- crosslayer_transcoder/utils/utils.py | 6 +++ tests/test_checkpoint_loading.py | 64 ++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 tests/test_checkpoint_loading.py diff --git a/crosslayer_transcoder/utils/utils.py b/crosslayer_transcoder/utils/utils.py index 3f38020..83e4d67 100644 --- a/crosslayer_transcoder/utils/utils.py +++ b/crosslayer_transcoder/utils/utils.py @@ -56,3 +56,9 @@ def plot_actvs(actvs): # Adjust layout to prevent overlap plt.tight_layout() + + +def load_model_from_lightning_checkpoint(model, checkpoint_path): + checkpoint = torch.load(checkpoint_path) + model.load_state_dict(checkpoint["state_dict"]) + return model \ No newline at end of file diff --git a/tests/test_checkpoint_loading.py b/tests/test_checkpoint_loading.py new file mode 100644 index 0000000..3fd6173 --- /dev/null +++ b/tests/test_checkpoint_loading.py @@ -0,0 +1,64 @@ +from crosslayer_transcoder.utils.utils import load_model_from_lightning_checkpoint + +def test_load_model_from_lightning_checkpoint(): + + from crosslayer_transcoder.metrics.dead_features import DeadFeatures + from crosslayer_transcoder.model.clt import ( + CrosslayerDecoder, + CrossLayerTranscoder, + Encoder, + ) + from crosslayer_transcoder.model.clt_lightning import CrossLayerTranscoderModule + from crosslayer_transcoder.model.jumprelu import JumpReLU + from crosslayer_transcoder.model.standardize import ( + DimensionwiseInputStandardizer, + DimensionwiseOutputStandardizer, + ) + + # TODO: find a better way to build the clt_module + # Create components based on default.yaml config + encoder = Encoder(d_acts=768, d_features=10_000, n_layers=12) + + decoder = CrosslayerDecoder(d_acts=768, d_features=10_000, n_layers=12) + + nonlinearity = JumpReLU(theta=0.03, bandwidth=0.01, n_layers=12, d_features=10_000) + + input_standardizer = DimensionwiseInputStandardizer(n_layers=12, activation_dim=768) + + output_standardizer = DimensionwiseOutputStandardizer( + n_layers=12, activation_dim=768 + ) + + model = CrossLayerTranscoder( + encoder=encoder, + decoder=decoder, + nonlinearity=nonlinearity, + input_standardizer=input_standardizer, + output_standardizer=output_standardizer, + ) + + dead_features = DeadFeatures( + n_features=10_000, + n_layers=12, + return_per_layer=True, + return_log_freqs=True, + return_neuron_indices=True, + ) + + clt_module = CrossLayerTranscoderModule( + model=model, + dead_features=dead_features, + learning_rate=1e-4, + compile=True, + lr_decay_step=80_000, + lr_decay_factor=0.1, + compute_dead_features=True, + compute_dead_features_every=500, + ) + + + checkpoint_path = "crosslayer_transcoder/checkpoints/clt.ckpt" + + model = load_model_from_lightning_checkpoint(clt_module, checkpoint_path) + + print(model) \ No newline at end of file From 476f9c6bc3f37503039a94ac6404a311f49ceefb Mon Sep 17 00:00:00 2001 From: jiito Date: Sat, 8 Nov 2025 17:15:35 +0000 Subject: [PATCH 48/99] debug config file --- config/debug.yaml | 162 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 config/debug.yaml diff --git a/config/debug.yaml b/config/debug.yaml new file mode 100644 index 0000000..d5d41ad --- /dev/null +++ b/config/debug.yaml @@ -0,0 +1,162 @@ +# Default configuration for CrossLayer Transcoder training +# This file uses Lightning CLI's automatic class construction + +seed_everything: 42 + +trainer: + # max_steps is number of gradient updates. If using gradient accumulation, this is not the number of batches. + max_steps: 10 + val_check_interval: 1 + limit_val_batches: 1 + enable_checkpointing: false # We use custom end-of-training checkpoint + num_sanity_val_steps: 0 # Can't run replacement model before standardizers are initialized + precision: "16-mixed" + accelerator: "gpu" + devices: [0] # [0] means cuda:0 + accumulate_grad_batches: 1 + logger: # WandB logger is recommended but other loggers are supported as well + class_path: lightning.pytorch.loggers.WandbLogger + init_args: + project: "clt" + name: "jumprelu" + save_dir: "./wandb" + callbacks: + - class_path: crosslayer_transcoder.utils.callbacks.EndOfTrainingCheckpointCallback + init_args: + checkpoint_dir: "checkpoints" + +model: + class_path: crosslayer_transcoder.model.clt_lightning.JumpReLUCrossLayerTranscoderModule + init_args: + model: + class_path: crosslayer_transcoder.model.clt.CrossLayerTranscoder + init_args: + encoder: + class_path: crosslayer_transcoder.model.clt.Encoder + init_args: + d_acts: 768 + d_features: 10_000 + n_layers: 12 + + decoder: + class_path: crosslayer_transcoder.model.clt.CrosslayerDecoder + init_args: + d_acts: 768 + d_features: 10_000 + n_layers: 12 + + nonlinearity: + class_path: crosslayer_transcoder.model.jumprelu.JumpReLU + init_args: + theta: 0.03 + bandwidth: 0.01 + n_layers: 12 + d_features: 10_000 + + input_standardizer: + class_path: crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer + init_args: + n_layers: 12 + activation_dim: 768 + + output_standardizer: + class_path: crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer + init_args: + n_layers: 12 + activation_dim: 768 + + # Pre-constructed replacement model + replacement_model: + class_path: crosslayer_transcoder.metrics.replacement_model_accuracy.ReplacementModelAccuracy + init_args: + model_name: "openai-community/gpt2" + device_map: "cuda:0" # should match trainer.devices + loader_batch_size: 2 + + # Pre-constructed dead features metric + dead_features: + class_path: crosslayer_transcoder.metrics.dead_features.DeadFeatures + init_args: + n_features: 10_000 + n_layers: 12 + return_per_layer: true + return_log_freqs: true + return_neuron_indices: true + + + # Training parameters + learning_rate: 1e-4 + compile: true # if using torch.compile + lr_decay_step: 80_000 # lr is scaled by lr_decay_factor after this many steps + lr_decay_factor: 0.1 + + lambda_sparsity: 0.0007 # sparsity loss weight + c_sparsity: 1 # sparsity loss coefficient + use_tanh: true # use tanh nonlinearity in the JumpReLU + pre_actv_loss: 1e-6 # pre-activation loss weight + + # Dead features computation settings + compute_dead_features: true + compute_dead_features_every: 500 + +data: + class_path: crosslayer_transcoder.data.datamodule.ActivationDataModule + init_args: + # Buffer settings + buffer_size: 100 # number of activations to store in the buffer + n_in_out: 2 # number of input and output layers + n_layers: 12 # number of layers in the model + activation_dim: 768 # dimension of the activations + dtype: "float16" # dtype of the activations + max_batch_size: 10 # maximum batch size for the data loader + + # Model settings for activation generation + model_name: "openai-community/gpt2" + model_dtype: "float32" + + # Dataset settings + dataset_name: "Skylion007/openwebtext" + dataset_split: "train" + max_sequence_length: 1024 + + # Generation settings + generation_batch_size: 10 + refresh_interval: 0.1 # time (s) between shell logs updates + + # Memory settings + shared_memory_name: "activation_buffer" + timeout_seconds: 30 + + # File paths + init_file: null # path to file with shuffled activations to initialize the buffer fast + # if null, activations are generated and training starts when the buffer is at least minimum_fill_threshold full + + # DataLoader settings + batch_size: 10 + num_workers: 1 + prefetch_factor: 2 + shuffle: true + persistent_workers: true + pin_memory: true + + minimum_fill_threshold: 0.2 # Only provide activations when buffer is at least 20% full + # to maintain sufficient shuffling + + use_shared_memory: true + + # Device configuration + device_map: "cuda:0" # "cpu", "auto", "cuda:0", "cuda:0,1,2,3" + deployment_policy: "gpu_only" # "cpu_only", "gpu_only", or "dynamic" + # dynamic will use CPU and only GPU if the buffer is almost empty to refill fast. Use this if you use a single GPU and have a beefy CPU. + + # WandB logging configuration for data generation + wandb_logging: + enabled: true # Enable WandB logging for data generation + project: "clt" # WandB project (should match trainer logger) + group: null # Group name (null = auto-generated from training run) + run_name: "debug" # Run name suffix + tags: ["debug"] # Tags for the data generation run + save_dir: "./wandb" # Directory for WandB files + log_interval: 5.0 # Logging interval in seconds + +ckpt_path: null \ No newline at end of file From 8c1fcb43f533c3fa44a3427e1a8ef812035f2d07 Mon Sep 17 00:00:00 2001 From: jiito Date: Sat, 8 Nov 2025 14:44:43 -0500 Subject: [PATCH 49/99] revert formatting changes in clt_lightning --- crosslayer_transcoder/model/clt_lightning.py | 88 +++++++++++++++----- 1 file changed, 67 insertions(+), 21 deletions(-) diff --git a/crosslayer_transcoder/model/clt_lightning.py b/crosslayer_transcoder/model/clt_lightning.py index b95fb44..39a874a 100644 --- a/crosslayer_transcoder/model/clt_lightning.py +++ b/crosslayer_transcoder/model/clt_lightning.py @@ -14,8 +14,14 @@ import wandb from crosslayer_transcoder.metrics.dead_features import DeadFeatures -from crosslayer_transcoder.metrics.replacement_model_accuracy import ReplacementModelAccuracy -from crosslayer_transcoder.model.clt import CrosslayerDecoder, CrossLayerTranscoder, Decoder +from crosslayer_transcoder.metrics.replacement_model_accuracy import ( + ReplacementModelAccuracy, +) +from crosslayer_transcoder.model.clt import ( + CrosslayerDecoder, + CrossLayerTranscoder, + Decoder, +) from crosslayer_transcoder.model.jumprelu import JumpReLU from crosslayer_transcoder.model.topk import BatchTopK @@ -49,7 +55,9 @@ def __init__( ): super().__init__(*args, **kwargs) - self.save_hyperparameters(ignore=["model", "replacement_model", "dead_features"]) + self.save_hyperparameters( + ignore=["model", "replacement_model", "dead_features"] + ) # torch.cuda.memory._record_memory_history(max_entries=100_000) # Store pre-constructed modules @@ -77,13 +85,16 @@ def __init__( self.beta2 = beta2 self.log_metrics_every = log_metrics_every - assert ( - self.model.encoder.n_layers == self.model.decoder.n_layers - ), "Encoder and decoder must have the same number of layers" + assert self.model.encoder.n_layers == self.model.decoder.n_layers, ( + "Encoder and decoder must have the same number of layers" + ) self.register_buffer( "last_active", - torch.zeros((self.model.encoder.n_layers, self.model.encoder.d_features), dtype=torch.long), + torch.zeros( + (self.model.encoder.n_layers, self.model.encoder.d_features), + dtype=torch.long, + ), ) def configure_model(self): @@ -107,7 +118,9 @@ def configure_model(self): } parallelize_module(self, tp_mesh, plan) - def forward(self, acts_norm: Float[torch.Tensor, "batch_size n_layers d_acts"]) -> Tuple[ + def forward( + self, acts_norm: Float[torch.Tensor, "batch_size n_layers d_acts"] + ) -> Tuple[ Float[torch.Tensor, "batch_size n_layers d_features"], # pre_actvs Float[torch.Tensor, "batch_size n_layers d_features"], # features Float[torch.Tensor, "batch_size n_layers d_acts"], # recons_norm @@ -130,13 +143,18 @@ def log_training_metrics(self, features, recons_norm, recons, mlp_out, batch_idx ss_err = (mlp_out_norm - recons_norm) ** 2 ss_err = ss_err.sum(dim=0) - ss_total = ((mlp_out_norm - mlp_out_norm.mean(dim=0, keepdim=True)) ** 2).sum(dim=0) + ss_total = ((mlp_out_norm - mlp_out_norm.mean(dim=0, keepdim=True)) ** 2).sum( + dim=0 + ) fvu = (ss_err / ss_total).mean() # (n_layers, d_model) self.log("metrics/fraction_of_variance_unexplained", fvu) fvu_per_layer = (ss_err / ss_total).mean(dim=-1) assert fvu_per_layer.shape == (self.model.encoder.n_layers,) for layer in range(self.model.encoder.n_layers): - self.log(f"layers/fraction_of_variance_unexplained/layer_{layer}", fvu_per_layer[layer]) + self.log( + f"layers/fraction_of_variance_unexplained/layer_{layer}", + fvu_per_layer[layer], + ) # number of tokens seen if not hasattr(self, "tokens_seen"): @@ -171,7 +189,8 @@ def log_training_metrics(self, features, recons_norm, recons, mlp_out, batch_idx self.log("metrics/recons_standardized_std", recons_norm.std()) self.log( "metrics/L0_avg_per_layer", - torch.count_nonzero(active_features) / (features.shape[0] * features.shape[1]), + torch.count_nonzero(active_features) + / (features.shape[0] * features.shape[1]), ) # Magnitude of feature activations - memory efficient version @@ -197,7 +216,9 @@ def log_training_metrics(self, features, recons_norm, recons, mlp_out, batch_idx # Log L0 table per layer if batch_idx % 500 == 1: - l0_per_layer = torch.count_nonzero(active_features, dim=(0, 2)) / features.shape[0] + l0_per_layer = ( + torch.count_nonzero(active_features, dim=(0, 2)) / features.shape[0] + ) if self.logger and isinstance(self.logger.experiment, wandb.wandb_run.Run): table = wandb.Table( @@ -205,7 +226,11 @@ def log_training_metrics(self, features, recons_norm, recons, mlp_out, batch_idx columns=["layer", "L0"], ) self.logger.experiment.log( - {"layers/L0_per_layer": wandb.plot.bar(table, "layer", "L0", title="L0 per Layer")}, + { + "layers/L0_per_layer": wandb.plot.bar( + table, "layer", "L0", title="L0 per Layer" + ) + }, step=self.global_step, ) @@ -234,7 +259,11 @@ def log_training_metrics(self, features, recons_norm, recons, mlp_out, batch_idx ): for layer in range(dead_log_freqs.shape[0]): self.logger.experiment.log( - {f"layers/log_feature_density/layer_{layer}": dead_log_freqs[layer]}, + { + f"layers/log_feature_density/layer_{layer}": dead_log_freqs[ + layer + ] + }, step=self.global_step, ) self.logger.experiment.log( @@ -304,11 +333,17 @@ def configure_optimizers(self): if self.optimizer == "adam": optimizer = torch.optim.Adam( - self.parameters(), lr=self.learning_rate, betas=(self.beta1, self.beta2), fused=True + self.parameters(), + lr=self.learning_rate, + betas=(self.beta1, self.beta2), + fused=True, ) elif self.optimizer == "adamw": optimizer = torch.optim.AdamW( - self.parameters(), lr=self.learning_rate, betas=(self.beta1, self.beta2), fused=True + self.parameters(), + lr=self.learning_rate, + betas=(self.beta1, self.beta2), + fused=True, ) else: raise ValueError(f"Optimizer {self.optimizer} not supported") @@ -398,7 +433,9 @@ def training_step(self, batch, batch_idx): if isinstance(self.model.decoder, CrosslayerDecoder): dec_norms = torch.zeros_like(features[:1]) for l in range(self.model.decoder.n_layers): - W = self.model.decoder.get_parameter(f"W_{l}") # (from_layer, d_features, d_acts) + W = self.model.decoder.get_parameter( + f"W_{l}" + ) # (from_layer, d_features, d_acts) dec_norms[:, : l + 1] = dec_norms[:, : l + 1] + (W**2).sum(dim=-1) dec_norms = dec_norms.sqrt() @@ -406,11 +443,17 @@ def training_step(self, batch, batch_idx): dec_norms = torch.sqrt((self.model.decoder.W**2).sum(dim=-1)) weighted_features = features * dec_norms * self.c - self.log("model/weighted_features_mean", weighted_features.detach().mean().cpu()) + self.log( + "model/weighted_features_mean", weighted_features.detach().mean().cpu() + ) if self.use_tanh: - weighted_features = torch.tanh(weighted_features) # (batch_size, n_layers, d_features) - sparsity = self.current_sparsity_penalty() * weighted_features.sum(dim=[1, 2]).mean() + weighted_features = torch.tanh( + weighted_features + ) # (batch_size, n_layers, d_features) + sparsity = ( + self.current_sparsity_penalty() * weighted_features.sum(dim=[1, 2]).mean() + ) self.log("training/sparsity_loss", sparsity) # Compute Pre-activation Loss @@ -462,7 +505,10 @@ def __init__( self.aux_loss_scale = aux_loss_scale self.register_buffer( "last_active", - torch.zeros((self.model.encoder.n_layers, self.model.encoder.d_features), dtype=torch.long), + torch.zeros( + (self.model.encoder.n_layers, self.model.encoder.d_features), + dtype=torch.long, + ), ) def training_step(self, batch, batch_idx): From ce034d7f715c739c5cc810c90085c9d1afa6db48 Mon Sep 17 00:00:00 2001 From: jiito Date: Sat, 8 Nov 2025 14:45:47 -0500 Subject: [PATCH 50/99] revert comment --- crosslayer_transcoder/model/standardize.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crosslayer_transcoder/model/standardize.py b/crosslayer_transcoder/model/standardize.py index 571a031..45b1b63 100644 --- a/crosslayer_transcoder/model/standardize.py +++ b/crosslayer_transcoder/model/standardize.py @@ -35,7 +35,7 @@ def __init__(self, n_layers, activation_dim): def initialize_from_batch( self, batch: Float[torch.Tensor, "batch_size io n_layers actv_dim"] ): - batch = batch[:, 0] # input + batch = batch[:, 0] self.mean.data = batch.mean(dim=0) self.std.data = batch.std(dim=0) self.std.data.clamp_(min=1e-8) From fb768e9ea20adf0aa214c8e7324283409f1a15ef Mon Sep 17 00:00:00 2001 From: jiito Date: Sat, 8 Nov 2025 14:50:11 -0500 Subject: [PATCH 51/99] rename to clearer method --- crosslayer_transcoder/utils/callbacks.py | 3 +-- .../utils/model_converters/circuit_tracer.py | 7 +++++-- .../utils/{ => model_converters}/model_converter.py | 3 ++- tests/test_convert_to_circuit_tracer.py | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) rename crosslayer_transcoder/utils/{ => model_converters}/model_converter.py (83%) diff --git a/crosslayer_transcoder/utils/callbacks.py b/crosslayer_transcoder/utils/callbacks.py index 0015799..f093ffe 100644 --- a/crosslayer_transcoder/utils/callbacks.py +++ b/crosslayer_transcoder/utils/callbacks.py @@ -76,8 +76,7 @@ def __init__(self, save_dir: str = "clt_module", kinds=["circuit_tracer"]): def _convert_model(self, pl_module): for kind in self.kinds: converter = self.converters[kind](save_dir=self.save_dir.as_posix()) - # NOTE: conversion also does the saving - converter.convert(pl_module) + converter.convert_and_save(pl_module) logger.info( f"{kind} model converted and saved to {self.save_dir.as_posix()}" ) diff --git a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py index 4a85ea0..895646a 100644 --- a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py +++ b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py @@ -4,7 +4,10 @@ import yaml from safetensors.torch import save_file -from crosslayer_transcoder.utils.model_converter import CLTModule, ModelConverter +from crosslayer_transcoder.utils.model_converters.model_converter import ( + CLTModule, + ModelConverter, +) class CircuitTracerConverter(ModelConverter): @@ -20,7 +23,7 @@ def __init__( self.save_dir.mkdir(parents=True, exist_ok=True) - def convert(self, model: CLTModule) -> CLTModule: + def convert_and_save(self, model): encoder = model.model.encoder input_standardizer = model.model.input_standardizer output_standardizer = model.model.output_standardizer diff --git a/crosslayer_transcoder/utils/model_converter.py b/crosslayer_transcoder/utils/model_converters/model_converter.py similarity index 83% rename from crosslayer_transcoder/utils/model_converter.py rename to crosslayer_transcoder/utils/model_converters/model_converter.py index e60ddcf..8442a01 100644 --- a/crosslayer_transcoder/utils/model_converter.py +++ b/crosslayer_transcoder/utils/model_converters/model_converter.py @@ -16,5 +16,6 @@ class ModelConverter(ABC): @abstractmethod - def convert(self, model: CLTModule) -> CLTModule: + # TODO: single resp + def convert_and_save(self, model: CLTModule) -> None: pass diff --git a/tests/test_convert_to_circuit_tracer.py b/tests/test_convert_to_circuit_tracer.py index c0dcd90..b779fe5 100644 --- a/tests/test_convert_to_circuit_tracer.py +++ b/tests/test_convert_to_circuit_tracer.py @@ -61,7 +61,7 @@ def test_circuit_tracer_converter(): save_dir = pathlib.Path("clt_module") converter = CircuitTracerConverter(save_dir=save_dir) - converter.convert(clt_module) + converter.convert_and_save(clt_module) if __name__ == "__main__": From d57b766671789d44d49f5a41378c5375a1edac69 Mon Sep 17 00:00:00 2001 From: jiito Date: Sat, 8 Nov 2025 17:02:38 -0500 Subject: [PATCH 52/99] add file checks --- tests/test_convert_to_circuit_tracer.py | 26 ++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/tests/test_convert_to_circuit_tracer.py b/tests/test_convert_to_circuit_tracer.py index b779fe5..c0ffdd6 100644 --- a/tests/test_convert_to_circuit_tracer.py +++ b/tests/test_convert_to_circuit_tracer.py @@ -2,9 +2,12 @@ CircuitTracerConverter, ) import pathlib +import pytest +import shutil -def test_circuit_tracer_converter(): +@pytest.fixture +def clt_module(): from crosslayer_transcoder.metrics.dead_features import DeadFeatures from crosslayer_transcoder.model.clt import ( CrosslayerDecoder, @@ -18,8 +21,6 @@ def test_circuit_tracer_converter(): DimensionwiseOutputStandardizer, ) - # TODO: find a better way to build the clt_module - # Create components based on default.yaml config encoder = Encoder(d_acts=768, d_features=10_000, n_layers=12) decoder = CrosslayerDecoder(d_acts=768, d_features=10_000, n_layers=12) @@ -59,10 +60,25 @@ def test_circuit_tracer_converter(): compute_dead_features_every=500, ) + return clt_module + + +def test_circuit_tracer_converter(clt_module): save_dir = pathlib.Path("clt_module") converter = CircuitTracerConverter(save_dir=save_dir) converter.convert_and_save(clt_module) + assert save_dir.exists() + assert ( + len(list(save_dir.glob("*.safetensors"))) + == clt_module.model.encoder.n_layers * 2 + ) + + assert (save_dir / "config.yaml").exists() + + for layer in range(12): + assert (save_dir / f"W_enc_{layer}.safetensors").exists() + assert (save_dir / f"W_dec_{layer}.safetensors").exists() -if __name__ == "__main__": - test_circuit_tracer_converter() + # cleanup + shutil.rmtree(save_dir) From c347ba24c45d9f53059ea413087e760fceab78d8 Mon Sep 17 00:00:00 2001 From: jiito Date: Sat, 8 Nov 2025 17:02:47 -0500 Subject: [PATCH 53/99] save each decoder --- .../utils/model_converters/circuit_tracer.py | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py index 895646a..7068424 100644 --- a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py +++ b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py @@ -57,26 +57,26 @@ def convert_and_save(self, model): layer_encoder_dict, f"{self.save_dir}/W_enc_{source_layer}.safetensors" ) - output_dec_i = torch.zeros([d_features, n_layers - source_layer, d_acts]) - - for k in range(source_layer, n_layers): - # get decoder mat for layer i --> k - decoder_w_k = decoder.get_parameter(f"W_{k}") - - # fold in output standardization for decoder weights using standardizer method - decoder_w_k_folded = output_standardizer.fold_in_decoder_weights_layer( - decoder_w_k.float(), k - ) - dec_i_k = decoder_w_k_folded[source_layer, ...] - assert dec_i_k.shape == ( - d_features, - d_acts, - ) - output_dec_i[:, k - source_layer, ...] = dec_i_k.cpu() - - decoder_dict = {f"W_dec_{source_layer}": output_dec_i} - - save_file(decoder_dict, f"{self.save_dir}/W_dec_{source_layer}.safetensors") + output_dec_i = torch.zeros([d_features, n_layers - source_layer, d_acts]) + + for k in range(source_layer, n_layers): + # get decoder mat for layer i --> k + decoder_w_k = decoder.get_parameter(f"W_{k}") + + # fold in output standardization for decoder weights using standardizer method + decoder_w_k_folded = output_standardizer.fold_in_decoder_weights_layer( + decoder_w_k.float(), k + ) + dec_i_k = decoder_w_k_folded[source_layer, ...] + assert dec_i_k.shape == ( + d_features, + d_acts, + ) + output_dec_i[:, k - source_layer, ...] = dec_i_k.cpu() + + decoder_dict = {f"W_dec_{source_layer}": output_dec_i} + + save_file(decoder_dict, f"{self.save_dir}/W_dec_{source_layer}.safetensors") config = { "model_kind": "cross_layer_transcoder", From 11d92ee97017d8ca1e9b4eb2708b1f2bcba935db Mon Sep 17 00:00:00 2001 From: jiito Date: Sat, 8 Nov 2025 17:03:08 -0500 Subject: [PATCH 54/99] rm unused import --- crosslayer_transcoder/utils/model_converters/circuit_tracer.py | 1 - 1 file changed, 1 deletion(-) diff --git a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py index 7068424..ae7e410 100644 --- a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py +++ b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py @@ -5,7 +5,6 @@ from safetensors.torch import save_file from crosslayer_transcoder.utils.model_converters.model_converter import ( - CLTModule, ModelConverter, ) From 705c4e88760f8c9b78ee7521d576843af07a2a05 Mon Sep 17 00:00:00 2001 From: jiito Date: Sat, 8 Nov 2025 17:34:41 -0500 Subject: [PATCH 55/99] move fixture out --- tests/conftest.py | 58 ++++++++++++++++++++++++ tests/test_convert_to_circuit_tracer.py | 59 +------------------------ 2 files changed, 59 insertions(+), 58 deletions(-) create mode 100644 tests/conftest.py diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..b066753 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,58 @@ +import pytest + + +@pytest.fixture(scope="session") +def clt_module(): + from crosslayer_transcoder.metrics.dead_features import DeadFeatures + from crosslayer_transcoder.model.clt import ( + CrosslayerDecoder, + CrossLayerTranscoder, + Encoder, + ) + from crosslayer_transcoder.model.clt_lightning import CrossLayerTranscoderModule + from crosslayer_transcoder.model.jumprelu import JumpReLU + from crosslayer_transcoder.model.standardize import ( + DimensionwiseInputStandardizer, + DimensionwiseOutputStandardizer, + ) + + encoder = Encoder(d_acts=768, d_features=10_000, n_layers=12) + + decoder = CrosslayerDecoder(d_acts=768, d_features=10_000, n_layers=12) + + nonlinearity = JumpReLU(theta=0.03, bandwidth=0.01, n_layers=12, d_features=10_000) + + input_standardizer = DimensionwiseInputStandardizer(n_layers=12, activation_dim=768) + + output_standardizer = DimensionwiseOutputStandardizer( + n_layers=12, activation_dim=768 + ) + + model = CrossLayerTranscoder( + encoder=encoder, + decoder=decoder, + nonlinearity=nonlinearity, + input_standardizer=input_standardizer, + output_standardizer=output_standardizer, + ) + + dead_features = DeadFeatures( + n_features=10_000, + n_layers=12, + return_per_layer=True, + return_log_freqs=True, + return_neuron_indices=True, + ) + + clt_module = CrossLayerTranscoderModule( + model=model, + dead_features=dead_features, + learning_rate=1e-4, + compile=True, + lr_decay_step=80_000, + lr_decay_factor=0.1, + compute_dead_features=True, + compute_dead_features_every=500, + ) + + return clt_module diff --git a/tests/test_convert_to_circuit_tracer.py b/tests/test_convert_to_circuit_tracer.py index c0ffdd6..224ba76 100644 --- a/tests/test_convert_to_circuit_tracer.py +++ b/tests/test_convert_to_circuit_tracer.py @@ -1,68 +1,11 @@ from crosslayer_transcoder.utils.model_converters.circuit_tracer import ( CircuitTracerConverter, ) + import pathlib -import pytest import shutil -@pytest.fixture -def clt_module(): - from crosslayer_transcoder.metrics.dead_features import DeadFeatures - from crosslayer_transcoder.model.clt import ( - CrosslayerDecoder, - CrossLayerTranscoder, - Encoder, - ) - from crosslayer_transcoder.model.clt_lightning import CrossLayerTranscoderModule - from crosslayer_transcoder.model.jumprelu import JumpReLU - from crosslayer_transcoder.model.standardize import ( - DimensionwiseInputStandardizer, - DimensionwiseOutputStandardizer, - ) - - encoder = Encoder(d_acts=768, d_features=10_000, n_layers=12) - - decoder = CrosslayerDecoder(d_acts=768, d_features=10_000, n_layers=12) - - nonlinearity = JumpReLU(theta=0.03, bandwidth=0.01, n_layers=12, d_features=10_000) - - input_standardizer = DimensionwiseInputStandardizer(n_layers=12, activation_dim=768) - - output_standardizer = DimensionwiseOutputStandardizer( - n_layers=12, activation_dim=768 - ) - - model = CrossLayerTranscoder( - encoder=encoder, - decoder=decoder, - nonlinearity=nonlinearity, - input_standardizer=input_standardizer, - output_standardizer=output_standardizer, - ) - - dead_features = DeadFeatures( - n_features=10_000, - n_layers=12, - return_per_layer=True, - return_log_freqs=True, - return_neuron_indices=True, - ) - - clt_module = CrossLayerTranscoderModule( - model=model, - dead_features=dead_features, - learning_rate=1e-4, - compile=True, - lr_decay_step=80_000, - lr_decay_factor=0.1, - compute_dead_features=True, - compute_dead_features_every=500, - ) - - return clt_module - - def test_circuit_tracer_converter(clt_module): save_dir = pathlib.Path("clt_module") converter = CircuitTracerConverter(save_dir=save_dir) From 72d1e1bed6400d5d05205fa0844e60474f524d51 Mon Sep 17 00:00:00 2001 From: jiito Date: Sat, 8 Nov 2025 17:34:49 -0500 Subject: [PATCH 56/99] rm prints --- crosslayer_transcoder/model/standardize.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/crosslayer_transcoder/model/standardize.py b/crosslayer_transcoder/model/standardize.py index 45b1b63..312a2c0 100644 --- a/crosslayer_transcoder/model/standardize.py +++ b/crosslayer_transcoder/model/standardize.py @@ -115,9 +115,6 @@ def fold_in_decoder_weights_layer( W_dec: Float[torch.Tensor, "layers d_features d_acts"], layer: int, ): - print("W_dec.shape:", W_dec.shape) - print("self.std.shape:", self.std.shape) - # Decoder is going to have dim 0 == i layers std = self.std[layer] From bfce3bb0360df9d0a1af52baa9c5a5c639677df1 Mon Sep 17 00:00:00 2001 From: jiito Date: Sat, 8 Nov 2025 17:35:08 -0500 Subject: [PATCH 57/99] fix: non-lin, rm hf upload --- .../utils/model_converters/circuit_tracer.py | 5 +- tests/test_circuit_tracer_integration.py | 48 +++++++++++-------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py index ae7e410..d384a1f 100644 --- a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py +++ b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py @@ -46,10 +46,9 @@ def convert_and_save(self, model): .cpu(), # Transpose! f"b_enc_{source_layer}": (b_enc_folded[source_layer].cpu()), f"b_dec_{source_layer}": (b_dec_folded[source_layer].cpu()), + # TODO: double check non-linearity compatibility f"threshold_{source_layer}": ( - nonlinearity.theta.cpu() - if hasattr(nonlinearity, "theta") - else torch.zeros(d_features) + nonlinearity.theta[:, source_layer, :].cpu() ), } save_file( diff --git a/tests/test_circuit_tracer_integration.py b/tests/test_circuit_tracer_integration.py index 26af500..5004281 100644 --- a/tests/test_circuit_tracer_integration.py +++ b/tests/test_circuit_tracer_integration.py @@ -1,29 +1,39 @@ -from circuit_tracer.utils.hf_utils import load_transcoder_from_hub -import torch +import pathlib +import shutil +from circuit_tracer.transcoder.cross_layer_transcoder import load_clt -# TODO: try the conversion and then try uploading +from crosslayer_transcoder.utils.model_converters.circuit_tracer import ( + CircuitTracerConverter, +) -def validate_upload(repo_id: str): +def test_circuit_tracer_integration(clt_module): """Verify uploaded model loads correctly.""" - # Load from HuggingFace - transcoder, config = load_transcoder_from_hub( - repo_id, - device=torch.device("cpu"), - dtype=torch.float32, - lazy_encoder=False, - lazy_decoder=False, + save_dir = pathlib.Path("clt_module_test") + feature_input_hook = "blocks.{layer}.hook_resid_pre" + feature_output_hook = "blocks.{layer}.hook_mlp_out" + + converter = CircuitTracerConverter( + save_dir=save_dir, + feature_input_hook=feature_input_hook, + feature_output_hook=feature_output_hook, ) + converter.convert_and_save(clt_module) - print( - f"✓ Dimensions: {transcoder.n_layers}L x {transcoder.d_transcoder}F x {transcoder.d_model}D" + transcoder = load_clt( + clt_path=save_dir.as_posix(), + lazy_decoder=False, + lazy_encoder=False, + feature_input_hook=feature_input_hook, + feature_output_hook=feature_output_hook, ) - print(f"✓ Encoder weights match") - print(f"✓ Config: {config['model_kind']}") + assert transcoder.n_layers == clt_module.model.encoder.n_layers + assert transcoder.d_transcoder == clt_module.model.encoder.d_features + assert transcoder.d_model == clt_module.model.encoder.d_acts + assert transcoder.feature_input_hook == feature_input_hook + assert transcoder.feature_output_hook == feature_output_hook -if __name__ == "__main__": - validate_upload( - repo_id="jiito/clt_test_gpt2_zero", - ) + # cleanup + shutil.rmtree(save_dir) From e13e04d97d6d07209492eb6d8c42422f556a2d52 Mon Sep 17 00:00:00 2001 From: jiito Date: Wed, 12 Nov 2025 20:43:50 -0800 Subject: [PATCH 58/99] add basic test for dowloading clt ckpt --- crosslayer_transcoder/utils/checkpoints.py | 14 +++++ crosslayer_transcoder/utils/utils.py | 5 -- tests/test_checkpoint_loading.py | 66 +++------------------- tests/test_circuit_tracer_integration.py | 1 + 4 files changed, 22 insertions(+), 64 deletions(-) create mode 100644 crosslayer_transcoder/utils/checkpoints.py diff --git a/crosslayer_transcoder/utils/checkpoints.py b/crosslayer_transcoder/utils/checkpoints.py new file mode 100644 index 0000000..8564dab --- /dev/null +++ b/crosslayer_transcoder/utils/checkpoints.py @@ -0,0 +1,14 @@ +import torch +from huggingface_hub import hf_hub_download +from crosslayer_transcoder.utils.model_converters.model_converter import CLTModule + +def load_model_from_lightning_checkpoint(model, checkpoint_path): + checkpoint = torch.load(checkpoint_path) + model.load_state_dict(checkpoint["state_dict"]) + return model + +def load_clt_from_hub(model: CLTModule, repo_id: str) -> CLTModule: + local_filename = "clt.ckpt" + checkpoint_path = hf_hub_download(repo_id=repo_id, local_dir=".", filename=local_filename) + model = load_model_from_lightning_checkpoint(model, checkpoint_path) + return model \ No newline at end of file diff --git a/crosslayer_transcoder/utils/utils.py b/crosslayer_transcoder/utils/utils.py index 83e4d67..ce90582 100644 --- a/crosslayer_transcoder/utils/utils.py +++ b/crosslayer_transcoder/utils/utils.py @@ -57,8 +57,3 @@ def plot_actvs(actvs): # Adjust layout to prevent overlap plt.tight_layout() - -def load_model_from_lightning_checkpoint(model, checkpoint_path): - checkpoint = torch.load(checkpoint_path) - model.load_state_dict(checkpoint["state_dict"]) - return model \ No newline at end of file diff --git a/tests/test_checkpoint_loading.py b/tests/test_checkpoint_loading.py index 3fd6173..007caae 100644 --- a/tests/test_checkpoint_loading.py +++ b/tests/test_checkpoint_loading.py @@ -1,64 +1,12 @@ -from crosslayer_transcoder.utils.utils import load_model_from_lightning_checkpoint -def test_load_model_from_lightning_checkpoint(): +# def test_load_model_from_lightning_checkpoint(clt_module): +# checkpoint_path = "crosslayer_transcoder/checkpoints/clt.ckpt" - from crosslayer_transcoder.metrics.dead_features import DeadFeatures - from crosslayer_transcoder.model.clt import ( - CrosslayerDecoder, - CrossLayerTranscoder, - Encoder, - ) - from crosslayer_transcoder.model.clt_lightning import CrossLayerTranscoderModule - from crosslayer_transcoder.model.jumprelu import JumpReLU - from crosslayer_transcoder.model.standardize import ( - DimensionwiseInputStandardizer, - DimensionwiseOutputStandardizer, - ) +# model = load_model_from_lightning_checkpoint(clt_module, checkpoint_path) - # TODO: find a better way to build the clt_module - # Create components based on default.yaml config - encoder = Encoder(d_acts=768, d_features=10_000, n_layers=12) - - decoder = CrosslayerDecoder(d_acts=768, d_features=10_000, n_layers=12) - - nonlinearity = JumpReLU(theta=0.03, bandwidth=0.01, n_layers=12, d_features=10_000) - - input_standardizer = DimensionwiseInputStandardizer(n_layers=12, activation_dim=768) - - output_standardizer = DimensionwiseOutputStandardizer( - n_layers=12, activation_dim=768 - ) - - model = CrossLayerTranscoder( - encoder=encoder, - decoder=decoder, - nonlinearity=nonlinearity, - input_standardizer=input_standardizer, - output_standardizer=output_standardizer, - ) - - dead_features = DeadFeatures( - n_features=10_000, - n_layers=12, - return_per_layer=True, - return_log_freqs=True, - return_neuron_indices=True, - ) - - clt_module = CrossLayerTranscoderModule( - model=model, - dead_features=dead_features, - learning_rate=1e-4, - compile=True, - lr_decay_step=80_000, - lr_decay_factor=0.1, - compute_dead_features=True, - compute_dead_features_every=500, - ) - - - checkpoint_path = "crosslayer_transcoder/checkpoints/clt.ckpt" - - model = load_model_from_lightning_checkpoint(clt_module, checkpoint_path) +# print(model) +def test_load_clt_from_hub(clt_module): + from crosslayer_transcoder.utils.checkpoints import load_clt_from_hub + model = load_clt_from_hub(clt_module, "georglange/gpt2-clt-topk-16-f-10k") print(model) \ No newline at end of file diff --git a/tests/test_circuit_tracer_integration.py b/tests/test_circuit_tracer_integration.py index 5004281..8f31aa8 100644 --- a/tests/test_circuit_tracer_integration.py +++ b/tests/test_circuit_tracer_integration.py @@ -21,6 +21,7 @@ def test_circuit_tracer_integration(clt_module): ) converter.convert_and_save(clt_module) + transcoder = load_clt( clt_path=save_dir.as_posix(), lazy_decoder=False, From 427101933970a6bbaa9abd2ed72af902f5600c4c Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 13 Nov 2025 06:03:27 +0000 Subject: [PATCH 59/99] basic checkpoint loading + test --- crosslayer_transcoder/utils/checkpoints.py | 3 ++- crosslayer_transcoder/utils/module_builder.py | 26 +++++++++++++++++++ tests/test_checkpoint_loading.py | 14 ++++------ tests/test_module_builder.py | 9 +++++++ 4 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 crosslayer_transcoder/utils/module_builder.py create mode 100644 tests/test_module_builder.py diff --git a/crosslayer_transcoder/utils/checkpoints.py b/crosslayer_transcoder/utils/checkpoints.py index 8564dab..1ac169b 100644 --- a/crosslayer_transcoder/utils/checkpoints.py +++ b/crosslayer_transcoder/utils/checkpoints.py @@ -3,7 +3,8 @@ from crosslayer_transcoder.utils.model_converters.model_converter import CLTModule def load_model_from_lightning_checkpoint(model, checkpoint_path): - checkpoint = torch.load(checkpoint_path) + # NOTE: we might have to adjust how to resolve the map_location + checkpoint = torch.load(checkpoint_path, map_location='cuda:0') model.load_state_dict(checkpoint["state_dict"]) return model diff --git a/crosslayer_transcoder/utils/module_builder.py b/crosslayer_transcoder/utils/module_builder.py new file mode 100644 index 0000000..6ffd750 --- /dev/null +++ b/crosslayer_transcoder/utils/module_builder.py @@ -0,0 +1,26 @@ +import importlib +import yaml +import torch.nn as nn + +def build_module_from_config(config: dict) -> nn.Module: + return init_from_config(config["model"]) + + +def init_from_config(config: dict) -> nn.Module: + class_path = config["class_path"] + module_name = ".".join(class_path.split(".")[:-1]) + class_name = class_path.split(".")[-1] + init_class = importlib.import_module(module_name) + init_class = getattr(init_class, class_name) + init_args = config["init_args"] + for key, value in init_args.items(): + print(key, value) + if isinstance(value, dict): + init_args[key] = init_from_config(value) + init_class = init_class(**init_args) + return init_class + +def yaml_to_config(yaml_path: str) -> dict: + with open(yaml_path, "r") as f: + config = yaml.load(f, Loader=yaml.FullLoader) + return config diff --git a/tests/test_checkpoint_loading.py b/tests/test_checkpoint_loading.py index 007caae..75bb291 100644 --- a/tests/test_checkpoint_loading.py +++ b/tests/test_checkpoint_loading.py @@ -1,12 +1,8 @@ -# def test_load_model_from_lightning_checkpoint(clt_module): -# checkpoint_path = "crosslayer_transcoder/checkpoints/clt.ckpt" +def test_load_model_from_lightning_checkpoint(clt_module): + from crosslayer_transcoder.utils.checkpoints import load_model_from_lightning_checkpoint + checkpoint_path = "crosslayer_transcoder/checkpoints/clt.ckpt" -# model = load_model_from_lightning_checkpoint(clt_module, checkpoint_path) + model = load_model_from_lightning_checkpoint(clt_module, checkpoint_path) -# print(model) - -def test_load_clt_from_hub(clt_module): - from crosslayer_transcoder.utils.checkpoints import load_clt_from_hub - model = load_clt_from_hub(clt_module, "georglange/gpt2-clt-topk-16-f-10k") - print(model) \ No newline at end of file + print(model) diff --git a/tests/test_module_builder.py b/tests/test_module_builder.py new file mode 100644 index 0000000..c12255d --- /dev/null +++ b/tests/test_module_builder.py @@ -0,0 +1,9 @@ +def test_build_module_from_config(clt_module): + from crosslayer_transcoder.utils.module_builder import build_module_from_config, yaml_to_config + config = yaml_to_config("config/default.yaml") + model = build_module_from_config(config) + + assert model.model.encoder.n_layers == clt_module.model.encoder.n_layers + assert model.model.decoder.n_layers == clt_module.model.decoder.n_layers + + From 62e2fd968a817a5b9e779147731661ff11ab9a95 Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 13 Nov 2025 07:19:43 +0000 Subject: [PATCH 60/99] add topk debug config --- config/topk-clt-debug.yaml | 163 +++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 config/topk-clt-debug.yaml diff --git a/config/topk-clt-debug.yaml b/config/topk-clt-debug.yaml new file mode 100644 index 0000000..9d643ce --- /dev/null +++ b/config/topk-clt-debug.yaml @@ -0,0 +1,163 @@ +# Configuration for TopK CrossLayer Transcoder training with auxiliary loss +# This file uses Lightning CLI's automatic class construction for TopK-based CLTs + +seed_everything: 42 + +trainer: + # max_steps is number of gradient updates. If using gradient accumulation, this is not the number of batches. + max_steps: 20_000 # 20M tokens + val_check_interval: 1_000 + limit_val_batches: 1 + enable_checkpointing: false # We use custom end-of-training checkpoint + num_sanity_val_steps: 0 # Can't run replacement model before standardizers are initialized + precision: "16-mixed" + accelerator: "gpu" + # TODO: this is kinda brittle from a UX perspective + devices: [0] # [1] for cuda:1 + accumulate_grad_batches: 1 + logger: # WandB logger is recommended but other loggers are supported as well + class_path: lightning.pytorch.loggers.WandbLogger + init_args: + project: "clt" + name: "topk-aux" + save_dir: "./wandb" + callbacks: + - class_path: crosslayer_transcoder.utils.callbacks.EndOfTrainingCheckpointCallback + init_args: + checkpoint_dir: "checkpoints" + +model: + class_path: crosslayer_transcoder.model.clt_lightning.TopKCrossLayerTranscoderModule + init_args: + model: + class_path: crosslayer_transcoder.model.clt.CrossLayerTranscoder + init_args: + encoder: + class_path: crosslayer_transcoder.model.clt.Encoder + init_args: + d_acts: 768 + d_features: 10_000 # 768 * 26 (larger feature dictionary for TopK) + n_layers: 12 + + decoder: + class_path: crosslayer_transcoder.model.clt.CrosslayerDecoder + init_args: + d_acts: 768 + d_features: 10_000 # 768 * 26 (larger feature dictionary for TopK) + n_layers: 12 + + nonlinearity: + class_path: crosslayer_transcoder.model.topk.PerLayerTopK + init_args: + k: 16 # Number of top features to keep per layer + + input_standardizer: + class_path: crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer + init_args: + n_layers: 12 + activation_dim: 768 + + output_standardizer: + class_path: crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer + init_args: + n_layers: 12 + activation_dim: 768 + + # Pre-constructed replacement model + replacement_model: + class_path: crosslayer_transcoder.metrics.replacement_model_accuracy.ReplacementModelAccuracy + init_args: + model_name: "openai-community/gpt2" + # TODO: this is kinda brittle from a UX perspective + device_map: "cuda:0" # should match trainer.devices + loader_batch_size: 2 + + # Pre-constructed dead features metric + dead_features: + class_path: crosslayer_transcoder.metrics.dead_features.DeadFeatures + init_args: + n_features: 10_000 + n_layers: 12 + return_per_layer: true + return_log_freqs: true + return_neuron_indices: true + + # Training parameters + learning_rate: 3e-4 + compile: true # if using torch.compile + lr_decay_step: 16_000 # lr is scaled by lr_decay_factor after this many steps + lr_decay_factor: 0.1 + + # TopK auxiliary loss configuration + topk_aux: + class_path: crosslayer_transcoder.model.topk.PerLayerTopK + init_args: + k: 512 # Number of top features to keep per layer for auxiliary loss + tokens_till_dead: 500_000 # Tokens to process before computing dead features + aux_loss_scale: 0.03125 # Scaling factor for auxiliary loss + + # Dead features computation settings + compute_dead_features: true + compute_dead_features_every: 500 + +data: + class_path: crosslayer_transcoder.data.datamodule.ActivationDataModule + init_args: + # Buffer settings + buffer_size: 3_000_000 # number of activations to store in the buffer + n_in_out: 2 # number of input and output layers + n_layers: 12 # number of layers in the model + activation_dim: 768 # dimension of the activations + dtype: "float16" # dtype of the activations + max_batch_size: 50000 # maximum batch size for the data loader + + # Model settings for activation generation + model_name: "openai-community/gpt2" + model_dtype: "float32" + + # Dataset settings + dataset_name: "Skylion007/openwebtext" + dataset_split: "train" + max_sequence_length: 1024 + + # Generation settings + generation_batch_size: 10 + refresh_interval: 0.1 # time (s) between shell logs updates + + # Memory settings + shared_memory_name: "activation_buffer" + timeout_seconds: 30 + + # File paths + init_file: null # path to file with shuffled activations to initialize the buffer fast + # if null, activations are generated and training starts when the buffer is at least minimum_fill_threshold full + + # DataLoader settings + batch_size: 1000 + num_workers: 10 + prefetch_factor: 2 + shuffle: true + persistent_workers: true + pin_memory: true + + minimum_fill_threshold: 0.2 # Only provide activations when buffer is at least 20% full + # to maintain sufficient shuffling + + use_shared_memory: true + + # Device configuration + device_map: "cuda:0" # "cpu", "auto", "cuda:0", "cuda:0,1,2,3" + deployment_policy: "gpu_only" # "cpu_only", "gpu_only", or "dynamic" + # dynamic will use CPU and only GPU if the buffer is almost empty to refill fast. Use this if you use a single GPU and have a beefy CPU. + + # WandB logging configuration for data generation + wandb_logging: + enabled: true # Enable WandB logging for data generation + project: "clt" # WandB project (should match trainer logger) + group: null # Group name (null = auto-generated from training run) + run_name: "data-generator-topk-aux" # Run name suffix + tags: ["data-generation"] # Tags for the data generation run + save_dir: "./wandb" # Directory for WandB files + log_interval: 5.0 # Logging interval in seconds + +ckpt_path: null \ No newline at end of file From d94a68110a1375c14a066c359bd618c31275b3b6 Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 13 Nov 2025 07:23:32 +0000 Subject: [PATCH 61/99] init replacement score notebook --- .../utils/replacement_score.ipynb | 309 ++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 crosslayer_transcoder/utils/replacement_score.ipynb diff --git a/crosslayer_transcoder/utils/replacement_score.ipynb b/crosslayer_transcoder/utils/replacement_score.ipynb new file mode 100644 index 0000000..071da59 --- /dev/null +++ b/crosslayer_transcoder/utils/replacement_score.ipynb @@ -0,0 +1,309 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1dc2a0d5", + "metadata": {}, + "source": [ + "# Replacement Score Test" + ] + }, + { + "cell_type": "markdown", + "id": "d19aa81f", + "metadata": {}, + "source": [ + "## Load the model from the local checkpoint (save from HF before)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b90bb04b", + "metadata": {}, + "outputs": [], + "source": [ + "import pathlib\n", + "import shutil\n", + "from circuit_tracer.transcoder.cross_layer_transcoder import load_clt\n", + "\n", + "from crosslayer_transcoder.utils.model_converters.circuit_tracer import (\n", + " CircuitTracerConverter,\n", + ")\n", + "from transformer_lens import HookedTransformerConfig\n", + "from transformer_lens.loading_from_pretrained import get_pretrained_model_config" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8d4ddba4", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "os.environ[\"HF_TOKEN\"] = \"ADD_TOKEN_HERE\"" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "c166ce94", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "model {'class_path': 'crosslayer_transcoder.model.clt.CrossLayerTranscoder', 'init_args': {'encoder': {'class_path': 'crosslayer_transcoder.model.clt.Encoder', 'init_args': {'d_acts': 768, 'd_features': 10000, 'n_layers': 12}}, 'decoder': {'class_path': 'crosslayer_transcoder.model.clt.CrosslayerDecoder', 'init_args': {'d_acts': 768, 'd_features': 10000, 'n_layers': 12}}, 'nonlinearity': {'class_path': 'crosslayer_transcoder.model.topk.PerLayerTopK', 'init_args': {'k': 16}}, 'input_standardizer': {'class_path': 'crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer', 'init_args': {'n_layers': 12, 'activation_dim': 768}}, 'output_standardizer': {'class_path': 'crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer', 'init_args': {'n_layers': 12, 'activation_dim': 768}}}}\n", + "encoder {'class_path': 'crosslayer_transcoder.model.clt.Encoder', 'init_args': {'d_acts': 768, 'd_features': 10000, 'n_layers': 12}}\n", + "d_acts 768\n", + "d_features 10000\n", + "n_layers 12\n", + "decoder {'class_path': 'crosslayer_transcoder.model.clt.CrosslayerDecoder', 'init_args': {'d_acts': 768, 'd_features': 10000, 'n_layers': 12}}\n", + "d_acts 768\n", + "d_features 10000\n", + "n_layers 12\n", + "nonlinearity {'class_path': 'crosslayer_transcoder.model.topk.PerLayerTopK', 'init_args': {'k': 16}}\n", + "k 16\n", + "input_standardizer {'class_path': 'crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer', 'init_args': {'n_layers': 12, 'activation_dim': 768}}\n", + "n_layers 12\n", + "activation_dim 768\n", + "output_standardizer {'class_path': 'crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer', 'init_args': {'n_layers': 12, 'activation_dim': 768}}\n", + "n_layers 12\n", + "activation_dim 768\n", + "replacement_model {'class_path': 'crosslayer_transcoder.metrics.replacement_model_accuracy.ReplacementModelAccuracy', 'init_args': {'model_name': 'openai-community/gpt2', 'device_map': 'cuda:0', 'loader_batch_size': 2}}\n", + "model_name openai-community/gpt2\n", + "device_map cuda:0\n", + "loader_batch_size 2\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "cadefb64507d4274bc276cc7bfc07cb2", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Loading dataset shards: 0%| | 0/80 [00:00 1024). Running this sequence through the model will result in indexing errors\n", + "Token indices sequence length is longer than the specified maximum sequence length for this model (1174 > 1024). Running this sequence through the model will result in indexing errors\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "dead_features {'class_path': 'crosslayer_transcoder.metrics.dead_features.DeadFeatures', 'init_args': {'n_features': 10000, 'n_layers': 12, 'return_per_layer': True, 'return_log_freqs': True, 'return_neuron_indices': True}}\n", + "n_features 10000\n", + "n_layers 12\n", + "return_per_layer True\n", + "return_log_freqs True\n", + "return_neuron_indices True\n", + "learning_rate 3e-4\n", + "compile True\n", + "lr_decay_step 16000\n", + "lr_decay_factor 0.1\n", + "topk_aux {'class_path': 'crosslayer_transcoder.model.topk.PerLayerTopK', 'init_args': {'k': 512}}\n", + "k 512\n", + "tokens_till_dead 500000\n", + "aux_loss_scale 0.03125\n", + "compute_dead_features True\n", + "compute_dead_features_every 500\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Token indices sequence length is longer than the specified maximum sequence length for this model (1561 > 1024). Running this sequence through the model will result in indexing errors\n", + "Token indices sequence length is longer than the specified maximum sequence length for this model (2027 > 1024). Running this sequence through the model will result in indexing errors\n", + "Token indices sequence length is longer than the specified maximum sequence length for this model (2459 > 1024). Running this sequence through the model will result in indexing errors\n", + "/root/crosslayer-transcoder/.venv/lib/python3.12/site-packages/lightning/pytorch/utilities/parsing.py:210: Attribute 'topk_aux' is an instance of `nn.Module` and is already saved during checkpointing. It is recommended to ignore them using `self.save_hyperparameters(ignore=['topk_aux'])`.\n" + ] + } + ], + "source": [ + "\n", + "\n", + "from crosslayer_transcoder.utils.module_builder import build_module_from_config, yaml_to_config\n", + "config = yaml_to_config(\"../../config/topk-clt-debug.yaml\")\n", + "clt_module = build_module_from_config(config)\n", + "\n", + "save_dir = pathlib.Path(\"clt_module_test\")\n", + "feature_input_hook = \"hook_resid_pre\"\n", + "feature_output_hook = \"hook_mlp_out\"\n", + "\n", + "converter = CircuitTracerConverter(\n", + "save_dir=save_dir,\n", + "feature_input_hook=feature_input_hook,\n", + " feature_output_hook=feature_output_hook,\n", + ")\n", + "converter.convert_and_save(clt_module)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "f8d8594b", + "metadata": {}, + "outputs": [], + "source": [ + "transcoder = load_clt(\n", + " clt_path=save_dir.as_posix(),\n", + " lazy_decoder=False,\n", + " lazy_encoder=False,\n", + " feature_input_hook=feature_input_hook,\n", + " feature_output_hook=feature_output_hook,\n", + ")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "1bcce2aa", + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "config = get_pretrained_model_config(\"gpt2\")\n", + "config.d_type = torch.float16" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "a3f41040", + "metadata": {}, + "outputs": [], + "source": [ + "from circuit_tracer import ReplacementModel\n", + "rm = ReplacementModel.from_config(\n", + " config=config,\n", + " transcoders=transcoder,\n", + ")\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "10269291", + "metadata": {}, + "outputs": [], + "source": [ + "prompt = (\n", + " \"The capital of state containing Dallas is\" # What you want to get the graph for\n", + ")\n", + "max_n_logits = 10 # How many logits to attribute from, max. We attribute to min(max_n_logits, n_logits_to_reach_desired_log_prob); see below for the latter\n", + "desired_logit_prob = 0.95 # Attribution will attribute from the minimum number of logits needed to reach this probability mass (or max_n_logits, whichever is lower)\n", + "max_feature_nodes = 8192 # Only attribute from this number of feature nodes, max. Lower is faster, but you will lose more of the graph. None means no limit.\n", + "batch_size = 256 # Batch size when attributing\n", + "offload = (\n", + " \"cpu\"\n", + ") # Offload various parts of the model during attribution to save memory. Can be 'disk', 'cpu', or None (keep on GPU)\n", + "verbose = True # Whether to display a tqdm progress bar and timing report\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "ecb6f82c", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Phase 0: Precomputing activations and vectors\n" + ] + }, + { + "ename": "OutOfMemoryError", + "evalue": "CUDA out of memory. Tried to allocate 15.62 GiB. GPU 0 has a total capacity of 31.37 GiB of which 7.31 GiB is free. Including non-PyTorch memory, this process has 24.05 GiB memory in use. Of the allocated memory 21.92 GiB is allocated by PyTorch, and 1.54 GiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation. See documentation for Memory Management (https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mOutOfMemoryError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[8]\u001b[39m\u001b[32m, line 10\u001b[39m\n\u001b[32m 7\u001b[39m torch.cuda.empty_cache()\n\u001b[32m 9\u001b[39m \u001b[38;5;66;03m# FOr some reason this takes up a lot of VRAM\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m10\u001b[39m graph = \u001b[43mattribute\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 11\u001b[39m \u001b[43m \u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m=\u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 12\u001b[39m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrm\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 13\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 14\u001b[39m \u001b[43m \u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 15\u001b[39m \u001b[43m \u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 16\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 17\u001b[39m \u001b[43m \u001b[49m\u001b[43moffload\u001b[49m\u001b[43m=\u001b[49m\u001b[43moffload\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 18\u001b[39m \u001b[43m \u001b[49m\u001b[43mverbose\u001b[49m\u001b[43m=\u001b[49m\u001b[43mverbose\u001b[49m\n\u001b[32m 19\u001b[39m \u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/crosslayer-transcoder/.venv/lib/python3.12/site-packages/circuit_tracer/attribution/attribute.py:137\u001b[39m, in \u001b[36mattribute\u001b[39m\u001b[34m(prompt, model, max_n_logits, desired_logit_prob, batch_size, max_feature_nodes, offload, verbose, update_interval)\u001b[39m\n\u001b[32m 135\u001b[39m offload_handles = []\n\u001b[32m 136\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m137\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_run_attribution\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 138\u001b[39m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 139\u001b[39m \u001b[43m \u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m=\u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 140\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 141\u001b[39m \u001b[43m \u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 142\u001b[39m \u001b[43m \u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 143\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 144\u001b[39m \u001b[43m \u001b[49m\u001b[43moffload\u001b[49m\u001b[43m=\u001b[49m\u001b[43moffload\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 145\u001b[39m \u001b[43m \u001b[49m\u001b[43mverbose\u001b[49m\u001b[43m=\u001b[49m\u001b[43mverbose\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 146\u001b[39m \u001b[43m \u001b[49m\u001b[43moffload_handles\u001b[49m\u001b[43m=\u001b[49m\u001b[43moffload_handles\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 147\u001b[39m \u001b[43m \u001b[49m\u001b[43mupdate_interval\u001b[49m\u001b[43m=\u001b[49m\u001b[43mupdate_interval\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 148\u001b[39m \u001b[43m \u001b[49m\u001b[43mlogger\u001b[49m\u001b[43m=\u001b[49m\u001b[43mlogger\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 149\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 150\u001b[39m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[32m 151\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m reload_handle \u001b[38;5;129;01min\u001b[39;00m offload_handles:\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/crosslayer-transcoder/.venv/lib/python3.12/site-packages/circuit_tracer/attribution/attribute.py:177\u001b[39m, in \u001b[36m_run_attribution\u001b[39m\u001b[34m(model, prompt, max_n_logits, desired_logit_prob, batch_size, max_feature_nodes, offload, verbose, offload_handles, logger, update_interval)\u001b[39m\n\u001b[32m 174\u001b[39m phase_start = time.time()\n\u001b[32m 175\u001b[39m input_ids = model.ensure_tokenized(prompt)\n\u001b[32m--> \u001b[39m\u001b[32m177\u001b[39m ctx = \u001b[43mmodel\u001b[49m\u001b[43m.\u001b[49m\u001b[43msetup_attribution\u001b[49m\u001b[43m(\u001b[49m\u001b[43minput_ids\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 178\u001b[39m activation_matrix = ctx.activation_matrix\n\u001b[32m 180\u001b[39m logger.info(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mPrecomputation completed in \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mtime.time()\u001b[38;5;250m \u001b[39m-\u001b[38;5;250m \u001b[39mphase_start\u001b[38;5;132;01m:\u001b[39;00m\u001b[33m.2f\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[33ms\u001b[39m\u001b[33m\"\u001b[39m)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/crosslayer-transcoder/.venv/lib/python3.12/site-packages/torch/utils/_contextlib.py:120\u001b[39m, in \u001b[36mcontext_decorator..decorate_context\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 117\u001b[39m \u001b[38;5;129m@functools\u001b[39m.wraps(func)\n\u001b[32m 118\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mdecorate_context\u001b[39m(*args, **kwargs):\n\u001b[32m 119\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m ctx_factory():\n\u001b[32m--> \u001b[39m\u001b[32m120\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/crosslayer-transcoder/.venv/lib/python3.12/site-packages/circuit_tracer/replacement_model.py:433\u001b[39m, in \u001b[36mReplacementModel.setup_attribution\u001b[39m\u001b[34m(self, inputs)\u001b[39m\n\u001b[32m 430\u001b[39m mlp_in_cache = torch.cat(\u001b[38;5;28mlist\u001b[39m(mlp_in_cache.values()), dim=\u001b[32m0\u001b[39m)\n\u001b[32m 431\u001b[39m mlp_out_cache = torch.cat(\u001b[38;5;28mlist\u001b[39m(mlp_out_cache.values()), dim=\u001b[32m0\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m433\u001b[39m attribution_data = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mtranscoders\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcompute_attribution_components\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmlp_in_cache\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 435\u001b[39m \u001b[38;5;66;03m# Compute error vectors\u001b[39;00m\n\u001b[32m 436\u001b[39m error_vectors = mlp_out_cache - attribution_data[\u001b[33m\"\u001b[39m\u001b[33mreconstruction\u001b[39m\u001b[33m\"\u001b[39m]\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/crosslayer-transcoder/.venv/lib/python3.12/site-packages/circuit_tracer/transcoder/cross_layer_transcoder.py:300\u001b[39m, in \u001b[36mCrossLayerTranscoder.compute_attribution_components\u001b[39m\u001b[34m(self, inputs)\u001b[39m\n\u001b[32m 285\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"Extract active features and their encoder/decoder vectors for attribution.\u001b[39;00m\n\u001b[32m 286\u001b[39m \n\u001b[32m 287\u001b[39m \u001b[33;03mArgs:\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 296\u001b[39m \u001b[33;03m - encoder_to_decoder_map: Mapping from encoder to decoder indices\u001b[39;00m\n\u001b[32m 297\u001b[39m \u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 298\u001b[39m features, encoder_vectors = \u001b[38;5;28mself\u001b[39m.encode_sparse(inputs, zero_first_pos=\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[32m 299\u001b[39m pos_ids, layer_ids, feat_ids, decoder_vectors, encoder_to_decoder_map = (\n\u001b[32m--> \u001b[39m\u001b[32m300\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mselect_decoder_vectors\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfeatures\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 301\u001b[39m )\n\u001b[32m 302\u001b[39m reconstruction = \u001b[38;5;28mself\u001b[39m.compute_reconstruction(pos_ids, layer_ids, decoder_vectors)\n\u001b[32m 304\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m {\n\u001b[32m 305\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mactivation_matrix\u001b[39m\u001b[33m\"\u001b[39m: features,\n\u001b[32m 306\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mreconstruction\u001b[39m\u001b[33m\"\u001b[39m: reconstruction,\n\u001b[32m (...)\u001b[39m\u001b[32m 310\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mdecoder_locations\u001b[39m\u001b[33m\"\u001b[39m: torch.stack((layer_ids, pos_ids)),\n\u001b[32m 311\u001b[39m }\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/crosslayer-transcoder/.venv/lib/python3.12/site-packages/circuit_tracer/transcoder/cross_layer_transcoder.py:260\u001b[39m, in \u001b[36mCrossLayerTranscoder.select_decoder_vectors\u001b[39m\u001b[34m(self, features)\u001b[39m\n\u001b[32m 258\u001b[39m layer_ids = torch.cat(layer_ids, dim=\u001b[32m0\u001b[39m)\n\u001b[32m 259\u001b[39m feat_ids = torch.cat(feat_ids, dim=\u001b[32m0\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m260\u001b[39m decoder_vectors = \u001b[43mtorch\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcat\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdecoder_vectors\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdim\u001b[49m\u001b[43m=\u001b[49m\u001b[32;43m0\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 261\u001b[39m encoder_mapping = torch.cat(encoder_mapping, dim=\u001b[32m0\u001b[39m)\n\u001b[32m 263\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m pos_ids, layer_ids, feat_ids, decoder_vectors, encoder_mapping\n", + "\u001b[31mOutOfMemoryError\u001b[39m: CUDA out of memory. Tried to allocate 15.62 GiB. GPU 0 has a total capacity of 31.37 GiB of which 7.31 GiB is free. Including non-PyTorch memory, this process has 24.05 GiB memory in use. Of the allocated memory 21.92 GiB is allocated by PyTorch, and 1.54 GiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation. See documentation for Memory Management (https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)" + ] + } + ], + "source": [ + "from pathlib import Path\n", + "import torch\n", + "\n", + "from circuit_tracer import ReplacementModel, attribute\n", + "from circuit_tracer.utils import create_graph_files\n", + "\n", + "torch.cuda.empty_cache()\n", + "\n", + "# FOr some reason this takes up a lot of VRAM\n", + "graph = attribute(\n", + " prompt=prompt,\n", + " model=rm,\n", + " max_n_logits=max_n_logits,\n", + " desired_logit_prob=desired_logit_prob,\n", + " batch_size=batch_size,\n", + " max_feature_nodes=max_feature_nodes,\n", + " offload=offload,\n", + " verbose=verbose\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "191aafa5", + "metadata": {}, + "outputs": [], + "source": [ + "graph_dir = 'graphs'\n", + "graph_name = 'example_graph.pt'\n", + "graph_dir = Path(graph_dir)\n", + "graph_dir.mkdir(exist_ok=True)\n", + "graph_path = graph_dir / graph_name\n", + "\n", + "graph.to_pt(graph_path)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 2be6460597538be0d1d4383f7434e4ca3daf46bb Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 13 Nov 2025 07:23:41 +0000 Subject: [PATCH 62/99] load from config --- .../utils/model_converters/circuit_tracer.py | 10 ++++++---- tests/test_circuit_tracer_integration.py | 5 ++++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py index d384a1f..524b46d 100644 --- a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py +++ b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py @@ -1,5 +1,6 @@ from pathlib import Path +from circuit_tracer.transcoder.cross_layer_transcoder import JumpReLU import torch import yaml from safetensors.torch import save_file @@ -46,11 +47,12 @@ def convert_and_save(self, model): .cpu(), # Transpose! f"b_enc_{source_layer}": (b_enc_folded[source_layer].cpu()), f"b_dec_{source_layer}": (b_dec_folded[source_layer].cpu()), - # TODO: double check non-linearity compatibility - f"threshold_{source_layer}": ( - nonlinearity.theta[:, source_layer, :].cpu() - ), } + # TODO: double check non-linearity compatibility + if isinstance(nonlinearity, JumpReLU): + layer_encoder_dict[f"threshold_{source_layer}"] = ( + nonlinearity.theta[:, source_layer, :].cpu() + ) save_file( layer_encoder_dict, f"{self.save_dir}/W_enc_{source_layer}.safetensors" ) diff --git a/tests/test_circuit_tracer_integration.py b/tests/test_circuit_tracer_integration.py index 8f31aa8..d6d7184 100644 --- a/tests/test_circuit_tracer_integration.py +++ b/tests/test_circuit_tracer_integration.py @@ -7,8 +7,11 @@ ) -def test_circuit_tracer_integration(clt_module): +def test_circuit_tracer_integration(): """Verify uploaded model loads correctly.""" + from crosslayer_transcoder.utils.module_builder import build_module_from_config, yaml_to_config + config = yaml_to_config("config/topk-clt-debug.yaml") + clt_module = build_module_from_config(config) save_dir = pathlib.Path("clt_module_test") feature_input_hook = "blocks.{layer}.hook_resid_pre" From 42e3ebf429190da5f45961903b7810f19bf02b4f Mon Sep 17 00:00:00 2001 From: jiito Date: Sat, 15 Nov 2025 22:37:38 +0000 Subject: [PATCH 63/99] init sanity check --- .../utils/sanity_check_model.ipynb | 269 ++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 crosslayer_transcoder/utils/sanity_check_model.ipynb diff --git a/crosslayer_transcoder/utils/sanity_check_model.ipynb b/crosslayer_transcoder/utils/sanity_check_model.ipynb new file mode 100644 index 0000000..03a52a8 --- /dev/null +++ b/crosslayer_transcoder/utils/sanity_check_model.ipynb @@ -0,0 +1,269 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "9e36e2f4", + "metadata": {}, + "source": [ + "# Sanity check model\n", + "\n", + "Sanity check the model checkpoint by loading it into our own arch and then running a prompt through the encoder to see what the sparsity of the model is" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "de7531d0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "model {'class_path': 'crosslayer_transcoder.model.clt.CrossLayerTranscoder', 'init_args': {'encoder': {'class_path': 'crosslayer_transcoder.model.clt.Encoder', 'init_args': {'d_acts': 768, 'd_features': 10000, 'n_layers': 12}}, 'decoder': {'class_path': 'crosslayer_transcoder.model.clt.CrosslayerDecoder', 'init_args': {'d_acts': 768, 'd_features': 10000, 'n_layers': 12}}, 'nonlinearity': {'class_path': 'crosslayer_transcoder.model.jumprelu.JumpReLU', 'init_args': {'theta': 0.03, 'bandwidth': 0.01, 'n_layers': 12, 'd_features': 10000}}, 'input_standardizer': {'class_path': 'crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer', 'init_args': {'n_layers': 12, 'activation_dim': 768}}, 'output_standardizer': {'class_path': 'crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer', 'init_args': {'n_layers': 12, 'activation_dim': 768}}}}\n", + "encoder {'class_path': 'crosslayer_transcoder.model.clt.Encoder', 'init_args': {'d_acts': 768, 'd_features': 10000, 'n_layers': 12}}\n", + "d_acts 768\n", + "d_features 10000\n", + "n_layers 12\n", + "decoder {'class_path': 'crosslayer_transcoder.model.clt.CrosslayerDecoder', 'init_args': {'d_acts': 768, 'd_features': 10000, 'n_layers': 12}}\n", + "d_acts 768\n", + "d_features 10000\n", + "n_layers 12\n", + "nonlinearity {'class_path': 'crosslayer_transcoder.model.jumprelu.JumpReLU', 'init_args': {'theta': 0.03, 'bandwidth': 0.01, 'n_layers': 12, 'd_features': 10000}}\n", + "theta 0.03\n", + "bandwidth 0.01\n", + "n_layers 12\n", + "d_features 10000\n", + "input_standardizer {'class_path': 'crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer', 'init_args': {'n_layers': 12, 'activation_dim': 768}}\n", + "n_layers 12\n", + "activation_dim 768\n", + "output_standardizer {'class_path': 'crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer', 'init_args': {'n_layers': 12, 'activation_dim': 768}}\n", + "n_layers 12\n", + "activation_dim 768\n", + "replacement_model {'class_path': 'crosslayer_transcoder.metrics.replacement_model_accuracy.ReplacementModelAccuracy', 'init_args': {'model_name': 'openai-community/gpt2', 'device_map': 'cuda:0', 'loader_batch_size': 2}}\n", + "model_name openai-community/gpt2\n", + "device_map cuda:0\n", + "loader_batch_size 2\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "6d361419e352494f9c94caa4397c8508", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Loading dataset shards: 0%| | 0/80 [00:00 1024). Running this sequence through the model will result in indexing errors\n", + "Token indices sequence length is longer than the specified maximum sequence length for this model (1561 > 1024). Running this sequence through the model will result in indexing errors\n", + "Token indices sequence length is longer than the specified maximum sequence length for this model (2027 > 1024). Running this sequence through the model will result in indexing errors\n", + "Token indices sequence length is longer than the specified maximum sequence length for this model (2459 > 1024). Running this sequence through the model will result in indexing errors\n", + "Token indices sequence length is longer than the specified maximum sequence length for this model (1174 > 1024). Running this sequence through the model will result in indexing errors\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "dead_features {'class_path': 'crosslayer_transcoder.metrics.dead_features.DeadFeatures', 'init_args': {'n_features': 10000, 'n_layers': 12, 'return_per_layer': True, 'return_log_freqs': True, 'return_neuron_indices': True}}\n", + "n_features 10000\n", + "n_layers 12\n", + "return_per_layer True\n", + "return_log_freqs True\n", + "return_neuron_indices True\n", + "learning_rate 3e-4\n", + "compile True\n", + "lr_decay_step 16000\n", + "lr_decay_factor 0.1\n", + "lambda_sparsity 0.0007\n", + "c_sparsity 1\n", + "use_tanh True\n", + "pre_actv_loss 1e-6\n", + "compute_dead_features True\n", + "compute_dead_features_every 500\n", + "JumpReLUCrossLayerTranscoderModule(\n", + " (model): CrossLayerTranscoder(\n", + " (encoder): Encoder()\n", + " (decoder): CrosslayerDecoder()\n", + " (nonlinearity): JumpReLU()\n", + " (input_standardizer): DimensionwiseInputStandardizer()\n", + " (output_standardizer): DimensionwiseOutputStandardizer()\n", + " )\n", + " (replacement_model): ReplacementModelAccuracy(\n", + " (replacement_model): ReplacementModel()\n", + " )\n", + " (dead_features): DeadFeatures()\n", + ")\n" + ] + } + ], + "source": [ + "from crosslayer_transcoder.utils.module_builder import build_module_from_config, yaml_to_config\n", + "from crosslayer_transcoder.utils.checkpoints import load_model_from_lightning_checkpoint\n", + "\n", + "config = yaml_to_config(\"../../config/circuit-tracer.yaml\")\n", + "clt_module = build_module_from_config(config)\n", + "\n", + "# load checkpoint\n", + "checkpoint = \"../checkpoints/clt.ckpt\"\n", + "\n", + "clt_module = load_model_from_lightning_checkpoint(clt_module, checkpoint)\n", + "\n", + "print(clt_module)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "597a9d92", + "metadata": {}, + "outputs": [], + "source": [ + "from nnsight import LanguageModel\n", + "prompt = (\n", + " \"The capital of state containing Dallas is\" # What you want to get the graph for\n", + ")\n", + "llm = LanguageModel(\"openai-community/gpt2\")" + ] + }, + { + "cell_type": "markdown", + "id": "d5030984", + "metadata": {}, + "source": [ + "## Collect Activations" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "cda0fb9b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([12, 7, 768])\n", + "torch.Size([12, 7, 768])\n" + ] + } + ], + "source": [ + "import torch\n", + "mlp_in_activations = []\n", + "mlp_out_activations = []\n", + "\n", + "with llm.trace(prompt) as trace:\n", + " for layer in range(12):\n", + " layer_activations = llm.transformer.h[layer].ln_2.input.save()\n", + " layer_activations = llm.transformer.h[layer].mlp.output.save()\n", + " mlp_in_activations.append(layer_activations.squeeze(0))\n", + " mlp_out_activations.append(layer_activations.squeeze(0))\n", + "\n", + "mlp_in_activations = torch.stack(mlp_in_activations, dim=0)\n", + "mlp_out_activations = torch.stack(mlp_out_activations, dim=0)\n", + "\n", + "print(mlp_in_activations.shape)\n", + "print(mlp_out_activations.shape)" + ] + }, + { + "cell_type": "markdown", + "id": "7d847db4", + "metadata": {}, + "source": [ + "## Run Encoder w activations" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "26589596", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([7, 12, 768])\n", + "torch.Size([7, 12, 768])\n", + "torch.Size([7, 2, 12, 768])\n", + "torch.Size([7, 12, 10000])\n", + "torch.Size([7, 12, 10000])\n", + "4162\n", + "49.5476188659668\n" + ] + } + ], + "source": [ + "import einops\n", + "\n", + "in_acts = einops.rearrange(mlp_in_activations, \"l b d -> b l d\")\n", + "out_acts = einops.rearrange(mlp_out_activations, \"l b d -> b l d\")\n", + "print(in_acts.shape)\n", + "print(out_acts.shape)\n", + "batch_acts = torch.stack([in_acts, out_acts], dim=1)\n", + "print(batch_acts.shape)\n", + "clt_module.model.initialize_standardizers(batch_acts)\n", + "pre_actvs, features, _, _ = clt_module.model(in_acts)\n", + "\n", + "print(pre_actvs.shape)\n", + "print(features.shape)\n", + "\n", + "sparse_features = features.to_sparse()\n", + "print(sparse_features._nnz())\n", + "\n", + "l0_avg_per_layer = torch.count_nonzero(features > 0) / (features.shape[0] * features.shape[1])\n", + "print(l0_avg_per_layer.item())\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ee75a5df", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2bdaa188", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 4631d61dafdc0dc9d2207941ff8bf7ca1f441b05 Mon Sep 17 00:00:00 2001 From: jiito Date: Sun, 16 Nov 2025 01:27:03 +0000 Subject: [PATCH 64/99] add sanity checks to replacement score --- .../utils/replacement_score.ipynb | 404 +++++++++++++++--- .../utils/sanity_check_model.ipynb | 5 +- 2 files changed, 342 insertions(+), 67 deletions(-) diff --git a/crosslayer_transcoder/utils/replacement_score.ipynb b/crosslayer_transcoder/utils/replacement_score.ipynb index 071da59..863ddb3 100644 --- a/crosslayer_transcoder/utils/replacement_score.ipynb +++ b/crosslayer_transcoder/utils/replacement_score.ipynb @@ -24,30 +24,17 @@ "outputs": [], "source": [ "import pathlib\n", - "import shutil\n", - "from circuit_tracer.transcoder.cross_layer_transcoder import load_clt\n", "\n", "from crosslayer_transcoder.utils.model_converters.circuit_tracer import (\n", " CircuitTracerConverter,\n", ")\n", - "from transformer_lens import HookedTransformerConfig\n", - "from transformer_lens.loading_from_pretrained import get_pretrained_model_config" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8d4ddba4", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "os.environ[\"HF_TOKEN\"] = \"ADD_TOKEN_HERE\"" + "from transformer_lens.loading_from_pretrained import get_pretrained_model_config\n", + "import torch" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "id": "c166ce94", "metadata": {}, "outputs": [ @@ -55,7 +42,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "model {'class_path': 'crosslayer_transcoder.model.clt.CrossLayerTranscoder', 'init_args': {'encoder': {'class_path': 'crosslayer_transcoder.model.clt.Encoder', 'init_args': {'d_acts': 768, 'd_features': 10000, 'n_layers': 12}}, 'decoder': {'class_path': 'crosslayer_transcoder.model.clt.CrosslayerDecoder', 'init_args': {'d_acts': 768, 'd_features': 10000, 'n_layers': 12}}, 'nonlinearity': {'class_path': 'crosslayer_transcoder.model.topk.PerLayerTopK', 'init_args': {'k': 16}}, 'input_standardizer': {'class_path': 'crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer', 'init_args': {'n_layers': 12, 'activation_dim': 768}}, 'output_standardizer': {'class_path': 'crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer', 'init_args': {'n_layers': 12, 'activation_dim': 768}}}}\n", + "model {'class_path': 'crosslayer_transcoder.model.clt.CrossLayerTranscoder', 'init_args': {'encoder': {'class_path': 'crosslayer_transcoder.model.clt.Encoder', 'init_args': {'d_acts': 768, 'd_features': 10000, 'n_layers': 12}}, 'decoder': {'class_path': 'crosslayer_transcoder.model.clt.CrosslayerDecoder', 'init_args': {'d_acts': 768, 'd_features': 10000, 'n_layers': 12}}, 'nonlinearity': {'class_path': 'crosslayer_transcoder.model.jumprelu.JumpReLU', 'init_args': {'theta': 0.03, 'bandwidth': 0.01, 'n_layers': 12, 'd_features': 10000}}, 'input_standardizer': {'class_path': 'crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer', 'init_args': {'n_layers': 12, 'activation_dim': 768}}, 'output_standardizer': {'class_path': 'crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer', 'init_args': {'n_layers': 12, 'activation_dim': 768}}}}\n", "encoder {'class_path': 'crosslayer_transcoder.model.clt.Encoder', 'init_args': {'d_acts': 768, 'd_features': 10000, 'n_layers': 12}}\n", "d_acts 768\n", "d_features 10000\n", @@ -64,8 +51,11 @@ "d_acts 768\n", "d_features 10000\n", "n_layers 12\n", - "nonlinearity {'class_path': 'crosslayer_transcoder.model.topk.PerLayerTopK', 'init_args': {'k': 16}}\n", - "k 16\n", + "nonlinearity {'class_path': 'crosslayer_transcoder.model.jumprelu.JumpReLU', 'init_args': {'theta': 0.03, 'bandwidth': 0.01, 'n_layers': 12, 'd_features': 10000}}\n", + "theta 0.03\n", + "bandwidth 0.01\n", + "n_layers 12\n", + "d_features 10000\n", "input_standardizer {'class_path': 'crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer', 'init_args': {'n_layers': 12, 'activation_dim': 768}}\n", "n_layers 12\n", "activation_dim 768\n", @@ -81,7 +71,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "cadefb64507d4274bc276cc7bfc07cb2", + "model_id": "4e2b2013930245f9a28c758cc4878010", "version_major": 2, "version_minor": 0 }, @@ -97,7 +87,10 @@ "output_type": "stream", "text": [ "Token indices sequence length is longer than the specified maximum sequence length for this model (1217 > 1024). Running this sequence through the model will result in indexing errors\n", - "Token indices sequence length is longer than the specified maximum sequence length for this model (1174 > 1024). Running this sequence through the model will result in indexing errors\n" + "Token indices sequence length is longer than the specified maximum sequence length for this model (1561 > 1024). Running this sequence through the model will result in indexing errors\n", + "Token indices sequence length is longer than the specified maximum sequence length for this model (1174 > 1024). Running this sequence through the model will result in indexing errors\n", + "Token indices sequence length is longer than the specified maximum sequence length for this model (2459 > 1024). Running this sequence through the model will result in indexing errors\n", + "Token indices sequence length is longer than the specified maximum sequence length for this model (2027 > 1024). Running this sequence through the model will result in indexing errors\n" ] }, { @@ -114,34 +107,54 @@ "compile True\n", "lr_decay_step 16000\n", "lr_decay_factor 0.1\n", - "topk_aux {'class_path': 'crosslayer_transcoder.model.topk.PerLayerTopK', 'init_args': {'k': 512}}\n", - "k 512\n", - "tokens_till_dead 500000\n", - "aux_loss_scale 0.03125\n", + "lambda_sparsity 0.0007\n", + "c_sparsity 1\n", + "use_tanh True\n", + "pre_actv_loss 1e-6\n", "compute_dead_features True\n", - "compute_dead_features_every 500\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Token indices sequence length is longer than the specified maximum sequence length for this model (1561 > 1024). Running this sequence through the model will result in indexing errors\n", - "Token indices sequence length is longer than the specified maximum sequence length for this model (2027 > 1024). Running this sequence through the model will result in indexing errors\n", - "Token indices sequence length is longer than the specified maximum sequence length for this model (2459 > 1024). Running this sequence through the model will result in indexing errors\n", - "/root/crosslayer-transcoder/.venv/lib/python3.12/site-packages/lightning/pytorch/utilities/parsing.py:210: Attribute 'topk_aux' is an instance of `nn.Module` and is already saved during checkpointing. It is recommended to ignore them using `self.save_hyperparameters(ignore=['topk_aux'])`.\n" + "compute_dead_features_every 500\n", + "JumpReLU()\n", + "torch.Size([1, 12, 10000])\n", + "JumpReLU()\n", + "torch.Size([1, 12, 10000])\n", + "JumpReLU()\n", + "torch.Size([1, 12, 10000])\n", + "JumpReLU()\n", + "torch.Size([1, 12, 10000])\n", + "JumpReLU()\n", + "torch.Size([1, 12, 10000])\n", + "JumpReLU()\n", + "torch.Size([1, 12, 10000])\n", + "JumpReLU()\n", + "torch.Size([1, 12, 10000])\n", + "JumpReLU()\n", + "torch.Size([1, 12, 10000])\n", + "JumpReLU()\n", + "torch.Size([1, 12, 10000])\n", + "JumpReLU()\n", + "torch.Size([1, 12, 10000])\n", + "JumpReLU()\n", + "torch.Size([1, 12, 10000])\n", + "JumpReLU()\n", + "torch.Size([1, 12, 10000])\n" ] } ], "source": [ - "\n", - "\n", "from crosslayer_transcoder.utils.module_builder import build_module_from_config, yaml_to_config\n", - "config = yaml_to_config(\"../../config/topk-clt-debug.yaml\")\n", + "from crosslayer_transcoder.utils.checkpoints import load_model_from_lightning_checkpoint\n", + "\n", + "config = yaml_to_config(\"../../config/circuit-tracer.yaml\")\n", "clt_module = build_module_from_config(config)\n", "\n", + "# load checkpoint\n", + "checkpoint = \"../checkpoints/clt.ckpt\"\n", + "\n", + "clt_module = load_model_from_lightning_checkpoint(clt_module, checkpoint)\n", + "\n", + "\n", "save_dir = pathlib.Path(\"clt_module_test\")\n", - "feature_input_hook = \"hook_resid_pre\"\n", + "feature_input_hook = \"hook_resid_mid\"\n", "feature_output_hook = \"hook_mlp_out\"\n", "\n", "converter = CircuitTracerConverter(\n", @@ -149,55 +162,236 @@ "feature_input_hook=feature_input_hook,\n", " feature_output_hook=feature_output_hook,\n", ")\n", - "converter.convert_and_save(clt_module)" + "converter.convert_and_save(clt_module, dtype=torch.bfloat16) " ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "id": "f8d8594b", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "12\n", + "['W_enc_0', 'b_dec_0', 'b_enc_0', 'threshold_0']\n", + "['W_enc_1', 'b_dec_1', 'b_enc_1', 'threshold_1']\n", + "['W_enc_2', 'b_dec_2', 'b_enc_2', 'threshold_2']\n", + "['W_enc_3', 'b_dec_3', 'b_enc_3', 'threshold_3']\n", + "['W_enc_4', 'b_dec_4', 'b_enc_4', 'threshold_4']\n", + "['W_enc_5', 'b_dec_5', 'b_enc_5', 'threshold_5']\n", + "['W_enc_6', 'b_dec_6', 'b_enc_6', 'threshold_6']\n", + "['W_enc_7', 'b_dec_7', 'b_enc_7', 'threshold_7']\n", + "['W_enc_8', 'b_dec_8', 'b_enc_8', 'threshold_8']\n", + "['W_enc_9', 'b_dec_9', 'b_enc_9', 'threshold_9']\n", + "['W_enc_10', 'b_dec_10', 'b_enc_10', 'threshold_10']\n", + "['W_enc_11', 'b_dec_11', 'b_enc_11', 'threshold_11']\n", + "dict_keys(['b_dec', 'b_enc', 'activation_function.threshold', 'W_enc', 'W_dec.0', 'W_dec.1', 'W_dec.2', 'W_dec.3', 'W_dec.4', 'W_dec.5', 'W_dec.6', 'W_dec.7', 'W_dec.8', 'W_dec.9', 'W_dec.10', 'W_dec.11'])\n", + "JumpReLU\n", + "W_enc\n", + "torch.Size([12, 10000, 768])\n" + ] + } + ], "source": [ - "transcoder = load_clt(\n", + "from circuit_tracer.transcoder.cross_layer_transcoder import load_clt\n", + "transcoder, state_dict_pre_load = load_clt(\n", " clt_path=save_dir.as_posix(),\n", " lazy_decoder=False,\n", " lazy_encoder=False,\n", " feature_input_hook=feature_input_hook,\n", " feature_output_hook=feature_output_hook,\n", + " dtype=torch.bfloat16,\n", ")\n" ] }, { "cell_type": "code", - "execution_count": 5, - "id": "1bcce2aa", + "execution_count": 13, + "id": "a5ec0f5a", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "clt_module_test\n" + ] + } + ], "source": [ + "import einops\n", + "from safetensors import safe_open\n", "import torch\n", - "config = get_pretrained_model_config(\"gpt2\")\n", - "config.d_type = torch.float16" + "import os\n", + "# sanity check against original model \n", + "\n", + "print(transcoder.clt_path)\n", + "clt_path = save_dir.as_posix()\n", + "assert transcoder.clt_path == clt_path\n", + "\n", + "# for i in range(clt_module.model.encoder.n_layers):\n", + "# # THESE SHOULD NOT be close\n", + "# assert not torch.allclose(clt_module.model.encoder.W[i].T.to('cuda:0'), transcoder.W_enc[i].to('cuda:0')) # should fail bc of folding \n", + "\n", + "# TEST: state_dict_pre_load weights match the files before being loaded into the model\n", + "for i in range(transcoder.n_layers):\n", + " enc_file = os.path.join(clt_path, f\"W_enc_{i}.safetensors\")\n", + " with safe_open(enc_file, framework=\"pt\", device=transcoder.device.type) as f:\n", + " w_file = f.get_tensor(f\"W_enc_{i}\").to(\n", + " dtype=state_dict_pre_load[\"W_enc\"][i].dtype, device=state_dict_pre_load[\"W_enc\"][i].device\n", + " )\n", + " w_state = state_dict_pre_load[\"W_enc\"][i]\n", + " assert w_file.shape == w_state.shape, f\"W_enc_{i} shape mismatch: {w_file.shape} != {w_state.shape}\"\n", + " assert w_file.dtype == w_state.dtype, f\"W_enc_{i} dtype mismatch: {w_file.dtype} != {w_state.dtype}\"\n", + " assert torch.allclose(w_file, w_state), (\n", + " i, (w_file - w_state).abs().max().item()\n", + " )\n", + "\n", + "\n", + "# TEST: weights in the files should equal weights from the transcoder\n", + "for i in range(transcoder.n_layers):\n", + " w_model = transcoder._get_encoder_weights(i) # works for both lazy and eager\n", + " enc_file = os.path.join(clt_path, f\"W_enc_{i}.safetensors\")\n", + " with safe_open(enc_file, framework=\"pt\", device=transcoder.device.type) as f:\n", + " w_file = f.get_tensor(f\"W_enc_{i}\").to(\n", + " dtype=w_model.dtype, device=w_model.device\n", + " )\n", + "\n", + " assert w_model.shape == w_file.shape\n", + " assert w_model.dtype == w_file.dtype\n", + " assert torch.allclose(w_model, w_file), (i, (w_model - w_file).abs().max().item())\n", + "\n", + "\n", + "# fold\n", + "standardizer = clt_module.model.input_standardizer\n", + "W_enc_folded, b_enc_folded = standardizer.fold_in_encoder(clt_module.model.encoder.W.to(dtype=torch.bfloat16), clt_module.model.encoder.b.to(dtype=torch.bfloat16))\n", + "\n", + "W_enc_folded = W_enc_folded.to(dtype=torch.bfloat16)\n", + "b_enc_folded = b_enc_folded.to(dtype=torch.bfloat16)\n", + "\n", + "state_dict = {}\n", + "device = clt_module.device \n", + "# TEST: eights in the file should equal the folded weights\n", + "for i in range(clt_module.model.encoder.n_layers):\n", + " enc_file = f\"W_enc_{i}.safetensors\"\n", + " with safe_open(os.path.join(clt_path, enc_file), framework=\"pt\", device=device.type) as f:\n", + " assert W_enc_folded[i].T.shape == f.get_tensor(f\"W_enc_{i}\").shape, f\"W_enc_{i} shape mismatch: {W_enc_folded[i].shape} != {f.get_tensor(f'W_enc_{i}').shape}\"\n", + " assert W_enc_folded[i].dtype == f.get_tensor(f\"W_enc_{i}\").dtype, f\"W_enc_{i} dtype mismatch: {W_enc_folded[i].dtype} != {f.get_tensor(f'W_enc_{i}').dtype}\"\n", + " assert torch.allclose(W_enc_folded[i].T, f.get_tensor(f\"W_enc_{i}\"))\n", + " assert torch.allclose(b_enc_folded[i], f.get_tensor(f\"b_enc_{i}\"))\n", + "\n", + "\n", + " # loaded model \n", + " assert transcoder.W_enc[i].shape == f.get_tensor(f\"W_enc_{i}\").shape\n", + " assert transcoder.W_enc[i].dtype == f.get_tensor(f\"W_enc_{i}\").dtype, f\"W_enc_{i} dtype mismatch: {transcoder.W_enc[i].dtype} != {f.get_tensor(f'W_enc_{i}').dtype}\"\n", + " assert torch.allclose(transcoder.W_enc[i], f.get_tensor(f\"W_enc_{i}\").to(\"cuda:0\"))\n", + "\n", + "\n", + " \n", + "\n", + "\n", + "for i in range(clt_module.model.encoder.n_layers):\n", + " rearranged_W_enc = einops.rearrange(\n", + " W_enc_folded[i],\n", + " \"d_acts d_features -> d_features d_acts\",\n", + " ).contiguous()\n", + " assert torch.allclose(rearranged_W_enc.to('cuda:0'), transcoder.W_enc[i].to('cuda:0'))\n", + " assert torch.allclose(b_enc_folded[i].to(dtype=torch.bfloat16).to('cuda:0'),transcoder.b_enc[i].to(dtype=torch.bfloat16).to('cuda:0'))" ] }, { "cell_type": "code", - "execution_count": 6, - "id": "a3f41040", + "execution_count": 14, + "id": "1bcce2aa", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CrossLayerTranscoder(\n", + " (activation_function): JumpReLU(\n", + " threshold=Parameter containing:\n", + " tensor([[[0.2344, 0.2080, 0.2246, ..., 0.2207, 0.2363, 0.2314]],\n", + " \n", + " [[0.2451, 0.2334, 0.2578, ..., 0.2676, 0.2432, 0.2256]],\n", + " \n", + " [[0.2402, 0.2363, 0.2402, ..., 0.2139, 0.2520, 0.2002]],\n", + " \n", + " ...,\n", + " \n", + " [[0.2168, 0.3789, 0.2480, ..., 0.2305, 0.3242, 0.2793]],\n", + " \n", + " [[0.2891, 0.2158, 0.1943, ..., 0.2793, 0.2812, 0.2949]],\n", + " \n", + " [[0.1934, 0.1543, 0.1758, ..., 0.2832, 0.2324, 0.2197]]],\n", + " device='cuda:0'), bandwidth=2\n", + " )\n", + " (W_dec): ParameterList(\n", + " (0): Parameter containing: [torch.float32 of size 10000x12x768 (cuda:0)]\n", + " (1): Parameter containing: [torch.float32 of size 10000x11x768 (cuda:0)]\n", + " (2): Parameter containing: [torch.float32 of size 10000x10x768 (cuda:0)]\n", + " (3): Parameter containing: [torch.float32 of size 10000x9x768 (cuda:0)]\n", + " (4): Parameter containing: [torch.float32 of size 10000x8x768 (cuda:0)]\n", + " (5): Parameter containing: [torch.float32 of size 10000x7x768 (cuda:0)]\n", + " (6): Parameter containing: [torch.float32 of size 10000x6x768 (cuda:0)]\n", + " (7): Parameter containing: [torch.float32 of size 10000x5x768 (cuda:0)]\n", + " (8): Parameter containing: [torch.float32 of size 10000x4x768 (cuda:0)]\n", + " (9): Parameter containing: [torch.float32 of size 10000x3x768 (cuda:0)]\n", + " (10): Parameter containing: [torch.float32 of size 10000x2x768 (cuda:0)]\n", + " (11): Parameter containing: [torch.float32 of size 10000x1x768 (cuda:0)]\n", + " )\n", + ")\n", + "torch.Size([12, 10000, 768])\n", + "[torch.Size([12, 10000, 768]), torch.Size([12, 768]), torch.Size([12, 10000]), torch.Size([12, 1, 10000]), torch.Size([10000, 12, 768]), torch.Size([10000, 11, 768]), torch.Size([10000, 10, 768]), torch.Size([10000, 9, 768]), torch.Size([10000, 8, 768]), torch.Size([10000, 7, 768]), torch.Size([10000, 6, 768]), torch.Size([10000, 5, 768]), torch.Size([10000, 4, 768]), torch.Size([10000, 3, 768]), torch.Size([10000, 2, 768]), torch.Size([10000, 1, 768])]\n", + "JumpReLU(\n", + " threshold=Parameter containing:\n", + " tensor([[[0.2344, 0.2080, 0.2246, ..., 0.2207, 0.2363, 0.2314]],\n", + " \n", + " [[0.2451, 0.2334, 0.2578, ..., 0.2676, 0.2432, 0.2256]],\n", + " \n", + " [[0.2402, 0.2363, 0.2402, ..., 0.2139, 0.2520, 0.2002]],\n", + " \n", + " ...,\n", + " \n", + " [[0.2168, 0.3789, 0.2480, ..., 0.2305, 0.3242, 0.2793]],\n", + " \n", + " [[0.2891, 0.2158, 0.1943, ..., 0.2793, 0.2812, 0.2949]],\n", + " \n", + " [[0.1934, 0.1543, 0.1758, ..., 0.2832, 0.2324, 0.2197]]],\n", + " device='cuda:0'), bandwidth=2\n", + ")\n" + ] + } + ], "source": [ "from circuit_tracer import ReplacementModel\n", + "\n", + "\n", + "config = get_pretrained_model_config(\"gpt2\")\n", + "config.d_type = torch.float16\n", "rm = ReplacementModel.from_config(\n", " config=config,\n", " transcoders=transcoder,\n", ")\n", + "\n", + "\n", + "print(rm.transcoders)\n", + "print(rm.transcoders.W_enc.shape)\n", + "assert torch.allclose(rm.transcoders.W_enc, transcoder.W_enc)\n", + "print([x.shape for x in list(rm.transcoders.parameters())])\n", + "print(rm.transcoders.activation_function)\n", + "\n", + "## TODO: sanity check model\n", "\n" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "id": "10269291", "metadata": {}, "outputs": [], @@ -207,8 +401,8 @@ ")\n", "max_n_logits = 10 # How many logits to attribute from, max. We attribute to min(max_n_logits, n_logits_to_reach_desired_log_prob); see below for the latter\n", "desired_logit_prob = 0.95 # Attribution will attribute from the minimum number of logits needed to reach this probability mass (or max_n_logits, whichever is lower)\n", - "max_feature_nodes = 8192 # Only attribute from this number of feature nodes, max. Lower is faster, but you will lose more of the graph. None means no limit.\n", - "batch_size = 256 # Batch size when attributing\n", + "max_feature_nodes = 100 # Only attribute from this number of feature nodes, max. Lower is faster, but you will lose more of the graph. None means no limit.\n", + "batch_size = 256//8 # Batch size when attributing\n", "offload = (\n", " \"cpu\"\n", ") # Offload various parts of the model during attribution to save memory. Can be 'disk', 'cpu', or None (keep on GPU)\n", @@ -217,7 +411,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 16, "id": "ecb6f82c", "metadata": {}, "outputs": [ @@ -228,21 +422,103 @@ "Phase 0: Precomputing activations and vectors\n" ] }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Tokens shape: torch.Size([8])\n", + "W_enc_layer shape: torch.Size([10000, 768])\n", + "sparse_W_enc_layer nnz: 7680000\n", + "layer_features shape: torch.Size([8, 10000])\n", + "sparse_pre_activations nnz: 80000\n", + "layer_features shape after activation: torch.Size([8, 10000])\n", + "sparse_layer nnz: 70000\n", + "W_enc_layer shape: torch.Size([10000, 768])\n", + "sparse_W_enc_layer nnz: 7680000\n", + "layer_features shape: torch.Size([8, 10000])\n", + "sparse_pre_activations nnz: 80000\n", + "layer_features shape after activation: torch.Size([8, 10000])\n", + "sparse_layer nnz: 70000\n", + "W_enc_layer shape: torch.Size([10000, 768])\n", + "sparse_W_enc_layer nnz: 7680000\n", + "layer_features shape: torch.Size([8, 10000])\n", + "sparse_pre_activations nnz: 80000\n", + "layer_features shape after activation: torch.Size([8, 10000])\n", + "sparse_layer nnz: 70000\n", + "W_enc_layer shape: torch.Size([10000, 768])\n", + "sparse_W_enc_layer nnz: 7680000\n", + "layer_features shape: torch.Size([8, 10000])\n", + "sparse_pre_activations nnz: 80000\n", + "layer_features shape after activation: torch.Size([8, 10000])\n", + "sparse_layer nnz: 70000\n", + "W_enc_layer shape: torch.Size([10000, 768])\n", + "sparse_W_enc_layer nnz: 7680000\n", + "layer_features shape: torch.Size([8, 10000])\n", + "sparse_pre_activations nnz: 80000\n", + "layer_features shape after activation: torch.Size([8, 10000])\n", + "sparse_layer nnz: 70000\n", + "W_enc_layer shape: torch.Size([10000, 768])\n", + "sparse_W_enc_layer nnz: 7680000\n", + "layer_features shape: torch.Size([8, 10000])\n", + "sparse_pre_activations nnz: 80000\n", + "layer_features shape after activation: torch.Size([8, 10000])\n", + "sparse_layer nnz: 70000\n", + "W_enc_layer shape: torch.Size([10000, 768])\n", + "sparse_W_enc_layer nnz: 7680000\n", + "layer_features shape: torch.Size([8, 10000])\n", + "sparse_pre_activations nnz: 80000\n", + "layer_features shape after activation: torch.Size([8, 10000])\n", + "sparse_layer nnz: 70000\n", + "W_enc_layer shape: torch.Size([10000, 768])\n", + "sparse_W_enc_layer nnz: 7680000\n", + "layer_features shape: torch.Size([8, 10000])\n", + "sparse_pre_activations nnz: 80000\n", + "layer_features shape after activation: torch.Size([8, 10000])\n", + "sparse_layer nnz: 70000\n", + "W_enc_layer shape: torch.Size([10000, 768])\n", + "sparse_W_enc_layer nnz: 7680000\n", + "layer_features shape: torch.Size([8, 10000])\n", + "sparse_pre_activations nnz: 80000\n", + "layer_features shape after activation: torch.Size([8, 10000])\n", + "sparse_layer nnz: 70000\n", + "W_enc_layer shape: torch.Size([10000, 768])\n", + "sparse_W_enc_layer nnz: 7680000\n", + "layer_features shape: torch.Size([8, 10000])\n", + "sparse_pre_activations nnz: 80000\n", + "layer_features shape after activation: torch.Size([8, 10000])\n", + "sparse_layer nnz: 70000\n", + "W_enc_layer shape: torch.Size([10000, 768])\n", + "sparse_W_enc_layer nnz: 7680000\n", + "layer_features shape: torch.Size([8, 10000])\n", + "sparse_pre_activations nnz: 80000\n", + "layer_features shape after activation: torch.Size([8, 10000])\n", + "sparse_layer nnz: 70000\n", + "W_enc_layer shape: torch.Size([10000, 768])\n", + "sparse_W_enc_layer nnz: 7680000\n", + "layer_features shape: torch.Size([8, 10000])\n", + "sparse_pre_activations nnz: 80000\n", + "layer_features shape after activation: torch.Size([8, 10000])\n", + "sparse_layer nnz: 70000\n", + "Features shape: torch.Size([12, 8, 10000])\n", + "Encoder vectors shape: torch.Size([840000, 768])\n", + "nnz: 840000\n" + ] + }, { "ename": "OutOfMemoryError", - "evalue": "CUDA out of memory. Tried to allocate 15.62 GiB. GPU 0 has a total capacity of 31.37 GiB of which 7.31 GiB is free. Including non-PyTorch memory, this process has 24.05 GiB memory in use. Of the allocated memory 21.92 GiB is allocated by PyTorch, and 1.54 GiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation. See documentation for Memory Management (https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)", + "evalue": "CUDA out of memory. Tried to allocate 15.62 GiB. GPU 0 has a total capacity of 44.34 GiB of which 10.35 GiB is free. Process 2086456 has 8.54 GiB memory in use. Process 2458041 has 25.44 GiB memory in use. Of the allocated memory 23.23 GiB is allocated by PyTorch, and 1.91 GiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation. See documentation for Memory Management (https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)", "output_type": "error", "traceback": [ "\u001b[31m---------------------------------------------------------------------------\u001b[39m", "\u001b[31mOutOfMemoryError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[8]\u001b[39m\u001b[32m, line 10\u001b[39m\n\u001b[32m 7\u001b[39m torch.cuda.empty_cache()\n\u001b[32m 9\u001b[39m \u001b[38;5;66;03m# FOr some reason this takes up a lot of VRAM\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m10\u001b[39m graph = \u001b[43mattribute\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 11\u001b[39m \u001b[43m \u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m=\u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 12\u001b[39m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrm\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 13\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 14\u001b[39m \u001b[43m \u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 15\u001b[39m \u001b[43m \u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 16\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 17\u001b[39m \u001b[43m \u001b[49m\u001b[43moffload\u001b[49m\u001b[43m=\u001b[49m\u001b[43moffload\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 18\u001b[39m \u001b[43m \u001b[49m\u001b[43mverbose\u001b[49m\u001b[43m=\u001b[49m\u001b[43mverbose\u001b[49m\n\u001b[32m 19\u001b[39m \u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/crosslayer-transcoder/.venv/lib/python3.12/site-packages/circuit_tracer/attribution/attribute.py:137\u001b[39m, in \u001b[36mattribute\u001b[39m\u001b[34m(prompt, model, max_n_logits, desired_logit_prob, batch_size, max_feature_nodes, offload, verbose, update_interval)\u001b[39m\n\u001b[32m 135\u001b[39m offload_handles = []\n\u001b[32m 136\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m137\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_run_attribution\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 138\u001b[39m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 139\u001b[39m \u001b[43m \u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m=\u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 140\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 141\u001b[39m \u001b[43m \u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 142\u001b[39m \u001b[43m \u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 143\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 144\u001b[39m \u001b[43m \u001b[49m\u001b[43moffload\u001b[49m\u001b[43m=\u001b[49m\u001b[43moffload\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 145\u001b[39m \u001b[43m \u001b[49m\u001b[43mverbose\u001b[49m\u001b[43m=\u001b[49m\u001b[43mverbose\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 146\u001b[39m \u001b[43m \u001b[49m\u001b[43moffload_handles\u001b[49m\u001b[43m=\u001b[49m\u001b[43moffload_handles\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 147\u001b[39m \u001b[43m \u001b[49m\u001b[43mupdate_interval\u001b[49m\u001b[43m=\u001b[49m\u001b[43mupdate_interval\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 148\u001b[39m \u001b[43m \u001b[49m\u001b[43mlogger\u001b[49m\u001b[43m=\u001b[49m\u001b[43mlogger\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 149\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 150\u001b[39m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[32m 151\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m reload_handle \u001b[38;5;129;01min\u001b[39;00m offload_handles:\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/crosslayer-transcoder/.venv/lib/python3.12/site-packages/circuit_tracer/attribution/attribute.py:177\u001b[39m, in \u001b[36m_run_attribution\u001b[39m\u001b[34m(model, prompt, max_n_logits, desired_logit_prob, batch_size, max_feature_nodes, offload, verbose, offload_handles, logger, update_interval)\u001b[39m\n\u001b[32m 174\u001b[39m phase_start = time.time()\n\u001b[32m 175\u001b[39m input_ids = model.ensure_tokenized(prompt)\n\u001b[32m--> \u001b[39m\u001b[32m177\u001b[39m ctx = \u001b[43mmodel\u001b[49m\u001b[43m.\u001b[49m\u001b[43msetup_attribution\u001b[49m\u001b[43m(\u001b[49m\u001b[43minput_ids\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 178\u001b[39m activation_matrix = ctx.activation_matrix\n\u001b[32m 180\u001b[39m logger.info(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mPrecomputation completed in \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mtime.time()\u001b[38;5;250m \u001b[39m-\u001b[38;5;250m \u001b[39mphase_start\u001b[38;5;132;01m:\u001b[39;00m\u001b[33m.2f\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[33ms\u001b[39m\u001b[33m\"\u001b[39m)\n", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[16]\u001b[39m\u001b[32m, line 10\u001b[39m\n\u001b[32m 7\u001b[39m torch.cuda.empty_cache()\n\u001b[32m 9\u001b[39m \u001b[38;5;66;03m# FOr some reason this takes up a lot of VRAM\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m10\u001b[39m graph = \u001b[43mattribute\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 11\u001b[39m \u001b[43m \u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m=\u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 12\u001b[39m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrm\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 13\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 14\u001b[39m \u001b[43m \u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 15\u001b[39m \u001b[43m \u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 16\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 17\u001b[39m \u001b[43m \u001b[49m\u001b[43moffload\u001b[49m\u001b[43m=\u001b[49m\u001b[43moffload\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 18\u001b[39m \u001b[43m \u001b[49m\u001b[43mverbose\u001b[49m\u001b[43m=\u001b[49m\u001b[43mverbose\u001b[49m\n\u001b[32m 19\u001b[39m \u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/attribution/attribute.py:137\u001b[39m, in \u001b[36mattribute\u001b[39m\u001b[34m(prompt, model, max_n_logits, desired_logit_prob, batch_size, max_feature_nodes, offload, verbose, update_interval)\u001b[39m\n\u001b[32m 135\u001b[39m offload_handles = []\n\u001b[32m 136\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m137\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_run_attribution\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 138\u001b[39m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 139\u001b[39m \u001b[43m \u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m=\u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 140\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 141\u001b[39m \u001b[43m \u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 142\u001b[39m \u001b[43m \u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 143\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 144\u001b[39m \u001b[43m \u001b[49m\u001b[43moffload\u001b[49m\u001b[43m=\u001b[49m\u001b[43moffload\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 145\u001b[39m \u001b[43m \u001b[49m\u001b[43mverbose\u001b[49m\u001b[43m=\u001b[49m\u001b[43mverbose\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 146\u001b[39m \u001b[43m \u001b[49m\u001b[43moffload_handles\u001b[49m\u001b[43m=\u001b[49m\u001b[43moffload_handles\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 147\u001b[39m \u001b[43m \u001b[49m\u001b[43mupdate_interval\u001b[49m\u001b[43m=\u001b[49m\u001b[43mupdate_interval\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 148\u001b[39m \u001b[43m \u001b[49m\u001b[43mlogger\u001b[49m\u001b[43m=\u001b[49m\u001b[43mlogger\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 149\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 150\u001b[39m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[32m 151\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m reload_handle \u001b[38;5;129;01min\u001b[39;00m offload_handles:\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/attribution/attribute.py:177\u001b[39m, in \u001b[36m_run_attribution\u001b[39m\u001b[34m(model, prompt, max_n_logits, desired_logit_prob, batch_size, max_feature_nodes, offload, verbose, offload_handles, logger, update_interval)\u001b[39m\n\u001b[32m 174\u001b[39m phase_start = time.time()\n\u001b[32m 175\u001b[39m input_ids = model.ensure_tokenized(prompt)\n\u001b[32m--> \u001b[39m\u001b[32m177\u001b[39m ctx = \u001b[43mmodel\u001b[49m\u001b[43m.\u001b[49m\u001b[43msetup_attribution\u001b[49m\u001b[43m(\u001b[49m\u001b[43minput_ids\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 178\u001b[39m activation_matrix = ctx.activation_matrix\n\u001b[32m 180\u001b[39m logger.info(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mPrecomputation completed in \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mtime.time()\u001b[38;5;250m \u001b[39m-\u001b[38;5;250m \u001b[39mphase_start\u001b[38;5;132;01m:\u001b[39;00m\u001b[33m.2f\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[33ms\u001b[39m\u001b[33m\"\u001b[39m)\n", "\u001b[36mFile \u001b[39m\u001b[32m~/crosslayer-transcoder/.venv/lib/python3.12/site-packages/torch/utils/_contextlib.py:120\u001b[39m, in \u001b[36mcontext_decorator..decorate_context\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 117\u001b[39m \u001b[38;5;129m@functools\u001b[39m.wraps(func)\n\u001b[32m 118\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mdecorate_context\u001b[39m(*args, **kwargs):\n\u001b[32m 119\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m ctx_factory():\n\u001b[32m--> \u001b[39m\u001b[32m120\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/crosslayer-transcoder/.venv/lib/python3.12/site-packages/circuit_tracer/replacement_model.py:433\u001b[39m, in \u001b[36mReplacementModel.setup_attribution\u001b[39m\u001b[34m(self, inputs)\u001b[39m\n\u001b[32m 430\u001b[39m mlp_in_cache = torch.cat(\u001b[38;5;28mlist\u001b[39m(mlp_in_cache.values()), dim=\u001b[32m0\u001b[39m)\n\u001b[32m 431\u001b[39m mlp_out_cache = torch.cat(\u001b[38;5;28mlist\u001b[39m(mlp_out_cache.values()), dim=\u001b[32m0\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m433\u001b[39m attribution_data = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mtranscoders\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcompute_attribution_components\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmlp_in_cache\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 435\u001b[39m \u001b[38;5;66;03m# Compute error vectors\u001b[39;00m\n\u001b[32m 436\u001b[39m error_vectors = mlp_out_cache - attribution_data[\u001b[33m\"\u001b[39m\u001b[33mreconstruction\u001b[39m\u001b[33m\"\u001b[39m]\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/crosslayer-transcoder/.venv/lib/python3.12/site-packages/circuit_tracer/transcoder/cross_layer_transcoder.py:300\u001b[39m, in \u001b[36mCrossLayerTranscoder.compute_attribution_components\u001b[39m\u001b[34m(self, inputs)\u001b[39m\n\u001b[32m 285\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"Extract active features and their encoder/decoder vectors for attribution.\u001b[39;00m\n\u001b[32m 286\u001b[39m \n\u001b[32m 287\u001b[39m \u001b[33;03mArgs:\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 296\u001b[39m \u001b[33;03m - encoder_to_decoder_map: Mapping from encoder to decoder indices\u001b[39;00m\n\u001b[32m 297\u001b[39m \u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 298\u001b[39m features, encoder_vectors = \u001b[38;5;28mself\u001b[39m.encode_sparse(inputs, zero_first_pos=\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[32m 299\u001b[39m pos_ids, layer_ids, feat_ids, decoder_vectors, encoder_to_decoder_map = (\n\u001b[32m--> \u001b[39m\u001b[32m300\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mselect_decoder_vectors\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfeatures\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 301\u001b[39m )\n\u001b[32m 302\u001b[39m reconstruction = \u001b[38;5;28mself\u001b[39m.compute_reconstruction(pos_ids, layer_ids, decoder_vectors)\n\u001b[32m 304\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m {\n\u001b[32m 305\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mactivation_matrix\u001b[39m\u001b[33m\"\u001b[39m: features,\n\u001b[32m 306\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mreconstruction\u001b[39m\u001b[33m\"\u001b[39m: reconstruction,\n\u001b[32m (...)\u001b[39m\u001b[32m 310\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mdecoder_locations\u001b[39m\u001b[33m\"\u001b[39m: torch.stack((layer_ids, pos_ids)),\n\u001b[32m 311\u001b[39m }\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/crosslayer-transcoder/.venv/lib/python3.12/site-packages/circuit_tracer/transcoder/cross_layer_transcoder.py:260\u001b[39m, in \u001b[36mCrossLayerTranscoder.select_decoder_vectors\u001b[39m\u001b[34m(self, features)\u001b[39m\n\u001b[32m 258\u001b[39m layer_ids = torch.cat(layer_ids, dim=\u001b[32m0\u001b[39m)\n\u001b[32m 259\u001b[39m feat_ids = torch.cat(feat_ids, dim=\u001b[32m0\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m260\u001b[39m decoder_vectors = \u001b[43mtorch\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcat\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdecoder_vectors\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdim\u001b[49m\u001b[43m=\u001b[49m\u001b[32;43m0\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 261\u001b[39m encoder_mapping = torch.cat(encoder_mapping, dim=\u001b[32m0\u001b[39m)\n\u001b[32m 263\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m pos_ids, layer_ids, feat_ids, decoder_vectors, encoder_mapping\n", - "\u001b[31mOutOfMemoryError\u001b[39m: CUDA out of memory. Tried to allocate 15.62 GiB. GPU 0 has a total capacity of 31.37 GiB of which 7.31 GiB is free. Including non-PyTorch memory, this process has 24.05 GiB memory in use. Of the allocated memory 21.92 GiB is allocated by PyTorch, and 1.54 GiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation. See documentation for Memory Management (https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)" + "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/replacement_model.py:435\u001b[39m, in \u001b[36mReplacementModel.setup_attribution\u001b[39m\u001b[34m(self, inputs)\u001b[39m\n\u001b[32m 432\u001b[39m mlp_in_cache = torch.cat(\u001b[38;5;28mlist\u001b[39m(mlp_in_cache.values()), dim=\u001b[32m0\u001b[39m)\n\u001b[32m 433\u001b[39m mlp_out_cache = torch.cat(\u001b[38;5;28mlist\u001b[39m(mlp_out_cache.values()), dim=\u001b[32m0\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m435\u001b[39m attribution_data = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mtranscoders\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcompute_attribution_components\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmlp_in_cache\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 437\u001b[39m \u001b[38;5;66;03m# Compute error vectors\u001b[39;00m\n\u001b[32m 438\u001b[39m error_vectors = mlp_out_cache - attribution_data[\u001b[33m\"\u001b[39m\u001b[33mreconstruction\u001b[39m\u001b[33m\"\u001b[39m]\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/transcoder/cross_layer_transcoder.py:321\u001b[39m, in \u001b[36mCrossLayerTranscoder.compute_attribution_components\u001b[39m\u001b[34m(self, inputs)\u001b[39m\n\u001b[32m 318\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mEncoder vectors shape: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mencoder_vectors.shape\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m)\n\u001b[32m 319\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mnnz: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfeatures._nnz()\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m)\n\u001b[32m 320\u001b[39m pos_ids, layer_ids, feat_ids, decoder_vectors, encoder_to_decoder_map = (\n\u001b[32m--> \u001b[39m\u001b[32m321\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mselect_decoder_vectors\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfeatures\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 322\u001b[39m )\n\u001b[32m 323\u001b[39m \u001b[38;5;28mprint\u001b[39m(features.shape)\n\u001b[32m 324\u001b[39m reconstruction = \u001b[38;5;28mself\u001b[39m.compute_reconstruction(pos_ids, layer_ids, decoder_vectors)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/transcoder/cross_layer_transcoder.py:278\u001b[39m, in \u001b[36mCrossLayerTranscoder.select_decoder_vectors\u001b[39m\u001b[34m(self, features)\u001b[39m\n\u001b[32m 276\u001b[39m layer_ids = torch.cat(layer_ids, dim=\u001b[32m0\u001b[39m)\n\u001b[32m 277\u001b[39m feat_ids = torch.cat(feat_ids, dim=\u001b[32m0\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m278\u001b[39m decoder_vectors = \u001b[43mtorch\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcat\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdecoder_vectors\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdim\u001b[49m\u001b[43m=\u001b[49m\u001b[32;43m0\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 279\u001b[39m encoder_mapping = torch.cat(encoder_mapping, dim=\u001b[32m0\u001b[39m)\n\u001b[32m 281\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m pos_ids, layer_ids, feat_ids, decoder_vectors, encoder_mapping\n", + "\u001b[31mOutOfMemoryError\u001b[39m: CUDA out of memory. Tried to allocate 15.62 GiB. GPU 0 has a total capacity of 44.34 GiB of which 10.35 GiB is free. Process 2086456 has 8.54 GiB memory in use. Process 2458041 has 25.44 GiB memory in use. Of the allocated memory 23.23 GiB is allocated by PyTorch, and 1.91 GiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation. See documentation for Memory Management (https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)" ] } ], diff --git a/crosslayer_transcoder/utils/sanity_check_model.ipynb b/crosslayer_transcoder/utils/sanity_check_model.ipynb index 03a52a8..3ed5f1e 100644 --- a/crosslayer_transcoder/utils/sanity_check_model.ipynb +++ b/crosslayer_transcoder/utils/sanity_check_model.ipynb @@ -188,7 +188,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": null, "id": "26589596", "metadata": {}, "outputs": [ @@ -216,9 +216,8 @@ "batch_acts = torch.stack([in_acts, out_acts], dim=1)\n", "print(batch_acts.shape)\n", "clt_module.model.initialize_standardizers(batch_acts)\n", - "pre_actvs, features, _, _ = clt_module.model(in_acts)\n", + "_, features, _, _ = clt_module.model(in_acts)\n", "\n", - "print(pre_actvs.shape)\n", "print(features.shape)\n", "\n", "sparse_features = features.to_sparse()\n", From 2f4a19e2b28ef71ae444d6ca31e3f923e19d2724 Mon Sep 17 00:00:00 2001 From: jiito Date: Sun, 16 Nov 2025 16:35:16 +0000 Subject: [PATCH 65/99] update debug config --- config/circuit-tracer.yaml | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/config/circuit-tracer.yaml b/config/circuit-tracer.yaml index a83a2c3..4f08eae 100644 --- a/config/circuit-tracer.yaml +++ b/config/circuit-tracer.yaml @@ -5,8 +5,8 @@ seed_everything: 42 trainer: # max_steps is number of gradient updates. If using gradient accumulation, this is not the number of batches. - max_steps: 100 - val_check_interval: 10 + max_steps: 100_000 + val_check_interval: 1_000 limit_val_batches: 1 enable_checkpointing: false # We use custom end-of-training checkpoint num_sanity_val_steps: 0 # Can't run replacement model before standardizers are initialized @@ -21,11 +21,9 @@ trainer: name: "circuit-tracer" save_dir: "./wandb" callbacks: - class_path: crosslayer_transcoder.utils.callbacks.ModelConversionCallback - init_args: - save_dir: "clt_module" - kinds: - - "circuit_tracer" + - class_path: crosslayer_transcoder.utils.callbacks.EndOfTrainingCheckpointCallback + init_args: + checkpoint_dir: "checkpoints" model: class_path: crosslayer_transcoder.model.clt_lightning.JumpReLUCrossLayerTranscoderModule @@ -87,9 +85,9 @@ model: # Training parameters - learning_rate: 1e-4 + learning_rate: 3e-4 compile: true # if using torch.compile - lr_decay_step: 80_000 # lr is scaled by lr_decay_factor after this many steps + lr_decay_step: 16_000 # lr is scaled by lr_decay_factor after this many steps lr_decay_factor: 0.1 lambda_sparsity: 0.0007 # sparsity loss weight @@ -99,18 +97,18 @@ model: # Dead features computation settings compute_dead_features: true - compute_dead_features_every: 50 + compute_dead_features_every: 500 data: class_path: crosslayer_transcoder.data.datamodule.ActivationDataModule init_args: # Buffer settings - buffer_size: 1_000 # number of activations to store in the buffer + buffer_size: 500_000 # number of activations to store in the buffer n_in_out: 2 # number of input and output layers n_layers: 12 # number of layers in the model activation_dim: 768 # dimension of the activations dtype: "float16" # dtype of the activations - max_batch_size: 500 # maximum batch size for the data loader + max_batch_size: 8000 # maximum batch size for the data loader # Model settings for activation generation model_name: "openai-community/gpt2" @@ -160,5 +158,6 @@ data: tags: ["data-generation"] # Tags for the data generation run save_dir: "./wandb" # Directory for WandB files log_interval: 5.0 # Logging interval in seconds + offline: true # Offline mode for WandB logging ckpt_path: null \ No newline at end of file From e00d31b4b77921bad77e63173a80e1947bb747ab Mon Sep 17 00:00:00 2001 From: jiito Date: Sun, 16 Nov 2025 16:35:42 +0000 Subject: [PATCH 66/99] sanity check --- .../utils/replacement_score.ipynb | 32 ++++--- .../utils/sanity_check_model.ipynb | 83 ++++++++++++------- 2 files changed, 75 insertions(+), 40 deletions(-) diff --git a/crosslayer_transcoder/utils/replacement_score.ipynb b/crosslayer_transcoder/utils/replacement_score.ipynb index 863ddb3..8ce5380 100644 --- a/crosslayer_transcoder/utils/replacement_score.ipynb +++ b/crosslayer_transcoder/utils/replacement_score.ipynb @@ -71,7 +71,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "4e2b2013930245f9a28c758cc4878010", + "model_id": "ce9409e1c34a4ae3b2bac2bf5299dfe6", "version_major": 2, "version_minor": 0 }, @@ -209,7 +209,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 4, "id": "a5ec0f5a", "metadata": {}, "outputs": [ @@ -304,7 +304,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 5, "id": "1bcce2aa", "metadata": {}, "outputs": [ @@ -391,7 +391,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 6, "id": "10269291", "metadata": {}, "outputs": [], @@ -411,7 +411,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 7, "id": "ecb6f82c", "metadata": {}, "outputs": [ @@ -432,72 +432,84 @@ "layer_features shape: torch.Size([8, 10000])\n", "sparse_pre_activations nnz: 80000\n", "layer_features shape after activation: torch.Size([8, 10000])\n", + "l0: 70000\n", "sparse_layer nnz: 70000\n", "W_enc_layer shape: torch.Size([10000, 768])\n", "sparse_W_enc_layer nnz: 7680000\n", "layer_features shape: torch.Size([8, 10000])\n", "sparse_pre_activations nnz: 80000\n", "layer_features shape after activation: torch.Size([8, 10000])\n", + "l0: 70000\n", "sparse_layer nnz: 70000\n", "W_enc_layer shape: torch.Size([10000, 768])\n", "sparse_W_enc_layer nnz: 7680000\n", "layer_features shape: torch.Size([8, 10000])\n", "sparse_pre_activations nnz: 80000\n", "layer_features shape after activation: torch.Size([8, 10000])\n", + "l0: 70000\n", "sparse_layer nnz: 70000\n", "W_enc_layer shape: torch.Size([10000, 768])\n", "sparse_W_enc_layer nnz: 7680000\n", "layer_features shape: torch.Size([8, 10000])\n", "sparse_pre_activations nnz: 80000\n", "layer_features shape after activation: torch.Size([8, 10000])\n", + "l0: 70000\n", "sparse_layer nnz: 70000\n", "W_enc_layer shape: torch.Size([10000, 768])\n", "sparse_W_enc_layer nnz: 7680000\n", "layer_features shape: torch.Size([8, 10000])\n", "sparse_pre_activations nnz: 80000\n", "layer_features shape after activation: torch.Size([8, 10000])\n", + "l0: 70000\n", "sparse_layer nnz: 70000\n", "W_enc_layer shape: torch.Size([10000, 768])\n", "sparse_W_enc_layer nnz: 7680000\n", "layer_features shape: torch.Size([8, 10000])\n", "sparse_pre_activations nnz: 80000\n", "layer_features shape after activation: torch.Size([8, 10000])\n", + "l0: 70000\n", "sparse_layer nnz: 70000\n", "W_enc_layer shape: torch.Size([10000, 768])\n", "sparse_W_enc_layer nnz: 7680000\n", "layer_features shape: torch.Size([8, 10000])\n", "sparse_pre_activations nnz: 80000\n", "layer_features shape after activation: torch.Size([8, 10000])\n", + "l0: 70000\n", "sparse_layer nnz: 70000\n", "W_enc_layer shape: torch.Size([10000, 768])\n", "sparse_W_enc_layer nnz: 7680000\n", "layer_features shape: torch.Size([8, 10000])\n", "sparse_pre_activations nnz: 80000\n", "layer_features shape after activation: torch.Size([8, 10000])\n", + "l0: 70000\n", "sparse_layer nnz: 70000\n", "W_enc_layer shape: torch.Size([10000, 768])\n", "sparse_W_enc_layer nnz: 7680000\n", "layer_features shape: torch.Size([8, 10000])\n", "sparse_pre_activations nnz: 80000\n", "layer_features shape after activation: torch.Size([8, 10000])\n", + "l0: 70000\n", "sparse_layer nnz: 70000\n", "W_enc_layer shape: torch.Size([10000, 768])\n", "sparse_W_enc_layer nnz: 7680000\n", "layer_features shape: torch.Size([8, 10000])\n", "sparse_pre_activations nnz: 80000\n", "layer_features shape after activation: torch.Size([8, 10000])\n", + "l0: 70000\n", "sparse_layer nnz: 70000\n", "W_enc_layer shape: torch.Size([10000, 768])\n", "sparse_W_enc_layer nnz: 7680000\n", "layer_features shape: torch.Size([8, 10000])\n", "sparse_pre_activations nnz: 80000\n", "layer_features shape after activation: torch.Size([8, 10000])\n", + "l0: 70000\n", "sparse_layer nnz: 70000\n", "W_enc_layer shape: torch.Size([10000, 768])\n", "sparse_W_enc_layer nnz: 7680000\n", "layer_features shape: torch.Size([8, 10000])\n", "sparse_pre_activations nnz: 80000\n", "layer_features shape after activation: torch.Size([8, 10000])\n", + "l0: 70000\n", "sparse_layer nnz: 70000\n", "Features shape: torch.Size([12, 8, 10000])\n", "Encoder vectors shape: torch.Size([840000, 768])\n", @@ -506,19 +518,19 @@ }, { "ename": "OutOfMemoryError", - "evalue": "CUDA out of memory. Tried to allocate 15.62 GiB. GPU 0 has a total capacity of 44.34 GiB of which 10.35 GiB is free. Process 2086456 has 8.54 GiB memory in use. Process 2458041 has 25.44 GiB memory in use. Of the allocated memory 23.23 GiB is allocated by PyTorch, and 1.91 GiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation. See documentation for Memory Management (https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)", + "evalue": "CUDA out of memory. Tried to allocate 15.62 GiB. GPU 0 has a total capacity of 44.34 GiB of which 10.35 GiB is free. Process 2491674 has 8.54 GiB memory in use. Process 2496736 has 25.44 GiB memory in use. Of the allocated memory 23.23 GiB is allocated by PyTorch, and 1.91 GiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation. See documentation for Memory Management (https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)", "output_type": "error", "traceback": [ "\u001b[31m---------------------------------------------------------------------------\u001b[39m", "\u001b[31mOutOfMemoryError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[16]\u001b[39m\u001b[32m, line 10\u001b[39m\n\u001b[32m 7\u001b[39m torch.cuda.empty_cache()\n\u001b[32m 9\u001b[39m \u001b[38;5;66;03m# FOr some reason this takes up a lot of VRAM\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m10\u001b[39m graph = \u001b[43mattribute\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 11\u001b[39m \u001b[43m \u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m=\u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 12\u001b[39m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrm\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 13\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 14\u001b[39m \u001b[43m \u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 15\u001b[39m \u001b[43m \u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 16\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 17\u001b[39m \u001b[43m \u001b[49m\u001b[43moffload\u001b[49m\u001b[43m=\u001b[49m\u001b[43moffload\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 18\u001b[39m \u001b[43m \u001b[49m\u001b[43mverbose\u001b[49m\u001b[43m=\u001b[49m\u001b[43mverbose\u001b[49m\n\u001b[32m 19\u001b[39m \u001b[43m)\u001b[49m\n", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[7]\u001b[39m\u001b[32m, line 10\u001b[39m\n\u001b[32m 7\u001b[39m torch.cuda.empty_cache()\n\u001b[32m 9\u001b[39m \u001b[38;5;66;03m# FOr some reason this takes up a lot of VRAM\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m10\u001b[39m graph = \u001b[43mattribute\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 11\u001b[39m \u001b[43m \u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m=\u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 12\u001b[39m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrm\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 13\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 14\u001b[39m \u001b[43m \u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 15\u001b[39m \u001b[43m \u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 16\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 17\u001b[39m \u001b[43m \u001b[49m\u001b[43moffload\u001b[49m\u001b[43m=\u001b[49m\u001b[43moffload\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 18\u001b[39m \u001b[43m \u001b[49m\u001b[43mverbose\u001b[49m\u001b[43m=\u001b[49m\u001b[43mverbose\u001b[49m\n\u001b[32m 19\u001b[39m \u001b[43m)\u001b[49m\n", "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/attribution/attribute.py:137\u001b[39m, in \u001b[36mattribute\u001b[39m\u001b[34m(prompt, model, max_n_logits, desired_logit_prob, batch_size, max_feature_nodes, offload, verbose, update_interval)\u001b[39m\n\u001b[32m 135\u001b[39m offload_handles = []\n\u001b[32m 136\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m137\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_run_attribution\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 138\u001b[39m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 139\u001b[39m \u001b[43m \u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m=\u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 140\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 141\u001b[39m \u001b[43m \u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 142\u001b[39m \u001b[43m \u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 143\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 144\u001b[39m \u001b[43m \u001b[49m\u001b[43moffload\u001b[49m\u001b[43m=\u001b[49m\u001b[43moffload\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 145\u001b[39m \u001b[43m \u001b[49m\u001b[43mverbose\u001b[49m\u001b[43m=\u001b[49m\u001b[43mverbose\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 146\u001b[39m \u001b[43m \u001b[49m\u001b[43moffload_handles\u001b[49m\u001b[43m=\u001b[49m\u001b[43moffload_handles\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 147\u001b[39m \u001b[43m \u001b[49m\u001b[43mupdate_interval\u001b[49m\u001b[43m=\u001b[49m\u001b[43mupdate_interval\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 148\u001b[39m \u001b[43m \u001b[49m\u001b[43mlogger\u001b[49m\u001b[43m=\u001b[49m\u001b[43mlogger\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 149\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 150\u001b[39m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[32m 151\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m reload_handle \u001b[38;5;129;01min\u001b[39;00m offload_handles:\n", "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/attribution/attribute.py:177\u001b[39m, in \u001b[36m_run_attribution\u001b[39m\u001b[34m(model, prompt, max_n_logits, desired_logit_prob, batch_size, max_feature_nodes, offload, verbose, offload_handles, logger, update_interval)\u001b[39m\n\u001b[32m 174\u001b[39m phase_start = time.time()\n\u001b[32m 175\u001b[39m input_ids = model.ensure_tokenized(prompt)\n\u001b[32m--> \u001b[39m\u001b[32m177\u001b[39m ctx = \u001b[43mmodel\u001b[49m\u001b[43m.\u001b[49m\u001b[43msetup_attribution\u001b[49m\u001b[43m(\u001b[49m\u001b[43minput_ids\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 178\u001b[39m activation_matrix = ctx.activation_matrix\n\u001b[32m 180\u001b[39m logger.info(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mPrecomputation completed in \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mtime.time()\u001b[38;5;250m \u001b[39m-\u001b[38;5;250m \u001b[39mphase_start\u001b[38;5;132;01m:\u001b[39;00m\u001b[33m.2f\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[33ms\u001b[39m\u001b[33m\"\u001b[39m)\n", "\u001b[36mFile \u001b[39m\u001b[32m~/crosslayer-transcoder/.venv/lib/python3.12/site-packages/torch/utils/_contextlib.py:120\u001b[39m, in \u001b[36mcontext_decorator..decorate_context\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 117\u001b[39m \u001b[38;5;129m@functools\u001b[39m.wraps(func)\n\u001b[32m 118\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mdecorate_context\u001b[39m(*args, **kwargs):\n\u001b[32m 119\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m ctx_factory():\n\u001b[32m--> \u001b[39m\u001b[32m120\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/replacement_model.py:435\u001b[39m, in \u001b[36mReplacementModel.setup_attribution\u001b[39m\u001b[34m(self, inputs)\u001b[39m\n\u001b[32m 432\u001b[39m mlp_in_cache = torch.cat(\u001b[38;5;28mlist\u001b[39m(mlp_in_cache.values()), dim=\u001b[32m0\u001b[39m)\n\u001b[32m 433\u001b[39m mlp_out_cache = torch.cat(\u001b[38;5;28mlist\u001b[39m(mlp_out_cache.values()), dim=\u001b[32m0\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m435\u001b[39m attribution_data = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mtranscoders\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcompute_attribution_components\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmlp_in_cache\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 437\u001b[39m \u001b[38;5;66;03m# Compute error vectors\u001b[39;00m\n\u001b[32m 438\u001b[39m error_vectors = mlp_out_cache - attribution_data[\u001b[33m\"\u001b[39m\u001b[33mreconstruction\u001b[39m\u001b[33m\"\u001b[39m]\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/transcoder/cross_layer_transcoder.py:321\u001b[39m, in \u001b[36mCrossLayerTranscoder.compute_attribution_components\u001b[39m\u001b[34m(self, inputs)\u001b[39m\n\u001b[32m 318\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mEncoder vectors shape: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mencoder_vectors.shape\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m)\n\u001b[32m 319\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mnnz: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfeatures._nnz()\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m)\n\u001b[32m 320\u001b[39m pos_ids, layer_ids, feat_ids, decoder_vectors, encoder_to_decoder_map = (\n\u001b[32m--> \u001b[39m\u001b[32m321\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mselect_decoder_vectors\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfeatures\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 322\u001b[39m )\n\u001b[32m 323\u001b[39m \u001b[38;5;28mprint\u001b[39m(features.shape)\n\u001b[32m 324\u001b[39m reconstruction = \u001b[38;5;28mself\u001b[39m.compute_reconstruction(pos_ids, layer_ids, decoder_vectors)\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/transcoder/cross_layer_transcoder.py:278\u001b[39m, in \u001b[36mCrossLayerTranscoder.select_decoder_vectors\u001b[39m\u001b[34m(self, features)\u001b[39m\n\u001b[32m 276\u001b[39m layer_ids = torch.cat(layer_ids, dim=\u001b[32m0\u001b[39m)\n\u001b[32m 277\u001b[39m feat_ids = torch.cat(feat_ids, dim=\u001b[32m0\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m278\u001b[39m decoder_vectors = \u001b[43mtorch\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcat\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdecoder_vectors\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdim\u001b[49m\u001b[43m=\u001b[49m\u001b[32;43m0\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 279\u001b[39m encoder_mapping = torch.cat(encoder_mapping, dim=\u001b[32m0\u001b[39m)\n\u001b[32m 281\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m pos_ids, layer_ids, feat_ids, decoder_vectors, encoder_mapping\n", - "\u001b[31mOutOfMemoryError\u001b[39m: CUDA out of memory. Tried to allocate 15.62 GiB. GPU 0 has a total capacity of 44.34 GiB of which 10.35 GiB is free. Process 2086456 has 8.54 GiB memory in use. Process 2458041 has 25.44 GiB memory in use. Of the allocated memory 23.23 GiB is allocated by PyTorch, and 1.91 GiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation. See documentation for Memory Management (https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)" + "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/transcoder/cross_layer_transcoder.py:323\u001b[39m, in \u001b[36mCrossLayerTranscoder.compute_attribution_components\u001b[39m\u001b[34m(self, inputs)\u001b[39m\n\u001b[32m 320\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mEncoder vectors shape: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mencoder_vectors.shape\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m)\n\u001b[32m 321\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mnnz: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfeatures._nnz()\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m)\n\u001b[32m 322\u001b[39m pos_ids, layer_ids, feat_ids, decoder_vectors, encoder_to_decoder_map = (\n\u001b[32m--> \u001b[39m\u001b[32m323\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mselect_decoder_vectors\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfeatures\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 324\u001b[39m )\n\u001b[32m 325\u001b[39m \u001b[38;5;28mprint\u001b[39m(features.shape)\n\u001b[32m 326\u001b[39m reconstruction = \u001b[38;5;28mself\u001b[39m.compute_reconstruction(pos_ids, layer_ids, decoder_vectors)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/transcoder/cross_layer_transcoder.py:280\u001b[39m, in \u001b[36mCrossLayerTranscoder.select_decoder_vectors\u001b[39m\u001b[34m(self, features)\u001b[39m\n\u001b[32m 278\u001b[39m layer_ids = torch.cat(layer_ids, dim=\u001b[32m0\u001b[39m)\n\u001b[32m 279\u001b[39m feat_ids = torch.cat(feat_ids, dim=\u001b[32m0\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m280\u001b[39m decoder_vectors = \u001b[43mtorch\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcat\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdecoder_vectors\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdim\u001b[49m\u001b[43m=\u001b[49m\u001b[32;43m0\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 281\u001b[39m encoder_mapping = torch.cat(encoder_mapping, dim=\u001b[32m0\u001b[39m)\n\u001b[32m 283\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m pos_ids, layer_ids, feat_ids, decoder_vectors, encoder_mapping\n", + "\u001b[31mOutOfMemoryError\u001b[39m: CUDA out of memory. Tried to allocate 15.62 GiB. GPU 0 has a total capacity of 44.34 GiB of which 10.35 GiB is free. Process 2491674 has 8.54 GiB memory in use. Process 2496736 has 25.44 GiB memory in use. Of the allocated memory 23.23 GiB is allocated by PyTorch, and 1.91 GiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation. See documentation for Memory Management (https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)" ] } ], diff --git a/crosslayer_transcoder/utils/sanity_check_model.ipynb b/crosslayer_transcoder/utils/sanity_check_model.ipynb index 3ed5f1e..a7bb873 100644 --- a/crosslayer_transcoder/utils/sanity_check_model.ipynb +++ b/crosslayer_transcoder/utils/sanity_check_model.ipynb @@ -49,7 +49,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "6d361419e352494f9c94caa4397c8508", + "model_id": "8e426a3f1ac340a1bf4985acf25807e6", "version_major": 2, "version_minor": 0 }, @@ -65,10 +65,10 @@ "output_type": "stream", "text": [ "Token indices sequence length is longer than the specified maximum sequence length for this model (1217 > 1024). Running this sequence through the model will result in indexing errors\n", + "Token indices sequence length is longer than the specified maximum sequence length for this model (1174 > 1024). Running this sequence through the model will result in indexing errors\n", "Token indices sequence length is longer than the specified maximum sequence length for this model (1561 > 1024). Running this sequence through the model will result in indexing errors\n", "Token indices sequence length is longer than the specified maximum sequence length for this model (2027 > 1024). Running this sequence through the model will result in indexing errors\n", - "Token indices sequence length is longer than the specified maximum sequence length for this model (2459 > 1024). Running this sequence through the model will result in indexing errors\n", - "Token indices sequence length is longer than the specified maximum sequence length for this model (1174 > 1024). Running this sequence through the model will result in indexing errors\n" + "Token indices sequence length is longer than the specified maximum sequence length for this model (2459 > 1024). Running this sequence through the model will result in indexing errors\n" ] }, { @@ -146,7 +146,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 3, "id": "cda0fb9b", "metadata": {}, "outputs": [ @@ -154,7 +154,6 @@ "name": "stdout", "output_type": "stream", "text": [ - "torch.Size([12, 7, 768])\n", "torch.Size([12, 7, 768])\n" ] } @@ -162,20 +161,15 @@ "source": [ "import torch\n", "mlp_in_activations = []\n", - "mlp_out_activations = []\n", "\n", "with llm.trace(prompt) as trace:\n", " for layer in range(12):\n", " layer_activations = llm.transformer.h[layer].ln_2.input.save()\n", - " layer_activations = llm.transformer.h[layer].mlp.output.save()\n", " mlp_in_activations.append(layer_activations.squeeze(0))\n", - " mlp_out_activations.append(layer_activations.squeeze(0))\n", "\n", "mlp_in_activations = torch.stack(mlp_in_activations, dim=0)\n", - "mlp_out_activations = torch.stack(mlp_out_activations, dim=0)\n", "\n", - "print(mlp_in_activations.shape)\n", - "print(mlp_out_activations.shape)" + "print(mlp_in_activations.shape)" ] }, { @@ -188,7 +182,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "26589596", "metadata": {}, "outputs": [ @@ -197,12 +191,9 @@ "output_type": "stream", "text": [ "torch.Size([7, 12, 768])\n", - "torch.Size([7, 12, 768])\n", - "torch.Size([7, 2, 12, 768])\n", "torch.Size([7, 12, 10000])\n", - "torch.Size([7, 12, 10000])\n", - "4162\n", - "49.5476188659668\n" + "sparse_features._nnz(): 17896\n", + "l0_avg_per_layer: 213.04762268066406\n" ] } ], @@ -210,35 +201,67 @@ "import einops\n", "\n", "in_acts = einops.rearrange(mlp_in_activations, \"l b d -> b l d\")\n", - "out_acts = einops.rearrange(mlp_out_activations, \"l b d -> b l d\")\n", "print(in_acts.shape)\n", - "print(out_acts.shape)\n", - "batch_acts = torch.stack([in_acts, out_acts], dim=1)\n", - "print(batch_acts.shape)\n", - "clt_module.model.initialize_standardizers(batch_acts)\n", - "_, features, _, _ = clt_module.model(in_acts)\n", + "# specifically don't init standarizers bc we've folded acts\n", + "features = clt_module.model.encode_folded(in_acts)\n", "\n", "print(features.shape)\n", "\n", "sparse_features = features.to_sparse()\n", - "print(sparse_features._nnz())\n", + "print(f\"sparse_features._nnz(): {sparse_features._nnz()}\")\n", + "\n", + "# double check these methods are the functional equivalent \n", + "assert sparse_features._nnz() == features.count_nonzero()\n", "\n", "l0_avg_per_layer = torch.count_nonzero(features > 0) / (features.shape[0] * features.shape[1])\n", - "print(l0_avg_per_layer.item())\n" + "print(f\"l0_avg_per_layer: {l0_avg_per_layer.item()}\")\n" ] }, { "cell_type": "code", - "execution_count": null, - "id": "ee75a5df", + "execution_count": 5, + "id": "753de1ca", "metadata": {}, - "outputs": [], - "source": [] + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([7, 12, 768])\n", + "torch.Size([7, 12, 10000])\n", + "sparse_features._nnz(): 17843\n", + "l0_avg_per_layer: 212.4166717529297\n" + ] + } + ], + "source": [ + "import einops\n", + "\n", + "in_acts = einops.rearrange(mlp_in_activations, \"l b d -> b l d\")\n", + "print(in_acts.shape)\n", + "in_acts = in_acts.to(torch.bfloat16)\n", + "clt_module.model.to(torch.bfloat16)\n", + "# specifically don't init standarizers bc we've folded acts\n", + "features = clt_module.model.encode_folded(in_acts)\n", + "\n", + "print(features.shape)\n", + "\n", + "sparse_features = features.to_sparse()\n", + "print(f\"sparse_features._nnz(): {sparse_features._nnz()}\")\n", + "\n", + "# double check these methods are the functional equivalent\n", + "assert sparse_features._nnz() == features.count_nonzero()\n", + "\n", + "l0_avg_per_layer = torch.count_nonzero(features > 0) / (\n", + " features.shape[0] * features.shape[1]\n", + ")\n", + "print(f\"l0_avg_per_layer: {l0_avg_per_layer.item()}\")\n" + ] }, { "cell_type": "code", "execution_count": null, - "id": "2bdaa188", + "id": "a2f90530", "metadata": {}, "outputs": [], "source": [] From e51ba777e491e5bd21e47498d8f9d09a7a6c1b11 Mon Sep 17 00:00:00 2001 From: jiito Date: Sun, 16 Nov 2025 16:36:29 +0000 Subject: [PATCH 67/99] add encode and encode folded --- crosslayer_transcoder/model/clt.py | 79 ++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 14 deletions(-) diff --git a/crosslayer_transcoder/model/clt.py b/crosslayer_transcoder/model/clt.py index cc58891..0790714 100644 --- a/crosslayer_transcoder/model/clt.py +++ b/crosslayer_transcoder/model/clt.py @@ -1,6 +1,7 @@ from typing import Tuple, Union import torch +from torch.func import functional_call import torch.nn as nn from einops import einsum from jaxtyping import Float @@ -51,7 +52,11 @@ def reset_parameters(self): dec_uniform_thresh = 1 / ((self.d_acts * self.n_layers) ** 0.5) self.W_dec.data.uniform_(-dec_uniform_thresh, dec_uniform_thresh) - mask = self.mask.unsqueeze(-1).unsqueeze(-1).repeat(1, 1, self.d_features, self.d_acts) + mask = ( + self.mask.unsqueeze(-1) + .unsqueeze(-1) + .repeat(1, 1, self.d_features, self.d_acts) + ) self.W_dec.data = torch.where(mask.bool(), self.W_dec.data, 0.0) if self.tied_init: @@ -63,7 +68,9 @@ def reset_parameters(self): # norm = self.W_dec.norm(p=2, dim=-1) # self.W_dec.data = self.W_dec.data / norm.unsqueeze(-1) - def initialize_standardizers(self, batch: Float[torch.Tensor, "batch_size io n_layers d_acts"]): + def initialize_standardizers( + self, batch: Float[torch.Tensor, "batch_size io n_layers d_acts"] + ): self.input_standardizer.initialize_from_batch(batch) self.output_standardizer.initialize_from_batch(batch) @@ -78,7 +85,9 @@ def decode( "from_layer to_layer -> batch_size to_layer d_acts", ) - def forward(self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"]) -> Tuple[ + def forward( + self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"] + ) -> Tuple[ Float[torch.Tensor, "batch_size n_layers d_features"], Float[torch.Tensor, "batch_size n_layers d_features"], Float[torch.Tensor, "batch_size n_layers d_acts"], @@ -132,7 +141,9 @@ def forward_layer( return pre_actvs def forward( - self, acts_norm: Float[torch.Tensor, "batch_size n_layers d_acts"], layer: str = "all" + self, + acts_norm: Float[torch.Tensor, "batch_size n_layers d_acts"], + layer: str = "all", ) -> Float[torch.Tensor, "batch_size n_layers d_features"]: # for inference if layer != "all": @@ -158,7 +169,9 @@ def __init__(self, d_acts: int, d_features: int, n_layers: int): self.d_acts = d_acts self.d_features = d_features self.n_layers = n_layers - self.register_parameter(f"W", nn.Parameter(torch.empty((n_layers, d_features, d_acts)))) + self.register_parameter( + f"W", nn.Parameter(torch.empty((n_layers, d_features, d_acts))) + ) self.reset_parameters() def reset_parameters(self): @@ -167,7 +180,9 @@ def reset_parameters(self): @torch.no_grad() def forward_layer( - self, features: Float[torch.Tensor, "batch_size seq from_layer d_features"], layer: int + self, + features: Float[torch.Tensor, "batch_size seq from_layer d_features"], + layer: int, ) -> Float[torch.Tensor, "batch_size seq d_acts"]: if features.ndim == 4: # (batch, seq, layer, d_features) features = features[:, :, layer, :] @@ -178,7 +193,9 @@ def forward_layer( ) def forward( - self, features: Float[torch.Tensor, "batch_size n_layers d_features"], layer: str = "all" + self, + features: Float[torch.Tensor, "batch_size n_layers d_features"], + layer: str = "all", ) -> Float[torch.Tensor, "batch_size n_layers d_acts"]: if layer != "all": return self.forward_layer(features, layer) @@ -198,14 +215,18 @@ def __init__(self, d_acts: int, d_features: int, n_layers: int): self.d_features = d_features self.n_layers = n_layers for i in range(n_layers): - self.register_parameter(f"W_{i}", nn.Parameter(torch.empty((i + 1, d_features, d_acts)))) + self.register_parameter( + f"W_{i}", nn.Parameter(torch.empty((i + 1, d_features, d_acts))) + ) self.register_parameter(f"b", nn.Parameter(torch.empty((n_layers, d_acts)))) self.reset_parameters() def reset_parameters(self): dec_uniform_thresh = 1 / ((self.d_acts * self.n_layers) ** 0.5) for i in range(self.n_layers): - self.get_parameter(f"W_{i}").data.uniform_(-dec_uniform_thresh, dec_uniform_thresh) + self.get_parameter(f"W_{i}").data.uniform_( + -dec_uniform_thresh, dec_uniform_thresh + ) # for l in range(i): # self.get_parameter(f"W_{i}").data[l, :, :] = self.get_parameter(f"W_{l}").data[l, :, :] * 0.0 @@ -213,7 +234,9 @@ def reset_parameters(self): @torch.no_grad() def forward_layer( - self, features: Float[torch.Tensor, "batch_size seq from_layer d_features"], layer: int + self, + features: Float[torch.Tensor, "batch_size seq from_layer d_features"], + layer: int, ) -> Float[torch.Tensor, "batch_size seq d_acts"]: return ( einsum( @@ -225,13 +248,19 @@ def forward_layer( ) def forward( - self, features: Float[torch.Tensor, "batch_size n_layers d_features"], layer: str = "all" + self, + features: Float[torch.Tensor, "batch_size n_layers d_features"], + layer: str = "all", ) -> Float[torch.Tensor, "batch_size n_layers d_acts"]: if layer != "all": return self.forward_layer(features, layer) recons = torch.empty( - features.shape[0], self.n_layers, self.d_acts, device=features.device, dtype=features.dtype + features.shape[0], + self.n_layers, + self.d_acts, + device=features.device, + dtype=features.dtype, ) for l in range(self.n_layers): W = self.get_parameter(f"W_{l}") @@ -269,11 +298,33 @@ def reset_parameters(self): self.encoder.reset_parameters() self.decoder.reset_parameters() - def initialize_standardizers(self, batch: Float[torch.Tensor, "batch_size io n_layers d_acts"]): + def initialize_standardizers( + self, batch: Float[torch.Tensor, "batch_size io n_layers d_acts"] + ): self.input_standardizer.initialize_from_batch(batch) self.output_standardizer.initialize_from_batch(batch) - def forward(self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"]) -> Tuple[ + def encode(self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"]): + pre_actvs = self.encoder(acts) + features = self.nonlinearity(pre_actvs) + return features + + def encode_folded(self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"]): + W_enc_folded, b_enc_folded = self.input_standardizer.fold_in_encoder( + self.encoder.W, self.encoder.b + ) + folded_params = { + "W": torch.nn.Parameter(W_enc_folded.clone().detach()), + "b": torch.nn.Parameter(b_enc_folded.clone().detach()), + } + pre_actvs = functional_call(self.encoder, folded_params, acts, {"layer": "all"}) + + features = self.nonlinearity(pre_actvs) + return features + + def forward( + self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"] + ) -> Tuple[ Float[torch.Tensor, "batch_size n_layers d_features"], # pre_actvs Float[torch.Tensor, "batch_size n_layers d_features"], # features Float[torch.Tensor, "batch_size n_layers d_acts"], # recons_norm From 5d99ebf9b6dd8000aaa49af35a1e809be7cd6a64 Mon Sep 17 00:00:00 2001 From: jiito Date: Sun, 16 Nov 2025 16:36:45 +0000 Subject: [PATCH 68/99] add dtype --- .../utils/model_converters/circuit_tracer.py | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py index 524b46d..31b8cf4 100644 --- a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py +++ b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py @@ -1,6 +1,6 @@ from pathlib import Path -from circuit_tracer.transcoder.cross_layer_transcoder import JumpReLU +import einops import torch import yaml from safetensors.torch import save_file @@ -8,14 +8,15 @@ from crosslayer_transcoder.utils.model_converters.model_converter import ( ModelConverter, ) +from crosslayer_transcoder.model.jumprelu import JumpReLU class CircuitTracerConverter(ModelConverter): def __init__( self, save_dir: str, - feature_input_hook: str = "blocks.{layer}.hook_resid_pre", - feature_output_hook: str = "blocks.{layer}.hook_mlp_out", + feature_input_hook: str = "hook_resid_mid", + feature_output_hook: str = "hook_mlp_out", ): self.save_dir = Path(save_dir) self.feature_input_hook = feature_input_hook @@ -23,7 +24,7 @@ def __init__( self.save_dir.mkdir(parents=True, exist_ok=True) - def convert_and_save(self, model): + def convert_and_save(self, model, dtype=torch.bfloat16): encoder = model.model.encoder input_standardizer = model.model.input_standardizer output_standardizer = model.model.output_standardizer @@ -33,25 +34,30 @@ def convert_and_save(self, model): d_acts = encoder.d_acts # -> circuit-tracer.d_model d_features = encoder.d_features # -> circuit-tracer.d_transcoder + # TODO: maybe pass in dtype W_enc_folded, b_enc_folded = input_standardizer.fold_in_encoder( - encoder.W.float(), encoder.b.float() + encoder.W.to(dtype), encoder.b.to(dtype) ) - b_dec_folded = output_standardizer.fold_in_decoder_bias(decoder.b.float()) + b_dec_folded = output_standardizer.fold_in_decoder_bias(decoder.b.to(dtype)) # encoder for source_layer in range(encoder.n_layers): + rearranged_W_enc = einops.rearrange( + W_enc_folded[source_layer], + "d_acts d_features -> d_features d_acts", + ).contiguous() layer_encoder_dict = { - f"W_enc_{source_layer}": W_enc_folded[source_layer] - .T.contiguous() - .cpu(), # Transpose! - f"b_enc_{source_layer}": (b_enc_folded[source_layer].cpu()), - f"b_dec_{source_layer}": (b_dec_folded[source_layer].cpu()), + f"W_enc_{source_layer}": rearranged_W_enc.cpu().to(dtype), + f"b_enc_{source_layer}": (b_enc_folded[source_layer].cpu().to(dtype)), + f"b_dec_{source_layer}": (b_dec_folded[source_layer].cpu().to(dtype)), } # TODO: double check non-linearity compatibility + print(nonlinearity) if isinstance(nonlinearity, JumpReLU): + print(nonlinearity.theta.shape) layer_encoder_dict[f"threshold_{source_layer}"] = ( - nonlinearity.theta[:, source_layer, :].cpu() + nonlinearity.theta[:, source_layer, :].cpu().to(dtype) ) save_file( layer_encoder_dict, f"{self.save_dir}/W_enc_{source_layer}.safetensors" @@ -65,18 +71,21 @@ def convert_and_save(self, model): # fold in output standardization for decoder weights using standardizer method decoder_w_k_folded = output_standardizer.fold_in_decoder_weights_layer( - decoder_w_k.float(), k + decoder_w_k.to(dtype), k ) dec_i_k = decoder_w_k_folded[source_layer, ...] assert dec_i_k.shape == ( d_features, d_acts, ) - output_dec_i[:, k - source_layer, ...] = dec_i_k.cpu() + output_dec_i[:, k - source_layer, ...] = dec_i_k.cpu().to(dtype) decoder_dict = {f"W_dec_{source_layer}": output_dec_i} - save_file(decoder_dict, f"{self.save_dir}/W_dec_{source_layer}.safetensors") + save_file( + decoder_dict, + f"{self.save_dir}/W_dec_{source_layer}.safetensors", + ) config = { "model_kind": "cross_layer_transcoder", From 26889e09048bafc35f851702d5c21473f94aff0a Mon Sep 17 00:00:00 2001 From: jiito Date: Sun, 16 Nov 2025 16:58:10 +0000 Subject: [PATCH 69/99] cleanup tests --- crosslayer_transcoder/model/clt.py | 4 +- crosslayer_transcoder/utils/module_builder.py | 3 +- .../utils/replacement_score.ipynb | 6 +- .../utils/sanity_check_model.ipynb | 180 +++++++++--------- 4 files changed, 101 insertions(+), 92 deletions(-) diff --git a/crosslayer_transcoder/model/clt.py b/crosslayer_transcoder/model/clt.py index 0790714..655b214 100644 --- a/crosslayer_transcoder/model/clt.py +++ b/crosslayer_transcoder/model/clt.py @@ -309,7 +309,9 @@ def encode(self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"]): features = self.nonlinearity(pre_actvs) return features - def encode_folded(self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"]): + def encode_with_standardizer_folding( + self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"] + ): W_enc_folded, b_enc_folded = self.input_standardizer.fold_in_encoder( self.encoder.W, self.encoder.b ) diff --git a/crosslayer_transcoder/utils/module_builder.py b/crosslayer_transcoder/utils/module_builder.py index 6ffd750..7d1494c 100644 --- a/crosslayer_transcoder/utils/module_builder.py +++ b/crosslayer_transcoder/utils/module_builder.py @@ -2,6 +2,7 @@ import yaml import torch.nn as nn + def build_module_from_config(config: dict) -> nn.Module: return init_from_config(config["model"]) @@ -14,12 +15,12 @@ def init_from_config(config: dict) -> nn.Module: init_class = getattr(init_class, class_name) init_args = config["init_args"] for key, value in init_args.items(): - print(key, value) if isinstance(value, dict): init_args[key] = init_from_config(value) init_class = init_class(**init_args) return init_class + def yaml_to_config(yaml_path: str) -> dict: with open(yaml_path, "r") as f: config = yaml.load(f, Loader=yaml.FullLoader) diff --git a/crosslayer_transcoder/utils/replacement_score.ipynb b/crosslayer_transcoder/utils/replacement_score.ipynb index 8ce5380..98bb328 100644 --- a/crosslayer_transcoder/utils/replacement_score.ipynb +++ b/crosslayer_transcoder/utils/replacement_score.ipynb @@ -209,7 +209,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "a5ec0f5a", "metadata": {}, "outputs": [ @@ -228,13 +228,9 @@ "import os\n", "# sanity check against original model \n", "\n", - "print(transcoder.clt_path)\n", "clt_path = save_dir.as_posix()\n", "assert transcoder.clt_path == clt_path\n", "\n", - "# for i in range(clt_module.model.encoder.n_layers):\n", - "# # THESE SHOULD NOT be close\n", - "# assert not torch.allclose(clt_module.model.encoder.W[i].T.to('cuda:0'), transcoder.W_enc[i].to('cuda:0')) # should fail bc of folding \n", "\n", "# TEST: state_dict_pre_load weights match the files before being loaded into the model\n", "for i in range(transcoder.n_layers):\n", diff --git a/crosslayer_transcoder/utils/sanity_check_model.ipynb b/crosslayer_transcoder/utils/sanity_check_model.ipynb index a7bb873..6db8e97 100644 --- a/crosslayer_transcoder/utils/sanity_check_model.ipynb +++ b/crosslayer_transcoder/utils/sanity_check_model.ipynb @@ -16,40 +16,10 @@ "id": "de7531d0", "metadata": {}, "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "model {'class_path': 'crosslayer_transcoder.model.clt.CrossLayerTranscoder', 'init_args': {'encoder': {'class_path': 'crosslayer_transcoder.model.clt.Encoder', 'init_args': {'d_acts': 768, 'd_features': 10000, 'n_layers': 12}}, 'decoder': {'class_path': 'crosslayer_transcoder.model.clt.CrosslayerDecoder', 'init_args': {'d_acts': 768, 'd_features': 10000, 'n_layers': 12}}, 'nonlinearity': {'class_path': 'crosslayer_transcoder.model.jumprelu.JumpReLU', 'init_args': {'theta': 0.03, 'bandwidth': 0.01, 'n_layers': 12, 'd_features': 10000}}, 'input_standardizer': {'class_path': 'crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer', 'init_args': {'n_layers': 12, 'activation_dim': 768}}, 'output_standardizer': {'class_path': 'crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer', 'init_args': {'n_layers': 12, 'activation_dim': 768}}}}\n", - "encoder {'class_path': 'crosslayer_transcoder.model.clt.Encoder', 'init_args': {'d_acts': 768, 'd_features': 10000, 'n_layers': 12}}\n", - "d_acts 768\n", - "d_features 10000\n", - "n_layers 12\n", - "decoder {'class_path': 'crosslayer_transcoder.model.clt.CrosslayerDecoder', 'init_args': {'d_acts': 768, 'd_features': 10000, 'n_layers': 12}}\n", - "d_acts 768\n", - "d_features 10000\n", - "n_layers 12\n", - "nonlinearity {'class_path': 'crosslayer_transcoder.model.jumprelu.JumpReLU', 'init_args': {'theta': 0.03, 'bandwidth': 0.01, 'n_layers': 12, 'd_features': 10000}}\n", - "theta 0.03\n", - "bandwidth 0.01\n", - "n_layers 12\n", - "d_features 10000\n", - "input_standardizer {'class_path': 'crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer', 'init_args': {'n_layers': 12, 'activation_dim': 768}}\n", - "n_layers 12\n", - "activation_dim 768\n", - "output_standardizer {'class_path': 'crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer', 'init_args': {'n_layers': 12, 'activation_dim': 768}}\n", - "n_layers 12\n", - "activation_dim 768\n", - "replacement_model {'class_path': 'crosslayer_transcoder.metrics.replacement_model_accuracy.ReplacementModelAccuracy', 'init_args': {'model_name': 'openai-community/gpt2', 'device_map': 'cuda:0', 'loader_batch_size': 2}}\n", - "model_name openai-community/gpt2\n", - "device_map cuda:0\n", - "loader_batch_size 2\n" - ] - }, { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "8e426a3f1ac340a1bf4985acf25807e6", + "model_id": "30928294793d45d7b42fe9bb296d4278", "version_major": 2, "version_minor": 0 }, @@ -65,32 +35,16 @@ "output_type": "stream", "text": [ "Token indices sequence length is longer than the specified maximum sequence length for this model (1217 > 1024). Running this sequence through the model will result in indexing errors\n", - "Token indices sequence length is longer than the specified maximum sequence length for this model (1174 > 1024). Running this sequence through the model will result in indexing errors\n", "Token indices sequence length is longer than the specified maximum sequence length for this model (1561 > 1024). Running this sequence through the model will result in indexing errors\n", - "Token indices sequence length is longer than the specified maximum sequence length for this model (2027 > 1024). Running this sequence through the model will result in indexing errors\n", - "Token indices sequence length is longer than the specified maximum sequence length for this model (2459 > 1024). Running this sequence through the model will result in indexing errors\n" + "Token indices sequence length is longer than the specified maximum sequence length for this model (1174 > 1024). Running this sequence through the model will result in indexing errors\n", + "Token indices sequence length is longer than the specified maximum sequence length for this model (2459 > 1024). Running this sequence through the model will result in indexing errors\n", + "Token indices sequence length is longer than the specified maximum sequence length for this model (2027 > 1024). Running this sequence through the model will result in indexing errors\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "dead_features {'class_path': 'crosslayer_transcoder.metrics.dead_features.DeadFeatures', 'init_args': {'n_features': 10000, 'n_layers': 12, 'return_per_layer': True, 'return_log_freqs': True, 'return_neuron_indices': True}}\n", - "n_features 10000\n", - "n_layers 12\n", - "return_per_layer True\n", - "return_log_freqs True\n", - "return_neuron_indices True\n", - "learning_rate 3e-4\n", - "compile True\n", - "lr_decay_step 16000\n", - "lr_decay_factor 0.1\n", - "lambda_sparsity 0.0007\n", - "c_sparsity 1\n", - "use_tanh True\n", - "pre_actv_loss 1e-6\n", - "compute_dead_features True\n", - "compute_dead_features_every 500\n", "JumpReLUCrossLayerTranscoderModule(\n", " (model): CrossLayerTranscoder(\n", " (encoder): Encoder()\n", @@ -111,17 +65,25 @@ "from crosslayer_transcoder.utils.module_builder import build_module_from_config, yaml_to_config\n", "from crosslayer_transcoder.utils.checkpoints import load_model_from_lightning_checkpoint\n", "\n", - "config = yaml_to_config(\"../../config/circuit-tracer.yaml\")\n", - "clt_module = build_module_from_config(config)\n", + "config_path = \"../../config/circuit-tracer.yaml\"\n", + "checkpoint_path = \"../checkpoints/clt.ckpt\"\n", "\n", - "# load checkpoint\n", - "checkpoint = \"../checkpoints/clt.ckpt\"\n", + "config = yaml_to_config(config_path)\n", + "clt_module = build_module_from_config(config)\n", "\n", - "clt_module = load_model_from_lightning_checkpoint(clt_module, checkpoint)\n", + "clt_module = load_model_from_lightning_checkpoint(clt_module, checkpoint_path)\n", "\n", "print(clt_module)" ] }, + { + "cell_type": "markdown", + "id": "d5030984", + "metadata": {}, + "source": [ + "## Collect Activations" + ] + }, { "cell_type": "code", "execution_count": 2, @@ -136,14 +98,6 @@ "llm = LanguageModel(\"openai-community/gpt2\")" ] }, - { - "cell_type": "markdown", - "id": "d5030984", - "metadata": {}, - "source": [ - "## Collect Activations" - ] - }, { "cell_type": "code", "execution_count": 3, @@ -172,17 +126,82 @@ "print(mlp_in_activations.shape)" ] }, + { + "cell_type": "code", + "execution_count": 4, + "id": "57664d1c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([7, 12, 768])\n" + ] + } + ], + "source": [ + "import einops\n", + "\n", + "in_acts = einops.rearrange(mlp_in_activations, \"l b d -> b l d\")\n", + "print(in_acts.shape)" + ] + }, + { + "cell_type": "markdown", + "id": "2d3dd5db", + "metadata": {}, + "source": [ + "## Encode w/o standarizer folding" + ] + }, + { + "cell_type": "markdown", + "id": "f8458d4d", + "metadata": {}, + "source": [] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "2e5b2b2e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([7, 12, 10000])\n", + "sparse_features._nnz(): 70298\n", + "l0_avg_per_layer: 836.8809814453125\n" + ] + } + ], + "source": [ + "features = clt_module.model.encode(in_acts)\n", + "\n", + "print(features.shape)\n", + "\n", + "sparse_features = features.to_sparse()\n", + "print(f\"sparse_features._nnz(): {sparse_features._nnz()}\")\n", + "\n", + "l0_avg_per_layer = torch.count_nonzero(features > 0) / (\n", + " features.shape[0] * features.shape[1]\n", + ")\n", + "print(f\"l0_avg_per_layer: {l0_avg_per_layer.item()}\")\n" + ] + }, { "cell_type": "markdown", "id": "7d847db4", "metadata": {}, "source": [ - "## Run Encoder w activations" + "## Encode w/ folding" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 6, "id": "26589596", "metadata": {}, "outputs": [ @@ -190,7 +209,6 @@ "name": "stdout", "output_type": "stream", "text": [ - "torch.Size([7, 12, 768])\n", "torch.Size([7, 12, 10000])\n", "sparse_features._nnz(): 17896\n", "l0_avg_per_layer: 213.04762268066406\n" @@ -198,28 +216,29 @@ } ], "source": [ - "import einops\n", "\n", - "in_acts = einops.rearrange(mlp_in_activations, \"l b d -> b l d\")\n", - "print(in_acts.shape)\n", - "# specifically don't init standarizers bc we've folded acts\n", - "features = clt_module.model.encode_folded(in_acts)\n", + "features = clt_module.model.encode_with_standardizer_folding(in_acts)\n", "\n", "print(features.shape)\n", "\n", "sparse_features = features.to_sparse()\n", "print(f\"sparse_features._nnz(): {sparse_features._nnz()}\")\n", "\n", - "# double check these methods are the functional equivalent \n", - "assert sparse_features._nnz() == features.count_nonzero()\n", - "\n", "l0_avg_per_layer = torch.count_nonzero(features > 0) / (features.shape[0] * features.shape[1])\n", "print(f\"l0_avg_per_layer: {l0_avg_per_layer.item()}\")\n" ] }, + { + "cell_type": "markdown", + "id": "130f0259", + "metadata": {}, + "source": [ + "## Run encoding in bfloat16" + ] + }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "id": "753de1ca", "metadata": {}, "outputs": [ @@ -227,7 +246,6 @@ "name": "stdout", "output_type": "stream", "text": [ - "torch.Size([7, 12, 768])\n", "torch.Size([7, 12, 10000])\n", "sparse_features._nnz(): 17843\n", "l0_avg_per_layer: 212.4166717529297\n" @@ -235,23 +253,15 @@ } ], "source": [ - "import einops\n", - "\n", - "in_acts = einops.rearrange(mlp_in_activations, \"l b d -> b l d\")\n", - "print(in_acts.shape)\n", "in_acts = in_acts.to(torch.bfloat16)\n", "clt_module.model.to(torch.bfloat16)\n", - "# specifically don't init standarizers bc we've folded acts\n", - "features = clt_module.model.encode_folded(in_acts)\n", + "features = clt_module.model.encode_with_standardizer_folding(in_acts)\n", "\n", "print(features.shape)\n", "\n", "sparse_features = features.to_sparse()\n", "print(f\"sparse_features._nnz(): {sparse_features._nnz()}\")\n", "\n", - "# double check these methods are the functional equivalent\n", - "assert sparse_features._nnz() == features.count_nonzero()\n", - "\n", "l0_avg_per_layer = torch.count_nonzero(features > 0) / (\n", " features.shape[0] * features.shape[1]\n", ")\n", From b5c2331c19b8df687c782b57354295434b28ed76 Mon Sep 17 00:00:00 2001 From: jiito Date: Sun, 16 Nov 2025 17:13:03 +0000 Subject: [PATCH 70/99] add progress bar --- .../utils/model_converters/circuit_tracer.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py index 31b8cf4..717e8cd 100644 --- a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py +++ b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py @@ -1,6 +1,7 @@ from pathlib import Path import einops +from tqdm import tqdm import torch import yaml from safetensors.torch import save_file @@ -42,7 +43,7 @@ def convert_and_save(self, model, dtype=torch.bfloat16): b_dec_folded = output_standardizer.fold_in_decoder_bias(decoder.b.to(dtype)) # encoder - for source_layer in range(encoder.n_layers): + for source_layer in tqdm(range(encoder.n_layers), desc="Converting CLT "): rearranged_W_enc = einops.rearrange( W_enc_folded[source_layer], "d_acts d_features -> d_features d_acts", @@ -53,9 +54,7 @@ def convert_and_save(self, model, dtype=torch.bfloat16): f"b_dec_{source_layer}": (b_dec_folded[source_layer].cpu().to(dtype)), } # TODO: double check non-linearity compatibility - print(nonlinearity) if isinstance(nonlinearity, JumpReLU): - print(nonlinearity.theta.shape) layer_encoder_dict[f"threshold_{source_layer}"] = ( nonlinearity.theta[:, source_layer, :].cpu().to(dtype) ) From 5d6ac4a0ff135d767d0e6ce15938143ad7b86ade Mon Sep 17 00:00:00 2001 From: jiito Date: Sun, 16 Nov 2025 17:13:06 +0000 Subject: [PATCH 71/99] run notebook sanity checks --- .../utils/replacement_score.ipynb | 323 +----------------- .../utils/sanity_check_model.ipynb | 241 ++++++++++++- 2 files changed, 241 insertions(+), 323 deletions(-) diff --git a/crosslayer_transcoder/utils/replacement_score.ipynb b/crosslayer_transcoder/utils/replacement_score.ipynb index 98bb328..4c843f8 100644 --- a/crosslayer_transcoder/utils/replacement_score.ipynb +++ b/crosslayer_transcoder/utils/replacement_score.ipynb @@ -38,40 +38,10 @@ "id": "c166ce94", "metadata": {}, "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "model {'class_path': 'crosslayer_transcoder.model.clt.CrossLayerTranscoder', 'init_args': {'encoder': {'class_path': 'crosslayer_transcoder.model.clt.Encoder', 'init_args': {'d_acts': 768, 'd_features': 10000, 'n_layers': 12}}, 'decoder': {'class_path': 'crosslayer_transcoder.model.clt.CrosslayerDecoder', 'init_args': {'d_acts': 768, 'd_features': 10000, 'n_layers': 12}}, 'nonlinearity': {'class_path': 'crosslayer_transcoder.model.jumprelu.JumpReLU', 'init_args': {'theta': 0.03, 'bandwidth': 0.01, 'n_layers': 12, 'd_features': 10000}}, 'input_standardizer': {'class_path': 'crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer', 'init_args': {'n_layers': 12, 'activation_dim': 768}}, 'output_standardizer': {'class_path': 'crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer', 'init_args': {'n_layers': 12, 'activation_dim': 768}}}}\n", - "encoder {'class_path': 'crosslayer_transcoder.model.clt.Encoder', 'init_args': {'d_acts': 768, 'd_features': 10000, 'n_layers': 12}}\n", - "d_acts 768\n", - "d_features 10000\n", - "n_layers 12\n", - "decoder {'class_path': 'crosslayer_transcoder.model.clt.CrosslayerDecoder', 'init_args': {'d_acts': 768, 'd_features': 10000, 'n_layers': 12}}\n", - "d_acts 768\n", - "d_features 10000\n", - "n_layers 12\n", - "nonlinearity {'class_path': 'crosslayer_transcoder.model.jumprelu.JumpReLU', 'init_args': {'theta': 0.03, 'bandwidth': 0.01, 'n_layers': 12, 'd_features': 10000}}\n", - "theta 0.03\n", - "bandwidth 0.01\n", - "n_layers 12\n", - "d_features 10000\n", - "input_standardizer {'class_path': 'crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer', 'init_args': {'n_layers': 12, 'activation_dim': 768}}\n", - "n_layers 12\n", - "activation_dim 768\n", - "output_standardizer {'class_path': 'crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer', 'init_args': {'n_layers': 12, 'activation_dim': 768}}\n", - "n_layers 12\n", - "activation_dim 768\n", - "replacement_model {'class_path': 'crosslayer_transcoder.metrics.replacement_model_accuracy.ReplacementModelAccuracy', 'init_args': {'model_name': 'openai-community/gpt2', 'device_map': 'cuda:0', 'loader_batch_size': 2}}\n", - "model_name openai-community/gpt2\n", - "device_map cuda:0\n", - "loader_batch_size 2\n" - ] - }, { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "ce9409e1c34a4ae3b2bac2bf5299dfe6", + "model_id": "03a327355ed64e53a3904d6c23fd3796", "version_major": 2, "version_minor": 0 }, @@ -87,56 +57,11 @@ "output_type": "stream", "text": [ "Token indices sequence length is longer than the specified maximum sequence length for this model (1217 > 1024). Running this sequence through the model will result in indexing errors\n", - "Token indices sequence length is longer than the specified maximum sequence length for this model (1561 > 1024). Running this sequence through the model will result in indexing errors\n", "Token indices sequence length is longer than the specified maximum sequence length for this model (1174 > 1024). Running this sequence through the model will result in indexing errors\n", + "Token indices sequence length is longer than the specified maximum sequence length for this model (1561 > 1024). Running this sequence through the model will result in indexing errors\n", + "Token indices sequence length is longer than the specified maximum sequence length for this model (2027 > 1024). Running this sequence through the model will result in indexing errors\n", "Token indices sequence length is longer than the specified maximum sequence length for this model (2459 > 1024). Running this sequence through the model will result in indexing errors\n", - "Token indices sequence length is longer than the specified maximum sequence length for this model (2027 > 1024). Running this sequence through the model will result in indexing errors\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "dead_features {'class_path': 'crosslayer_transcoder.metrics.dead_features.DeadFeatures', 'init_args': {'n_features': 10000, 'n_layers': 12, 'return_per_layer': True, 'return_log_freqs': True, 'return_neuron_indices': True}}\n", - "n_features 10000\n", - "n_layers 12\n", - "return_per_layer True\n", - "return_log_freqs True\n", - "return_neuron_indices True\n", - "learning_rate 3e-4\n", - "compile True\n", - "lr_decay_step 16000\n", - "lr_decay_factor 0.1\n", - "lambda_sparsity 0.0007\n", - "c_sparsity 1\n", - "use_tanh True\n", - "pre_actv_loss 1e-6\n", - "compute_dead_features True\n", - "compute_dead_features_every 500\n", - "JumpReLU()\n", - "torch.Size([1, 12, 10000])\n", - "JumpReLU()\n", - "torch.Size([1, 12, 10000])\n", - "JumpReLU()\n", - "torch.Size([1, 12, 10000])\n", - "JumpReLU()\n", - "torch.Size([1, 12, 10000])\n", - "JumpReLU()\n", - "torch.Size([1, 12, 10000])\n", - "JumpReLU()\n", - "torch.Size([1, 12, 10000])\n", - "JumpReLU()\n", - "torch.Size([1, 12, 10000])\n", - "JumpReLU()\n", - "torch.Size([1, 12, 10000])\n", - "JumpReLU()\n", - "torch.Size([1, 12, 10000])\n", - "JumpReLU()\n", - "torch.Size([1, 12, 10000])\n", - "JumpReLU()\n", - "torch.Size([1, 12, 10000])\n", - "JumpReLU()\n", - "torch.Size([1, 12, 10000])\n" + "Converting CLT : 100%|██████████| 12/12 [00:24<00:00, 2.01s/it]\n" ] } ], @@ -188,10 +113,7 @@ "['W_enc_9', 'b_dec_9', 'b_enc_9', 'threshold_9']\n", "['W_enc_10', 'b_dec_10', 'b_enc_10', 'threshold_10']\n", "['W_enc_11', 'b_dec_11', 'b_enc_11', 'threshold_11']\n", - "dict_keys(['b_dec', 'b_enc', 'activation_function.threshold', 'W_enc', 'W_dec.0', 'W_dec.1', 'W_dec.2', 'W_dec.3', 'W_dec.4', 'W_dec.5', 'W_dec.6', 'W_dec.7', 'W_dec.8', 'W_dec.9', 'W_dec.10', 'W_dec.11'])\n", - "JumpReLU\n", - "W_enc\n", - "torch.Size([12, 10000, 768])\n" + "dict_keys(['b_dec', 'b_enc', 'activation_function.threshold', 'W_enc', 'W_dec.0', 'W_dec.1', 'W_dec.2', 'W_dec.3', 'W_dec.4', 'W_dec.5', 'W_dec.6', 'W_dec.7', 'W_dec.8', 'W_dec.9', 'W_dec.10', 'W_dec.11'])\n" ] } ], @@ -209,160 +131,10 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "a5ec0f5a", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "clt_module_test\n" - ] - } - ], - "source": [ - "import einops\n", - "from safetensors import safe_open\n", - "import torch\n", - "import os\n", - "# sanity check against original model \n", - "\n", - "clt_path = save_dir.as_posix()\n", - "assert transcoder.clt_path == clt_path\n", - "\n", - "\n", - "# TEST: state_dict_pre_load weights match the files before being loaded into the model\n", - "for i in range(transcoder.n_layers):\n", - " enc_file = os.path.join(clt_path, f\"W_enc_{i}.safetensors\")\n", - " with safe_open(enc_file, framework=\"pt\", device=transcoder.device.type) as f:\n", - " w_file = f.get_tensor(f\"W_enc_{i}\").to(\n", - " dtype=state_dict_pre_load[\"W_enc\"][i].dtype, device=state_dict_pre_load[\"W_enc\"][i].device\n", - " )\n", - " w_state = state_dict_pre_load[\"W_enc\"][i]\n", - " assert w_file.shape == w_state.shape, f\"W_enc_{i} shape mismatch: {w_file.shape} != {w_state.shape}\"\n", - " assert w_file.dtype == w_state.dtype, f\"W_enc_{i} dtype mismatch: {w_file.dtype} != {w_state.dtype}\"\n", - " assert torch.allclose(w_file, w_state), (\n", - " i, (w_file - w_state).abs().max().item()\n", - " )\n", - "\n", - "\n", - "# TEST: weights in the files should equal weights from the transcoder\n", - "for i in range(transcoder.n_layers):\n", - " w_model = transcoder._get_encoder_weights(i) # works for both lazy and eager\n", - " enc_file = os.path.join(clt_path, f\"W_enc_{i}.safetensors\")\n", - " with safe_open(enc_file, framework=\"pt\", device=transcoder.device.type) as f:\n", - " w_file = f.get_tensor(f\"W_enc_{i}\").to(\n", - " dtype=w_model.dtype, device=w_model.device\n", - " )\n", - "\n", - " assert w_model.shape == w_file.shape\n", - " assert w_model.dtype == w_file.dtype\n", - " assert torch.allclose(w_model, w_file), (i, (w_model - w_file).abs().max().item())\n", - "\n", - "\n", - "# fold\n", - "standardizer = clt_module.model.input_standardizer\n", - "W_enc_folded, b_enc_folded = standardizer.fold_in_encoder(clt_module.model.encoder.W.to(dtype=torch.bfloat16), clt_module.model.encoder.b.to(dtype=torch.bfloat16))\n", - "\n", - "W_enc_folded = W_enc_folded.to(dtype=torch.bfloat16)\n", - "b_enc_folded = b_enc_folded.to(dtype=torch.bfloat16)\n", - "\n", - "state_dict = {}\n", - "device = clt_module.device \n", - "# TEST: eights in the file should equal the folded weights\n", - "for i in range(clt_module.model.encoder.n_layers):\n", - " enc_file = f\"W_enc_{i}.safetensors\"\n", - " with safe_open(os.path.join(clt_path, enc_file), framework=\"pt\", device=device.type) as f:\n", - " assert W_enc_folded[i].T.shape == f.get_tensor(f\"W_enc_{i}\").shape, f\"W_enc_{i} shape mismatch: {W_enc_folded[i].shape} != {f.get_tensor(f'W_enc_{i}').shape}\"\n", - " assert W_enc_folded[i].dtype == f.get_tensor(f\"W_enc_{i}\").dtype, f\"W_enc_{i} dtype mismatch: {W_enc_folded[i].dtype} != {f.get_tensor(f'W_enc_{i}').dtype}\"\n", - " assert torch.allclose(W_enc_folded[i].T, f.get_tensor(f\"W_enc_{i}\"))\n", - " assert torch.allclose(b_enc_folded[i], f.get_tensor(f\"b_enc_{i}\"))\n", - "\n", - "\n", - " # loaded model \n", - " assert transcoder.W_enc[i].shape == f.get_tensor(f\"W_enc_{i}\").shape\n", - " assert transcoder.W_enc[i].dtype == f.get_tensor(f\"W_enc_{i}\").dtype, f\"W_enc_{i} dtype mismatch: {transcoder.W_enc[i].dtype} != {f.get_tensor(f'W_enc_{i}').dtype}\"\n", - " assert torch.allclose(transcoder.W_enc[i], f.get_tensor(f\"W_enc_{i}\").to(\"cuda:0\"))\n", - "\n", - "\n", - " \n", - "\n", - "\n", - "for i in range(clt_module.model.encoder.n_layers):\n", - " rearranged_W_enc = einops.rearrange(\n", - " W_enc_folded[i],\n", - " \"d_acts d_features -> d_features d_acts\",\n", - " ).contiguous()\n", - " assert torch.allclose(rearranged_W_enc.to('cuda:0'), transcoder.W_enc[i].to('cuda:0'))\n", - " assert torch.allclose(b_enc_folded[i].to(dtype=torch.bfloat16).to('cuda:0'),transcoder.b_enc[i].to(dtype=torch.bfloat16).to('cuda:0'))" - ] - }, - { - "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "id": "1bcce2aa", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CrossLayerTranscoder(\n", - " (activation_function): JumpReLU(\n", - " threshold=Parameter containing:\n", - " tensor([[[0.2344, 0.2080, 0.2246, ..., 0.2207, 0.2363, 0.2314]],\n", - " \n", - " [[0.2451, 0.2334, 0.2578, ..., 0.2676, 0.2432, 0.2256]],\n", - " \n", - " [[0.2402, 0.2363, 0.2402, ..., 0.2139, 0.2520, 0.2002]],\n", - " \n", - " ...,\n", - " \n", - " [[0.2168, 0.3789, 0.2480, ..., 0.2305, 0.3242, 0.2793]],\n", - " \n", - " [[0.2891, 0.2158, 0.1943, ..., 0.2793, 0.2812, 0.2949]],\n", - " \n", - " [[0.1934, 0.1543, 0.1758, ..., 0.2832, 0.2324, 0.2197]]],\n", - " device='cuda:0'), bandwidth=2\n", - " )\n", - " (W_dec): ParameterList(\n", - " (0): Parameter containing: [torch.float32 of size 10000x12x768 (cuda:0)]\n", - " (1): Parameter containing: [torch.float32 of size 10000x11x768 (cuda:0)]\n", - " (2): Parameter containing: [torch.float32 of size 10000x10x768 (cuda:0)]\n", - " (3): Parameter containing: [torch.float32 of size 10000x9x768 (cuda:0)]\n", - " (4): Parameter containing: [torch.float32 of size 10000x8x768 (cuda:0)]\n", - " (5): Parameter containing: [torch.float32 of size 10000x7x768 (cuda:0)]\n", - " (6): Parameter containing: [torch.float32 of size 10000x6x768 (cuda:0)]\n", - " (7): Parameter containing: [torch.float32 of size 10000x5x768 (cuda:0)]\n", - " (8): Parameter containing: [torch.float32 of size 10000x4x768 (cuda:0)]\n", - " (9): Parameter containing: [torch.float32 of size 10000x3x768 (cuda:0)]\n", - " (10): Parameter containing: [torch.float32 of size 10000x2x768 (cuda:0)]\n", - " (11): Parameter containing: [torch.float32 of size 10000x1x768 (cuda:0)]\n", - " )\n", - ")\n", - "torch.Size([12, 10000, 768])\n", - "[torch.Size([12, 10000, 768]), torch.Size([12, 768]), torch.Size([12, 10000]), torch.Size([12, 1, 10000]), torch.Size([10000, 12, 768]), torch.Size([10000, 11, 768]), torch.Size([10000, 10, 768]), torch.Size([10000, 9, 768]), torch.Size([10000, 8, 768]), torch.Size([10000, 7, 768]), torch.Size([10000, 6, 768]), torch.Size([10000, 5, 768]), torch.Size([10000, 4, 768]), torch.Size([10000, 3, 768]), torch.Size([10000, 2, 768]), torch.Size([10000, 1, 768])]\n", - "JumpReLU(\n", - " threshold=Parameter containing:\n", - " tensor([[[0.2344, 0.2080, 0.2246, ..., 0.2207, 0.2363, 0.2314]],\n", - " \n", - " [[0.2451, 0.2334, 0.2578, ..., 0.2676, 0.2432, 0.2256]],\n", - " \n", - " [[0.2402, 0.2363, 0.2402, ..., 0.2139, 0.2520, 0.2002]],\n", - " \n", - " ...,\n", - " \n", - " [[0.2168, 0.3789, 0.2480, ..., 0.2305, 0.3242, 0.2793]],\n", - " \n", - " [[0.2891, 0.2158, 0.1943, ..., 0.2793, 0.2812, 0.2949]],\n", - " \n", - " [[0.1934, 0.1543, 0.1758, ..., 0.2832, 0.2324, 0.2197]]],\n", - " device='cuda:0'), bandwidth=2\n", - ")\n" - ] - } - ], + "outputs": [], "source": [ "from circuit_tracer import ReplacementModel\n", "\n", @@ -375,19 +147,12 @@ ")\n", "\n", "\n", - "print(rm.transcoders)\n", - "print(rm.transcoders.W_enc.shape)\n", - "assert torch.allclose(rm.transcoders.W_enc, transcoder.W_enc)\n", - "print([x.shape for x in list(rm.transcoders.parameters())])\n", - "print(rm.transcoders.activation_function)\n", - "\n", - "## TODO: sanity check model\n", "\n" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "id": "10269291", "metadata": {}, "outputs": [], @@ -407,7 +172,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "id": "ecb6f82c", "metadata": {}, "outputs": [ @@ -423,88 +188,28 @@ "output_type": "stream", "text": [ "Tokens shape: torch.Size([8])\n", - "W_enc_layer shape: torch.Size([10000, 768])\n", - "sparse_W_enc_layer nnz: 7680000\n", - "layer_features shape: torch.Size([8, 10000])\n", - "sparse_pre_activations nnz: 80000\n", - "layer_features shape after activation: torch.Size([8, 10000])\n", "l0: 70000\n", "sparse_layer nnz: 70000\n", - "W_enc_layer shape: torch.Size([10000, 768])\n", - "sparse_W_enc_layer nnz: 7680000\n", - "layer_features shape: torch.Size([8, 10000])\n", - "sparse_pre_activations nnz: 80000\n", - "layer_features shape after activation: torch.Size([8, 10000])\n", "l0: 70000\n", "sparse_layer nnz: 70000\n", - "W_enc_layer shape: torch.Size([10000, 768])\n", - "sparse_W_enc_layer nnz: 7680000\n", - "layer_features shape: torch.Size([8, 10000])\n", - "sparse_pre_activations nnz: 80000\n", - "layer_features shape after activation: torch.Size([8, 10000])\n", "l0: 70000\n", "sparse_layer nnz: 70000\n", - "W_enc_layer shape: torch.Size([10000, 768])\n", - "sparse_W_enc_layer nnz: 7680000\n", - "layer_features shape: torch.Size([8, 10000])\n", - "sparse_pre_activations nnz: 80000\n", - "layer_features shape after activation: torch.Size([8, 10000])\n", "l0: 70000\n", "sparse_layer nnz: 70000\n", - "W_enc_layer shape: torch.Size([10000, 768])\n", - "sparse_W_enc_layer nnz: 7680000\n", - "layer_features shape: torch.Size([8, 10000])\n", - "sparse_pre_activations nnz: 80000\n", - "layer_features shape after activation: torch.Size([8, 10000])\n", "l0: 70000\n", "sparse_layer nnz: 70000\n", - "W_enc_layer shape: torch.Size([10000, 768])\n", - "sparse_W_enc_layer nnz: 7680000\n", - "layer_features shape: torch.Size([8, 10000])\n", - "sparse_pre_activations nnz: 80000\n", - "layer_features shape after activation: torch.Size([8, 10000])\n", "l0: 70000\n", "sparse_layer nnz: 70000\n", - "W_enc_layer shape: torch.Size([10000, 768])\n", - "sparse_W_enc_layer nnz: 7680000\n", - "layer_features shape: torch.Size([8, 10000])\n", - "sparse_pre_activations nnz: 80000\n", - "layer_features shape after activation: torch.Size([8, 10000])\n", "l0: 70000\n", "sparse_layer nnz: 70000\n", - "W_enc_layer shape: torch.Size([10000, 768])\n", - "sparse_W_enc_layer nnz: 7680000\n", - "layer_features shape: torch.Size([8, 10000])\n", - "sparse_pre_activations nnz: 80000\n", - "layer_features shape after activation: torch.Size([8, 10000])\n", "l0: 70000\n", "sparse_layer nnz: 70000\n", - "W_enc_layer shape: torch.Size([10000, 768])\n", - "sparse_W_enc_layer nnz: 7680000\n", - "layer_features shape: torch.Size([8, 10000])\n", - "sparse_pre_activations nnz: 80000\n", - "layer_features shape after activation: torch.Size([8, 10000])\n", "l0: 70000\n", "sparse_layer nnz: 70000\n", - "W_enc_layer shape: torch.Size([10000, 768])\n", - "sparse_W_enc_layer nnz: 7680000\n", - "layer_features shape: torch.Size([8, 10000])\n", - "sparse_pre_activations nnz: 80000\n", - "layer_features shape after activation: torch.Size([8, 10000])\n", "l0: 70000\n", "sparse_layer nnz: 70000\n", - "W_enc_layer shape: torch.Size([10000, 768])\n", - "sparse_W_enc_layer nnz: 7680000\n", - "layer_features shape: torch.Size([8, 10000])\n", - "sparse_pre_activations nnz: 80000\n", - "layer_features shape after activation: torch.Size([8, 10000])\n", "l0: 70000\n", "sparse_layer nnz: 70000\n", - "W_enc_layer shape: torch.Size([10000, 768])\n", - "sparse_W_enc_layer nnz: 7680000\n", - "layer_features shape: torch.Size([8, 10000])\n", - "sparse_pre_activations nnz: 80000\n", - "layer_features shape after activation: torch.Size([8, 10000])\n", "l0: 70000\n", "sparse_layer nnz: 70000\n", "Features shape: torch.Size([12, 8, 10000])\n", @@ -514,19 +219,19 @@ }, { "ename": "OutOfMemoryError", - "evalue": "CUDA out of memory. Tried to allocate 15.62 GiB. GPU 0 has a total capacity of 44.34 GiB of which 10.35 GiB is free. Process 2491674 has 8.54 GiB memory in use. Process 2496736 has 25.44 GiB memory in use. Of the allocated memory 23.23 GiB is allocated by PyTorch, and 1.91 GiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation. See documentation for Memory Management (https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)", + "evalue": "CUDA out of memory. Tried to allocate 15.62 GiB. GPU 0 has a total capacity of 44.34 GiB of which 10.55 GiB is free. Process 3607992 has 8.54 GiB memory in use. Process 3613770 has 25.24 GiB memory in use. Of the allocated memory 23.21 GiB is allocated by PyTorch, and 1.72 GiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation. See documentation for Memory Management (https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)", "output_type": "error", "traceback": [ "\u001b[31m---------------------------------------------------------------------------\u001b[39m", "\u001b[31mOutOfMemoryError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[7]\u001b[39m\u001b[32m, line 10\u001b[39m\n\u001b[32m 7\u001b[39m torch.cuda.empty_cache()\n\u001b[32m 9\u001b[39m \u001b[38;5;66;03m# FOr some reason this takes up a lot of VRAM\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m10\u001b[39m graph = \u001b[43mattribute\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 11\u001b[39m \u001b[43m \u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m=\u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 12\u001b[39m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrm\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 13\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 14\u001b[39m \u001b[43m \u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 15\u001b[39m \u001b[43m \u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 16\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 17\u001b[39m \u001b[43m \u001b[49m\u001b[43moffload\u001b[49m\u001b[43m=\u001b[49m\u001b[43moffload\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 18\u001b[39m \u001b[43m \u001b[49m\u001b[43mverbose\u001b[49m\u001b[43m=\u001b[49m\u001b[43mverbose\u001b[49m\n\u001b[32m 19\u001b[39m \u001b[43m)\u001b[49m\n", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[6]\u001b[39m\u001b[32m, line 10\u001b[39m\n\u001b[32m 7\u001b[39m torch.cuda.empty_cache()\n\u001b[32m 9\u001b[39m \u001b[38;5;66;03m# FOr some reason this takes up a lot of VRAM\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m10\u001b[39m graph = \u001b[43mattribute\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 11\u001b[39m \u001b[43m \u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m=\u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 12\u001b[39m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrm\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 13\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 14\u001b[39m \u001b[43m \u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 15\u001b[39m \u001b[43m \u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 16\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 17\u001b[39m \u001b[43m \u001b[49m\u001b[43moffload\u001b[49m\u001b[43m=\u001b[49m\u001b[43moffload\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 18\u001b[39m \u001b[43m \u001b[49m\u001b[43mverbose\u001b[49m\u001b[43m=\u001b[49m\u001b[43mverbose\u001b[49m\n\u001b[32m 19\u001b[39m \u001b[43m)\u001b[49m\n", "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/attribution/attribute.py:137\u001b[39m, in \u001b[36mattribute\u001b[39m\u001b[34m(prompt, model, max_n_logits, desired_logit_prob, batch_size, max_feature_nodes, offload, verbose, update_interval)\u001b[39m\n\u001b[32m 135\u001b[39m offload_handles = []\n\u001b[32m 136\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m137\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_run_attribution\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 138\u001b[39m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 139\u001b[39m \u001b[43m \u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m=\u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 140\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 141\u001b[39m \u001b[43m \u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 142\u001b[39m \u001b[43m \u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 143\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 144\u001b[39m \u001b[43m \u001b[49m\u001b[43moffload\u001b[49m\u001b[43m=\u001b[49m\u001b[43moffload\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 145\u001b[39m \u001b[43m \u001b[49m\u001b[43mverbose\u001b[49m\u001b[43m=\u001b[49m\u001b[43mverbose\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 146\u001b[39m \u001b[43m \u001b[49m\u001b[43moffload_handles\u001b[49m\u001b[43m=\u001b[49m\u001b[43moffload_handles\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 147\u001b[39m \u001b[43m \u001b[49m\u001b[43mupdate_interval\u001b[49m\u001b[43m=\u001b[49m\u001b[43mupdate_interval\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 148\u001b[39m \u001b[43m \u001b[49m\u001b[43mlogger\u001b[49m\u001b[43m=\u001b[49m\u001b[43mlogger\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 149\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 150\u001b[39m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[32m 151\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m reload_handle \u001b[38;5;129;01min\u001b[39;00m offload_handles:\n", "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/attribution/attribute.py:177\u001b[39m, in \u001b[36m_run_attribution\u001b[39m\u001b[34m(model, prompt, max_n_logits, desired_logit_prob, batch_size, max_feature_nodes, offload, verbose, offload_handles, logger, update_interval)\u001b[39m\n\u001b[32m 174\u001b[39m phase_start = time.time()\n\u001b[32m 175\u001b[39m input_ids = model.ensure_tokenized(prompt)\n\u001b[32m--> \u001b[39m\u001b[32m177\u001b[39m ctx = \u001b[43mmodel\u001b[49m\u001b[43m.\u001b[49m\u001b[43msetup_attribution\u001b[49m\u001b[43m(\u001b[49m\u001b[43minput_ids\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 178\u001b[39m activation_matrix = ctx.activation_matrix\n\u001b[32m 180\u001b[39m logger.info(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mPrecomputation completed in \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mtime.time()\u001b[38;5;250m \u001b[39m-\u001b[38;5;250m \u001b[39mphase_start\u001b[38;5;132;01m:\u001b[39;00m\u001b[33m.2f\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[33ms\u001b[39m\u001b[33m\"\u001b[39m)\n", "\u001b[36mFile \u001b[39m\u001b[32m~/crosslayer-transcoder/.venv/lib/python3.12/site-packages/torch/utils/_contextlib.py:120\u001b[39m, in \u001b[36mcontext_decorator..decorate_context\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 117\u001b[39m \u001b[38;5;129m@functools\u001b[39m.wraps(func)\n\u001b[32m 118\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mdecorate_context\u001b[39m(*args, **kwargs):\n\u001b[32m 119\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m ctx_factory():\n\u001b[32m--> \u001b[39m\u001b[32m120\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/replacement_model.py:435\u001b[39m, in \u001b[36mReplacementModel.setup_attribution\u001b[39m\u001b[34m(self, inputs)\u001b[39m\n\u001b[32m 432\u001b[39m mlp_in_cache = torch.cat(\u001b[38;5;28mlist\u001b[39m(mlp_in_cache.values()), dim=\u001b[32m0\u001b[39m)\n\u001b[32m 433\u001b[39m mlp_out_cache = torch.cat(\u001b[38;5;28mlist\u001b[39m(mlp_out_cache.values()), dim=\u001b[32m0\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m435\u001b[39m attribution_data = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mtranscoders\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcompute_attribution_components\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmlp_in_cache\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 437\u001b[39m \u001b[38;5;66;03m# Compute error vectors\u001b[39;00m\n\u001b[32m 438\u001b[39m error_vectors = mlp_out_cache - attribution_data[\u001b[33m\"\u001b[39m\u001b[33mreconstruction\u001b[39m\u001b[33m\"\u001b[39m]\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/transcoder/cross_layer_transcoder.py:323\u001b[39m, in \u001b[36mCrossLayerTranscoder.compute_attribution_components\u001b[39m\u001b[34m(self, inputs)\u001b[39m\n\u001b[32m 320\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mEncoder vectors shape: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mencoder_vectors.shape\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m)\n\u001b[32m 321\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mnnz: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfeatures._nnz()\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m)\n\u001b[32m 322\u001b[39m pos_ids, layer_ids, feat_ids, decoder_vectors, encoder_to_decoder_map = (\n\u001b[32m--> \u001b[39m\u001b[32m323\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mselect_decoder_vectors\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfeatures\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 324\u001b[39m )\n\u001b[32m 325\u001b[39m \u001b[38;5;28mprint\u001b[39m(features.shape)\n\u001b[32m 326\u001b[39m reconstruction = \u001b[38;5;28mself\u001b[39m.compute_reconstruction(pos_ids, layer_ids, decoder_vectors)\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/transcoder/cross_layer_transcoder.py:280\u001b[39m, in \u001b[36mCrossLayerTranscoder.select_decoder_vectors\u001b[39m\u001b[34m(self, features)\u001b[39m\n\u001b[32m 278\u001b[39m layer_ids = torch.cat(layer_ids, dim=\u001b[32m0\u001b[39m)\n\u001b[32m 279\u001b[39m feat_ids = torch.cat(feat_ids, dim=\u001b[32m0\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m280\u001b[39m decoder_vectors = \u001b[43mtorch\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcat\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdecoder_vectors\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdim\u001b[49m\u001b[43m=\u001b[49m\u001b[32;43m0\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 281\u001b[39m encoder_mapping = torch.cat(encoder_mapping, dim=\u001b[32m0\u001b[39m)\n\u001b[32m 283\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m pos_ids, layer_ids, feat_ids, decoder_vectors, encoder_mapping\n", - "\u001b[31mOutOfMemoryError\u001b[39m: CUDA out of memory. Tried to allocate 15.62 GiB. GPU 0 has a total capacity of 44.34 GiB of which 10.35 GiB is free. Process 2491674 has 8.54 GiB memory in use. Process 2496736 has 25.44 GiB memory in use. Of the allocated memory 23.23 GiB is allocated by PyTorch, and 1.91 GiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation. See documentation for Memory Management (https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)" + "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/transcoder/cross_layer_transcoder.py:313\u001b[39m, in \u001b[36mCrossLayerTranscoder.compute_attribution_components\u001b[39m\u001b[34m(self, inputs)\u001b[39m\n\u001b[32m 310\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mEncoder vectors shape: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mencoder_vectors.shape\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m)\n\u001b[32m 311\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mnnz: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfeatures._nnz()\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m)\n\u001b[32m 312\u001b[39m pos_ids, layer_ids, feat_ids, decoder_vectors, encoder_to_decoder_map = (\n\u001b[32m--> \u001b[39m\u001b[32m313\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mselect_decoder_vectors\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfeatures\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 314\u001b[39m )\n\u001b[32m 315\u001b[39m \u001b[38;5;28mprint\u001b[39m(features.shape)\n\u001b[32m 316\u001b[39m reconstruction = \u001b[38;5;28mself\u001b[39m.compute_reconstruction(pos_ids, layer_ids, decoder_vectors)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/transcoder/cross_layer_transcoder.py:270\u001b[39m, in \u001b[36mCrossLayerTranscoder.select_decoder_vectors\u001b[39m\u001b[34m(self, features)\u001b[39m\n\u001b[32m 268\u001b[39m layer_ids = torch.cat(layer_ids, dim=\u001b[32m0\u001b[39m)\n\u001b[32m 269\u001b[39m feat_ids = torch.cat(feat_ids, dim=\u001b[32m0\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m270\u001b[39m decoder_vectors = \u001b[43mtorch\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcat\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdecoder_vectors\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdim\u001b[49m\u001b[43m=\u001b[49m\u001b[32;43m0\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 271\u001b[39m encoder_mapping = torch.cat(encoder_mapping, dim=\u001b[32m0\u001b[39m)\n\u001b[32m 273\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m pos_ids, layer_ids, feat_ids, decoder_vectors, encoder_mapping\n", + "\u001b[31mOutOfMemoryError\u001b[39m: CUDA out of memory. Tried to allocate 15.62 GiB. GPU 0 has a total capacity of 44.34 GiB of which 10.55 GiB is free. Process 3607992 has 8.54 GiB memory in use. Process 3613770 has 25.24 GiB memory in use. Of the allocated memory 23.21 GiB is allocated by PyTorch, and 1.72 GiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation. See documentation for Memory Management (https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)" ] } ], diff --git a/crosslayer_transcoder/utils/sanity_check_model.ipynb b/crosslayer_transcoder/utils/sanity_check_model.ipynb index 6db8e97..cc86dc0 100644 --- a/crosslayer_transcoder/utils/sanity_check_model.ipynb +++ b/crosslayer_transcoder/utils/sanity_check_model.ipynb @@ -5,9 +5,15 @@ "id": "9e36e2f4", "metadata": {}, "source": [ - "# Sanity check model\n", - "\n", - "Sanity check the model checkpoint by loading it into our own arch and then running a prompt through the encoder to see what the sparsity of the model is" + "# Model Sanity checks\n" + ] + }, + { + "cell_type": "markdown", + "id": "5cecc0fd", + "metadata": {}, + "source": [ + "## Load into `crosslayer-transcoder` arch" ] }, { @@ -19,7 +25,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "30928294793d45d7b42fe9bb296d4278", + "model_id": "b802f1a7433c4a82b12ae6355db951ed", "version_major": 2, "version_minor": 0 }, @@ -35,10 +41,10 @@ "output_type": "stream", "text": [ "Token indices sequence length is longer than the specified maximum sequence length for this model (1217 > 1024). Running this sequence through the model will result in indexing errors\n", - "Token indices sequence length is longer than the specified maximum sequence length for this model (1561 > 1024). Running this sequence through the model will result in indexing errors\n", "Token indices sequence length is longer than the specified maximum sequence length for this model (1174 > 1024). Running this sequence through the model will result in indexing errors\n", - "Token indices sequence length is longer than the specified maximum sequence length for this model (2459 > 1024). Running this sequence through the model will result in indexing errors\n", - "Token indices sequence length is longer than the specified maximum sequence length for this model (2027 > 1024). Running this sequence through the model will result in indexing errors\n" + "Token indices sequence length is longer than the specified maximum sequence length for this model (1561 > 1024). Running this sequence through the model will result in indexing errors\n", + "Token indices sequence length is longer than the specified maximum sequence length for this model (2027 > 1024). Running this sequence through the model will result in indexing errors\n", + "Token indices sequence length is longer than the specified maximum sequence length for this model (2459 > 1024). Running this sequence through the model will result in indexing errors\n" ] }, { @@ -81,7 +87,7 @@ "id": "d5030984", "metadata": {}, "source": [ - "## Collect Activations" + "### Collect Activations" ] }, { @@ -152,7 +158,7 @@ "id": "2d3dd5db", "metadata": {}, "source": [ - "## Encode w/o standarizer folding" + "### Encode w/o standarizer folding" ] }, { @@ -196,7 +202,7 @@ "id": "7d847db4", "metadata": {}, "source": [ - "## Encode w/ folding" + "### Encode w/ folding" ] }, { @@ -233,7 +239,7 @@ "id": "130f0259", "metadata": {}, "source": [ - "## Run encoding in bfloat16" + "### Run encoding in bfloat16" ] }, { @@ -268,13 +274,220 @@ "print(f\"l0_avg_per_layer: {l0_avg_per_layer.item()}\")\n" ] }, + { + "cell_type": "markdown", + "id": "eeca368d", + "metadata": {}, + "source": [ + "## Interface w circuit tracer" + ] + }, { "cell_type": "code", - "execution_count": null, - "id": "a2f90530", + "execution_count": 8, + "id": "34ce09c7", "metadata": {}, "outputs": [], - "source": [] + "source": [ + "import pathlib\n", + "from crosslayer_transcoder.utils.model_converters.circuit_tracer import (\n", + " CircuitTracerConverter,\n", + ")\n", + "from circuit_tracer.transcoder.cross_layer_transcoder import load_clt" + ] + }, + { + "cell_type": "markdown", + "id": "6c839fca", + "metadata": {}, + "source": [ + "### Convert model to circuit-tracer format and save `.safetensors`" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "8c55f63b", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Converting CLT : 100%|██████████| 12/12 [00:10<00:00, 1.13it/s]\n" + ] + } + ], + "source": [ + "save_dir = pathlib.Path(\"clt_module_test\")\n", + "feature_input_hook = \"hook_resid_mid\"\n", + "feature_output_hook = \"hook_mlp_out\"\n", + "\n", + "converter = CircuitTracerConverter(\n", + "save_dir=save_dir,\n", + "feature_input_hook=feature_input_hook,\n", + " feature_output_hook=feature_output_hook,\n", + ")\n", + "converter.convert_and_save(clt_module, dtype=torch.bfloat16) " + ] + }, + { + "cell_type": "markdown", + "id": "9c9b91b8", + "metadata": {}, + "source": [ + "### Load CLT into circuit-tracer" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "eb5ad901", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "12\n", + "['W_enc_0', 'b_dec_0', 'b_enc_0', 'threshold_0']\n", + "['W_enc_1', 'b_dec_1', 'b_enc_1', 'threshold_1']\n", + "['W_enc_2', 'b_dec_2', 'b_enc_2', 'threshold_2']\n", + "['W_enc_3', 'b_dec_3', 'b_enc_3', 'threshold_3']\n", + "['W_enc_4', 'b_dec_4', 'b_enc_4', 'threshold_4']\n", + "['W_enc_5', 'b_dec_5', 'b_enc_5', 'threshold_5']\n", + "['W_enc_6', 'b_dec_6', 'b_enc_6', 'threshold_6']\n", + "['W_enc_7', 'b_dec_7', 'b_enc_7', 'threshold_7']\n", + "['W_enc_8', 'b_dec_8', 'b_enc_8', 'threshold_8']\n", + "['W_enc_9', 'b_dec_9', 'b_enc_9', 'threshold_9']\n", + "['W_enc_10', 'b_dec_10', 'b_enc_10', 'threshold_10']\n", + "['W_enc_11', 'b_dec_11', 'b_enc_11', 'threshold_11']\n", + "dict_keys(['b_dec', 'b_enc', 'activation_function.threshold', 'W_enc', 'W_dec.0', 'W_dec.1', 'W_dec.2', 'W_dec.3', 'W_dec.4', 'W_dec.5', 'W_dec.6', 'W_dec.7', 'W_dec.8', 'W_dec.9', 'W_dec.10', 'W_dec.11'])\n" + ] + } + ], + "source": [ + "\n", + "circuit_tracer_transcoder, state_dict_pre_load = load_clt(\n", + " clt_path=save_dir.as_posix(),\n", + " lazy_decoder=False,\n", + " lazy_encoder=False,\n", + " feature_input_hook=feature_input_hook,\n", + " feature_output_hook=feature_output_hook,\n", + " dtype=torch.bfloat16,\n", + ")\n" + ] + }, + { + "cell_type": "markdown", + "id": "b3df8f67", + "metadata": {}, + "source": [ + "### Sanity checks for loaded model" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "78ff27a5", + "metadata": {}, + "outputs": [], + "source": [ + "import einops\n", + "from safetensors import safe_open\n", + "import torch\n", + "import os\n", + "# sanity check against original model\n", + "\n", + "clt_path = save_dir.as_posix()\n", + "assert circuit_tracer_transcoder.clt_path == clt_path\n", + "\n", + "\n", + "# TEST: state_dict_pre_load weights match the files before being loaded into the model\n", + "for i in range(circuit_tracer_transcoder.n_layers):\n", + " enc_file = os.path.join(clt_path, f\"W_enc_{i}.safetensors\")\n", + " with safe_open(enc_file, framework=\"pt\", device=circuit_tracer_transcoder.device.type) as f:\n", + " w_file = f.get_tensor(f\"W_enc_{i}\").to(\n", + " dtype=state_dict_pre_load[\"W_enc\"][i].dtype,\n", + " device=state_dict_pre_load[\"W_enc\"][i].device,\n", + " )\n", + " w_state = state_dict_pre_load[\"W_enc\"][i]\n", + " assert w_file.shape == w_state.shape, (\n", + " f\"W_enc_{i} shape mismatch: {w_file.shape} != {w_state.shape}\"\n", + " )\n", + " assert w_file.dtype == w_state.dtype, (\n", + " f\"W_enc_{i} dtype mismatch: {w_file.dtype} != {w_state.dtype}\"\n", + " )\n", + " assert torch.allclose(w_file, w_state), (\n", + " i,\n", + " (w_file - w_state).abs().max().item(),\n", + " )\n", + "\n", + "\n", + "# TEST: weights in the files should equal weights from the circuit_tracer_transcoder\n", + "for i in range(circuit_tracer_transcoder.n_layers):\n", + " w_model = circuit_tracer_transcoder._get_encoder_weights(i) # works for both lazy and eager\n", + " enc_file = os.path.join(clt_path, f\"W_enc_{i}.safetensors\")\n", + " with safe_open(enc_file, framework=\"pt\", device=circuit_tracer_transcoder.device.type) as f:\n", + " w_file = f.get_tensor(f\"W_enc_{i}\").to(\n", + " dtype=w_model.dtype, device=w_model.device\n", + " )\n", + "\n", + " assert w_model.shape == w_file.shape\n", + " assert w_model.dtype == w_file.dtype\n", + " assert torch.allclose(w_model, w_file), (i, (w_model - w_file).abs().max().item())\n", + "\n", + "\n", + "# fold\n", + "standardizer = clt_module.model.input_standardizer\n", + "W_enc_folded, b_enc_folded = standardizer.fold_in_encoder(\n", + " clt_module.model.encoder.W.to(dtype=torch.bfloat16),\n", + " clt_module.model.encoder.b.to(dtype=torch.bfloat16),\n", + ")\n", + "\n", + "W_enc_folded = W_enc_folded.to(dtype=torch.bfloat16)\n", + "b_enc_folded = b_enc_folded.to(dtype=torch.bfloat16)\n", + "\n", + "state_dict = {}\n", + "device = clt_module.device\n", + "# TEST: eights in the file should equal the folded weights\n", + "for i in range(clt_module.model.encoder.n_layers):\n", + " enc_file = f\"W_enc_{i}.safetensors\"\n", + " with safe_open(\n", + " os.path.join(clt_path, enc_file), framework=\"pt\", device=device.type\n", + " ) as f:\n", + " assert W_enc_folded[i].T.shape == f.get_tensor(f\"W_enc_{i}\").shape, (\n", + " f\"W_enc_{i} shape mismatch: {W_enc_folded[i].shape} != {f.get_tensor(f'W_enc_{i}').shape}\"\n", + " )\n", + " assert W_enc_folded[i].dtype == f.get_tensor(f\"W_enc_{i}\").dtype, (\n", + " f\"W_enc_{i} dtype mismatch: {W_enc_folded[i].dtype} != {f.get_tensor(f'W_enc_{i}').dtype}\"\n", + " )\n", + " assert torch.allclose(W_enc_folded[i].T, f.get_tensor(f\"W_enc_{i}\"))\n", + " assert torch.allclose(b_enc_folded[i], f.get_tensor(f\"b_enc_{i}\"))\n", + "\n", + " # loaded model\n", + " assert circuit_tracer_transcoder.W_enc[i].shape == f.get_tensor(f\"W_enc_{i}\").shape\n", + " assert circuit_tracer_transcoder.W_enc[i].dtype == f.get_tensor(f\"W_enc_{i}\").dtype, (\n", + " f\"W_enc_{i} dtype mismatch: {circuit_tracer_transcoder.W_enc[i].dtype} != {f.get_tensor(f'W_enc_{i}').dtype}\"\n", + " )\n", + " assert torch.allclose(\n", + " circuit_tracer_transcoder.W_enc[i], f.get_tensor(f\"W_enc_{i}\").to(\"cuda:0\")\n", + " )\n", + "\n", + "\n", + "for i in range(clt_module.model.encoder.n_layers):\n", + " rearranged_W_enc = einops.rearrange(\n", + " W_enc_folded[i],\n", + " \"d_acts d_features -> d_features d_acts\",\n", + " ).contiguous()\n", + " assert torch.allclose(\n", + " rearranged_W_enc.to(\"cuda:0\"), circuit_tracer_transcoder.W_enc[i].to(\"cuda:0\")\n", + " )\n", + " assert torch.allclose(\n", + " b_enc_folded[i].to(dtype=torch.bfloat16).to(\"cuda:0\"),\n", + " circuit_tracer_transcoder.b_enc[i].to(dtype=torch.bfloat16).to(\"cuda:0\"),\n", + " )\n" + ] } ], "metadata": { From a872e3f9c19f9587b2fd139152ca884987838b11 Mon Sep 17 00:00:00 2001 From: jiito Date: Mon, 17 Nov 2025 17:16:13 +0000 Subject: [PATCH 72/99] fix: load from pretrained and update deps --- .../utils/replacement_score.ipynb | 363 +++++--- .../utils/sanity_check_model.ipynb | 814 +++++++++++++++++- pyproject.toml | 5 +- uv.lock | 2 +- 4 files changed, 1051 insertions(+), 133 deletions(-) diff --git a/crosslayer_transcoder/utils/replacement_score.ipynb b/crosslayer_transcoder/utils/replacement_score.ipynb index 4c843f8..d54874e 100644 --- a/crosslayer_transcoder/utils/replacement_score.ipynb +++ b/crosslayer_transcoder/utils/replacement_score.ipynb @@ -8,14 +8,6 @@ "# Replacement Score Test" ] }, - { - "cell_type": "markdown", - "id": "d19aa81f", - "metadata": {}, - "source": [ - "## Load the model from the local checkpoint (save from HF before)" - ] - }, { "cell_type": "code", "execution_count": 1, @@ -23,25 +15,51 @@ "metadata": {}, "outputs": [], "source": [ - "import pathlib\n", - "\n", "from crosslayer_transcoder.utils.model_converters.circuit_tracer import (\n", " CircuitTracerConverter,\n", ")\n", - "from transformer_lens.loading_from_pretrained import get_pretrained_model_config\n", - "import torch" + "import torch\n" + ] + }, + { + "cell_type": "markdown", + "id": "a091f9ee", + "metadata": {}, + "source": [ + "### Config" ] }, { "cell_type": "code", "execution_count": 2, + "id": "a37586eb", + "metadata": {}, + "outputs": [], + "source": [ + "DTYPE = torch.bfloat16\n", + "checkpoint = \"../checkpoints/clt.ckpt\"\n", + "config_path = \"../../config/circuit-tracer.yaml\"\n", + "identifier = \"gpt2-crosslayer-clt-v1\"" + ] + }, + { + "cell_type": "markdown", + "id": "b4458999", + "metadata": {}, + "source": [ + "### Load model from local checkpoint " + ] + }, + { + "cell_type": "code", + "execution_count": 3, "id": "c166ce94", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "03a327355ed64e53a3904d6c23fd3796", + "model_id": "9143e88a119645a5b1e1857fbb6893e7", "version_major": 2, "version_minor": 0 }, @@ -57,11 +75,10 @@ "output_type": "stream", "text": [ "Token indices sequence length is longer than the specified maximum sequence length for this model (1217 > 1024). Running this sequence through the model will result in indexing errors\n", - "Token indices sequence length is longer than the specified maximum sequence length for this model (1174 > 1024). Running this sequence through the model will result in indexing errors\n", "Token indices sequence length is longer than the specified maximum sequence length for this model (1561 > 1024). Running this sequence through the model will result in indexing errors\n", - "Token indices sequence length is longer than the specified maximum sequence length for this model (2027 > 1024). Running this sequence through the model will result in indexing errors\n", "Token indices sequence length is longer than the specified maximum sequence length for this model (2459 > 1024). Running this sequence through the model will result in indexing errors\n", - "Converting CLT : 100%|██████████| 12/12 [00:24<00:00, 2.01s/it]\n" + "Token indices sequence length is longer than the specified maximum sequence length for this model (1174 > 1024). Running this sequence through the model will result in indexing errors\n", + "Token indices sequence length is longer than the specified maximum sequence length for this model (2027 > 1024). Running this sequence through the model will result in indexing errors\n" ] } ], @@ -69,16 +86,27 @@ "from crosslayer_transcoder.utils.module_builder import build_module_from_config, yaml_to_config\n", "from crosslayer_transcoder.utils.checkpoints import load_model_from_lightning_checkpoint\n", "\n", - "config = yaml_to_config(\"../../config/circuit-tracer.yaml\")\n", + "config = yaml_to_config(config_path)\n", "clt_module = build_module_from_config(config)\n", - "\n", - "# load checkpoint\n", - "checkpoint = \"../checkpoints/clt.ckpt\"\n", - "\n", - "clt_module = load_model_from_lightning_checkpoint(clt_module, checkpoint)\n", - "\n", - "\n", - "save_dir = pathlib.Path(\"clt_module_test\")\n", + "clt_module = load_model_from_lightning_checkpoint(clt_module, checkpoint)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "f259397a", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Converting CLT : 100%|██████████| 12/12 [00:23<00:00, 1.99s/it]\n" + ] + } + ], + "source": [ + "save_dir = \"clt_module_test\"\n", "feature_input_hook = \"hook_resid_mid\"\n", "feature_output_hook = \"hook_mlp_out\"\n", "\n", @@ -87,72 +115,80 @@ "feature_input_hook=feature_input_hook,\n", " feature_output_hook=feature_output_hook,\n", ")\n", - "converter.convert_and_save(clt_module, dtype=torch.bfloat16) " + "converter.convert_and_save(clt_module, dtype=DTYPE) " + ] + }, + { + "cell_type": "markdown", + "id": "ae50d526", + "metadata": {}, + "source": [ + "### Load model from local converted checkpoint\n", + "\n", + "In the future, this could be loaded from huggingface using the `ReplacementModel.from_pretrained`" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 5, "id": "f8d8594b", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "12\n", - "['W_enc_0', 'b_dec_0', 'b_enc_0', 'threshold_0']\n", - "['W_enc_1', 'b_dec_1', 'b_enc_1', 'threshold_1']\n", - "['W_enc_2', 'b_dec_2', 'b_enc_2', 'threshold_2']\n", - "['W_enc_3', 'b_dec_3', 'b_enc_3', 'threshold_3']\n", - "['W_enc_4', 'b_dec_4', 'b_enc_4', 'threshold_4']\n", - "['W_enc_5', 'b_dec_5', 'b_enc_5', 'threshold_5']\n", - "['W_enc_6', 'b_dec_6', 'b_enc_6', 'threshold_6']\n", - "['W_enc_7', 'b_dec_7', 'b_enc_7', 'threshold_7']\n", - "['W_enc_8', 'b_dec_8', 'b_enc_8', 'threshold_8']\n", - "['W_enc_9', 'b_dec_9', 'b_enc_9', 'threshold_9']\n", - "['W_enc_10', 'b_dec_10', 'b_enc_10', 'threshold_10']\n", - "['W_enc_11', 'b_dec_11', 'b_enc_11', 'threshold_11']\n", - "dict_keys(['b_dec', 'b_enc', 'activation_function.threshold', 'W_enc', 'W_dec.0', 'W_dec.1', 'W_dec.2', 'W_dec.3', 'W_dec.4', 'W_dec.5', 'W_dec.6', 'W_dec.7', 'W_dec.8', 'W_dec.9', 'W_dec.10', 'W_dec.11'])\n" - ] - } - ], + "outputs": [], "source": [ "from circuit_tracer.transcoder.cross_layer_transcoder import load_clt\n", - "transcoder, state_dict_pre_load = load_clt(\n", - " clt_path=save_dir.as_posix(),\n", + "circuit_tracer_clt = load_clt(\n", + " clt_path=save_dir,\n", " lazy_decoder=False,\n", " lazy_encoder=False,\n", " feature_input_hook=feature_input_hook,\n", " feature_output_hook=feature_output_hook,\n", - " dtype=torch.bfloat16,\n", + " dtype=DTYPE,\n", + " scan=identifier\n", ")\n" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 6, "id": "1bcce2aa", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "`torch_dtype` is deprecated! Use `dtype` instead!\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loaded pretrained model gpt2 into HookedTransformer\n" + ] + } + ], "source": [ "from circuit_tracer import ReplacementModel\n", "\n", - "\n", - "config = get_pretrained_model_config(\"gpt2\")\n", - "config.d_type = torch.float16\n", - "rm = ReplacementModel.from_config(\n", - " config=config,\n", - " transcoders=transcoder,\n", - ")\n", - "\n", - "\n", - "\n" + "rm = ReplacementModel.from_pretrained_and_transcoders(\n", + " \"gpt2\",\n", + " circuit_tracer_clt,\n", + " dtype=DTYPE,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "8448dc8b", + "metadata": {}, + "source": [ + "### Attribution" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "id": "10269291", "metadata": {}, "outputs": [], @@ -162,17 +198,14 @@ ")\n", "max_n_logits = 10 # How many logits to attribute from, max. We attribute to min(max_n_logits, n_logits_to_reach_desired_log_prob); see below for the latter\n", "desired_logit_prob = 0.95 # Attribution will attribute from the minimum number of logits needed to reach this probability mass (or max_n_logits, whichever is lower)\n", - "max_feature_nodes = 100 # Only attribute from this number of feature nodes, max. Lower is faster, but you will lose more of the graph. None means no limit.\n", - "batch_size = 256//8 # Batch size when attributing\n", - "offload = (\n", - " \"cpu\"\n", - ") # Offload various parts of the model during attribution to save memory. Can be 'disk', 'cpu', or None (keep on GPU)\n", + "max_feature_nodes = 8192 # Only attribute from this number of feature nodes, max. Lower is faster, but you will lose more of the graph. None means no limit.\n", + "batch_size = 256 # Batch size when attributing\n", "verbose = True # Whether to display a tqdm progress bar and timing report\n" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 8, "id": "ecb6f82c", "metadata": {}, "outputs": [ @@ -180,58 +213,22 @@ "name": "stderr", "output_type": "stream", "text": [ - "Phase 0: Precomputing activations and vectors\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Tokens shape: torch.Size([8])\n", - "l0: 70000\n", - "sparse_layer nnz: 70000\n", - "l0: 70000\n", - "sparse_layer nnz: 70000\n", - "l0: 70000\n", - "sparse_layer nnz: 70000\n", - "l0: 70000\n", - "sparse_layer nnz: 70000\n", - "l0: 70000\n", - "sparse_layer nnz: 70000\n", - "l0: 70000\n", - "sparse_layer nnz: 70000\n", - "l0: 70000\n", - "sparse_layer nnz: 70000\n", - "l0: 70000\n", - "sparse_layer nnz: 70000\n", - "l0: 70000\n", - "sparse_layer nnz: 70000\n", - "l0: 70000\n", - "sparse_layer nnz: 70000\n", - "l0: 70000\n", - "sparse_layer nnz: 70000\n", - "l0: 70000\n", - "sparse_layer nnz: 70000\n", - "Features shape: torch.Size([12, 8, 10000])\n", - "Encoder vectors shape: torch.Size([840000, 768])\n", - "nnz: 840000\n" - ] - }, - { - "ename": "OutOfMemoryError", - "evalue": "CUDA out of memory. Tried to allocate 15.62 GiB. GPU 0 has a total capacity of 44.34 GiB of which 10.55 GiB is free. Process 3607992 has 8.54 GiB memory in use. Process 3613770 has 25.24 GiB memory in use. Of the allocated memory 23.21 GiB is allocated by PyTorch, and 1.72 GiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation. See documentation for Memory Management (https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)", - "output_type": "error", - "traceback": [ - "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mOutOfMemoryError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[6]\u001b[39m\u001b[32m, line 10\u001b[39m\n\u001b[32m 7\u001b[39m torch.cuda.empty_cache()\n\u001b[32m 9\u001b[39m \u001b[38;5;66;03m# FOr some reason this takes up a lot of VRAM\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m10\u001b[39m graph = \u001b[43mattribute\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 11\u001b[39m \u001b[43m \u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m=\u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 12\u001b[39m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrm\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 13\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 14\u001b[39m \u001b[43m \u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 15\u001b[39m \u001b[43m \u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 16\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 17\u001b[39m \u001b[43m \u001b[49m\u001b[43moffload\u001b[49m\u001b[43m=\u001b[49m\u001b[43moffload\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 18\u001b[39m \u001b[43m \u001b[49m\u001b[43mverbose\u001b[49m\u001b[43m=\u001b[49m\u001b[43mverbose\u001b[49m\n\u001b[32m 19\u001b[39m \u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/attribution/attribute.py:137\u001b[39m, in \u001b[36mattribute\u001b[39m\u001b[34m(prompt, model, max_n_logits, desired_logit_prob, batch_size, max_feature_nodes, offload, verbose, update_interval)\u001b[39m\n\u001b[32m 135\u001b[39m offload_handles = []\n\u001b[32m 136\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m137\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_run_attribution\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 138\u001b[39m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 139\u001b[39m \u001b[43m \u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m=\u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 140\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_n_logits\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 141\u001b[39m \u001b[43m \u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdesired_logit_prob\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 142\u001b[39m \u001b[43m \u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 143\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_feature_nodes\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 144\u001b[39m \u001b[43m \u001b[49m\u001b[43moffload\u001b[49m\u001b[43m=\u001b[49m\u001b[43moffload\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 145\u001b[39m \u001b[43m \u001b[49m\u001b[43mverbose\u001b[49m\u001b[43m=\u001b[49m\u001b[43mverbose\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 146\u001b[39m \u001b[43m \u001b[49m\u001b[43moffload_handles\u001b[49m\u001b[43m=\u001b[49m\u001b[43moffload_handles\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 147\u001b[39m \u001b[43m \u001b[49m\u001b[43mupdate_interval\u001b[49m\u001b[43m=\u001b[49m\u001b[43mupdate_interval\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 148\u001b[39m \u001b[43m \u001b[49m\u001b[43mlogger\u001b[49m\u001b[43m=\u001b[49m\u001b[43mlogger\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 149\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 150\u001b[39m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[32m 151\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m reload_handle \u001b[38;5;129;01min\u001b[39;00m offload_handles:\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/attribution/attribute.py:177\u001b[39m, in \u001b[36m_run_attribution\u001b[39m\u001b[34m(model, prompt, max_n_logits, desired_logit_prob, batch_size, max_feature_nodes, offload, verbose, offload_handles, logger, update_interval)\u001b[39m\n\u001b[32m 174\u001b[39m phase_start = time.time()\n\u001b[32m 175\u001b[39m input_ids = model.ensure_tokenized(prompt)\n\u001b[32m--> \u001b[39m\u001b[32m177\u001b[39m ctx = \u001b[43mmodel\u001b[49m\u001b[43m.\u001b[49m\u001b[43msetup_attribution\u001b[49m\u001b[43m(\u001b[49m\u001b[43minput_ids\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 178\u001b[39m activation_matrix = ctx.activation_matrix\n\u001b[32m 180\u001b[39m logger.info(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mPrecomputation completed in \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mtime.time()\u001b[38;5;250m \u001b[39m-\u001b[38;5;250m \u001b[39mphase_start\u001b[38;5;132;01m:\u001b[39;00m\u001b[33m.2f\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[33ms\u001b[39m\u001b[33m\"\u001b[39m)\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/crosslayer-transcoder/.venv/lib/python3.12/site-packages/torch/utils/_contextlib.py:120\u001b[39m, in \u001b[36mcontext_decorator..decorate_context\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 117\u001b[39m \u001b[38;5;129m@functools\u001b[39m.wraps(func)\n\u001b[32m 118\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mdecorate_context\u001b[39m(*args, **kwargs):\n\u001b[32m 119\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m ctx_factory():\n\u001b[32m--> \u001b[39m\u001b[32m120\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/replacement_model.py:435\u001b[39m, in \u001b[36mReplacementModel.setup_attribution\u001b[39m\u001b[34m(self, inputs)\u001b[39m\n\u001b[32m 432\u001b[39m mlp_in_cache = torch.cat(\u001b[38;5;28mlist\u001b[39m(mlp_in_cache.values()), dim=\u001b[32m0\u001b[39m)\n\u001b[32m 433\u001b[39m mlp_out_cache = torch.cat(\u001b[38;5;28mlist\u001b[39m(mlp_out_cache.values()), dim=\u001b[32m0\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m435\u001b[39m attribution_data = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mtranscoders\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcompute_attribution_components\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmlp_in_cache\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 437\u001b[39m \u001b[38;5;66;03m# Compute error vectors\u001b[39;00m\n\u001b[32m 438\u001b[39m error_vectors = mlp_out_cache - attribution_data[\u001b[33m\"\u001b[39m\u001b[33mreconstruction\u001b[39m\u001b[33m\"\u001b[39m]\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/transcoder/cross_layer_transcoder.py:313\u001b[39m, in \u001b[36mCrossLayerTranscoder.compute_attribution_components\u001b[39m\u001b[34m(self, inputs)\u001b[39m\n\u001b[32m 310\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mEncoder vectors shape: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mencoder_vectors.shape\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m)\n\u001b[32m 311\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mnnz: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfeatures._nnz()\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m)\n\u001b[32m 312\u001b[39m pos_ids, layer_ids, feat_ids, decoder_vectors, encoder_to_decoder_map = (\n\u001b[32m--> \u001b[39m\u001b[32m313\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mselect_decoder_vectors\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfeatures\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 314\u001b[39m )\n\u001b[32m 315\u001b[39m \u001b[38;5;28mprint\u001b[39m(features.shape)\n\u001b[32m 316\u001b[39m reconstruction = \u001b[38;5;28mself\u001b[39m.compute_reconstruction(pos_ids, layer_ids, decoder_vectors)\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/transcoder/cross_layer_transcoder.py:270\u001b[39m, in \u001b[36mCrossLayerTranscoder.select_decoder_vectors\u001b[39m\u001b[34m(self, features)\u001b[39m\n\u001b[32m 268\u001b[39m layer_ids = torch.cat(layer_ids, dim=\u001b[32m0\u001b[39m)\n\u001b[32m 269\u001b[39m feat_ids = torch.cat(feat_ids, dim=\u001b[32m0\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m270\u001b[39m decoder_vectors = \u001b[43mtorch\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcat\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdecoder_vectors\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdim\u001b[49m\u001b[43m=\u001b[49m\u001b[32;43m0\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 271\u001b[39m encoder_mapping = torch.cat(encoder_mapping, dim=\u001b[32m0\u001b[39m)\n\u001b[32m 273\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m pos_ids, layer_ids, feat_ids, decoder_vectors, encoder_mapping\n", - "\u001b[31mOutOfMemoryError\u001b[39m: CUDA out of memory. Tried to allocate 15.62 GiB. GPU 0 has a total capacity of 44.34 GiB of which 10.55 GiB is free. Process 3607992 has 8.54 GiB memory in use. Process 3613770 has 25.24 GiB memory in use. Of the allocated memory 23.21 GiB is allocated by PyTorch, and 1.72 GiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation. See documentation for Memory Management (https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)" + "Phase 0: Precomputing activations and vectors\n", + "Precomputation completed in 0.51s\n", + "Found 1316 active features\n", + "Phase 1: Running forward pass\n", + "Forward pass completed in 0.04s\n", + "Phase 2: Building input vectors\n", + "Selected 10 logits with cumulative probability 0.2871\n", + "Will include 1316 of 1316 feature nodes\n", + "Input vectors built in 0.04s\n", + "Phase 3: Computing logit attributions\n", + "sys:1: UserWarning: Full backward hook is firing when gradients are computed with respect to module outputs since no inputs require gradients. See https://docs.pytorch.org/docs/main/generated/torch.nn.Module.html#torch.nn.Module.register_full_backward_hook for more details.\n", + "Logit attributions completed in 0.05s\n", + "Phase 4: Computing feature attributions\n", + "Feature influence computation: 100%|██████████| 1316/1316 [00:00<00:00, 7560.45it/s]\n", + "Feature attributions completed in 0.18s\n", + "Attribution completed in 0.82s\n" ] } ], @@ -239,12 +236,11 @@ "from pathlib import Path\n", "import torch\n", "\n", - "from circuit_tracer import ReplacementModel, attribute\n", + "from circuit_tracer import attribute\n", "from circuit_tracer.utils import create_graph_files\n", "\n", "torch.cuda.empty_cache()\n", "\n", - "# FOr some reason this takes up a lot of VRAM\n", "graph = attribute(\n", " prompt=prompt,\n", " model=rm,\n", @@ -252,14 +248,53 @@ " desired_logit_prob=desired_logit_prob,\n", " batch_size=batch_size,\n", " max_feature_nodes=max_feature_nodes,\n", - " offload=offload,\n", + " offload=None,\n", " verbose=verbose\n", ")" ] }, + { + "cell_type": "markdown", + "id": "06fa0b05", + "metadata": {}, + "source": [ + "### Replacement Score" + ] + }, { "cell_type": "code", "execution_count": null, + "id": "4008f230", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(0.7424161434173584, 0.919729471206665)" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from circuit_tracer.graph import compute_graph_scores\n", + "print(\"replacement score, completeness score\")\n", + "compute_graph_scores(graph)" + ] + }, + { + "cell_type": "markdown", + "id": "e33c5e46", + "metadata": {}, + "source": [ + "### Viz" + ] + }, + { + "cell_type": "code", + "execution_count": 10, "id": "191aafa5", "metadata": {}, "outputs": [], @@ -272,6 +307,82 @@ "\n", "graph.to_pt(graph_path)" ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "9e4da199", + "metadata": {}, + "outputs": [], + "source": [ + "slug = \"dallas-austin\" # this is the name that you assign to the graph\n", + "graph_file_dir = \"./graph_files\" # where to write the graph files. no need to make this one; create_graph_files does that for you\n", + "node_threshold = (\n", + " 0.8 # keep only the minimum # of nodes whose cumulative influence is >= 0.8\n", + ")\n", + "edge_threshold = (\n", + " 0.98 # keep only the minimum # of edges whose cumulative influence is >= 0.98\n", + ")\n", + "\n", + "create_graph_files(\n", + " graph_or_path=graph_path, # the graph to create files for\n", + " slug=slug,\n", + " output_path=graph_file_dir,\n", + " node_threshold=node_threshold,\n", + " edge_threshold=edge_threshold,\n", + ")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "50185332", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Use the IFrame below, or open your graph here: f'http://localhost:8046/index.html'\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from circuit_tracer.frontend.local_server import serve\n", + "from IPython.display import IFrame\n", + "\n", + "port = 8046\n", + "server = serve(data_dir=\"./graph_files/\", port=port)\n", + "\n", + "\n", + "print(\n", + " f\"Use the IFrame below, or open your graph here: f'http://localhost:{port}/index.html'\"\n", + ")\n", + "display(\n", + " IFrame(src=f\"http://localhost:{port}/index.html\", width=\"100%\", height=\"800px\")\n", + ")\n" + ] } ], "metadata": { diff --git a/crosslayer_transcoder/utils/sanity_check_model.ipynb b/crosslayer_transcoder/utils/sanity_check_model.ipynb index cc86dc0..3a1ec4b 100644 --- a/crosslayer_transcoder/utils/sanity_check_model.ipynb +++ b/crosslayer_transcoder/utils/sanity_check_model.ipynb @@ -25,7 +25,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "b802f1a7433c4a82b12ae6355db951ed", + "model_id": "ade35ae315f8420ebf9281b299159eda", "version_major": 2, "version_minor": 0 }, @@ -41,10 +41,10 @@ "output_type": "stream", "text": [ "Token indices sequence length is longer than the specified maximum sequence length for this model (1217 > 1024). Running this sequence through the model will result in indexing errors\n", - "Token indices sequence length is longer than the specified maximum sequence length for this model (1174 > 1024). Running this sequence through the model will result in indexing errors\n", "Token indices sequence length is longer than the specified maximum sequence length for this model (1561 > 1024). Running this sequence through the model will result in indexing errors\n", - "Token indices sequence length is longer than the specified maximum sequence length for this model (2027 > 1024). Running this sequence through the model will result in indexing errors\n", - "Token indices sequence length is longer than the specified maximum sequence length for this model (2459 > 1024). Running this sequence through the model will result in indexing errors\n" + "Token indices sequence length is longer than the specified maximum sequence length for this model (1174 > 1024). Running this sequence through the model will result in indexing errors\n", + "Token indices sequence length is longer than the specified maximum sequence length for this model (2459 > 1024). Running this sequence through the model will result in indexing errors\n", + "Token indices sequence length is longer than the specified maximum sequence length for this model (2027 > 1024). Running this sequence through the model will result in indexing errors\n" ] }, { @@ -314,7 +314,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "Converting CLT : 100%|██████████| 12/12 [00:10<00:00, 1.13it/s]\n" + "Converting CLT : 100%|██████████| 12/12 [00:13<00:00, 1.15s/it]\n" ] } ], @@ -488,6 +488,810 @@ " circuit_tracer_transcoder.b_enc[i].to(dtype=torch.bfloat16).to(\"cuda:0\"),\n", " )\n" ] + }, + { + "cell_type": "markdown", + "id": "8973a435", + "metadata": {}, + "source": [ + "### Test Loaded CLT encoding" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "60b75b1b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([12, 7, 768])\n", + "cuda:0 torch.bfloat16\n", + "layer 0 nnz: 426\n", + "layer 1 nnz: 204\n", + "layer 2 nnz: 107\n", + "layer 3 nnz: 94\n", + "layer 4 nnz: 104\n", + "layer 5 nnz: 72\n", + "layer 6 nnz: 88\n", + "layer 7 nnz: 36\n", + "layer 8 nnz: 35\n", + "layer 9 nnz: 18\n", + "layer 10 nnz: 14\n", + "layer 11 nnz: 2\n" + ] + }, + { + "data": { + "text/plain": [ + "(tensor(indices=tensor([[ 0, 0, 0, ..., 10, 11, 11],\n", + " [ 1, 1, 1, ..., 6, 1, 6],\n", + " [ 71, 193, 330, ..., 9154, 7738, 433]]),\n", + " values=tensor([-0.7852, 1.4062, 1.7812, ..., 1.3203, 1.1094,\n", + " 0.4297]),\n", + " device='cuda:0', size=(12, 7, 10000), nnz=1200, dtype=torch.bfloat16,\n", + " layout=torch.sparse_coo, grad_fn=),\n", + " tensor([[-1.9409e-02, -1.8677e-02, -5.5420e-02, ..., 2.7222e-02,\n", + " 2.3438e-01, -2.4609e-01],\n", + " [-2.0447e-03, 3.7109e-02, 6.4697e-03, ..., -4.1797e-01,\n", + " -2.8516e-01, 6.2988e-02],\n", + " [-2.6978e-02, -1.0193e-02, 6.5613e-04, ..., -4.7656e-01,\n", + " -2.8564e-02, -1.9824e-01],\n", + " ...,\n", + " [ 2.1210e-03, 1.1520e-03, 6.0730e-03, ..., -2.9907e-03,\n", + " -1.3885e-03, 5.0964e-03],\n", + " [-2.5787e-03, 1.1826e-03, 5.6152e-03, ..., 4.8218e-03,\n", + " 5.2795e-03, 4.4861e-03],\n", + " [-1.7700e-03, 2.0695e-04, 3.0975e-03, ..., 1.2436e-03,\n", + " 5.0049e-03, -2.8839e-03]], device='cuda:0', dtype=torch.bfloat16,\n", + " grad_fn=))" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "in_acts_clt = einops.rearrange(in_acts, \"b l d -> l b d\")\n", + "assert in_acts_clt.shape == (12, 7, 768), in_acts_clt.shape\n", + "\n", + "in_acts_clt = in_acts_clt.to(\"cuda:0\")\n", + "\n", + "print(in_acts_clt.shape)\n", + "print(in_acts_clt.device, in_acts_clt.dtype)\n", + "\n", + "circuit_tracer_transcoder.encode_sparse(in_acts_clt)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "6d5efd4c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([7, 12, 768])\n", + "cuda:0 torch.bfloat16\n", + "layer 0 nnz: 426\n", + "layer 1 nnz: 204\n", + "layer 2 nnz: 107\n", + "layer 3 nnz: 94\n", + "layer 4 nnz: 104\n", + "layer 5 nnz: 72\n", + "layer 6 nnz: 88\n", + "layer 7 nnz: 36\n", + "layer 8 nnz: 35\n", + "layer 9 nnz: 18\n", + "layer 10 nnz: 14\n", + "layer 11 nnz: 2\n", + "nnz features: 1200\n", + "torch.Size([12, 7, 10000])\n" + ] + }, + { + "data": { + "text/plain": [ + "{'activation_matrix': tensor(indices=tensor([[ 0, 0, 0, ..., 10, 11, 11],\n", + " [ 1, 1, 1, ..., 6, 1, 6],\n", + " [ 71, 193, 330, ..., 9154, 7738, 433]]),\n", + " values=tensor([-0.7852, 1.4062, 1.7812, ..., 1.3203, 1.1094,\n", + " 0.4297]),\n", + " device='cuda:0', size=(12, 7, 10000), nnz=1200, dtype=torch.bfloat16,\n", + " layout=torch.sparse_coo, grad_fn=),\n", + " 'reconstruction': tensor([[[-3.6621e-02, 9.7656e-02, 5.9814e-03, ..., -6.0547e-02,\n", + " -5.7373e-02, -1.0986e-01],\n", + " [-1.9531e+00, 6.2109e-01, -1.5625e+00, ..., 1.0547e+00,\n", + " 1.2939e-02, -2.5977e-01],\n", + " [ 4.8340e-02, 7.9688e-01, 1.2695e-01, ..., -6.1719e-01,\n", + " 7.6953e-01, -5.2490e-02],\n", + " ...,\n", + " [-1.9688e+00, 1.0312e+00, 4.0430e-01, ..., 2.0117e-01,\n", + " 1.2969e+00, -4.1406e-01],\n", + " [-1.1016e+00, 3.1641e-01, -2.0312e-01, ..., -1.9062e+00,\n", + " 1.0312e+00, -5.5078e-01],\n", + " [-1.2578e+00, 4.8242e-01, -1.0625e+00, ..., 1.1641e+00,\n", + " 7.5195e-02, 6.9531e-01]],\n", + " \n", + " [[-4.6875e-02, -5.6885e-02, 5.7373e-03, ..., 6.4453e-02,\n", + " 5.8350e-02, -4.2480e-02],\n", + " [-2.6758e-01, 1.1562e+00, -3.1836e-01, ..., 7.1875e-01,\n", + " 1.1406e+00, -2.3633e-01],\n", + " [-3.2471e-02, 1.0703e+00, 8.9844e-01, ..., 6.1719e-01,\n", + " 6.9922e-01, 7.5391e-01],\n", + " ...,\n", + " [-2.8076e-02, 1.0859e+00, 6.2500e-01, ..., 4.6680e-01,\n", + " 9.6484e-01, 1.4844e+00],\n", + " [-4.9219e-01, 4.0820e-01, 1.0625e+00, ..., 1.1484e+00,\n", + " 9.0625e-01, 4.1797e-01],\n", + " [-3.1445e-01, 1.3379e-01, 7.7734e-01, ..., 1.1953e+00,\n", + " 9.4922e-01, 4.7266e-01]],\n", + " \n", + " [[-1.4038e-02, -4.1016e-02, 2.8442e-02, ..., -1.6357e-02,\n", + " 1.1597e-02, -2.0752e-03],\n", + " [-3.7109e-01, 1.7969e-01, -5.2734e-01, ..., -1.5391e+00,\n", + " 1.0400e-01, 5.4297e-01],\n", + " [ 1.7773e-01, -1.6699e-01, 2.8906e-01, ..., -1.7773e-01,\n", + " 2.9492e-01, 6.0156e-01],\n", + " ...,\n", + " [-5.0391e-01, -1.6504e-01, -1.5918e-01, ..., -1.2188e+00,\n", + " 1.5137e-02, 3.7695e-01],\n", + " [-2.0508e-01, 5.4688e-01, -3.6719e-01, ..., -2.7539e-01,\n", + " -3.7109e-02, -8.1543e-02],\n", + " [-1.9727e-01, -7.0312e-01, 1.2451e-01, ..., -4.2383e-01,\n", + " -3.0664e-01, 8.9844e-02]],\n", + " \n", + " ...,\n", + " \n", + " [[ 4.8523e-03, 2.9907e-02, -2.6367e-01, ..., 1.5076e-02,\n", + " 1.1572e-01, -1.3379e-01],\n", + " [-4.5117e-01, 3.6328e-01, 8.1250e-01, ..., -3.2422e-01,\n", + " 1.5391e+00, -2.4707e-01],\n", + " [-6.1719e-01, 2.7344e-01, 1.0625e+00, ..., -2.8906e-01,\n", + " 4.3750e-01, -2.4609e-01],\n", + " ...,\n", + " [-1.4355e-01, 4.6875e-01, 2.5586e-01, ..., -2.5977e-01,\n", + " 1.8516e+00, -7.9297e-01],\n", + " [ 1.0156e+00, 3.3789e-01, 1.1250e+00, ..., 1.3477e-01,\n", + " 1.6992e-01, 8.5938e-01],\n", + " [-9.8438e-01, 8.7109e-01, -8.5938e-02, ..., -9.5703e-01,\n", + " 8.4961e-02, -9.6680e-02]],\n", + " \n", + " [[-1.5527e-01, 1.5332e-01, -2.9688e-01, ..., 6.4453e-02,\n", + " 8.1055e-02, -2.4512e-01],\n", + " [-2.2852e-01, 1.2500e-01, 1.5078e+00, ..., -2.2969e+00,\n", + " 6.4453e-01, 3.8672e-01],\n", + " [-1.9531e-03, -6.7969e-01, 1.8750e+00, ..., -4.3164e-01,\n", + " -3.2031e-01, -9.6680e-02],\n", + " ...,\n", + " [ 3.1641e-01, 1.2031e+00, 4.8438e-01, ..., -1.6328e+00,\n", + " 1.3047e+00, 7.0703e-01],\n", + " [-5.4297e-01, -3.0859e-01, 4.5312e-01, ..., -3.8477e-01,\n", + " -1.3984e+00, 3.4375e-01],\n", + " [-1.3359e+00, 8.1250e-01, -6.6406e-01, ..., 5.9375e-01,\n", + " 1.2656e+00, 2.5391e-01]],\n", + " \n", + " [[ 2.2339e-02, 3.0078e-01, -2.5195e-01, ..., 5.0049e-02,\n", + " -1.1719e-01, 8.3008e-03],\n", + " [-1.4375e+00, 9.2188e-01, 1.9219e+00, ..., 5.0391e-01,\n", + " -1.4609e+00, -1.9727e-01],\n", + " [ 4.8828e-01, -9.9609e-01, 2.1719e+00, ..., 3.1250e-01,\n", + " 1.1094e+00, 1.8164e-01],\n", + " ...,\n", + " [ 4.3359e-01, 3.9258e-01, 9.1406e-01, ..., -1.1484e+00,\n", + " -6.4844e-01, -8.6426e-02],\n", + " [ 8.8281e-01, 4.1797e-01, 1.4531e+00, ..., -1.0547e+00,\n", + " -1.4297e+00, 3.2812e-01],\n", + " [-1.0625e+00, 5.2344e-01, 1.8438e+00, ..., -7.2656e-01,\n", + " -1.0791e-01, 2.0117e-01]]], device='cuda:0', dtype=torch.bfloat16,\n", + " grad_fn=),\n", + " 'encoder_vecs': tensor([[-1.9409e-02, -1.8677e-02, -5.5420e-02, ..., 2.7222e-02,\n", + " 2.3438e-01, -2.4609e-01],\n", + " [-2.0447e-03, 3.7109e-02, 6.4697e-03, ..., -4.1797e-01,\n", + " -2.8516e-01, 6.2988e-02],\n", + " [-2.6978e-02, -1.0193e-02, 6.5613e-04, ..., -4.7656e-01,\n", + " -2.8564e-02, -1.9824e-01],\n", + " ...,\n", + " [ 2.1210e-03, 1.1520e-03, 6.0730e-03, ..., -2.9907e-03,\n", + " -1.3885e-03, 5.0964e-03],\n", + " [-2.5787e-03, 1.1826e-03, 5.6152e-03, ..., 4.8218e-03,\n", + " 5.2795e-03, 4.4861e-03],\n", + " [-1.7700e-03, 2.0695e-04, 3.0975e-03, ..., 1.2436e-03,\n", + " 5.0049e-03, -2.8839e-03]], device='cuda:0', dtype=torch.bfloat16,\n", + " grad_fn=),\n", + " 'decoder_vecs': tensor([[-0.0295, -0.0025, -0.0366, ..., 0.0030, -0.0586, 0.0383],\n", + " [ 0.0062, -0.0219, -0.0461, ..., -0.0248, -0.0233, -0.0234],\n", + " [-0.0356, -0.0102, -0.0253, ..., 0.0181, -0.0050, -0.0097],\n", + " ...,\n", + " [ 0.0645, 0.2080, 0.0251, ..., 0.2402, -0.1494, 0.2539],\n", + " [-0.6055, 0.2598, 0.0117, ..., 0.3906, -0.2422, -0.0237],\n", + " [ 0.0732, 0.1108, 0.0193, ..., 0.0023, 0.0161, 0.0840]],\n", + " device='cuda:0', dtype=torch.bfloat16, grad_fn=),\n", + " 'encoder_to_decoder_map': tensor([ 0, 0, 0, ..., 1197, 1198, 1199], device='cuda:0'),\n", + " 'decoder_locations': tensor([[ 0, 1, 2, ..., 11, 11, 11],\n", + " [ 1, 1, 1, ..., 6, 1, 6]], device='cuda:0')}" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(in_acts.shape)\n", + "print(in_acts_clt.device, in_acts_clt.dtype)\n", + "circuit_tracer_transcoder.compute_attribution_components(in_acts_clt)" + ] + }, + { + "cell_type": "markdown", + "id": "412783b9", + "metadata": {}, + "source": [ + "### Test with ReplacementModel" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "0db2198d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "12\n", + "['W_enc_0', 'b_dec_0', 'b_enc_0', 'threshold_0']\n", + "['W_enc_1', 'b_dec_1', 'b_enc_1', 'threshold_1']\n", + "['W_enc_2', 'b_dec_2', 'b_enc_2', 'threshold_2']\n", + "['W_enc_3', 'b_dec_3', 'b_enc_3', 'threshold_3']\n", + "['W_enc_4', 'b_dec_4', 'b_enc_4', 'threshold_4']\n", + "['W_enc_5', 'b_dec_5', 'b_enc_5', 'threshold_5']\n", + "['W_enc_6', 'b_dec_6', 'b_enc_6', 'threshold_6']\n", + "['W_enc_7', 'b_dec_7', 'b_enc_7', 'threshold_7']\n", + "['W_enc_8', 'b_dec_8', 'b_enc_8', 'threshold_8']\n", + "['W_enc_9', 'b_dec_9', 'b_enc_9', 'threshold_9']\n", + "['W_enc_10', 'b_dec_10', 'b_enc_10', 'threshold_10']\n", + "['W_enc_11', 'b_dec_11', 'b_enc_11', 'threshold_11']\n", + "dict_keys(['b_dec', 'b_enc', 'activation_function.threshold', 'W_enc', 'W_dec.0', 'W_dec.1', 'W_dec.2', 'W_dec.3', 'W_dec.4', 'W_dec.5', 'W_dec.6', 'W_dec.7', 'W_dec.8', 'W_dec.9', 'W_dec.10', 'W_dec.11'])\n", + "cuda:0 torch.bfloat16\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "`torch_dtype` is deprecated! Use `dtype` instead!\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "2b23ff4f5c51409d955f08b2997ef3b6", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "model.safetensors: 0%| | 0.00/548M [00:00.save_hook at 0x7ae5023fd800>, is_backward=False)), ('blocks.1.hook_resid_mid', functools.partial(.save_hook at 0x7ae5023fd800>, is_backward=False)), ('blocks.2.hook_resid_mid', functools.partial(.save_hook at 0x7ae5023fd800>, is_backward=False)), ('blocks.3.hook_resid_mid', functools.partial(.save_hook at 0x7ae5023fd800>, is_backward=False)), ('blocks.4.hook_resid_mid', functools.partial(.save_hook at 0x7ae5023fd800>, is_backward=False)), ('blocks.5.hook_resid_mid', functools.partial(.save_hook at 0x7ae5023fd800>, is_backward=False)), ('blocks.6.hook_resid_mid', functools.partial(.save_hook at 0x7ae5023fd800>, is_backward=False)), ('blocks.7.hook_resid_mid', functools.partial(.save_hook at 0x7ae5023fd800>, is_backward=False)), ('blocks.8.hook_resid_mid', functools.partial(.save_hook at 0x7ae5023fd800>, is_backward=False)), ('blocks.9.hook_resid_mid', functools.partial(.save_hook at 0x7ae5023fd800>, is_backward=False)), ('blocks.10.hook_resid_mid', functools.partial(.save_hook at 0x7ae5023fd800>, is_backward=False)), ('blocks.11.hook_resid_mid', functools.partial(.save_hook at 0x7ae5023fd800>, is_backward=False))]\n", + "torch.Size([1, 8, 50257])\n", + "dict_items([('blocks.0.hook_resid_mid', tensor([[[ 0.8292, -0.2081, 0.0887, ..., -0.0029, 0.1603, 0.3562],\n", + " [-0.1627, 0.2027, -0.5368, ..., 0.0968, -0.0061, 0.1409],\n", + " [-0.3465, 0.0869, -0.5563, ..., 0.1135, -0.0570, 0.1199],\n", + " ...,\n", + " [-0.1875, 0.4008, -0.3190, ..., -0.1480, 0.0055, 0.0641],\n", + " [ 1.6809, 0.5578, -0.5070, ..., -0.1841, 0.2872, 0.2613],\n", + " [ 0.6528, 0.3823, -0.1777, ..., 0.0927, -0.0343, -0.0222]]],\n", + " device='cuda:0')), ('blocks.1.hook_resid_mid', tensor([[[ 0.7366, 0.2633, 0.8380, ..., 1.7356, 1.5534, 0.6067],\n", + " [-0.5045, -0.0267, -0.7114, ..., -0.1848, -0.7491, 0.1695],\n", + " [-1.7334, 0.7541, -1.7714, ..., 1.5820, -1.9192, 0.4845],\n", + " ...,\n", + " [-1.0849, 1.4963, -0.1123, ..., 0.4767, 0.3309, -0.0391],\n", + " [ 2.0111, 0.8939, -1.4627, ..., -1.8787, 0.2278, -0.1587],\n", + " [ 0.0421, 0.7707, -0.8557, ..., 1.4787, -0.7605, 0.9899]]],\n", + " device='cuda:0')), ('blocks.2.hook_resid_mid', tensor([[[ 0.1488, -0.0781, 0.5468, ..., 1.6689, 1.4880, 0.7661],\n", + " [-0.8259, -0.2939, -0.8941, ..., -0.2092, -1.2692, -0.1108],\n", + " [-1.8970, 1.6090, -1.9269, ..., 1.9306, -1.9026, -0.4079],\n", + " ...,\n", + " [-1.1005, 1.7253, -0.0383, ..., 0.5634, 0.8792, 0.7951],\n", + " [ 1.4697, 0.5930, -1.6843, ..., -1.3790, 0.4047, -0.5614],\n", + " [ 0.2322, 0.4183, -0.6936, ..., 1.5644, -0.6832, 1.2189]]],\n", + " device='cuda:0')), ('blocks.3.hook_resid_mid', tensor([[[ 0.0661, -0.1998, 0.5140, ..., 1.4456, 1.4002, 0.6470],\n", + " [-1.0289, -0.3439, -0.1235, ..., -0.2292, -1.3801, 0.0214],\n", + " [-2.1646, 2.4593, -1.8518, ..., 1.1662, -2.2947, -0.1005],\n", + " ...,\n", + " [-1.3023, 1.3682, 1.3973, ..., -0.0248, 1.2654, 1.1106],\n", + " [ 0.9751, 1.2863, -1.5901, ..., -1.4095, 0.1266, -0.3963],\n", + " [ 0.2027, 0.0645, 0.2270, ..., 1.8477, -1.4379, 1.0276]]],\n", + " device='cuda:0')), ('blocks.4.hook_resid_mid', tensor([[[-0.0580, -0.3595, 0.4574, ..., 1.3160, 1.2230, 0.6406],\n", + " [-2.1363, -0.6073, 0.0711, ..., 0.4583, -1.1995, 0.7196],\n", + " [-3.6694, 1.7980, -3.0582, ..., 2.2501, -3.4340, 0.4635],\n", + " ...,\n", + " [-1.6586, 0.7425, 0.8882, ..., 1.1538, 0.6740, 1.4706],\n", + " [ 0.9481, 1.3355, -2.4056, ..., -1.7796, -0.1907, -0.4598],\n", + " [-0.3690, 0.3992, -0.0730, ..., 2.2794, -1.3240, 1.2353]]],\n", + " device='cuda:0')), ('blocks.5.hook_resid_mid', tensor([[[-0.1437, -0.3980, 0.4653, ..., 1.2557, 1.1286, 0.5841],\n", + " [-2.2264, -0.4958, 0.1818, ..., 0.8170, -1.5775, 1.1018],\n", + " [-4.1140, 2.5474, -3.6180, ..., 1.9292, -4.2118, 0.7760],\n", + " ...,\n", + " [-2.2961, 1.4702, 1.1608, ..., 1.1624, 0.2801, 1.7627],\n", + " [ 0.7102, 1.5051, -2.4009, ..., -1.0501, -0.9454, -0.8125],\n", + " [ 0.1730, 0.4505, 0.5230, ..., 3.3662, -0.8115, 1.7597]]],\n", + " device='cuda:0')), ('blocks.6.hook_resid_mid', tensor([[[-0.1418, -0.3710, 0.5526, ..., 1.1364, 1.0140, 0.5661],\n", + " [-2.5741, -0.4803, 0.4509, ..., 1.0593, -1.5936, 0.7250],\n", + " [-4.1928, 2.8387, -4.2037, ..., 2.6937, -3.5340, 0.7354],\n", + " ...,\n", + " [-1.9225, 0.5152, 0.6427, ..., 1.6845, -0.2169, 2.0397],\n", + " [ 1.4380, 1.3117, -1.7126, ..., -0.9297, -0.0077, -0.7019],\n", + " [-0.1650, 0.4262, 0.3057, ..., 4.4950, -1.5823, 2.7732]]],\n", + " device='cuda:0')), ('blocks.7.hook_resid_mid', tensor([[[-0.2448, -0.2811, 0.5022, ..., 1.1156, 0.8833, 0.3835],\n", + " [-2.4570, 0.8735, 0.5153, ..., 0.5349, -2.2505, -0.0874],\n", + " [-6.9050, 4.1731, -3.5826, ..., 3.0283, -4.0174, 0.5070],\n", + " ...,\n", + " [-1.6423, 0.6971, -0.2637, ..., 1.0385, 0.8479, 3.1449],\n", + " [ 2.2448, 0.6985, -2.0658, ..., -1.3574, -0.2864, -0.4600],\n", + " [-0.5407, 1.7449, -0.9142, ..., 4.4162, -0.3360, 4.1052]]],\n", + " device='cuda:0')), ('blocks.8.hook_resid_mid', tensor([[[-0.2317, -0.1742, 0.4076, ..., 1.2093, 0.9779, 0.3468],\n", + " [-2.3272, 0.8944, 1.0235, ..., 0.7030, -1.8648, -0.9032],\n", + " [-7.0494, 5.2281, -4.1065, ..., 2.0068, -4.1265, 0.3011],\n", + " ...,\n", + " [-1.0423, 0.8841, -0.8168, ..., 0.7086, 1.1515, 2.5642],\n", + " [ 2.4226, 0.2734, -2.7923, ..., -2.6671, 0.6658, 0.2542],\n", + " [-0.1577, 2.4592, -1.3308, ..., 3.5287, -1.5098, 5.1052]]],\n", + " device='cuda:0')), ('blocks.9.hook_resid_mid', tensor([[[-0.2822, -0.0332, 0.3085, ..., 1.3752, 0.9603, 0.0852],\n", + " [-2.3929, 0.8874, 1.0884, ..., 1.0155, -1.2947, -1.3692],\n", + " [-7.3202, 5.6661, -5.4029, ..., 2.8207, -4.6241, 0.1844],\n", + " ...,\n", + " [-1.2294, 2.5105, -1.7207, ..., 0.9849, 2.8533, 3.4939],\n", + " [ 2.6443, 0.1823, -2.7417, ..., -1.1531, 0.9782, 1.3396],\n", + " [-0.3001, 3.6369, -0.4387, ..., 3.9318, -0.6444, 4.0109]]],\n", + " device='cuda:0')), ('blocks.10.hook_resid_mid', tensor([[[-2.9332e-01, 2.8656e-02, -8.5813e-04, ..., 1.3900e+00,\n", + " 1.1820e+00, -1.1640e-01],\n", + " [-2.4854e+00, 7.7822e-01, 2.2521e+00, ..., -1.2356e-01,\n", + " -2.6242e-01, -2.2910e+00],\n", + " [-8.0578e+00, 4.5745e+00, -7.5444e+00, ..., 2.7251e+00,\n", + " -4.2399e+00, -1.0159e+00],\n", + " ...,\n", + " [-2.2039e+00, 3.8935e+00, -1.7146e+00, ..., 1.6282e+00,\n", + " 5.3636e+00, 1.2540e+00],\n", + " [ 2.9170e+00, 2.3938e+00, -2.3362e+00, ..., 1.7417e-03,\n", + " 9.3079e-01, 2.0680e+00],\n", + " [-1.1518e+00, 4.4683e+00, -3.3433e+00, ..., 3.5590e+00,\n", + " -1.9450e-01, 4.3937e+00]]], device='cuda:0')), ('blocks.11.hook_resid_mid', tensor([[[-0.3818, 0.0473, -0.4384, ..., 1.5397, 1.6579, -0.2553],\n", + " [-2.4054, 0.1560, 3.3125, ..., 0.1850, 0.5278, -2.4760],\n", + " [-9.4641, 4.7007, -6.5114, ..., 2.8988, -4.4499, -1.5477],\n", + " ...,\n", + " [ 1.4269, 3.2414, 0.5623, ..., 1.0460, 5.8567, -1.0748],\n", + " [ 2.2601, 1.4785, -2.1479, ..., 1.0913, -0.9739, 2.9741],\n", + " [-1.4892, 4.4865, -4.1967, ..., 4.0651, 1.1076, 4.7898]]],\n", + " device='cuda:0'))])\n", + "cuda:0 torch.float32\n" + ] + } + ], + "source": [ + "\n", + "if isinstance(prompt, str):\n", + " tokens = rm.ensure_tokenized(prompt)\n", + "else:\n", + " tokens = prompt.squeeze()\n", + "# COuld it be the caching hooks?\n", + "mlp_in_cache, mlp_in_caching_hooks, _ = rm.get_caching_hooks(\n", + " lambda name: rm.feature_input_hook in name\n", + ")\n", + "print(mlp_in_caching_hooks)\n", + "\n", + "mlp_out_cache, mlp_out_caching_hooks, _ = rm.get_caching_hooks(\n", + " lambda name: rm.feature_output_hook in name\n", + ")\n", + "logits = rm.run_with_hooks(tokens, fwd_hooks=mlp_in_caching_hooks + mlp_out_caching_hooks)\n", + "print(logits.shape)\n", + "\n", + "\n", + "print(mlp_in_cache.items())\n", + "\n", + "mlp_in_cache = torch.cat(list(mlp_in_cache.values()), dim=0)\n", + "mlp_out_cache = torch.cat(list(mlp_out_cache.values()), dim=0)\n", + "print(mlp_in_cache.device, mlp_in_cache.dtype)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "ab63b8c4", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "You're using a GPT2TokenizerFast tokenizer. Please note that with a fast tokenizer, using the `__call__` method is faster than using a method to encode the text followed by a call to the `pad` method to get a padded encoding.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([12, 8, 768])\n" + ] + } + ], + "source": [ + "nnsight_acts = []\n", + "with llm.trace(tokens) as trace:\n", + " for layer in range(12):\n", + " layer_activations = llm.transformer.h[layer].ln_2.input.save()\n", + " nnsight_acts.append(layer_activations.squeeze(0))\n", + "\n", + "nnsight_acts = torch.stack(nnsight_acts, dim=0)\n", + "\n", + "print(nnsight_acts.shape)\n", + "nnsight_acts = nnsight_acts.to(\"cuda:0\").to(torch.bfloat16)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "0ef9ad21", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "cuda:0 torch.bfloat16\n" + ] + } + ], + "source": [ + "mlp_in_cache = mlp_in_cache.to(\"cuda:0\").to(torch.bfloat16)\n", + "print(mlp_in_cache.device, mlp_in_cache.dtype)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "1d9f797e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([8, 768]) torch.Size([8, 768])\n", + "cuda:0 cuda:0\n", + "torch.bfloat16 torch.bfloat16\n", + "nans?: False, False\n", + "max diff: 0.001953125\n", + "----------------------------------------------------------------------------------------------------\n", + "torch.Size([8, 768]) torch.Size([8, 768])\n", + "cuda:0 cuda:0\n", + "torch.bfloat16 torch.bfloat16\n", + "nans?: False, False\n", + "max diff: 0.000244140625\n", + "----------------------------------------------------------------------------------------------------\n", + "torch.Size([8, 768]) torch.Size([8, 768])\n", + "cuda:0 cuda:0\n", + "torch.bfloat16 torch.bfloat16\n", + "nans?: False, False\n", + "max diff: 0.0009765625\n", + "----------------------------------------------------------------------------------------------------\n", + "torch.Size([8, 768]) torch.Size([8, 768])\n", + "cuda:0 cuda:0\n", + "torch.bfloat16 torch.bfloat16\n", + "nans?: False, False\n", + "max diff: 0.0\n", + "----------------------------------------------------------------------------------------------------\n", + "torch.Size([8, 768]) torch.Size([8, 768])\n", + "cuda:0 cuda:0\n", + "torch.bfloat16 torch.bfloat16\n", + "nans?: False, False\n", + "max diff: 0.015625\n", + "----------------------------------------------------------------------------------------------------\n", + "torch.Size([8, 768]) torch.Size([8, 768])\n", + "cuda:0 cuda:0\n", + "torch.bfloat16 torch.bfloat16\n", + "nans?: False, False\n", + "max diff: 0.015625\n", + "----------------------------------------------------------------------------------------------------\n", + "torch.Size([8, 768]) torch.Size([8, 768])\n", + "cuda:0 cuda:0\n", + "torch.bfloat16 torch.bfloat16\n", + "nans?: False, False\n", + "max diff: 0.00048828125\n", + "----------------------------------------------------------------------------------------------------\n", + "torch.Size([8, 768]) torch.Size([8, 768])\n", + "cuda:0 cuda:0\n", + "torch.bfloat16 torch.bfloat16\n", + "nans?: False, False\n", + "max diff: 0.0078125\n", + "----------------------------------------------------------------------------------------------------\n", + "torch.Size([8, 768]) torch.Size([8, 768])\n", + "cuda:0 cuda:0\n", + "torch.bfloat16 torch.bfloat16\n", + "nans?: False, False\n", + "max diff: 0.0078125\n", + "----------------------------------------------------------------------------------------------------\n", + "torch.Size([8, 768]) torch.Size([8, 768])\n", + "cuda:0 cuda:0\n", + "torch.bfloat16 torch.bfloat16\n", + "nans?: False, False\n", + "max diff: 0.015625\n", + "----------------------------------------------------------------------------------------------------\n", + "torch.Size([8, 768]) torch.Size([8, 768])\n", + "cuda:0 cuda:0\n", + "torch.bfloat16 torch.bfloat16\n", + "nans?: False, False\n", + "max diff: 0.015625\n", + "----------------------------------------------------------------------------------------------------\n", + "torch.Size([8, 768]) torch.Size([8, 768])\n", + "cuda:0 cuda:0\n", + "torch.bfloat16 torch.bfloat16\n", + "nans?: False, False\n", + "max diff: 0.015625\n", + "----------------------------------------------------------------------------------------------------\n" + ] + } + ], + "source": [ + "## TEST Difference between nnsight and TL activations\n", + "for i in range(12):\n", + " print(nnsight_acts[i].shape, mlp_in_cache[i].shape)\n", + " print(nnsight_acts[i].device, mlp_in_cache[i].device)\n", + " print(nnsight_acts[i].dtype, mlp_in_cache[i].dtype)\n", + " print(f\"nans?: {torch.isnan(nnsight_acts[i]).any()}, {torch.isnan(mlp_in_cache[i]).any()}\")\n", + " print(f\"max diff: {(nnsight_acts[i] - mlp_in_cache[i]).abs().max().item()}\")\n", + " print(\"-\"*100)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "3187e1a3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([12, 8, 768]) cuda:0 torch.bfloat16\n", + "torch.Size([12, 8, 768]) cuda:0 torch.bfloat16\n", + "layer 0 nnz: 467\n", + "layer 1 nnz: 241\n", + "layer 2 nnz: 130\n", + "layer 3 nnz: 108\n", + "layer 4 nnz: 107\n", + "layer 5 nnz: 66\n", + "layer 6 nnz: 88\n", + "layer 7 nnz: 42\n", + "layer 8 nnz: 31\n", + "layer 9 nnz: 18\n", + "layer 10 nnz: 12\n", + "layer 11 nnz: 1\n", + "nnz features: 1311\n", + "torch.Size([12, 8, 10000])\n", + "layer 0 nnz: 467\n", + "layer 1 nnz: 241\n", + "layer 2 nnz: 130\n", + "layer 3 nnz: 108\n", + "layer 4 nnz: 107\n", + "layer 5 nnz: 66\n", + "layer 6 nnz: 88\n", + "layer 7 nnz: 42\n", + "layer 8 nnz: 31\n", + "layer 9 nnz: 18\n", + "layer 10 nnz: 12\n", + "layer 11 nnz: 1\n", + "nnz features: 1311\n", + "torch.Size([12, 8, 10000])\n" + ] + } + ], + "source": [ + "print(nnsight_acts.shape, nnsight_acts.device, nnsight_acts.dtype)\n", + "print(mlp_in_cache.shape, mlp_in_cache.device, mlp_in_cache.dtype)\n", + "attribution_data_a = circuit_tracer_transcoder.compute_attribution_components(nnsight_acts)\n", + "attribution_data_c = circuit_tracer_transcoder.compute_attribution_components(mlp_in_cache)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "8e4d00ff", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "cuda:0 torch.float32\n" + ] + }, + { + "ename": "RuntimeError", + "evalue": "expected scalar type BFloat16 but found Float", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mRuntimeError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[20]\u001b[39m\u001b[32m, line 2\u001b[39m\n\u001b[32m 1\u001b[39m \u001b[38;5;28mprint\u001b[39m(circuit_tracer_transcoder_copy.device, circuit_tracer_transcoder_copy.dtype)\n\u001b[32m----> \u001b[39m\u001b[32m2\u001b[39m attribution_data_e = \u001b[43mcircuit_tracer_transcoder_copy\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcompute_attribution_components\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmlp_in_cache\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 3\u001b[39m attribution_data_e = circuit_tracer_transcoder_copy.compute_attribution_components(in_acts_clt)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/transcoder/cross_layer_transcoder.py:306\u001b[39m, in \u001b[36mCrossLayerTranscoder.compute_attribution_components\u001b[39m\u001b[34m(self, inputs)\u001b[39m\n\u001b[32m 292\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mcompute_attribution_components\u001b[39m(\u001b[38;5;28mself\u001b[39m, inputs):\n\u001b[32m 293\u001b[39m \u001b[38;5;250m \u001b[39m\u001b[33;03m\"\"\"Extract active features and their encoder/decoder vectors for attribution.\u001b[39;00m\n\u001b[32m 294\u001b[39m \n\u001b[32m 295\u001b[39m \u001b[33;03m Args:\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 304\u001b[39m \u001b[33;03m - encoder_to_decoder_map: Mapping from encoder to decoder indices\u001b[39;00m\n\u001b[32m 305\u001b[39m \u001b[33;03m \"\"\"\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m306\u001b[39m features, encoder_vectors = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mencode_sparse\u001b[49m\u001b[43m(\u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mzero_first_pos\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m)\u001b[49m\n\u001b[32m 307\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mnnz features: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfeatures._nnz()\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m)\n\u001b[32m 308\u001b[39m pos_ids, layer_ids, feat_ids, decoder_vectors, encoder_to_decoder_map = (\n\u001b[32m 309\u001b[39m \u001b[38;5;28mself\u001b[39m.select_decoder_vectors(features)\n\u001b[32m 310\u001b[39m )\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/circuit-tracer/circuit_tracer/transcoder/cross_layer_transcoder.py:193\u001b[39m, in \u001b[36mCrossLayerTranscoder.encode_sparse\u001b[39m\u001b[34m(self, x, zero_first_pos)\u001b[39m\n\u001b[32m 190\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m layer_id \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(\u001b[38;5;28mself\u001b[39m.n_layers):\n\u001b[32m 191\u001b[39m W_enc_layer = \u001b[38;5;28mself\u001b[39m._get_encoder_weights(layer_id)\n\u001b[32m 192\u001b[39m layer_features = (\n\u001b[32m--> \u001b[39m\u001b[32m193\u001b[39m \u001b[43mtorch\u001b[49m\u001b[43m.\u001b[49m\u001b[43meinsum\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mbd,fd->bf\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mx\u001b[49m\u001b[43m[\u001b[49m\u001b[43mlayer_id\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mW_enc_layer\u001b[49m\u001b[43m)\u001b[49m + \u001b[38;5;28mself\u001b[39m.b_enc[layer_id]\n\u001b[32m 194\u001b[39m )\n\u001b[32m 195\u001b[39m layer_features = \u001b[38;5;28mself\u001b[39m.apply_activation_function(layer_id, layer_features)\n\u001b[32m 196\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m zero_first_pos:\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/crosslayer-transcoder/.venv/lib/python3.12/site-packages/torch/functional.py:373\u001b[39m, in \u001b[36meinsum\u001b[39m\u001b[34m(*args)\u001b[39m\n\u001b[32m 368\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m einsum(equation, *_operands)\n\u001b[32m 370\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(operands) <= \u001b[32m2\u001b[39m \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m opt_einsum.enabled:\n\u001b[32m 371\u001b[39m \u001b[38;5;66;03m# the path for contracting 0 or 1 time(s) is already optimized\u001b[39;00m\n\u001b[32m 372\u001b[39m \u001b[38;5;66;03m# or the user has disabled using opt_einsum\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m373\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_VF\u001b[49m\u001b[43m.\u001b[49m\u001b[43meinsum\u001b[49m\u001b[43m(\u001b[49m\u001b[43mequation\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43moperands\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;66;03m# type: ignore[attr-defined]\u001b[39;00m\n\u001b[32m 375\u001b[39m path = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m 376\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m opt_einsum.is_available():\n", + "\u001b[31mRuntimeError\u001b[39m: expected scalar type BFloat16 but found Float" + ] + } + ], + "source": [ + "print(circuit_tracer_transcoder_copy.device, circuit_tracer_transcoder_copy.dtype)\n", + "attribution_data_e = circuit_tracer_transcoder_copy.compute_attribution_components(mlp_in_cache)\n", + "attribution_data_e = circuit_tracer_transcoder_copy.compute_attribution_components(in_acts_clt)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "48295bb6", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "attribution_data = rm.transcoders.compute_attribution_components(mlp_in_cache)" + ] + }, + { + "cell_type": "markdown", + "id": "4983b9eb", + "metadata": {}, + "source": [ + "### Attribution test" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9f9ea5c4", + "metadata": {}, + "outputs": [], + "source": [ + "max_n_logits = 10 # How many logits to attribute from, max. We attribute to min(max_n_logits, n_logits_to_reach_desired_log_prob); see below for the latter\n", + "desired_logit_prob = 0.95 # Attribution will attribute from the minimum number of logits needed to reach this probability mass (or max_n_logits, whichever is lower)\n", + "max_feature_nodes = 100 # Only attribute from this number of feature nodes, max. Lower is faster, but you will lose more of the graph. None means no limit.\n", + "batch_size = 256 // 8 # Batch size when attributing\n", + "offload = \"cpu\" # Offload various parts of the model during attribution to save memory. Can be 'disk', 'cpu', or None (keep on GPU)\n", + "verbose = True # Whether to display a tqdm progress bar and timing report\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "93c54601", + "metadata": {}, + "outputs": [], + "source": [ + "from pathlib import Path\n", + "import torch\n", + "\n", + "from circuit_tracer import ReplacementModel, attribute\n", + "from circuit_tracer.utils import create_graph_files\n", + "\n", + "torch.cuda.empty_cache()\n", + "\n", + "# FOr some reason this takes up a lot of VRAM\n", + "graph = attribute(\n", + " prompt=prompt,\n", + " model=rm,\n", + " max_n_logits=max_n_logits,\n", + " desired_logit_prob=desired_logit_prob,\n", + " batch_size=batch_size,\n", + " max_feature_nodes=max_feature_nodes,\n", + " offload=offload,\n", + " verbose=verbose,\n", + ")\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c454ee0b", + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/pyproject.toml b/pyproject.toml index 67f93cf..e89fce0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,7 +24,7 @@ dependencies = [ "numpy>=1.24.0", "jsonargparse[signatures]>=4.27.7", "modal>=1.1.4", - "circuit-tracer@git+https://github.com/safety-research/circuit-tracer.git@main", + "circuit-tracer", "hf-transfer>=0.1.9", ] @@ -47,6 +47,9 @@ dev-dependencies = [ "pytest>=8.4.1", ] +[tool.uv.sources] +circuit-tracer = { git = "https://github.com/safety-research/circuit-tracer.git", rev = "main" } + [tool.hatch.metadata] allow-direct-references=true diff --git a/uv.lock b/uv.lock index 8dd4d48..fc6fd6f 100644 --- a/uv.lock +++ b/uv.lock @@ -422,7 +422,7 @@ dev = [ [package.metadata] requires-dist = [ { name = "circuit-tracer", git = "https://github.com/safety-research/circuit-tracer.git?rev=main" }, - { name = "circuit-tracer", marker = "extra == 'dev'" }, + { name = "circuit-tracer", marker = "extra == 'dev'", git = "https://github.com/safety-research/circuit-tracer.git?rev=main" }, { name = "datasets", specifier = "==3.6.0" }, { name = "einops", specifier = ">=0.8.1" }, { name = "h5py", specifier = ">=3.13.0" }, From fec1d0ee3d0f122c4b3dfd1b110cc152f025df8a Mon Sep 17 00:00:00 2001 From: jiito Date: Mon, 17 Nov 2025 17:16:47 +0000 Subject: [PATCH 73/99] save titles --- crosslayer_transcoder/utils/replacement_score.ipynb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/crosslayer_transcoder/utils/replacement_score.ipynb b/crosslayer_transcoder/utils/replacement_score.ipynb index d54874e..a56a4e6 100644 --- a/crosslayer_transcoder/utils/replacement_score.ipynb +++ b/crosslayer_transcoder/utils/replacement_score.ipynb @@ -263,17 +263,24 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "id": "4008f230", "metadata": {}, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "replacement score, completeness score\n" + ] + }, { "data": { "text/plain": [ "(0.7424161434173584, 0.919729471206665)" ] }, - "execution_count": 9, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } From d4945785864fe85dbf5934db0cc8a323751269f4 Mon Sep 17 00:00:00 2001 From: jiito Date: Mon, 17 Nov 2025 09:39:42 -0800 Subject: [PATCH 74/99] restore util file --- crosslayer_transcoder/utils/utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/crosslayer_transcoder/utils/utils.py b/crosslayer_transcoder/utils/utils.py index ce90582..3f38020 100644 --- a/crosslayer_transcoder/utils/utils.py +++ b/crosslayer_transcoder/utils/utils.py @@ -56,4 +56,3 @@ def plot_actvs(actvs): # Adjust layout to prevent overlap plt.tight_layout() - From 0b2a114dc25c37dc658423a468433038a17dc773 Mon Sep 17 00:00:00 2001 From: jiito Date: Mon, 17 Nov 2025 09:48:23 -0800 Subject: [PATCH 75/99] restore formatting --- config/debug.yaml | 162 ---------------------------- config/topk-clt-debug.yaml | 163 ----------------------------- crosslayer_transcoder/model/clt.py | 81 +++----------- 3 files changed, 14 insertions(+), 392 deletions(-) delete mode 100644 config/debug.yaml delete mode 100644 config/topk-clt-debug.yaml diff --git a/config/debug.yaml b/config/debug.yaml deleted file mode 100644 index d5d41ad..0000000 --- a/config/debug.yaml +++ /dev/null @@ -1,162 +0,0 @@ -# Default configuration for CrossLayer Transcoder training -# This file uses Lightning CLI's automatic class construction - -seed_everything: 42 - -trainer: - # max_steps is number of gradient updates. If using gradient accumulation, this is not the number of batches. - max_steps: 10 - val_check_interval: 1 - limit_val_batches: 1 - enable_checkpointing: false # We use custom end-of-training checkpoint - num_sanity_val_steps: 0 # Can't run replacement model before standardizers are initialized - precision: "16-mixed" - accelerator: "gpu" - devices: [0] # [0] means cuda:0 - accumulate_grad_batches: 1 - logger: # WandB logger is recommended but other loggers are supported as well - class_path: lightning.pytorch.loggers.WandbLogger - init_args: - project: "clt" - name: "jumprelu" - save_dir: "./wandb" - callbacks: - - class_path: crosslayer_transcoder.utils.callbacks.EndOfTrainingCheckpointCallback - init_args: - checkpoint_dir: "checkpoints" - -model: - class_path: crosslayer_transcoder.model.clt_lightning.JumpReLUCrossLayerTranscoderModule - init_args: - model: - class_path: crosslayer_transcoder.model.clt.CrossLayerTranscoder - init_args: - encoder: - class_path: crosslayer_transcoder.model.clt.Encoder - init_args: - d_acts: 768 - d_features: 10_000 - n_layers: 12 - - decoder: - class_path: crosslayer_transcoder.model.clt.CrosslayerDecoder - init_args: - d_acts: 768 - d_features: 10_000 - n_layers: 12 - - nonlinearity: - class_path: crosslayer_transcoder.model.jumprelu.JumpReLU - init_args: - theta: 0.03 - bandwidth: 0.01 - n_layers: 12 - d_features: 10_000 - - input_standardizer: - class_path: crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer - init_args: - n_layers: 12 - activation_dim: 768 - - output_standardizer: - class_path: crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer - init_args: - n_layers: 12 - activation_dim: 768 - - # Pre-constructed replacement model - replacement_model: - class_path: crosslayer_transcoder.metrics.replacement_model_accuracy.ReplacementModelAccuracy - init_args: - model_name: "openai-community/gpt2" - device_map: "cuda:0" # should match trainer.devices - loader_batch_size: 2 - - # Pre-constructed dead features metric - dead_features: - class_path: crosslayer_transcoder.metrics.dead_features.DeadFeatures - init_args: - n_features: 10_000 - n_layers: 12 - return_per_layer: true - return_log_freqs: true - return_neuron_indices: true - - - # Training parameters - learning_rate: 1e-4 - compile: true # if using torch.compile - lr_decay_step: 80_000 # lr is scaled by lr_decay_factor after this many steps - lr_decay_factor: 0.1 - - lambda_sparsity: 0.0007 # sparsity loss weight - c_sparsity: 1 # sparsity loss coefficient - use_tanh: true # use tanh nonlinearity in the JumpReLU - pre_actv_loss: 1e-6 # pre-activation loss weight - - # Dead features computation settings - compute_dead_features: true - compute_dead_features_every: 500 - -data: - class_path: crosslayer_transcoder.data.datamodule.ActivationDataModule - init_args: - # Buffer settings - buffer_size: 100 # number of activations to store in the buffer - n_in_out: 2 # number of input and output layers - n_layers: 12 # number of layers in the model - activation_dim: 768 # dimension of the activations - dtype: "float16" # dtype of the activations - max_batch_size: 10 # maximum batch size for the data loader - - # Model settings for activation generation - model_name: "openai-community/gpt2" - model_dtype: "float32" - - # Dataset settings - dataset_name: "Skylion007/openwebtext" - dataset_split: "train" - max_sequence_length: 1024 - - # Generation settings - generation_batch_size: 10 - refresh_interval: 0.1 # time (s) between shell logs updates - - # Memory settings - shared_memory_name: "activation_buffer" - timeout_seconds: 30 - - # File paths - init_file: null # path to file with shuffled activations to initialize the buffer fast - # if null, activations are generated and training starts when the buffer is at least minimum_fill_threshold full - - # DataLoader settings - batch_size: 10 - num_workers: 1 - prefetch_factor: 2 - shuffle: true - persistent_workers: true - pin_memory: true - - minimum_fill_threshold: 0.2 # Only provide activations when buffer is at least 20% full - # to maintain sufficient shuffling - - use_shared_memory: true - - # Device configuration - device_map: "cuda:0" # "cpu", "auto", "cuda:0", "cuda:0,1,2,3" - deployment_policy: "gpu_only" # "cpu_only", "gpu_only", or "dynamic" - # dynamic will use CPU and only GPU if the buffer is almost empty to refill fast. Use this if you use a single GPU and have a beefy CPU. - - # WandB logging configuration for data generation - wandb_logging: - enabled: true # Enable WandB logging for data generation - project: "clt" # WandB project (should match trainer logger) - group: null # Group name (null = auto-generated from training run) - run_name: "debug" # Run name suffix - tags: ["debug"] # Tags for the data generation run - save_dir: "./wandb" # Directory for WandB files - log_interval: 5.0 # Logging interval in seconds - -ckpt_path: null \ No newline at end of file diff --git a/config/topk-clt-debug.yaml b/config/topk-clt-debug.yaml deleted file mode 100644 index 9d643ce..0000000 --- a/config/topk-clt-debug.yaml +++ /dev/null @@ -1,163 +0,0 @@ -# Configuration for TopK CrossLayer Transcoder training with auxiliary loss -# This file uses Lightning CLI's automatic class construction for TopK-based CLTs - -seed_everything: 42 - -trainer: - # max_steps is number of gradient updates. If using gradient accumulation, this is not the number of batches. - max_steps: 20_000 # 20M tokens - val_check_interval: 1_000 - limit_val_batches: 1 - enable_checkpointing: false # We use custom end-of-training checkpoint - num_sanity_val_steps: 0 # Can't run replacement model before standardizers are initialized - precision: "16-mixed" - accelerator: "gpu" - # TODO: this is kinda brittle from a UX perspective - devices: [0] # [1] for cuda:1 - accumulate_grad_batches: 1 - logger: # WandB logger is recommended but other loggers are supported as well - class_path: lightning.pytorch.loggers.WandbLogger - init_args: - project: "clt" - name: "topk-aux" - save_dir: "./wandb" - callbacks: - - class_path: crosslayer_transcoder.utils.callbacks.EndOfTrainingCheckpointCallback - init_args: - checkpoint_dir: "checkpoints" - -model: - class_path: crosslayer_transcoder.model.clt_lightning.TopKCrossLayerTranscoderModule - init_args: - model: - class_path: crosslayer_transcoder.model.clt.CrossLayerTranscoder - init_args: - encoder: - class_path: crosslayer_transcoder.model.clt.Encoder - init_args: - d_acts: 768 - d_features: 10_000 # 768 * 26 (larger feature dictionary for TopK) - n_layers: 12 - - decoder: - class_path: crosslayer_transcoder.model.clt.CrosslayerDecoder - init_args: - d_acts: 768 - d_features: 10_000 # 768 * 26 (larger feature dictionary for TopK) - n_layers: 12 - - nonlinearity: - class_path: crosslayer_transcoder.model.topk.PerLayerTopK - init_args: - k: 16 # Number of top features to keep per layer - - input_standardizer: - class_path: crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer - init_args: - n_layers: 12 - activation_dim: 768 - - output_standardizer: - class_path: crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer - init_args: - n_layers: 12 - activation_dim: 768 - - # Pre-constructed replacement model - replacement_model: - class_path: crosslayer_transcoder.metrics.replacement_model_accuracy.ReplacementModelAccuracy - init_args: - model_name: "openai-community/gpt2" - # TODO: this is kinda brittle from a UX perspective - device_map: "cuda:0" # should match trainer.devices - loader_batch_size: 2 - - # Pre-constructed dead features metric - dead_features: - class_path: crosslayer_transcoder.metrics.dead_features.DeadFeatures - init_args: - n_features: 10_000 - n_layers: 12 - return_per_layer: true - return_log_freqs: true - return_neuron_indices: true - - # Training parameters - learning_rate: 3e-4 - compile: true # if using torch.compile - lr_decay_step: 16_000 # lr is scaled by lr_decay_factor after this many steps - lr_decay_factor: 0.1 - - # TopK auxiliary loss configuration - topk_aux: - class_path: crosslayer_transcoder.model.topk.PerLayerTopK - init_args: - k: 512 # Number of top features to keep per layer for auxiliary loss - tokens_till_dead: 500_000 # Tokens to process before computing dead features - aux_loss_scale: 0.03125 # Scaling factor for auxiliary loss - - # Dead features computation settings - compute_dead_features: true - compute_dead_features_every: 500 - -data: - class_path: crosslayer_transcoder.data.datamodule.ActivationDataModule - init_args: - # Buffer settings - buffer_size: 3_000_000 # number of activations to store in the buffer - n_in_out: 2 # number of input and output layers - n_layers: 12 # number of layers in the model - activation_dim: 768 # dimension of the activations - dtype: "float16" # dtype of the activations - max_batch_size: 50000 # maximum batch size for the data loader - - # Model settings for activation generation - model_name: "openai-community/gpt2" - model_dtype: "float32" - - # Dataset settings - dataset_name: "Skylion007/openwebtext" - dataset_split: "train" - max_sequence_length: 1024 - - # Generation settings - generation_batch_size: 10 - refresh_interval: 0.1 # time (s) between shell logs updates - - # Memory settings - shared_memory_name: "activation_buffer" - timeout_seconds: 30 - - # File paths - init_file: null # path to file with shuffled activations to initialize the buffer fast - # if null, activations are generated and training starts when the buffer is at least minimum_fill_threshold full - - # DataLoader settings - batch_size: 1000 - num_workers: 10 - prefetch_factor: 2 - shuffle: true - persistent_workers: true - pin_memory: true - - minimum_fill_threshold: 0.2 # Only provide activations when buffer is at least 20% full - # to maintain sufficient shuffling - - use_shared_memory: true - - # Device configuration - device_map: "cuda:0" # "cpu", "auto", "cuda:0", "cuda:0,1,2,3" - deployment_policy: "gpu_only" # "cpu_only", "gpu_only", or "dynamic" - # dynamic will use CPU and only GPU if the buffer is almost empty to refill fast. Use this if you use a single GPU and have a beefy CPU. - - # WandB logging configuration for data generation - wandb_logging: - enabled: true # Enable WandB logging for data generation - project: "clt" # WandB project (should match trainer logger) - group: null # Group name (null = auto-generated from training run) - run_name: "data-generator-topk-aux" # Run name suffix - tags: ["data-generation"] # Tags for the data generation run - save_dir: "./wandb" # Directory for WandB files - log_interval: 5.0 # Logging interval in seconds - -ckpt_path: null \ No newline at end of file diff --git a/crosslayer_transcoder/model/clt.py b/crosslayer_transcoder/model/clt.py index 655b214..cc58891 100644 --- a/crosslayer_transcoder/model/clt.py +++ b/crosslayer_transcoder/model/clt.py @@ -1,7 +1,6 @@ from typing import Tuple, Union import torch -from torch.func import functional_call import torch.nn as nn from einops import einsum from jaxtyping import Float @@ -52,11 +51,7 @@ def reset_parameters(self): dec_uniform_thresh = 1 / ((self.d_acts * self.n_layers) ** 0.5) self.W_dec.data.uniform_(-dec_uniform_thresh, dec_uniform_thresh) - mask = ( - self.mask.unsqueeze(-1) - .unsqueeze(-1) - .repeat(1, 1, self.d_features, self.d_acts) - ) + mask = self.mask.unsqueeze(-1).unsqueeze(-1).repeat(1, 1, self.d_features, self.d_acts) self.W_dec.data = torch.where(mask.bool(), self.W_dec.data, 0.0) if self.tied_init: @@ -68,9 +63,7 @@ def reset_parameters(self): # norm = self.W_dec.norm(p=2, dim=-1) # self.W_dec.data = self.W_dec.data / norm.unsqueeze(-1) - def initialize_standardizers( - self, batch: Float[torch.Tensor, "batch_size io n_layers d_acts"] - ): + def initialize_standardizers(self, batch: Float[torch.Tensor, "batch_size io n_layers d_acts"]): self.input_standardizer.initialize_from_batch(batch) self.output_standardizer.initialize_from_batch(batch) @@ -85,9 +78,7 @@ def decode( "from_layer to_layer -> batch_size to_layer d_acts", ) - def forward( - self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"] - ) -> Tuple[ + def forward(self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"]) -> Tuple[ Float[torch.Tensor, "batch_size n_layers d_features"], Float[torch.Tensor, "batch_size n_layers d_features"], Float[torch.Tensor, "batch_size n_layers d_acts"], @@ -141,9 +132,7 @@ def forward_layer( return pre_actvs def forward( - self, - acts_norm: Float[torch.Tensor, "batch_size n_layers d_acts"], - layer: str = "all", + self, acts_norm: Float[torch.Tensor, "batch_size n_layers d_acts"], layer: str = "all" ) -> Float[torch.Tensor, "batch_size n_layers d_features"]: # for inference if layer != "all": @@ -169,9 +158,7 @@ def __init__(self, d_acts: int, d_features: int, n_layers: int): self.d_acts = d_acts self.d_features = d_features self.n_layers = n_layers - self.register_parameter( - f"W", nn.Parameter(torch.empty((n_layers, d_features, d_acts))) - ) + self.register_parameter(f"W", nn.Parameter(torch.empty((n_layers, d_features, d_acts)))) self.reset_parameters() def reset_parameters(self): @@ -180,9 +167,7 @@ def reset_parameters(self): @torch.no_grad() def forward_layer( - self, - features: Float[torch.Tensor, "batch_size seq from_layer d_features"], - layer: int, + self, features: Float[torch.Tensor, "batch_size seq from_layer d_features"], layer: int ) -> Float[torch.Tensor, "batch_size seq d_acts"]: if features.ndim == 4: # (batch, seq, layer, d_features) features = features[:, :, layer, :] @@ -193,9 +178,7 @@ def forward_layer( ) def forward( - self, - features: Float[torch.Tensor, "batch_size n_layers d_features"], - layer: str = "all", + self, features: Float[torch.Tensor, "batch_size n_layers d_features"], layer: str = "all" ) -> Float[torch.Tensor, "batch_size n_layers d_acts"]: if layer != "all": return self.forward_layer(features, layer) @@ -215,18 +198,14 @@ def __init__(self, d_acts: int, d_features: int, n_layers: int): self.d_features = d_features self.n_layers = n_layers for i in range(n_layers): - self.register_parameter( - f"W_{i}", nn.Parameter(torch.empty((i + 1, d_features, d_acts))) - ) + self.register_parameter(f"W_{i}", nn.Parameter(torch.empty((i + 1, d_features, d_acts)))) self.register_parameter(f"b", nn.Parameter(torch.empty((n_layers, d_acts)))) self.reset_parameters() def reset_parameters(self): dec_uniform_thresh = 1 / ((self.d_acts * self.n_layers) ** 0.5) for i in range(self.n_layers): - self.get_parameter(f"W_{i}").data.uniform_( - -dec_uniform_thresh, dec_uniform_thresh - ) + self.get_parameter(f"W_{i}").data.uniform_(-dec_uniform_thresh, dec_uniform_thresh) # for l in range(i): # self.get_parameter(f"W_{i}").data[l, :, :] = self.get_parameter(f"W_{l}").data[l, :, :] * 0.0 @@ -234,9 +213,7 @@ def reset_parameters(self): @torch.no_grad() def forward_layer( - self, - features: Float[torch.Tensor, "batch_size seq from_layer d_features"], - layer: int, + self, features: Float[torch.Tensor, "batch_size seq from_layer d_features"], layer: int ) -> Float[torch.Tensor, "batch_size seq d_acts"]: return ( einsum( @@ -248,19 +225,13 @@ def forward_layer( ) def forward( - self, - features: Float[torch.Tensor, "batch_size n_layers d_features"], - layer: str = "all", + self, features: Float[torch.Tensor, "batch_size n_layers d_features"], layer: str = "all" ) -> Float[torch.Tensor, "batch_size n_layers d_acts"]: if layer != "all": return self.forward_layer(features, layer) recons = torch.empty( - features.shape[0], - self.n_layers, - self.d_acts, - device=features.device, - dtype=features.dtype, + features.shape[0], self.n_layers, self.d_acts, device=features.device, dtype=features.dtype ) for l in range(self.n_layers): W = self.get_parameter(f"W_{l}") @@ -298,35 +269,11 @@ def reset_parameters(self): self.encoder.reset_parameters() self.decoder.reset_parameters() - def initialize_standardizers( - self, batch: Float[torch.Tensor, "batch_size io n_layers d_acts"] - ): + def initialize_standardizers(self, batch: Float[torch.Tensor, "batch_size io n_layers d_acts"]): self.input_standardizer.initialize_from_batch(batch) self.output_standardizer.initialize_from_batch(batch) - def encode(self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"]): - pre_actvs = self.encoder(acts) - features = self.nonlinearity(pre_actvs) - return features - - def encode_with_standardizer_folding( - self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"] - ): - W_enc_folded, b_enc_folded = self.input_standardizer.fold_in_encoder( - self.encoder.W, self.encoder.b - ) - folded_params = { - "W": torch.nn.Parameter(W_enc_folded.clone().detach()), - "b": torch.nn.Parameter(b_enc_folded.clone().detach()), - } - pre_actvs = functional_call(self.encoder, folded_params, acts, {"layer": "all"}) - - features = self.nonlinearity(pre_actvs) - return features - - def forward( - self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"] - ) -> Tuple[ + def forward(self, acts: Float[torch.Tensor, "batch_size n_layers d_acts"]) -> Tuple[ Float[torch.Tensor, "batch_size n_layers d_features"], # pre_actvs Float[torch.Tensor, "batch_size n_layers d_features"], # features Float[torch.Tensor, "batch_size n_layers d_acts"], # recons_norm From 6a03202249a57a07a7d407c4faab01f75702f6c8 Mon Sep 17 00:00:00 2001 From: jiito Date: Tue, 18 Nov 2025 05:45:34 +0000 Subject: [PATCH 76/99] cleanup tests and unused methods --- crosslayer_transcoder/utils/checkpoints.py | 15 --------------- .../utils/replacement_score.ipynb | 13 +++++++------ .../utils/sanity_check_model.ipynb | 7 ++++--- tests/conftest.py | 2 +- tests/test_checkpoint_loading.py | 8 -------- tests/test_convert_to_circuit_tracer.py | 6 +++--- tests/test_module_builder.py | 7 ++----- 7 files changed, 17 insertions(+), 41 deletions(-) delete mode 100644 crosslayer_transcoder/utils/checkpoints.py delete mode 100644 tests/test_checkpoint_loading.py diff --git a/crosslayer_transcoder/utils/checkpoints.py b/crosslayer_transcoder/utils/checkpoints.py deleted file mode 100644 index 1ac169b..0000000 --- a/crosslayer_transcoder/utils/checkpoints.py +++ /dev/null @@ -1,15 +0,0 @@ -import torch -from huggingface_hub import hf_hub_download -from crosslayer_transcoder.utils.model_converters.model_converter import CLTModule - -def load_model_from_lightning_checkpoint(model, checkpoint_path): - # NOTE: we might have to adjust how to resolve the map_location - checkpoint = torch.load(checkpoint_path, map_location='cuda:0') - model.load_state_dict(checkpoint["state_dict"]) - return model - -def load_clt_from_hub(model: CLTModule, repo_id: str) -> CLTModule: - local_filename = "clt.ckpt" - checkpoint_path = hf_hub_download(repo_id=repo_id, local_dir=".", filename=local_filename) - model = load_model_from_lightning_checkpoint(model, checkpoint_path) - return model \ No newline at end of file diff --git a/crosslayer_transcoder/utils/replacement_score.ipynb b/crosslayer_transcoder/utils/replacement_score.ipynb index a56a4e6..c7f8d20 100644 --- a/crosslayer_transcoder/utils/replacement_score.ipynb +++ b/crosslayer_transcoder/utils/replacement_score.ipynb @@ -31,13 +31,13 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "a37586eb", "metadata": {}, "outputs": [], "source": [ "DTYPE = torch.bfloat16\n", - "checkpoint = \"../checkpoints/clt.ckpt\"\n", + "checkpoint_path = \"../checkpoints/clt.ckpt\"\n", "config_path = \"../../config/circuit-tracer.yaml\"\n", "identifier = \"gpt2-crosslayer-clt-v1\"" ] @@ -52,7 +52,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "c166ce94", "metadata": {}, "outputs": [ @@ -84,11 +84,12 @@ ], "source": [ "from crosslayer_transcoder.utils.module_builder import build_module_from_config, yaml_to_config\n", - "from crosslayer_transcoder.utils.checkpoints import load_model_from_lightning_checkpoint\n", "\n", "config = yaml_to_config(config_path)\n", "clt_module = build_module_from_config(config)\n", - "clt_module = load_model_from_lightning_checkpoint(clt_module, checkpoint)\n" + "\n", + "checkpoint = torch.load(checkpoint_path, map_location='cuda:0')\n", + "clt_module.load_state_dict(checkpoint[\"state_dict\"])\n" ] }, { @@ -296,7 +297,7 @@ "id": "e33c5e46", "metadata": {}, "source": [ - "### Viz" + "### [Optional] Viz" ] }, { diff --git a/crosslayer_transcoder/utils/sanity_check_model.ipynb b/crosslayer_transcoder/utils/sanity_check_model.ipynb index 3a1ec4b..c246848 100644 --- a/crosslayer_transcoder/utils/sanity_check_model.ipynb +++ b/crosslayer_transcoder/utils/sanity_check_model.ipynb @@ -18,7 +18,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "de7531d0", "metadata": {}, "outputs": [ @@ -69,7 +69,7 @@ ], "source": [ "from crosslayer_transcoder.utils.module_builder import build_module_from_config, yaml_to_config\n", - "from crosslayer_transcoder.utils.checkpoints import load_model_from_lightning_checkpoint\n", + "import torch\n", "\n", "config_path = \"../../config/circuit-tracer.yaml\"\n", "checkpoint_path = \"../checkpoints/clt.ckpt\"\n", @@ -77,7 +77,8 @@ "config = yaml_to_config(config_path)\n", "clt_module = build_module_from_config(config)\n", "\n", - "clt_module = load_model_from_lightning_checkpoint(clt_module, checkpoint_path)\n", + "checkpoint = torch.load(checkpoint_path, map_location='cuda:0')\n", + "clt_module.load_state_dict(checkpoint[\"state_dict\"])\n", "\n", "print(clt_module)" ] diff --git a/tests/conftest.py b/tests/conftest.py index b066753..308eac7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,7 +2,7 @@ @pytest.fixture(scope="session") -def clt_module(): +def jumprelu_clt_module(): from crosslayer_transcoder.metrics.dead_features import DeadFeatures from crosslayer_transcoder.model.clt import ( CrosslayerDecoder, diff --git a/tests/test_checkpoint_loading.py b/tests/test_checkpoint_loading.py deleted file mode 100644 index 75bb291..0000000 --- a/tests/test_checkpoint_loading.py +++ /dev/null @@ -1,8 +0,0 @@ - -def test_load_model_from_lightning_checkpoint(clt_module): - from crosslayer_transcoder.utils.checkpoints import load_model_from_lightning_checkpoint - checkpoint_path = "crosslayer_transcoder/checkpoints/clt.ckpt" - - model = load_model_from_lightning_checkpoint(clt_module, checkpoint_path) - - print(model) diff --git a/tests/test_convert_to_circuit_tracer.py b/tests/test_convert_to_circuit_tracer.py index 224ba76..4d1a7ba 100644 --- a/tests/test_convert_to_circuit_tracer.py +++ b/tests/test_convert_to_circuit_tracer.py @@ -6,15 +6,15 @@ import shutil -def test_circuit_tracer_converter(clt_module): +def test_circuit_tracer_converter(jumprelu_clt_module): save_dir = pathlib.Path("clt_module") converter = CircuitTracerConverter(save_dir=save_dir) - converter.convert_and_save(clt_module) + converter.convert_and_save(jumprelu_clt_module) assert save_dir.exists() assert ( len(list(save_dir.glob("*.safetensors"))) - == clt_module.model.encoder.n_layers * 2 + == jumprelu_clt_module.model.encoder.n_layers * 2 ) assert (save_dir / "config.yaml").exists() diff --git a/tests/test_module_builder.py b/tests/test_module_builder.py index c12255d..f03bf0c 100644 --- a/tests/test_module_builder.py +++ b/tests/test_module_builder.py @@ -1,9 +1,6 @@ -def test_build_module_from_config(clt_module): +def test_build_module_from_config(): from crosslayer_transcoder.utils.module_builder import build_module_from_config, yaml_to_config config = yaml_to_config("config/default.yaml") - model = build_module_from_config(config) - - assert model.model.encoder.n_layers == clt_module.model.encoder.n_layers - assert model.model.decoder.n_layers == clt_module.model.decoder.n_layers + build_module_from_config(config) From 8652e3a1eb8922bcff8cb250639dbc75abb82290 Mon Sep 17 00:00:00 2001 From: jiito Date: Tue, 18 Nov 2025 05:53:42 +0000 Subject: [PATCH 77/99] test: config of hook points for callback --- config/circuit-tracer.yaml | 5 +++++ crosslayer_transcoder/utils/callbacks.py | 17 ++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/config/circuit-tracer.yaml b/config/circuit-tracer.yaml index 4f08eae..4b1884f 100644 --- a/config/circuit-tracer.yaml +++ b/config/circuit-tracer.yaml @@ -24,6 +24,11 @@ trainer: - class_path: crosslayer_transcoder.utils.callbacks.EndOfTrainingCheckpointCallback init_args: checkpoint_dir: "checkpoints" + - class_path: crosslayer_transcoder.utils.callbacks.ModelConversionCallback + init_args: + save_dir: "clt_module" + kinds: ["circuit_tracer"] + on_event: ["on_test_batch_start"] model: class_path: crosslayer_transcoder.model.clt_lightning.JumpReLUCrossLayerTranscoderModule diff --git a/crosslayer_transcoder/utils/callbacks.py b/crosslayer_transcoder/utils/callbacks.py index f093ffe..f5ee081 100644 --- a/crosslayer_transcoder/utils/callbacks.py +++ b/crosslayer_transcoder/utils/callbacks.py @@ -61,19 +61,26 @@ def on_train_end(self, trainer, pl_module): checkpoint_path = self.checkpoint_dir / "clt.ckpt" trainer.save_checkpoint(checkpoint_path) - class ModelConversionCallback(L.Callback): """Callback to convert the model to a circuit-tracer model.""" - def __init__(self, save_dir: str = "clt_module", kinds=["circuit_tracer"]): + # Note: you can't type these with List + def __init__(self, save_dir: str = "clt_module", kinds=["circuit_tracer"], on_event=["on_train_batch_end"]): super().__init__() self.save_dir = Path(save_dir) self.kinds = kinds + self.on_event = on_event self.converters = { "circuit_tracer": CircuitTracerConverter, } + self._setup_hooks() + + def _setup_hooks(self): + for event in self.on_event: + setattr(self, event, lambda *args, **kwargs: self._convert_model(*args, **kwargs)) - def _convert_model(self, pl_module): + # Note: this should have the signature as all Lightning callbacks + def _convert_model(self, trainer, pl_module, **kwargs): for kind in self.kinds: converter = self.converters[kind](save_dir=self.save_dir.as_posix()) converter.convert_and_save(pl_module) @@ -81,10 +88,6 @@ def _convert_model(self, pl_module): f"{kind} model converted and saved to {self.save_dir.as_posix()}" ) - # TODO: for testing, just turn on the train batch end - def on_train_batch_end(self, trainer, pl_module): - self._convert_model(pl_module) - class HuggingFaceCallback(L.Callback): """Callback to upload the model to Hugging Face.""" From 718586a4cc64f515ac3e5f2be615c7032dd7e36e Mon Sep 17 00:00:00 2001 From: jiito Date: Tue, 18 Nov 2025 06:42:40 +0000 Subject: [PATCH 78/99] use partial --- config/circuit-tracer.yaml | 2 +- crosslayer_transcoder/utils/callbacks.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/config/circuit-tracer.yaml b/config/circuit-tracer.yaml index 4b1884f..145bed3 100644 --- a/config/circuit-tracer.yaml +++ b/config/circuit-tracer.yaml @@ -28,7 +28,7 @@ trainer: init_args: save_dir: "clt_module" kinds: ["circuit_tracer"] - on_event: ["on_test_batch_start"] + on_event: ["on_train_start"] model: class_path: crosslayer_transcoder.model.clt_lightning.JumpReLUCrossLayerTranscoderModule diff --git a/crosslayer_transcoder/utils/callbacks.py b/crosslayer_transcoder/utils/callbacks.py index f5ee081..7b6169e 100644 --- a/crosslayer_transcoder/utils/callbacks.py +++ b/crosslayer_transcoder/utils/callbacks.py @@ -3,6 +3,7 @@ """ from ast import List +from functools import partial import logging from pathlib import Path @@ -77,10 +78,12 @@ def __init__(self, save_dir: str = "clt_module", kinds=["circuit_tracer"], on_ev def _setup_hooks(self): for event in self.on_event: - setattr(self, event, lambda *args, **kwargs: self._convert_model(*args, **kwargs)) + logger.info(f"Setting up hook for {event}...") + setattr(self, event, partial(self._convert_model)) # Note: this should have the signature as all Lightning callbacks def _convert_model(self, trainer, pl_module, **kwargs): + logger.info(f"Converting model to {self.kinds}...") for kind in self.kinds: converter = self.converters[kind](save_dir=self.save_dir.as_posix()) converter.convert_and_save(pl_module) From 81298bb09886120574fe06e77dac402a1c91728c Mon Sep 17 00:00:00 2001 From: jiito Date: Tue, 18 Nov 2025 09:25:55 -0800 Subject: [PATCH 79/99] refactor: rename and delete indirection --- crosslayer_transcoder/utils/module_builder.py | 13 +------------ .../utils/replacement_score.ipynb | 8 +++++--- .../utils/sanity_check_model.ipynb | 8 +++++--- tests/test_circuit_tracer_integration.py | 14 ++++++++------ tests/test_module_builder.py | 6 ------ 5 files changed, 19 insertions(+), 30 deletions(-) delete mode 100644 tests/test_module_builder.py diff --git a/crosslayer_transcoder/utils/module_builder.py b/crosslayer_transcoder/utils/module_builder.py index 7d1494c..6097cfc 100644 --- a/crosslayer_transcoder/utils/module_builder.py +++ b/crosslayer_transcoder/utils/module_builder.py @@ -1,13 +1,8 @@ import importlib -import yaml import torch.nn as nn def build_module_from_config(config: dict) -> nn.Module: - return init_from_config(config["model"]) - - -def init_from_config(config: dict) -> nn.Module: class_path = config["class_path"] module_name = ".".join(class_path.split(".")[:-1]) class_name = class_path.split(".")[-1] @@ -16,12 +11,6 @@ def init_from_config(config: dict) -> nn.Module: init_args = config["init_args"] for key, value in init_args.items(): if isinstance(value, dict): - init_args[key] = init_from_config(value) + init_args[key] = build_module_from_config(value) init_class = init_class(**init_args) return init_class - - -def yaml_to_config(yaml_path: str) -> dict: - with open(yaml_path, "r") as f: - config = yaml.load(f, Loader=yaml.FullLoader) - return config diff --git a/crosslayer_transcoder/utils/replacement_score.ipynb b/crosslayer_transcoder/utils/replacement_score.ipynb index c7f8d20..683c638 100644 --- a/crosslayer_transcoder/utils/replacement_score.ipynb +++ b/crosslayer_transcoder/utils/replacement_score.ipynb @@ -83,10 +83,12 @@ } ], "source": [ - "from crosslayer_transcoder.utils.module_builder import build_module_from_config, yaml_to_config\n", + "from crosslayer_transcoder.utils.module_builder import build_module_from_config\n", + "import yaml\n", "\n", - "config = yaml_to_config(config_path)\n", - "clt_module = build_module_from_config(config)\n", + "with open(config_path, \"r\") as f:\n", + " config = yaml.load(f, Loader=yaml.FullLoader)\n", + " clt_module = build_module_from_config(config[\"model\"])\n", "\n", "checkpoint = torch.load(checkpoint_path, map_location='cuda:0')\n", "clt_module.load_state_dict(checkpoint[\"state_dict\"])\n" diff --git a/crosslayer_transcoder/utils/sanity_check_model.ipynb b/crosslayer_transcoder/utils/sanity_check_model.ipynb index c246848..f5b1e0c 100644 --- a/crosslayer_transcoder/utils/sanity_check_model.ipynb +++ b/crosslayer_transcoder/utils/sanity_check_model.ipynb @@ -68,14 +68,16 @@ } ], "source": [ - "from crosslayer_transcoder.utils.module_builder import build_module_from_config, yaml_to_config\n", + "import yaml\n", + "from crosslayer_transcoder.utils.module_builder import build_module_from_config \n", "import torch\n", "\n", "config_path = \"../../config/circuit-tracer.yaml\"\n", "checkpoint_path = \"../checkpoints/clt.ckpt\"\n", "\n", - "config = yaml_to_config(config_path)\n", - "clt_module = build_module_from_config(config)\n", + "with open(config_path, \"r\") as f:\n", + " config = yaml.load(f, Loader=yaml.FullLoader)\n", + " clt_module = build_module_from_config(config[\"model\"])\n", "\n", "checkpoint = torch.load(checkpoint_path, map_location='cuda:0')\n", "clt_module.load_state_dict(checkpoint[\"state_dict\"])\n", diff --git a/tests/test_circuit_tracer_integration.py b/tests/test_circuit_tracer_integration.py index d6d7184..02e8757 100644 --- a/tests/test_circuit_tracer_integration.py +++ b/tests/test_circuit_tracer_integration.py @@ -9,13 +9,16 @@ def test_circuit_tracer_integration(): """Verify uploaded model loads correctly.""" - from crosslayer_transcoder.utils.module_builder import build_module_from_config, yaml_to_config - config = yaml_to_config("config/topk-clt-debug.yaml") - clt_module = build_module_from_config(config) + from crosslayer_transcoder.utils.module_builder import build_module_from_config + import yaml + + with open("config/circuit-tracer.yaml", "r") as f: + config = yaml.load(f, Loader=yaml.FullLoader) + clt_module = build_module_from_config(config["model"]) save_dir = pathlib.Path("clt_module_test") - feature_input_hook = "blocks.{layer}.hook_resid_pre" - feature_output_hook = "blocks.{layer}.hook_mlp_out" + feature_input_hook = "hook_resid_mid" + feature_output_hook = "hook_mlp_out" converter = CircuitTracerConverter( save_dir=save_dir, @@ -24,7 +27,6 @@ def test_circuit_tracer_integration(): ) converter.convert_and_save(clt_module) - transcoder = load_clt( clt_path=save_dir.as_posix(), lazy_decoder=False, diff --git a/tests/test_module_builder.py b/tests/test_module_builder.py deleted file mode 100644 index f03bf0c..0000000 --- a/tests/test_module_builder.py +++ /dev/null @@ -1,6 +0,0 @@ -def test_build_module_from_config(): - from crosslayer_transcoder.utils.module_builder import build_module_from_config, yaml_to_config - config = yaml_to_config("config/default.yaml") - build_module_from_config(config) - - From 0c664412df601f2f07b41ae2d4b9ac55e5201447 Mon Sep 17 00:00:00 2001 From: jiito Date: Tue, 18 Nov 2025 18:52:41 -0800 Subject: [PATCH 80/99] refactor: change to protocol over ABC --- crosslayer_transcoder/utils/callbacks.py | 39 +++++++------------ .../utils/model_converters/model_converter.py | 10 ++--- 2 files changed, 17 insertions(+), 32 deletions(-) diff --git a/crosslayer_transcoder/utils/callbacks.py b/crosslayer_transcoder/utils/callbacks.py index 7b6169e..3e5f55f 100644 --- a/crosslayer_transcoder/utils/callbacks.py +++ b/crosslayer_transcoder/utils/callbacks.py @@ -2,13 +2,12 @@ Simple Lightning callbacks for CrossLayer Transcoder training. """ -from ast import List -from functools import partial import logging +from functools import partial from pathlib import Path -from huggingface_hub import upload_folder import lightning as L +from huggingface_hub import upload_folder from torch.profiler import ( ProfilerActivity, profile, @@ -16,9 +15,7 @@ tensorboard_trace_handler, ) -from crosslayer_transcoder.utils.model_converters.circuit_tracer import ( - CircuitTracerConverter, -) +from crosslayer_transcoder.utils.model_converters.model_converter import ModelConverter logger = logging.getLogger(__name__) @@ -62,34 +59,26 @@ def on_train_end(self, trainer, pl_module): checkpoint_path = self.checkpoint_dir / "clt.ckpt" trainer.save_checkpoint(checkpoint_path) + class ModelConversionCallback(L.Callback): """Callback to convert the model to a circuit-tracer model.""" # Note: you can't type these with List - def __init__(self, save_dir: str = "clt_module", kinds=["circuit_tracer"], on_event=["on_train_batch_end"]): + def __init__(self, converter: ModelConverter, on_events=["on_train_batch_end"]): super().__init__() - self.save_dir = Path(save_dir) - self.kinds = kinds - self.on_event = on_event - self.converters = { - "circuit_tracer": CircuitTracerConverter, - } - self._setup_hooks() - - def _setup_hooks(self): - for event in self.on_event: - logger.info(f"Setting up hook for {event}...") + self.converter = converter + self.on_events = on_events + self._setup_callbacks() + + def _setup_callbacks(self): + for event in self.on_events: setattr(self, event, partial(self._convert_model)) # Note: this should have the signature as all Lightning callbacks def _convert_model(self, trainer, pl_module, **kwargs): - logger.info(f"Converting model to {self.kinds}...") - for kind in self.kinds: - converter = self.converters[kind](save_dir=self.save_dir.as_posix()) - converter.convert_and_save(pl_module) - logger.info( - f"{kind} model converted and saved to {self.save_dir.as_posix()}" - ) + logger.info("Converting model...") + self.converter.convert_and_save(pl_module) + logger.info("Model converted and saved ") class HuggingFaceCallback(L.Callback): diff --git a/crosslayer_transcoder/utils/model_converters/model_converter.py b/crosslayer_transcoder/utils/model_converters/model_converter.py index 8442a01..da24c2e 100644 --- a/crosslayer_transcoder/utils/model_converters/model_converter.py +++ b/crosslayer_transcoder/utils/model_converters/model_converter.py @@ -1,5 +1,4 @@ -from abc import ABC, abstractmethod -from typing import Union +from typing import Protocol, Union from crosslayer_transcoder.model.clt_lightning import ( CrossLayerTranscoderModule, @@ -14,8 +13,5 @@ ] -class ModelConverter(ABC): - @abstractmethod - # TODO: single resp - def convert_and_save(self, model: CLTModule) -> None: - pass +class ModelConverter(Protocol): + def convert_and_save(self, model: CLTModule) -> None: ... From 3550185104b9161208effa88967e2c1b97aa4286 Mon Sep 17 00:00:00 2001 From: jiito Date: Tue, 18 Nov 2025 18:57:13 -0800 Subject: [PATCH 81/99] add safety to module builder --- crosslayer_transcoder/utils/module_builder.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/crosslayer_transcoder/utils/module_builder.py b/crosslayer_transcoder/utils/module_builder.py index 6097cfc..87f4265 100644 --- a/crosslayer_transcoder/utils/module_builder.py +++ b/crosslayer_transcoder/utils/module_builder.py @@ -3,14 +3,21 @@ def build_module_from_config(config: dict) -> nn.Module: + """Naive module builder that constructs a module from a yaml config.""" class_path = config["class_path"] module_name = ".".join(class_path.split(".")[:-1]) class_name = class_path.split(".")[-1] init_class = importlib.import_module(module_name) init_class = getattr(init_class, class_name) - init_args = config["init_args"] + init_args = config.get("init_args", {}) + + if not init_args: + return init_class() + for key, value in init_args.items(): - if isinstance(value, dict): + if isinstance(value, dict) and "class_path" in value: init_args[key] = build_module_from_config(value) + init_class = init_class(**init_args) + return init_class From a28f4a1f51e02ac4bf37646f76409872cb463dc9 Mon Sep 17 00:00:00 2001 From: jiito Date: Sat, 22 Nov 2025 09:13:40 -0800 Subject: [PATCH 82/99] fix: circuit tracer converter callback --- config/circuit-tracer.yaml | 10 ++++++++-- crosslayer_transcoder/utils/callbacks.py | 6 ++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/config/circuit-tracer.yaml b/config/circuit-tracer.yaml index 145bed3..5621d16 100644 --- a/config/circuit-tracer.yaml +++ b/config/circuit-tracer.yaml @@ -27,8 +27,14 @@ trainer: - class_path: crosslayer_transcoder.utils.callbacks.ModelConversionCallback init_args: save_dir: "clt_module" - kinds: ["circuit_tracer"] - on_event: ["on_train_start"] + on_events: + - "on_train_batch_end" + converter: + class_path: crosslayer_transcoder.utils.model_converters.circuit_tracer.CircuitTracerConverter + init_args: + save_dir: "circuit-tracer" + feature_input_hook: "hook_resid_mid" + feature_output_hook: "hook_mlp_out" model: class_path: crosslayer_transcoder.model.clt_lightning.JumpReLUCrossLayerTranscoderModule diff --git a/crosslayer_transcoder/utils/callbacks.py b/crosslayer_transcoder/utils/callbacks.py index 3e5f55f..c09fb81 100644 --- a/crosslayer_transcoder/utils/callbacks.py +++ b/crosslayer_transcoder/utils/callbacks.py @@ -5,6 +5,7 @@ import logging from functools import partial from pathlib import Path +from typing import List import lightning as L from huggingface_hub import upload_folder @@ -64,9 +65,10 @@ class ModelConversionCallback(L.Callback): """Callback to convert the model to a circuit-tracer model.""" # Note: you can't type these with List - def __init__(self, converter: ModelConverter, on_events=["on_train_batch_end"]): + def __init__( + self, converter: ModelConverter, on_events: List[str] = ["on_train_batch_end"] + ): super().__init__() - self.converter = converter self.on_events = on_events self._setup_callbacks() From 2746ea8ceb74266878ffdcc4ec1b8f1ed1b11a80 Mon Sep 17 00:00:00 2001 From: jiito Date: Mon, 1 Dec 2025 20:11:16 +0000 Subject: [PATCH 83/99] fix: remove direct typehints and add comments --- config/circuit-tracer.yaml | 4 +--- crosslayer_transcoder/utils/callbacks.py | 6 ++++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/config/circuit-tracer.yaml b/config/circuit-tracer.yaml index 5621d16..ac51f56 100644 --- a/config/circuit-tracer.yaml +++ b/config/circuit-tracer.yaml @@ -26,15 +26,13 @@ trainer: checkpoint_dir: "checkpoints" - class_path: crosslayer_transcoder.utils.callbacks.ModelConversionCallback init_args: - save_dir: "clt_module" - on_events: - - "on_train_batch_end" converter: class_path: crosslayer_transcoder.utils.model_converters.circuit_tracer.CircuitTracerConverter init_args: save_dir: "circuit-tracer" feature_input_hook: "hook_resid_mid" feature_output_hook: "hook_mlp_out" + on_events: ["on_train_batch_end"] model: class_path: crosslayer_transcoder.model.clt_lightning.JumpReLUCrossLayerTranscoderModule diff --git a/crosslayer_transcoder/utils/callbacks.py b/crosslayer_transcoder/utils/callbacks.py index c09fb81..11a8545 100644 --- a/crosslayer_transcoder/utils/callbacks.py +++ b/crosslayer_transcoder/utils/callbacks.py @@ -64,9 +64,11 @@ def on_train_end(self, trainer, pl_module): class ModelConversionCallback(L.Callback): """Callback to convert the model to a circuit-tracer model.""" - # Note: you can't type these with List + # Note: you can't type these directly with List or ModelConverter def __init__( - self, converter: ModelConverter, on_events: List[str] = ["on_train_batch_end"] + self, + converter, # type: ModelConverter + on_events=["on_train_batch_end"], # type: List[str] ): super().__init__() self.on_events = on_events From 0100c1dbb10c9c6822b1c700d58f4eba8f734477 Mon Sep 17 00:00:00 2001 From: jiito Date: Wed, 3 Dec 2025 10:04:52 +0000 Subject: [PATCH 84/99] borken for comparison --- crosslayer_transcoder/utils/callbacks.py | 6 +++--- .../utils/model_converters/model_converter.py | 7 ++++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/crosslayer_transcoder/utils/callbacks.py b/crosslayer_transcoder/utils/callbacks.py index 11a8545..afe7ea8 100644 --- a/crosslayer_transcoder/utils/callbacks.py +++ b/crosslayer_transcoder/utils/callbacks.py @@ -66,9 +66,9 @@ class ModelConversionCallback(L.Callback): # Note: you can't type these directly with List or ModelConverter def __init__( - self, - converter, # type: ModelConverter - on_events=["on_train_batch_end"], # type: List[str] + self, + converter: ModelConverter, + on_events: List[str] = ["on_train_batch_end"], # type: List[str] ): super().__init__() self.on_events = on_events diff --git a/crosslayer_transcoder/utils/model_converters/model_converter.py b/crosslayer_transcoder/utils/model_converters/model_converter.py index da24c2e..89e7724 100644 --- a/crosslayer_transcoder/utils/model_converters/model_converter.py +++ b/crosslayer_transcoder/utils/model_converters/model_converter.py @@ -1,5 +1,7 @@ from typing import Protocol, Union +import torch + from crosslayer_transcoder.model.clt_lightning import ( CrossLayerTranscoderModule, JumpReLUCrossLayerTranscoderModule, @@ -14,4 +16,7 @@ class ModelConverter(Protocol): - def convert_and_save(self, model: CLTModule) -> None: ... + def convert_and_save( + self, model: CLTModule, dtype: torch.dtype = torch.bfloat16 + ) -> None: + pass From 1b4e8d6996954f6b52e99119112f6670c3d8ba31 Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 4 Dec 2025 10:28:18 +0000 Subject: [PATCH 85/99] fix: protocol typing --- crosslayer_transcoder/utils/callbacks.py | 1 + .../utils/model_converters/model_converter.py | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/crosslayer_transcoder/utils/callbacks.py b/crosslayer_transcoder/utils/callbacks.py index afe7ea8..0cbc4af 100644 --- a/crosslayer_transcoder/utils/callbacks.py +++ b/crosslayer_transcoder/utils/callbacks.py @@ -71,6 +71,7 @@ def __init__( on_events: List[str] = ["on_train_batch_end"], # type: List[str] ): super().__init__() + self.converter = converter self.on_events = on_events self._setup_callbacks() diff --git a/crosslayer_transcoder/utils/model_converters/model_converter.py b/crosslayer_transcoder/utils/model_converters/model_converter.py index 89e7724..d521ed4 100644 --- a/crosslayer_transcoder/utils/model_converters/model_converter.py +++ b/crosslayer_transcoder/utils/model_converters/model_converter.py @@ -1,4 +1,4 @@ -from typing import Protocol, Union +from typing import Any, Protocol, Union import torch @@ -17,6 +17,7 @@ class ModelConverter(Protocol): def convert_and_save( - self, model: CLTModule, dtype: torch.dtype = torch.bfloat16 + # NOTE: we type the model arg as any to avoid an issue with jsonargparse + self, model: Any, dtype: torch.dtype = torch.bfloat16 ) -> None: pass From c87117a5526b713adb07aa1f52d53dd3d6ce2935 Mon Sep 17 00:00:00 2001 From: jiito Date: Mon, 8 Dec 2025 20:41:39 +0000 Subject: [PATCH 86/99] add runtime_checkable to protocol --- .../utils/model_converters/circuit_tracer.py | 6 ++++-- .../utils/model_converters/model_converter.py | 8 +++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py index 717e8cd..f977cba 100644 --- a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py +++ b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py @@ -7,6 +7,7 @@ from safetensors.torch import save_file from crosslayer_transcoder.utils.model_converters.model_converter import ( + CLTModule, ModelConverter, ) from crosslayer_transcoder.model.jumprelu import JumpReLU @@ -25,7 +26,9 @@ def __init__( self.save_dir.mkdir(parents=True, exist_ok=True) - def convert_and_save(self, model, dtype=torch.bfloat16): + def convert_and_save( + self, model: CLTModule, dtype: torch.dtype = torch.bfloat16 + ) -> None: encoder = model.model.encoder input_standardizer = model.model.input_standardizer output_standardizer = model.model.output_standardizer @@ -35,7 +38,6 @@ def convert_and_save(self, model, dtype=torch.bfloat16): d_acts = encoder.d_acts # -> circuit-tracer.d_model d_features = encoder.d_features # -> circuit-tracer.d_transcoder - # TODO: maybe pass in dtype W_enc_folded, b_enc_folded = input_standardizer.fold_in_encoder( encoder.W.to(dtype), encoder.b.to(dtype) ) diff --git a/crosslayer_transcoder/utils/model_converters/model_converter.py b/crosslayer_transcoder/utils/model_converters/model_converter.py index d521ed4..3786dfc 100644 --- a/crosslayer_transcoder/utils/model_converters/model_converter.py +++ b/crosslayer_transcoder/utils/model_converters/model_converter.py @@ -1,4 +1,4 @@ -from typing import Any, Protocol, Union +from typing import Protocol, Union, runtime_checkable import torch @@ -15,9 +15,11 @@ ] +@runtime_checkable class ModelConverter(Protocol): def convert_and_save( - # NOTE: we type the model arg as any to avoid an issue with jsonargparse - self, model: Any, dtype: torch.dtype = torch.bfloat16 + self, + model: CLTModule, + dtype: torch.dtype = torch.bfloat16, ) -> None: pass From c9b0fc65b4b2f9c5672d6ec2887d98c648ef4f27 Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 15 Jan 2026 13:18:09 -0800 Subject: [PATCH 87/99] fix: move tests --- .../test_circuit_tracer_integration.py | 14 +++-- .../test_convert_to_circuit_tracer.py | 0 tests/conftest.py | 62 ++++++++++--------- 3 files changed, 42 insertions(+), 34 deletions(-) rename tests/{ => circuit_tracer}/test_circuit_tracer_integration.py (79%) rename tests/{ => circuit_tracer}/test_convert_to_circuit_tracer.py (100%) diff --git a/tests/test_circuit_tracer_integration.py b/tests/circuit_tracer/test_circuit_tracer_integration.py similarity index 79% rename from tests/test_circuit_tracer_integration.py rename to tests/circuit_tracer/test_circuit_tracer_integration.py index 02e8757..274dee4 100644 --- a/tests/test_circuit_tracer_integration.py +++ b/tests/circuit_tracer/test_circuit_tracer_integration.py @@ -1,7 +1,10 @@ import pathlib import shutil +from unittest.mock import MagicMock +import yaml from circuit_tracer.transcoder.cross_layer_transcoder import load_clt +from crosslayer_transcoder.model.clt import CrossLayerTranscoder from crosslayer_transcoder.utils.model_converters.circuit_tracer import ( CircuitTracerConverter, ) @@ -9,12 +12,13 @@ def test_circuit_tracer_integration(): """Verify uploaded model loads correctly.""" - from crosslayer_transcoder.utils.module_builder import build_module_from_config - import yaml - with open("config/circuit-tracer.yaml", "r") as f: - config = yaml.load(f, Loader=yaml.FullLoader) - clt_module = build_module_from_config(config["model"]) + config = yaml.safe_load(f) + model_config = config["model"]["init_args"]["model"] + clt_model = CrossLayerTranscoder.from_config(model_config) + + clt_module = MagicMock() + clt_module.model = clt_model save_dir = pathlib.Path("clt_module_test") feature_input_hook = "hook_resid_mid" diff --git a/tests/test_convert_to_circuit_tracer.py b/tests/circuit_tracer/test_convert_to_circuit_tracer.py similarity index 100% rename from tests/test_convert_to_circuit_tracer.py rename to tests/circuit_tracer/test_convert_to_circuit_tracer.py diff --git a/tests/conftest.py b/tests/conftest.py index 308eac7..85d0fba 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,37 +4,41 @@ @pytest.fixture(scope="session") def jumprelu_clt_module(): from crosslayer_transcoder.metrics.dead_features import DeadFeatures - from crosslayer_transcoder.model.clt import ( - CrosslayerDecoder, - CrossLayerTranscoder, - Encoder, - ) + from crosslayer_transcoder.model.clt import CrossLayerTranscoder from crosslayer_transcoder.model.clt_lightning import CrossLayerTranscoderModule - from crosslayer_transcoder.model.jumprelu import JumpReLU - from crosslayer_transcoder.model.standardize import ( - DimensionwiseInputStandardizer, - DimensionwiseOutputStandardizer, - ) - - encoder = Encoder(d_acts=768, d_features=10_000, n_layers=12) - - decoder = CrosslayerDecoder(d_acts=768, d_features=10_000, n_layers=12) - - nonlinearity = JumpReLU(theta=0.03, bandwidth=0.01, n_layers=12, d_features=10_000) - input_standardizer = DimensionwiseInputStandardizer(n_layers=12, activation_dim=768) - - output_standardizer = DimensionwiseOutputStandardizer( - n_layers=12, activation_dim=768 - ) - - model = CrossLayerTranscoder( - encoder=encoder, - decoder=decoder, - nonlinearity=nonlinearity, - input_standardizer=input_standardizer, - output_standardizer=output_standardizer, - ) + model_config = { + "class_path": "crosslayer_transcoder.model.clt.CrossLayerTranscoder", + "init_args": { + "encoder": { + "class_path": "crosslayer_transcoder.model.clt.Encoder", + "init_args": {"d_acts": 768, "d_features": 10_000, "n_layers": 12}, + }, + "decoder": { + "class_path": "crosslayer_transcoder.model.clt.CrosslayerDecoder", + "init_args": {"d_acts": 768, "d_features": 10_000, "n_layers": 12}, + }, + "nonlinearity": { + "class_path": "crosslayer_transcoder.model.jumprelu.JumpReLU", + "init_args": { + "theta": 0.03, + "bandwidth": 0.01, + "n_layers": 12, + "d_features": 10_000, + }, + }, + "input_standardizer": { + "class_path": "crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer", + "init_args": {"n_layers": 12, "activation_dim": 768}, + }, + "output_standardizer": { + "class_path": "crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer", + "init_args": {"n_layers": 12, "activation_dim": 768}, + }, + }, + } + + model = CrossLayerTranscoder.from_config(model_config) dead_features = DeadFeatures( n_features=10_000, From 40d1291d16c95a5a30263505a74d2276ad6d7a83 Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 15 Jan 2026 14:38:49 -0800 Subject: [PATCH 88/99] add relu error test --- .../test_circuit_tracer_integration.py | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tests/circuit_tracer/test_circuit_tracer_integration.py b/tests/circuit_tracer/test_circuit_tracer_integration.py index 274dee4..200ed26 100644 --- a/tests/circuit_tracer/test_circuit_tracer_integration.py +++ b/tests/circuit_tracer/test_circuit_tracer_integration.py @@ -1,8 +1,10 @@ import pathlib import shutil from unittest.mock import MagicMock +import torch import yaml from circuit_tracer.transcoder.cross_layer_transcoder import load_clt +import pytest from crosslayer_transcoder.model.clt import CrossLayerTranscoder from crosslayer_transcoder.utils.model_converters.circuit_tracer import ( @@ -47,3 +49,50 @@ def test_circuit_tracer_integration(): # cleanup shutil.rmtree(save_dir) + + +def test_topk_nonlinearity(): + model_config = { + "class_path": "crosslayer_transcoder.model.clt.CrossLayerTranscoder", + "init_args": { + "encoder": { + "class_path": "crosslayer_transcoder.model.clt.Encoder", + "init_args": {"d_acts": 768, "d_features": 10_000, "n_layers": 12}, + }, + "decoder": { + "class_path": "crosslayer_transcoder.model.clt.CrosslayerDecoder", + "init_args": {"d_acts": 768, "d_features": 10_000, "n_layers": 12}, + }, + "nonlinearity": { + "class_path": "crosslayer_transcoder.model.topk.PerLayerTopK", + "init_args": { + "k": 8, + }, + }, + "input_standardizer": { + "class_path": "crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer", + "init_args": {"n_layers": 12, "activation_dim": 768}, + }, + "output_standardizer": { + "class_path": "crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer", + "init_args": {"n_layers": 12, "activation_dim": 768}, + }, + }, + } + clt_model = CrossLayerTranscoder.from_config(model_config) + clt_module = MagicMock() + clt_module.model = clt_model + save_dir = pathlib.Path("topk_clt_module_test") + feature_input_hook = "hook_resid_mid" + feature_output_hook = "hook_mlp_out" + + with pytest.raises( + ValueError, + match="TopK nonlinearity is not supported by circuit-tracer.", + ): + converter = CircuitTracerConverter( + save_dir=save_dir, + feature_input_hook=feature_input_hook, + feature_output_hook=feature_output_hook, + ) + converter.convert_and_save(clt_module) From 3e57bb1ae520e7f6ae2d0e0972172c66140a0565 Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 15 Jan 2026 14:50:08 -0800 Subject: [PATCH 89/99] fix: uv sync --- .github/workflows/pr-pytest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-pytest.yml b/.github/workflows/pr-pytest.yml index 981dba5..587a026 100644 --- a/.github/workflows/pr-pytest.yml +++ b/.github/workflows/pr-pytest.yml @@ -21,7 +21,7 @@ jobs: run: pip install uv - name: Install dependencies - run: uv install + run: uv sync --no-dev - name: Run pytest run: uv run pytest From 9349b54d913d620d64672a5658ce30a427ca6af6 Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 15 Jan 2026 14:53:29 -0800 Subject: [PATCH 90/99] fix: workflow following uv docs --- .github/workflows/pr-pytest.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pr-pytest.yml b/.github/workflows/pr-pytest.yml index 587a026..01d4e8e 100644 --- a/.github/workflows/pr-pytest.yml +++ b/.github/workflows/pr-pytest.yml @@ -18,10 +18,10 @@ jobs: python-version: "3.11" - name: Install uv - run: pip install uv + uses: astral-sh/setup-uv@v7 - - name: Install dependencies - run: uv sync --no-dev + - name: Install the project + run: uv sync --locked --all-extras --dev - - name: Run pytest + - name: Run tests run: uv run pytest From 68165febc271446e8425d651f71f761a727a8c6a Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 15 Jan 2026 15:48:59 -0800 Subject: [PATCH 91/99] fix: stopgap ignore dataset --- .github/workflows/pr-pytest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-pytest.yml b/.github/workflows/pr-pytest.yml index 01d4e8e..2973c2f 100644 --- a/.github/workflows/pr-pytest.yml +++ b/.github/workflows/pr-pytest.yml @@ -24,4 +24,4 @@ jobs: run: uv sync --locked --all-extras --dev - name: Run tests - run: uv run pytest + run: uv run pytest --ignore=tests/test_text_dataset.py From ab7a0ec0dbb4cd99aceaecc1b099efd13490d885 Mon Sep 17 00:00:00 2001 From: jiito Date: Tue, 27 Jan 2026 16:28:59 -0800 Subject: [PATCH 92/99] small formatting fixes --- crosslayer_transcoder/model/clt.py | 20 ++++++++-------- crosslayer_transcoder/utils/module_builder.py | 23 ------------------- .../utils/replacement_score.ipynb | 15 ++++++++---- pyproject.toml | 3 +++ .../test_circuit_tracer_integration.py | 1 - 5 files changed, 23 insertions(+), 39 deletions(-) delete mode 100644 crosslayer_transcoder/utils/module_builder.py diff --git a/crosslayer_transcoder/model/clt.py b/crosslayer_transcoder/model/clt.py index d420522..eb13339 100644 --- a/crosslayer_transcoder/model/clt.py +++ b/crosslayer_transcoder/model/clt.py @@ -202,16 +202,16 @@ def __init__(self, d_acts: int, d_features: int, n_layers: int): self.d_features = d_features self.n_layers = n_layers self.register_parameter( - f"W", nn.Parameter(torch.empty((n_layers, d_features, d_acts))) + "W", nn.Parameter(torch.empty((n_layers, d_features, d_acts))) ) - self.register_parameter(f"b", nn.Parameter(torch.empty((n_layers, d_acts)))) + self.register_parameter("b", nn.Parameter(torch.empty((n_layers, d_acts)))) self._is_folded = False self.reset_parameters() def reset_parameters(self): dec_uniform_thresh = 1 / ((self.d_acts * self.n_layers) ** 0.5) - self.get_parameter(f"W").data.uniform_(-dec_uniform_thresh, dec_uniform_thresh) - self.get_parameter(f"b").data.zero_() + self.get_parameter("W").data.uniform_(-dec_uniform_thresh, dec_uniform_thresh) + self.get_parameter("b").data.zero_() @torch.no_grad() def forward_layer( @@ -224,7 +224,7 @@ def forward_layer( return ( einsum( features, - self.get_parameter(f"W")[layer], + self.get_parameter("W")[layer], "batch_size seq d_features, d_features d_acts -> batch_size seq d_acts", ) + self.b[layer] @@ -287,7 +287,7 @@ def __init__(self, d_acts: int, d_features: int, n_layers: int): f"W_{i}", nn.Parameter(torch.empty((i + 1, d_features, d_acts))) ) self._is_folded = False - self.register_parameter(f"b", nn.Parameter(torch.empty((n_layers, d_acts)))) + self.register_parameter("b", nn.Parameter(torch.empty((n_layers, d_acts)))) self.reset_parameters() def reset_parameters(self): @@ -331,15 +331,15 @@ def forward( device=features.device, dtype=features.dtype, ) - for l in range(self.n_layers): - W = self.get_parameter(f"W_{l}") - selected_features = features[:, : l + 1] + for layer_idx in range(self.n_layers): + W = self.get_parameter(f"W_{layer_idx}") + selected_features = features[:, : layer_idx + 1] l_recons = einsum( selected_features, W, "batch_size n_layers d_features, n_layers d_features d_acts -> batch_size d_acts", ) - recons[:, l, :] = l_recons + recons[:, layer_idx, :] = l_recons recons = recons + self.b.to(features.dtype) return recons diff --git a/crosslayer_transcoder/utils/module_builder.py b/crosslayer_transcoder/utils/module_builder.py deleted file mode 100644 index 87f4265..0000000 --- a/crosslayer_transcoder/utils/module_builder.py +++ /dev/null @@ -1,23 +0,0 @@ -import importlib -import torch.nn as nn - - -def build_module_from_config(config: dict) -> nn.Module: - """Naive module builder that constructs a module from a yaml config.""" - class_path = config["class_path"] - module_name = ".".join(class_path.split(".")[:-1]) - class_name = class_path.split(".")[-1] - init_class = importlib.import_module(module_name) - init_class = getattr(init_class, class_name) - init_args = config.get("init_args", {}) - - if not init_args: - return init_class() - - for key, value in init_args.items(): - if isinstance(value, dict) and "class_path" in value: - init_args[key] = build_module_from_config(value) - - init_class = init_class(**init_args) - - return init_class diff --git a/crosslayer_transcoder/utils/replacement_score.ipynb b/crosslayer_transcoder/utils/replacement_score.ipynb index 683c638..8f6f659 100644 --- a/crosslayer_transcoder/utils/replacement_score.ipynb +++ b/crosslayer_transcoder/utils/replacement_score.ipynb @@ -5,7 +5,7 @@ "id": "1dc2a0d5", "metadata": {}, "source": [ - "# Replacement Score Test" + "# Compute Graph Replacement Score" ] }, { @@ -36,10 +36,14 @@ "metadata": {}, "outputs": [], "source": [ + "import os\n", + "\n", + "\n", "DTYPE = torch.bfloat16\n", "checkpoint_path = \"../checkpoints/clt.ckpt\"\n", "config_path = \"../../config/circuit-tracer.yaml\"\n", - "identifier = \"gpt2-crosslayer-clt-v1\"" + "identifier = \"gpt2-crosslayer-clt-v1\"\n", + "assert os.path.exists(checkpoint_path)\n" ] }, { @@ -83,12 +87,13 @@ } ], "source": [ - "from crosslayer_transcoder.utils.module_builder import build_module_from_config\n", "import yaml\n", "\n", + "from crosslayer_transcoder.model.clt import CrossLayerTranscoder\n", + "\n", "with open(config_path, \"r\") as f:\n", " config = yaml.load(f, Loader=yaml.FullLoader)\n", - " clt_module = build_module_from_config(config[\"model\"])\n", + " clt_module = CrossLayerTranscoder.from_config(config[\"model\"])\n", "\n", "checkpoint = torch.load(checkpoint_path, map_location='cuda:0')\n", "clt_module.load_state_dict(checkpoint[\"state_dict\"])\n" @@ -411,7 +416,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.3" + "version": "3.12.9" } }, "nbformat": 4, diff --git a/pyproject.toml b/pyproject.toml index ac0879c..eaf26eb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,3 +53,6 @@ allow-direct-references=true [tool.black] line-length = 110 + +[tool.ruff.lint] +ignore = ["F722"] \ No newline at end of file diff --git a/tests/circuit_tracer/test_circuit_tracer_integration.py b/tests/circuit_tracer/test_circuit_tracer_integration.py index 200ed26..8ae1443 100644 --- a/tests/circuit_tracer/test_circuit_tracer_integration.py +++ b/tests/circuit_tracer/test_circuit_tracer_integration.py @@ -1,7 +1,6 @@ import pathlib import shutil from unittest.mock import MagicMock -import torch import yaml from circuit_tracer.transcoder.cross_layer_transcoder import load_clt import pytest From 766e9ca92b2ea52e568a1de83daf59bd82212a57 Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 5 Feb 2026 08:45:24 -0800 Subject: [PATCH 93/99] wip: refactor from_pretratined to take hf_urls --- .../model/serializable_module.py | 41 ++++++-- .../utils/replacement_score.ipynb | 90 ++++++++++++----- pyproject.toml | 1 + .../test_from_config_and_checkpoint.py | 98 +++++++++++++++++++ .../test_from_pretrained.py | 28 ++++++ 5 files changed, 224 insertions(+), 34 deletions(-) create mode 100644 tests/serializable-module/test_from_config_and_checkpoint.py create mode 100644 tests/serializable-module/test_from_pretrained.py diff --git a/crosslayer_transcoder/model/serializable_module.py b/crosslayer_transcoder/model/serializable_module.py index 80ee9a4..349696b 100644 --- a/crosslayer_transcoder/model/serializable_module.py +++ b/crosslayer_transcoder/model/serializable_module.py @@ -4,6 +4,7 @@ from typing import Any, Dict, Self, TypedDict, Union import yaml +from huggingface_hub import snapshot_download from safetensors.torch import load_file, save_file from torch import nn @@ -30,8 +31,12 @@ def from_config(cls, config: ConfigDict) -> Self: for key, value in init_args.items(): if isinstance(value, dict) and "class_path" in value: - target_module_name, target_class_name = value["class_path"].rsplit(".", 1) - target_cls = getattr(importlib.import_module(target_module_name), target_class_name) + target_module_name, target_class_name = value["class_path"].rsplit( + ".", 1 + ) + target_cls = getattr( + importlib.import_module(target_module_name), target_class_name + ) resolved_args[key] = target_cls.from_config(value) else: resolved_args[key] = value @@ -52,17 +57,39 @@ def save_pretrained( @classmethod def from_pretrained(cls, directory: Union[Path, str]) -> Self: - """Load model from directory.""" - directory = Path(directory) - with open(directory / "config.yaml") as f: + """Load model from local directory or HuggingFace Hub repository.""" + path = Path(directory) + + if not path.exists(): + local_path = snapshot_download( + repo_id=str(directory), + allow_patterns=["config.yaml", "checkpoint.safetensors"], + ) + path = Path(local_path) + + with open(path / "config.yaml") as f: full_config = yaml.safe_load(f) model_config = full_config.get("model") if model_config is None: raise ValueError("Model config not found in config.yaml", full_config) - model = cls.from_config(model_config) - model.load_state_dict(load_file(directory / "checkpoint.safetensors")) + if "class_path" in model_config: + target_module_name, target_class_name = model_config["class_path"].rsplit( + ".", 1 + ) + target_cls = getattr( + importlib.import_module(target_module_name), target_class_name + ) + if target_cls is not cls: + raise ValueError( + f"Model class mismatch: {target_cls} != {cls}. You are trying to load a {target_cls} model, but the current class is {cls}." + ) + else: + target_cls = cls + + model = target_cls.from_config(model_config) + model.load_state_dict(load_file(path / "checkpoint.safetensors")) model._is_folded = model_config.get("is_folded", False) diff --git a/crosslayer_transcoder/utils/replacement_score.ipynb b/crosslayer_transcoder/utils/replacement_score.ipynb index 8f6f659..e02120b 100644 --- a/crosslayer_transcoder/utils/replacement_score.ipynb +++ b/crosslayer_transcoder/utils/replacement_score.ipynb @@ -18,7 +18,9 @@ "from crosslayer_transcoder.utils.model_converters.circuit_tracer import (\n", " CircuitTracerConverter,\n", ")\n", - "import torch\n" + "import torch\n", + "import os\n", + "import yaml\n" ] }, { @@ -31,19 +33,12 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "a37586eb", "metadata": {}, "outputs": [], "source": [ - "import os\n", - "\n", - "\n", - "DTYPE = torch.bfloat16\n", - "checkpoint_path = \"../checkpoints/clt.ckpt\"\n", - "config_path = \"../../config/circuit-tracer.yaml\"\n", - "identifier = \"gpt2-crosslayer-clt-v1\"\n", - "assert os.path.exists(checkpoint_path)\n" + "huggingface_path = \"georglange/crosslayer-transcoder-topk-16k\"" ] }, { @@ -51,24 +46,52 @@ "id": "b4458999", "metadata": {}, "source": [ - "### Load model from local checkpoint " + "### Load model from HuggingFace " ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "c166ce94", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "9143e88a119645a5b1e1857fbb6893e7", + "model_id": "f25f0390655d4b2790d60bbf69b55e2d", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Fetching 2 files: 0%| | 0/2 [00:00 1024). Running this sequence through the model will result in indexing errors\n", - "Token indices sequence length is longer than the specified maximum sequence length for this model (1561 > 1024). Running this sequence through the model will result in indexing errors\n", - "Token indices sequence length is longer than the specified maximum sequence length for this model (2459 > 1024). Running this sequence through the model will result in indexing errors\n", - "Token indices sequence length is longer than the specified maximum sequence length for this model (1174 > 1024). Running this sequence through the model will result in indexing errors\n", - "Token indices sequence length is longer than the specified maximum sequence length for this model (2027 > 1024). Running this sequence through the model will result in indexing errors\n" + "Cancellation requested; stopping current tasks.\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mKeyboardInterrupt\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[3]\u001b[39m\u001b[32m, line 4\u001b[39m\n\u001b[32m 1\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mcrosslayer_transcoder\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mmodel\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mserializable_module\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m SerializableModule\n\u001b[32m----> \u001b[39m\u001b[32m4\u001b[39m clt_model = \u001b[43mSerializableModule\u001b[49m\u001b[43m.\u001b[49m\u001b[43mfrom_pretrained\u001b[49m\u001b[43m(\u001b[49m\u001b[43mhuggingface_path\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 5\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m clt_model.is_folded \n", + "\u001b[36mFile \u001b[39m\u001b[32m~/git/crosslayer-transcoder/crosslayer_transcoder/model/serializable_module.py:64\u001b[39m, in \u001b[36mSerializableModule.from_pretrained\u001b[39m\u001b[34m(cls, directory)\u001b[39m\n\u001b[32m 61\u001b[39m path = Path(directory)\n\u001b[32m 63\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m path.exists():\n\u001b[32m---> \u001b[39m\u001b[32m64\u001b[39m local_path = \u001b[43msnapshot_download\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 65\u001b[39m \u001b[43m \u001b[49m\u001b[43mrepo_id\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mstr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mdirectory\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 66\u001b[39m \u001b[43m \u001b[49m\u001b[43mallow_patterns\u001b[49m\u001b[43m=\u001b[49m\u001b[43m[\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mconfig.yaml\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mcheckpoint.safetensors\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 67\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 68\u001b[39m path = Path(local_path)\n\u001b[32m 70\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mopen\u001b[39m(path / \u001b[33m\"\u001b[39m\u001b[33mconfig.yaml\u001b[39m\u001b[33m\"\u001b[39m) \u001b[38;5;28;01mas\u001b[39;00m f:\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/git/crosslayer-transcoder/.venv/lib/python3.12/site-packages/huggingface_hub/utils/_validators.py:114\u001b[39m, in \u001b[36mvalidate_hf_hub_args.._inner_fn\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 111\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m check_use_auth_token:\n\u001b[32m 112\u001b[39m kwargs = smoothly_deprecate_use_auth_token(fn_name=fn.\u001b[34m__name__\u001b[39m, has_token=has_token, kwargs=kwargs)\n\u001b[32m--> \u001b[39m\u001b[32m114\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfn\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/git/crosslayer-transcoder/.venv/lib/python3.12/site-packages/huggingface_hub/_snapshot_download.py:327\u001b[39m, in \u001b[36msnapshot_download\u001b[39m\u001b[34m(repo_id, repo_type, revision, cache_dir, local_dir, library_name, library_version, user_agent, proxies, etag_timeout, force_download, token, local_files_only, allow_patterns, ignore_patterns, max_workers, tqdm_class, headers, endpoint, local_dir_use_symlinks, resume_download)\u001b[39m\n\u001b[32m 325\u001b[39m _inner_hf_hub_download(file)\n\u001b[32m 326\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m327\u001b[39m \u001b[43mthread_map\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 328\u001b[39m \u001b[43m \u001b[49m\u001b[43m_inner_hf_hub_download\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 329\u001b[39m \u001b[43m \u001b[49m\u001b[43mfiltered_repo_files\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 330\u001b[39m \u001b[43m \u001b[49m\u001b[43mdesc\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtqdm_desc\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 331\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_workers\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_workers\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 332\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# User can use its own tqdm class or the default one from `huggingface_hub.utils`\u001b[39;49;00m\n\u001b[32m 333\u001b[39m \u001b[43m \u001b[49m\u001b[43mtqdm_class\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtqdm_class\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mhf_tqdm\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 334\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 336\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m local_dir \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 337\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mstr\u001b[39m(os.path.realpath(local_dir))\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/git/crosslayer-transcoder/.venv/lib/python3.12/site-packages/tqdm/contrib/concurrent.py:69\u001b[39m, in \u001b[36mthread_map\u001b[39m\u001b[34m(fn, *iterables, **tqdm_kwargs)\u001b[39m\n\u001b[32m 55\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 56\u001b[39m \u001b[33;03mEquivalent of `list(map(fn, *iterables))`\u001b[39;00m\n\u001b[32m 57\u001b[39m \u001b[33;03mdriven by `concurrent.futures.ThreadPoolExecutor`.\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 66\u001b[39m \u001b[33;03m [default: max(32, cpu_count() + 4)].\u001b[39;00m\n\u001b[32m 67\u001b[39m \u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 68\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mconcurrent\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mfutures\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m ThreadPoolExecutor\n\u001b[32m---> \u001b[39m\u001b[32m69\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_executor_map\u001b[49m\u001b[43m(\u001b[49m\u001b[43mThreadPoolExecutor\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfn\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43miterables\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mtqdm_kwargs\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/git/crosslayer-transcoder/.venv/lib/python3.12/site-packages/tqdm/contrib/concurrent.py:51\u001b[39m, in \u001b[36m_executor_map\u001b[39m\u001b[34m(PoolExecutor, fn, *iterables, **tqdm_kwargs)\u001b[39m\n\u001b[32m 47\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m ensure_lock(tqdm_class, lock_name=lock_name) \u001b[38;5;28;01mas\u001b[39;00m lk:\n\u001b[32m 48\u001b[39m \u001b[38;5;66;03m# share lock in case workers are already using `tqdm`\u001b[39;00m\n\u001b[32m 49\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m PoolExecutor(max_workers=max_workers, initializer=tqdm_class.set_lock,\n\u001b[32m 50\u001b[39m initargs=(lk,)) \u001b[38;5;28;01mas\u001b[39;00m ex:\n\u001b[32m---> \u001b[39m\u001b[32m51\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mlist\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mtqdm_class\u001b[49m\u001b[43m(\u001b[49m\u001b[43mex\u001b[49m\u001b[43m.\u001b[49m\u001b[43mmap\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfn\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43miterables\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mchunksize\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchunksize\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/git/crosslayer-transcoder/.venv/lib/python3.12/site-packages/tqdm/notebook.py:250\u001b[39m, in \u001b[36mtqdm_notebook.__iter__\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 248\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m 249\u001b[39m it = \u001b[38;5;28msuper\u001b[39m().\u001b[34m__iter__\u001b[39m()\n\u001b[32m--> \u001b[39m\u001b[32m250\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mobj\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mit\u001b[49m\u001b[43m:\u001b[49m\n\u001b[32m 251\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# return super(tqdm...) will not catch exception\u001b[39;49;00m\n\u001b[32m 252\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43;01myield\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mobj\u001b[49m\n\u001b[32m 253\u001b[39m \u001b[38;5;66;03m# NB: except ... [ as ...] breaks IPython async KeyboardInterrupt\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/git/crosslayer-transcoder/.venv/lib/python3.12/site-packages/tqdm/std.py:1181\u001b[39m, in \u001b[36mtqdm.__iter__\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 1178\u001b[39m time = \u001b[38;5;28mself\u001b[39m._time\n\u001b[32m 1180\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m-> \u001b[39m\u001b[32m1181\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mobj\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43miterable\u001b[49m\u001b[43m:\u001b[49m\n\u001b[32m 1182\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43;01myield\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mobj\u001b[49m\n\u001b[32m 1183\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# Update and possibly print the progressbar.\u001b[39;49;00m\n\u001b[32m 1184\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# Note: does not call self.update(1) for speed optimisation.\u001b[39;49;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/.local/share/uv/python/cpython-3.12.9-macos-aarch64-none/lib/python3.12/concurrent/futures/_base.py:619\u001b[39m, in \u001b[36mExecutor.map..result_iterator\u001b[39m\u001b[34m()\u001b[39m\n\u001b[32m 616\u001b[39m \u001b[38;5;28;01mwhile\u001b[39;00m fs:\n\u001b[32m 617\u001b[39m \u001b[38;5;66;03m# Careful not to keep a reference to the popped future\u001b[39;00m\n\u001b[32m 618\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m timeout \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m619\u001b[39m \u001b[38;5;28;01myield\u001b[39;00m \u001b[43m_result_or_cancel\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfs\u001b[49m\u001b[43m.\u001b[49m\u001b[43mpop\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 620\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 621\u001b[39m \u001b[38;5;28;01myield\u001b[39;00m _result_or_cancel(fs.pop(), end_time - time.monotonic())\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/.local/share/uv/python/cpython-3.12.9-macos-aarch64-none/lib/python3.12/concurrent/futures/_base.py:317\u001b[39m, in \u001b[36m_result_or_cancel\u001b[39m\u001b[34m(***failed resolving arguments***)\u001b[39m\n\u001b[32m 315\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m 316\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m317\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfut\u001b[49m\u001b[43m.\u001b[49m\u001b[43mresult\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 318\u001b[39m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[32m 319\u001b[39m fut.cancel()\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/.local/share/uv/python/cpython-3.12.9-macos-aarch64-none/lib/python3.12/concurrent/futures/_base.py:451\u001b[39m, in \u001b[36mFuture.result\u001b[39m\u001b[34m(self, timeout)\u001b[39m\n\u001b[32m 448\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._state == FINISHED:\n\u001b[32m 449\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m.__get_result()\n\u001b[32m--> \u001b[39m\u001b[32m451\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_condition\u001b[49m\u001b[43m.\u001b[49m\u001b[43mwait\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 453\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._state \u001b[38;5;129;01min\u001b[39;00m [CANCELLED, CANCELLED_AND_NOTIFIED]:\n\u001b[32m 454\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m CancelledError()\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/.local/share/uv/python/cpython-3.12.9-macos-aarch64-none/lib/python3.12/threading.py:355\u001b[39m, in \u001b[36mCondition.wait\u001b[39m\u001b[34m(self, timeout)\u001b[39m\n\u001b[32m 353\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m: \u001b[38;5;66;03m# restore state no matter what (e.g., KeyboardInterrupt)\u001b[39;00m\n\u001b[32m 354\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m timeout \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m355\u001b[39m \u001b[43mwaiter\u001b[49m\u001b[43m.\u001b[49m\u001b[43macquire\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 356\u001b[39m gotit = \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[32m 357\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n", + "\u001b[31mKeyboardInterrupt\u001b[39m: " ] } ], "source": [ - "import yaml\n", - "\n", - "from crosslayer_transcoder.model.clt import CrossLayerTranscoder\n", + "from crosslayer_transcoder.model.serializable_module import SerializableModule\n", "\n", - "with open(config_path, \"r\") as f:\n", - " config = yaml.load(f, Loader=yaml.FullLoader)\n", - " clt_module = CrossLayerTranscoder.from_config(config[\"model\"])\n", "\n", - "checkpoint = torch.load(checkpoint_path, map_location='cuda:0')\n", - "clt_module.load_state_dict(checkpoint[\"state_dict\"])\n" + "clt_model = SerializableModule.from_pretrained(huggingface_path)\n", + "assert clt_model.is_folded " ] }, { diff --git a/pyproject.toml b/pyproject.toml index eaf26eb..c7891f1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,6 +26,7 @@ dependencies = [ "modal>=1.1.4", "circuit-tracer", "hf-transfer>=0.1.9", + "huggingface_hub>=0.20.0", ] [project.optional-dependencies] diff --git a/tests/serializable-module/test_from_config_and_checkpoint.py b/tests/serializable-module/test_from_config_and_checkpoint.py new file mode 100644 index 0000000..99087ca --- /dev/null +++ b/tests/serializable-module/test_from_config_and_checkpoint.py @@ -0,0 +1,98 @@ +from pathlib import Path + +import pytest +import yaml +from safetensors.torch import save_file + +from crosslayer_transcoder.model.clt import CrossLayerTranscoder + + +def test_missing_checkpoint(config_dict, tmp_model_dir): + config_path = Path(tmp_model_dir) / "config.yaml" + with open(config_path, "w") as f: + yaml.dump({"model": config_dict}, f) + + with pytest.raises(FileNotFoundError, match="Checkpoint file not found"): + CrossLayerTranscoder.from_config_and_checkpoint( + config_path, Path(tmp_model_dir) / "checkpoint.safetensors" + ) + + +def test_missing_config(config_dict, tmp_model_dir): + model = CrossLayerTranscoder.from_config(config_dict) + checkpoint_path = Path(tmp_model_dir) / "checkpoint.safetensors" + save_file(model.state_dict(), checkpoint_path) + + with pytest.raises(FileNotFoundError, match="Config file not found"): + CrossLayerTranscoder.from_config_and_checkpoint( + Path(tmp_model_dir) / "config.yaml", checkpoint_path + ) + + +def test_missing_model_key_in_config(config_dict, tmp_model_dir): + model = CrossLayerTranscoder.from_config(config_dict) + dir_path = Path(tmp_model_dir) + config_path = dir_path / "config.yaml" + checkpoint_path = dir_path / "checkpoint.safetensors" + + with open(config_path, "w") as f: + yaml.dump({"wrong_key": config_dict}, f) + save_file(model.state_dict(), checkpoint_path) + + with pytest.raises(ValueError, match="Model config not found"): + CrossLayerTranscoder.from_config_and_checkpoint(config_path, checkpoint_path) + + +def test_is_folded_true(config_dict, tmp_model_dir): + model = CrossLayerTranscoder.from_config(config_dict) + dir_path = Path(tmp_model_dir) + config_path = dir_path / "config.yaml" + checkpoint_path = dir_path / "checkpoint.safetensors" + + config_with_folded = config_dict.copy() + config_with_folded["is_folded"] = True + with open(config_path, "w") as f: + yaml.dump({"model": config_with_folded}, f) + save_file(model.state_dict(), checkpoint_path) + + loaded = CrossLayerTranscoder.from_config_and_checkpoint( + config_path, checkpoint_path + ) + + assert loaded._is_folded is True + + +def test_is_folded_false(config_dict, tmp_model_dir): + model = CrossLayerTranscoder.from_config(config_dict) + dir_path = Path(tmp_model_dir) + config_path = dir_path / "config.yaml" + checkpoint_path = dir_path / "checkpoint.safetensors" + + config_with_folded = config_dict.copy() + config_with_folded["is_folded"] = False + with open(config_path, "w") as f: + yaml.dump({"model": config_with_folded}, f) + save_file(model.state_dict(), checkpoint_path) + + loaded = CrossLayerTranscoder.from_config_and_checkpoint( + config_path, checkpoint_path + ) + + assert loaded._is_folded is False + + +def test_is_folded_defaults_false_when_missing(config_dict, tmp_model_dir): + model = CrossLayerTranscoder.from_config(config_dict) + dir_path = Path(tmp_model_dir) + config_path = dir_path / "config.yaml" + checkpoint_path = dir_path / "checkpoint.safetensors" + + with open(config_path, "w") as f: + yaml.dump({"model": config_dict}, f) + save_file(model.state_dict(), checkpoint_path) + + loaded = CrossLayerTranscoder.from_config_and_checkpoint( + config_path, checkpoint_path + ) + + assert loaded._is_folded is False diff --git a/tests/serializable-module/test_from_pretrained.py b/tests/serializable-module/test_from_pretrained.py new file mode 100644 index 0000000..82d23e6 --- /dev/null +++ b/tests/serializable-module/test_from_pretrained.py @@ -0,0 +1,28 @@ +from pathlib import Path + +import torch + +from crosslayer_transcoder.model.clt import CrossLayerTranscoder + + +def test_round_trip(config_dict, tmp_model_dir): + original = CrossLayerTranscoder.from_config(config_dict) + original.save_pretrained(Path(tmp_model_dir)) + + loaded = CrossLayerTranscoder.from_pretrained(tmp_model_dir) + + assert isinstance(loaded, CrossLayerTranscoder) + original_state = original.state_dict() + loaded_state = loaded.state_dict() + assert original_state.keys() == loaded_state.keys() + for key in original_state: + assert torch.allclose(original_state[key], loaded_state[key], equal_nan=True) + + +def test_accepts_string_path(config_dict, tmp_model_dir): + original = CrossLayerTranscoder.from_config(config_dict) + original.save_pretrained(Path(tmp_model_dir)) + + loaded = CrossLayerTranscoder.from_pretrained(str(tmp_model_dir)) + + assert isinstance(loaded, CrossLayerTranscoder) From 625f5b2ba71251503a0dd4d71400326bcb4e3c0c Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 5 Feb 2026 17:58:37 +0000 Subject: [PATCH 94/99] refactor to avoid lightning module --- .../model/serializable_module.py | 4 - .../utils/model_converters/circuit_tracer.py | 22 +- .../utils/replacement_score.ipynb | 223 ++++-------------- uv.lock | 2 + 4 files changed, 60 insertions(+), 191 deletions(-) diff --git a/crosslayer_transcoder/model/serializable_module.py b/crosslayer_transcoder/model/serializable_module.py index 349696b..91cc110 100644 --- a/crosslayer_transcoder/model/serializable_module.py +++ b/crosslayer_transcoder/model/serializable_module.py @@ -81,10 +81,6 @@ def from_pretrained(cls, directory: Union[Path, str]) -> Self: target_cls = getattr( importlib.import_module(target_module_name), target_class_name ) - if target_cls is not cls: - raise ValueError( - f"Model class mismatch: {target_cls} != {cls}. You are trying to load a {target_cls} model, but the current class is {cls}." - ) else: target_cls = cls diff --git a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py index c8b330f..ad03f59 100644 --- a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py +++ b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py @@ -6,9 +6,13 @@ import yaml from safetensors.torch import save_file -from crosslayer_transcoder.model import BatchTopK, PerLayerBatchTopK, PerLayerTopK +from crosslayer_transcoder.model import ( + BatchTopK, + CrossLayerTranscoder, + PerLayerBatchTopK, + PerLayerTopK, +) from crosslayer_transcoder.utils.model_converters.model_converter import ( - CLTModule, ModelConverter, ) from crosslayer_transcoder.model.jumprelu import JumpReLU @@ -32,22 +36,20 @@ def __init__( self.save_dir.mkdir(parents=True, exist_ok=True) def convert_and_save( - self, model: CLTModule, dtype: torch.dtype = torch.bfloat16 + self, model: CrossLayerTranscoder, dtype: torch.dtype = torch.bfloat16 ) -> None: - if isinstance( - model.model.nonlinearity, (PerLayerTopK, BatchTopK, PerLayerBatchTopK) - ): + if isinstance(model.nonlinearity, (PerLayerTopK, BatchTopK, PerLayerBatchTopK)): logger.warning( "TopK nonlinearity is not supported by circuit-tracer. Skipping conversion." ) raise ValueError("TopK nonlinearity is not supported by circuit-tracer.") # NOTE: this mutates the model in-place. Potentially bad, but a tradeoff for copying a huge model. - model.model.fold() + model.fold() - encoder = model.model.encoder - decoder = model.model.decoder - nonlinearity = model.model.nonlinearity + encoder = model.encoder + decoder = model.decoder + nonlinearity = model.nonlinearity n_layers = encoder.n_layers d_acts = encoder.d_acts # -> circuit-tracer.d_model d_features = encoder.d_features # -> circuit-tracer.d_transcoder diff --git a/crosslayer_transcoder/utils/replacement_score.ipynb b/crosslayer_transcoder/utils/replacement_score.ipynb index e02120b..32b789d 100644 --- a/crosslayer_transcoder/utils/replacement_score.ipynb +++ b/crosslayer_transcoder/utils/replacement_score.ipynb @@ -8,21 +8,6 @@ "# Compute Graph Replacement Score" ] }, - { - "cell_type": "code", - "execution_count": 1, - "id": "b90bb04b", - "metadata": {}, - "outputs": [], - "source": [ - "from crosslayer_transcoder.utils.model_converters.circuit_tracer import (\n", - " CircuitTracerConverter,\n", - ")\n", - "import torch\n", - "import os\n", - "import yaml\n" - ] - }, { "cell_type": "markdown", "id": "a091f9ee", @@ -33,7 +18,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "id": "a37586eb", "metadata": {}, "outputs": [], @@ -51,14 +36,14 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "id": "c166ce94", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "f25f0390655d4b2790d60bbf69b55e2d", + "model_id": "38bc56a28c4644ef8bd26328563e7a6d", "version_major": 2, "version_minor": 0 }, @@ -68,63 +53,6 @@ }, "metadata": {}, "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "6ea70cc5de73400596bc8cde06743266", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "checkpoint.safetensors: 0%| | 0.00/4.42G [00:00 \u001b[39m\u001b[32m4\u001b[39m clt_model = \u001b[43mSerializableModule\u001b[49m\u001b[43m.\u001b[49m\u001b[43mfrom_pretrained\u001b[49m\u001b[43m(\u001b[49m\u001b[43mhuggingface_path\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 5\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m clt_model.is_folded \n", - "\u001b[36mFile \u001b[39m\u001b[32m~/git/crosslayer-transcoder/crosslayer_transcoder/model/serializable_module.py:64\u001b[39m, in \u001b[36mSerializableModule.from_pretrained\u001b[39m\u001b[34m(cls, directory)\u001b[39m\n\u001b[32m 61\u001b[39m path = Path(directory)\n\u001b[32m 63\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m path.exists():\n\u001b[32m---> \u001b[39m\u001b[32m64\u001b[39m local_path = \u001b[43msnapshot_download\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 65\u001b[39m \u001b[43m \u001b[49m\u001b[43mrepo_id\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mstr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mdirectory\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 66\u001b[39m \u001b[43m \u001b[49m\u001b[43mallow_patterns\u001b[49m\u001b[43m=\u001b[49m\u001b[43m[\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mconfig.yaml\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mcheckpoint.safetensors\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 67\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 68\u001b[39m path = Path(local_path)\n\u001b[32m 70\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mopen\u001b[39m(path / \u001b[33m\"\u001b[39m\u001b[33mconfig.yaml\u001b[39m\u001b[33m\"\u001b[39m) \u001b[38;5;28;01mas\u001b[39;00m f:\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/git/crosslayer-transcoder/.venv/lib/python3.12/site-packages/huggingface_hub/utils/_validators.py:114\u001b[39m, in \u001b[36mvalidate_hf_hub_args.._inner_fn\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 111\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m check_use_auth_token:\n\u001b[32m 112\u001b[39m kwargs = smoothly_deprecate_use_auth_token(fn_name=fn.\u001b[34m__name__\u001b[39m, has_token=has_token, kwargs=kwargs)\n\u001b[32m--> \u001b[39m\u001b[32m114\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfn\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/git/crosslayer-transcoder/.venv/lib/python3.12/site-packages/huggingface_hub/_snapshot_download.py:327\u001b[39m, in \u001b[36msnapshot_download\u001b[39m\u001b[34m(repo_id, repo_type, revision, cache_dir, local_dir, library_name, library_version, user_agent, proxies, etag_timeout, force_download, token, local_files_only, allow_patterns, ignore_patterns, max_workers, tqdm_class, headers, endpoint, local_dir_use_symlinks, resume_download)\u001b[39m\n\u001b[32m 325\u001b[39m _inner_hf_hub_download(file)\n\u001b[32m 326\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m327\u001b[39m \u001b[43mthread_map\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 328\u001b[39m \u001b[43m \u001b[49m\u001b[43m_inner_hf_hub_download\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 329\u001b[39m \u001b[43m \u001b[49m\u001b[43mfiltered_repo_files\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 330\u001b[39m \u001b[43m \u001b[49m\u001b[43mdesc\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtqdm_desc\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 331\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_workers\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_workers\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 332\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# User can use its own tqdm class or the default one from `huggingface_hub.utils`\u001b[39;49;00m\n\u001b[32m 333\u001b[39m \u001b[43m \u001b[49m\u001b[43mtqdm_class\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtqdm_class\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mhf_tqdm\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 334\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 336\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m local_dir \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 337\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mstr\u001b[39m(os.path.realpath(local_dir))\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/git/crosslayer-transcoder/.venv/lib/python3.12/site-packages/tqdm/contrib/concurrent.py:69\u001b[39m, in \u001b[36mthread_map\u001b[39m\u001b[34m(fn, *iterables, **tqdm_kwargs)\u001b[39m\n\u001b[32m 55\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 56\u001b[39m \u001b[33;03mEquivalent of `list(map(fn, *iterables))`\u001b[39;00m\n\u001b[32m 57\u001b[39m \u001b[33;03mdriven by `concurrent.futures.ThreadPoolExecutor`.\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 66\u001b[39m \u001b[33;03m [default: max(32, cpu_count() + 4)].\u001b[39;00m\n\u001b[32m 67\u001b[39m \u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 68\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mconcurrent\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mfutures\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m ThreadPoolExecutor\n\u001b[32m---> \u001b[39m\u001b[32m69\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_executor_map\u001b[49m\u001b[43m(\u001b[49m\u001b[43mThreadPoolExecutor\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfn\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43miterables\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mtqdm_kwargs\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/git/crosslayer-transcoder/.venv/lib/python3.12/site-packages/tqdm/contrib/concurrent.py:51\u001b[39m, in \u001b[36m_executor_map\u001b[39m\u001b[34m(PoolExecutor, fn, *iterables, **tqdm_kwargs)\u001b[39m\n\u001b[32m 47\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m ensure_lock(tqdm_class, lock_name=lock_name) \u001b[38;5;28;01mas\u001b[39;00m lk:\n\u001b[32m 48\u001b[39m \u001b[38;5;66;03m# share lock in case workers are already using `tqdm`\u001b[39;00m\n\u001b[32m 49\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m PoolExecutor(max_workers=max_workers, initializer=tqdm_class.set_lock,\n\u001b[32m 50\u001b[39m initargs=(lk,)) \u001b[38;5;28;01mas\u001b[39;00m ex:\n\u001b[32m---> \u001b[39m\u001b[32m51\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mlist\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mtqdm_class\u001b[49m\u001b[43m(\u001b[49m\u001b[43mex\u001b[49m\u001b[43m.\u001b[49m\u001b[43mmap\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfn\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43miterables\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mchunksize\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchunksize\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/git/crosslayer-transcoder/.venv/lib/python3.12/site-packages/tqdm/notebook.py:250\u001b[39m, in \u001b[36mtqdm_notebook.__iter__\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 248\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m 249\u001b[39m it = \u001b[38;5;28msuper\u001b[39m().\u001b[34m__iter__\u001b[39m()\n\u001b[32m--> \u001b[39m\u001b[32m250\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mobj\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mit\u001b[49m\u001b[43m:\u001b[49m\n\u001b[32m 251\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# return super(tqdm...) will not catch exception\u001b[39;49;00m\n\u001b[32m 252\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43;01myield\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mobj\u001b[49m\n\u001b[32m 253\u001b[39m \u001b[38;5;66;03m# NB: except ... [ as ...] breaks IPython async KeyboardInterrupt\u001b[39;00m\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/git/crosslayer-transcoder/.venv/lib/python3.12/site-packages/tqdm/std.py:1181\u001b[39m, in \u001b[36mtqdm.__iter__\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 1178\u001b[39m time = \u001b[38;5;28mself\u001b[39m._time\n\u001b[32m 1180\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m-> \u001b[39m\u001b[32m1181\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mobj\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43miterable\u001b[49m\u001b[43m:\u001b[49m\n\u001b[32m 1182\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43;01myield\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mobj\u001b[49m\n\u001b[32m 1183\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# Update and possibly print the progressbar.\u001b[39;49;00m\n\u001b[32m 1184\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# Note: does not call self.update(1) for speed optimisation.\u001b[39;49;00m\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/.local/share/uv/python/cpython-3.12.9-macos-aarch64-none/lib/python3.12/concurrent/futures/_base.py:619\u001b[39m, in \u001b[36mExecutor.map..result_iterator\u001b[39m\u001b[34m()\u001b[39m\n\u001b[32m 616\u001b[39m \u001b[38;5;28;01mwhile\u001b[39;00m fs:\n\u001b[32m 617\u001b[39m \u001b[38;5;66;03m# Careful not to keep a reference to the popped future\u001b[39;00m\n\u001b[32m 618\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m timeout \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m619\u001b[39m \u001b[38;5;28;01myield\u001b[39;00m \u001b[43m_result_or_cancel\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfs\u001b[49m\u001b[43m.\u001b[49m\u001b[43mpop\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 620\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 621\u001b[39m \u001b[38;5;28;01myield\u001b[39;00m _result_or_cancel(fs.pop(), end_time - time.monotonic())\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/.local/share/uv/python/cpython-3.12.9-macos-aarch64-none/lib/python3.12/concurrent/futures/_base.py:317\u001b[39m, in \u001b[36m_result_or_cancel\u001b[39m\u001b[34m(***failed resolving arguments***)\u001b[39m\n\u001b[32m 315\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m 316\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m317\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfut\u001b[49m\u001b[43m.\u001b[49m\u001b[43mresult\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 318\u001b[39m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[32m 319\u001b[39m fut.cancel()\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/.local/share/uv/python/cpython-3.12.9-macos-aarch64-none/lib/python3.12/concurrent/futures/_base.py:451\u001b[39m, in \u001b[36mFuture.result\u001b[39m\u001b[34m(self, timeout)\u001b[39m\n\u001b[32m 448\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._state == FINISHED:\n\u001b[32m 449\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m.__get_result()\n\u001b[32m--> \u001b[39m\u001b[32m451\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_condition\u001b[49m\u001b[43m.\u001b[49m\u001b[43mwait\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 453\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._state \u001b[38;5;129;01min\u001b[39;00m [CANCELLED, CANCELLED_AND_NOTIFIED]:\n\u001b[32m 454\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m CancelledError()\n", - "\u001b[36mFile \u001b[39m\u001b[32m~/.local/share/uv/python/cpython-3.12.9-macos-aarch64-none/lib/python3.12/threading.py:355\u001b[39m, in \u001b[36mCondition.wait\u001b[39m\u001b[34m(self, timeout)\u001b[39m\n\u001b[32m 353\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m: \u001b[38;5;66;03m# restore state no matter what (e.g., KeyboardInterrupt)\u001b[39;00m\n\u001b[32m 354\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m timeout \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m355\u001b[39m \u001b[43mwaiter\u001b[49m\u001b[43m.\u001b[49m\u001b[43macquire\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 356\u001b[39m gotit = \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[32m 357\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n", - "\u001b[31mKeyboardInterrupt\u001b[39m: " - ] } ], "source": [ @@ -132,7 +60,18 @@ "\n", "\n", "clt_model = SerializableModule.from_pretrained(huggingface_path)\n", - "assert clt_model.is_folded " + "assert clt_model._is_folded " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "95a146b5", + "metadata": {}, + "outputs": [], + "source": [ + "from crosslayer_transcoder.model.clt import CrossLayerTranscoder\n", + "assert isinstance(clt_model, CrossLayerTranscoder)" ] }, { @@ -145,12 +84,27 @@ "name": "stderr", "output_type": "stream", "text": [ - "Converting CLT : 100%|██████████| 12/12 [00:23<00:00, 1.99s/it]\n" + "TopK nonlinearity is not supported by circuit-tracer. Skipping conversion.\n" + ] + }, + { + "ename": "ValueError", + "evalue": "TopK nonlinearity is not supported by circuit-tracer.", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mValueError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[4]\u001b[39m\u001b[32m, line 13\u001b[39m\n\u001b[32m 6\u001b[39m feature_output_hook = \u001b[33m\"\u001b[39m\u001b[33mhook_mlp_out\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 8\u001b[39m converter = CircuitTracerConverter(\n\u001b[32m 9\u001b[39m save_dir=save_dir,\n\u001b[32m 10\u001b[39m feature_input_hook=feature_input_hook,\n\u001b[32m 11\u001b[39m feature_output_hook=feature_output_hook,\n\u001b[32m 12\u001b[39m )\n\u001b[32m---> \u001b[39m\u001b[32m13\u001b[39m \u001b[43mconverter\u001b[49m\u001b[43m.\u001b[49m\u001b[43mconvert_and_save\u001b[49m\u001b[43m(\u001b[49m\u001b[43mclt_model\u001b[49m\u001b[43m)\u001b[49m \n", + "\u001b[36mFile \u001b[39m\u001b[32m~/crosslayer-transcoder/crosslayer_transcoder/utils/model_converters/circuit_tracer.py:46\u001b[39m, in \u001b[36mCircuitTracerConverter.convert_and_save\u001b[39m\u001b[34m(self, model, dtype)\u001b[39m\n\u001b[32m 42\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(model.nonlinearity, (PerLayerTopK, BatchTopK, PerLayerBatchTopK)):\n\u001b[32m 43\u001b[39m logger.warning(\n\u001b[32m 44\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mTopK nonlinearity is not supported by circuit-tracer. Skipping conversion.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 45\u001b[39m )\n\u001b[32m---> \u001b[39m\u001b[32m46\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[33m\"\u001b[39m\u001b[33mTopK nonlinearity is not supported by circuit-tracer.\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m 48\u001b[39m \u001b[38;5;66;03m# NOTE: this mutates the model in-place. Potentially bad, but a tradeoff for copying a huge model.\u001b[39;00m\n\u001b[32m 49\u001b[39m model.fold()\n", + "\u001b[31mValueError\u001b[39m: TopK nonlinearity is not supported by circuit-tracer." ] } ], "source": [ - "save_dir = \"clt_module_test\"\n", + "from crosslayer_transcoder.utils.model_converters.circuit_tracer import (\n", + " CircuitTracerConverter,\n", + ")\n", + "save_dir = \"circuit_tracing_replacement_score\"\n", "feature_input_hook = \"hook_resid_mid\"\n", "feature_output_hook = \"hook_mlp_out\"\n", "\n", @@ -159,7 +113,7 @@ "feature_input_hook=feature_input_hook,\n", " feature_output_hook=feature_output_hook,\n", ")\n", - "converter.convert_and_save(clt_module, dtype=DTYPE) " + "converter.convert_and_save(clt_model) " ] }, { @@ -174,7 +128,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "f8d8594b", "metadata": {}, "outputs": [], @@ -193,25 +147,10 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "1bcce2aa", "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "`torch_dtype` is deprecated! Use `dtype` instead!\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Loaded pretrained model gpt2 into HookedTransformer\n" - ] - } - ], + "outputs": [], "source": [ "from circuit_tracer import ReplacementModel\n", "\n", @@ -232,7 +171,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "id": "10269291", "metadata": {}, "outputs": [], @@ -249,33 +188,10 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "id": "ecb6f82c", "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Phase 0: Precomputing activations and vectors\n", - "Precomputation completed in 0.51s\n", - "Found 1316 active features\n", - "Phase 1: Running forward pass\n", - "Forward pass completed in 0.04s\n", - "Phase 2: Building input vectors\n", - "Selected 10 logits with cumulative probability 0.2871\n", - "Will include 1316 of 1316 feature nodes\n", - "Input vectors built in 0.04s\n", - "Phase 3: Computing logit attributions\n", - "sys:1: UserWarning: Full backward hook is firing when gradients are computed with respect to module outputs since no inputs require gradients. See https://docs.pytorch.org/docs/main/generated/torch.nn.Module.html#torch.nn.Module.register_full_backward_hook for more details.\n", - "Logit attributions completed in 0.05s\n", - "Phase 4: Computing feature attributions\n", - "Feature influence computation: 100%|██████████| 1316/1316 [00:00<00:00, 7560.45it/s]\n", - "Feature attributions completed in 0.18s\n", - "Attribution completed in 0.82s\n" - ] - } - ], + "outputs": [], "source": [ "from pathlib import Path\n", "import torch\n", @@ -307,28 +223,10 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "id": "4008f230", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "replacement score, completeness score\n" - ] - }, - { - "data": { - "text/plain": [ - "(0.7424161434173584, 0.919729471206665)" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from circuit_tracer.graph import compute_graph_scores\n", "print(\"replacement score, completeness score\")\n", @@ -345,7 +243,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "id": "191aafa5", "metadata": {}, "outputs": [], @@ -361,7 +259,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "id": "9e4da199", "metadata": {}, "outputs": [], @@ -386,39 +284,10 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "id": "50185332", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Use the IFrame below, or open your graph here: f'http://localhost:8046/index.html'\n" - ] - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "from circuit_tracer.frontend.local_server import serve\n", "from IPython.display import IFrame\n", @@ -452,7 +321,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.9" + "version": "3.12.12" } }, "nbformat": 4, diff --git a/uv.lock b/uv.lock index fc6fd6f..3534df2 100644 --- a/uv.lock +++ b/uv.lock @@ -393,6 +393,7 @@ dependencies = [ { name = "einops" }, { name = "h5py" }, { name = "hf-transfer" }, + { name = "huggingface-hub" }, { name = "jaxtyping" }, { name = "jsonargparse", extra = ["signatures"] }, { name = "lightning" }, @@ -427,6 +428,7 @@ requires-dist = [ { name = "einops", specifier = ">=0.8.1" }, { name = "h5py", specifier = ">=3.13.0" }, { name = "hf-transfer", specifier = ">=0.1.9" }, + { name = "huggingface-hub", specifier = ">=0.20.0" }, { name = "ipykernel", marker = "extra == 'dev'", specifier = ">=6.29.5" }, { name = "jaxtyping", specifier = ">=0.3.2" }, { name = "jsonargparse", extras = ["signatures"], specifier = ">=4.27.7" }, From be142182232a65736af83bf2ce3cfb2e59c97f53 Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 5 Feb 2026 19:09:26 +0000 Subject: [PATCH 95/99] feat: support PerLayerTopK activation function --- .../utils/model_converters/circuit_tracer.py | 7 +- .../utils/replacement_score.ipynb | 224 +++++++++++++++--- 2 files changed, 195 insertions(+), 36 deletions(-) diff --git a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py index ad03f59..9d216e5 100644 --- a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py +++ b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py @@ -12,6 +12,7 @@ PerLayerBatchTopK, PerLayerTopK, ) +from crosslayer_transcoder.model.topk import TopK from crosslayer_transcoder.utils.model_converters.model_converter import ( ModelConverter, ) @@ -38,7 +39,7 @@ def __init__( def convert_and_save( self, model: CrossLayerTranscoder, dtype: torch.dtype = torch.bfloat16 ) -> None: - if isinstance(model.nonlinearity, (PerLayerTopK, BatchTopK, PerLayerBatchTopK)): + if isinstance(model.nonlinearity, (BatchTopK, PerLayerBatchTopK)): logger.warning( "TopK nonlinearity is not supported by circuit-tracer. Skipping conversion." ) @@ -75,6 +76,10 @@ def convert_and_save( layer_encoder_dict[f"threshold_{source_layer}"] = ( nonlinearity.theta[:, source_layer, :].cpu().to(dtype) ) + if isinstance(nonlinearity, PerLayerTopK): + layer_encoder_dict[f"k_{source_layer}"] = torch.tensor( + [nonlinearity.k], dtype=torch.int + ) save_file( layer_encoder_dict, f"{self.save_dir}/W_enc_{source_layer}.safetensors" diff --git a/crosslayer_transcoder/utils/replacement_score.ipynb b/crosslayer_transcoder/utils/replacement_score.ipynb index 32b789d..c8fdd61 100644 --- a/crosslayer_transcoder/utils/replacement_score.ipynb +++ b/crosslayer_transcoder/utils/replacement_score.ipynb @@ -5,7 +5,7 @@ "id": "1dc2a0d5", "metadata": {}, "source": [ - "# Compute Graph Replacement Score" + "# Compute Graph Replacement Score & Visualize" ] }, { @@ -43,7 +43,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "38bc56a28c4644ef8bd26328563e7a6d", + "model_id": "8e3de157afec4833b82d7e98ae88a658", "version_major": 2, "version_minor": 0 }, @@ -84,19 +84,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "TopK nonlinearity is not supported by circuit-tracer. Skipping conversion.\n" - ] - }, - { - "ename": "ValueError", - "evalue": "TopK nonlinearity is not supported by circuit-tracer.", - "output_type": "error", - "traceback": [ - "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mValueError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[4]\u001b[39m\u001b[32m, line 13\u001b[39m\n\u001b[32m 6\u001b[39m feature_output_hook = \u001b[33m\"\u001b[39m\u001b[33mhook_mlp_out\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 8\u001b[39m converter = CircuitTracerConverter(\n\u001b[32m 9\u001b[39m save_dir=save_dir,\n\u001b[32m 10\u001b[39m feature_input_hook=feature_input_hook,\n\u001b[32m 11\u001b[39m feature_output_hook=feature_output_hook,\n\u001b[32m 12\u001b[39m )\n\u001b[32m---> \u001b[39m\u001b[32m13\u001b[39m \u001b[43mconverter\u001b[49m\u001b[43m.\u001b[49m\u001b[43mconvert_and_save\u001b[49m\u001b[43m(\u001b[49m\u001b[43mclt_model\u001b[49m\u001b[43m)\u001b[49m \n", - "\u001b[36mFile \u001b[39m\u001b[32m~/crosslayer-transcoder/crosslayer_transcoder/utils/model_converters/circuit_tracer.py:46\u001b[39m, in \u001b[36mCircuitTracerConverter.convert_and_save\u001b[39m\u001b[34m(self, model, dtype)\u001b[39m\n\u001b[32m 42\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(model.nonlinearity, (PerLayerTopK, BatchTopK, PerLayerBatchTopK)):\n\u001b[32m 43\u001b[39m logger.warning(\n\u001b[32m 44\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mTopK nonlinearity is not supported by circuit-tracer. Skipping conversion.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 45\u001b[39m )\n\u001b[32m---> \u001b[39m\u001b[32m46\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[33m\"\u001b[39m\u001b[33mTopK nonlinearity is not supported by circuit-tracer.\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m 48\u001b[39m \u001b[38;5;66;03m# NOTE: this mutates the model in-place. Potentially bad, but a tradeoff for copying a huge model.\u001b[39;00m\n\u001b[32m 49\u001b[39m model.fold()\n", - "\u001b[31mValueError\u001b[39m: TopK nonlinearity is not supported by circuit-tracer." + "Converting CLT encoder: 100%|██████████| 12/12 [00:33<00:00, 2.77s/it]\n" ] } ], @@ -128,36 +116,148 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "f8d8594b", "metadata": {}, "outputs": [], "source": [ "from circuit_tracer.transcoder.cross_layer_transcoder import load_clt\n", + "scan_id = \"dallas-austin\"\n", "circuit_tracer_clt = load_clt(\n", " clt_path=save_dir,\n", " lazy_decoder=False,\n", " lazy_encoder=False,\n", " feature_input_hook=feature_input_hook,\n", " feature_output_hook=feature_output_hook,\n", - " dtype=DTYPE,\n", - " scan=identifier\n", + " scan=scan_id\n", ")\n" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "1bcce2aa", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "462db96b956a4063996a865c840c3ec7", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "config.json: 0%| | 0.00/665 [00:00 Date: Thu, 5 Feb 2026 22:58:25 +0000 Subject: [PATCH 96/99] fix: tests --- .../test_circuit_tracer_integration.py | 61 +----------- .../test_convert_to_circuit_tracer.py | 7 +- tests/conftest.py | 25 +---- .../test_from_config_and_checkpoint.py | 98 ------------------- .../test_from_pretrained.py | 28 ------ 5 files changed, 10 insertions(+), 209 deletions(-) delete mode 100644 tests/serializable-module/test_from_config_and_checkpoint.py delete mode 100644 tests/serializable-module/test_from_pretrained.py diff --git a/tests/circuit_tracer/test_circuit_tracer_integration.py b/tests/circuit_tracer/test_circuit_tracer_integration.py index 8ae1443..cc0fcd7 100644 --- a/tests/circuit_tracer/test_circuit_tracer_integration.py +++ b/tests/circuit_tracer/test_circuit_tracer_integration.py @@ -12,14 +12,10 @@ def test_circuit_tracer_integration(): - """Verify uploaded model loads correctly.""" with open("config/circuit-tracer.yaml", "r") as f: config = yaml.safe_load(f) model_config = config["model"]["init_args"]["model"] - clt_model = CrossLayerTranscoder.from_config(model_config) - - clt_module = MagicMock() - clt_module.model = clt_model + clt = CrossLayerTranscoder.from_config(model_config) save_dir = pathlib.Path("clt_module_test") feature_input_hook = "hook_resid_mid" @@ -30,7 +26,7 @@ def test_circuit_tracer_integration(): feature_input_hook=feature_input_hook, feature_output_hook=feature_output_hook, ) - converter.convert_and_save(clt_module) + converter.convert_and_save(clt) transcoder = load_clt( clt_path=save_dir.as_posix(), @@ -40,58 +36,11 @@ def test_circuit_tracer_integration(): feature_output_hook=feature_output_hook, ) - assert transcoder.n_layers == clt_module.model.encoder.n_layers - assert transcoder.d_transcoder == clt_module.model.encoder.d_features - assert transcoder.d_model == clt_module.model.encoder.d_acts + assert transcoder.n_layers == clt.encoder.n_layers + assert transcoder.d_transcoder == clt.encoder.d_features + assert transcoder.d_model == clt.encoder.d_acts assert transcoder.feature_input_hook == feature_input_hook assert transcoder.feature_output_hook == feature_output_hook # cleanup shutil.rmtree(save_dir) - - -def test_topk_nonlinearity(): - model_config = { - "class_path": "crosslayer_transcoder.model.clt.CrossLayerTranscoder", - "init_args": { - "encoder": { - "class_path": "crosslayer_transcoder.model.clt.Encoder", - "init_args": {"d_acts": 768, "d_features": 10_000, "n_layers": 12}, - }, - "decoder": { - "class_path": "crosslayer_transcoder.model.clt.CrosslayerDecoder", - "init_args": {"d_acts": 768, "d_features": 10_000, "n_layers": 12}, - }, - "nonlinearity": { - "class_path": "crosslayer_transcoder.model.topk.PerLayerTopK", - "init_args": { - "k": 8, - }, - }, - "input_standardizer": { - "class_path": "crosslayer_transcoder.model.standardize.DimensionwiseInputStandardizer", - "init_args": {"n_layers": 12, "activation_dim": 768}, - }, - "output_standardizer": { - "class_path": "crosslayer_transcoder.model.standardize.DimensionwiseOutputStandardizer", - "init_args": {"n_layers": 12, "activation_dim": 768}, - }, - }, - } - clt_model = CrossLayerTranscoder.from_config(model_config) - clt_module = MagicMock() - clt_module.model = clt_model - save_dir = pathlib.Path("topk_clt_module_test") - feature_input_hook = "hook_resid_mid" - feature_output_hook = "hook_mlp_out" - - with pytest.raises( - ValueError, - match="TopK nonlinearity is not supported by circuit-tracer.", - ): - converter = CircuitTracerConverter( - save_dir=save_dir, - feature_input_hook=feature_input_hook, - feature_output_hook=feature_output_hook, - ) - converter.convert_and_save(clt_module) diff --git a/tests/circuit_tracer/test_convert_to_circuit_tracer.py b/tests/circuit_tracer/test_convert_to_circuit_tracer.py index 4d1a7ba..b94073f 100644 --- a/tests/circuit_tracer/test_convert_to_circuit_tracer.py +++ b/tests/circuit_tracer/test_convert_to_circuit_tracer.py @@ -6,15 +6,14 @@ import shutil -def test_circuit_tracer_converter(jumprelu_clt_module): +def test_circuit_tracer_converter(jumprelu_clt): save_dir = pathlib.Path("clt_module") converter = CircuitTracerConverter(save_dir=save_dir) - converter.convert_and_save(jumprelu_clt_module) + converter.convert_and_save(jumprelu_clt) assert save_dir.exists() assert ( - len(list(save_dir.glob("*.safetensors"))) - == jumprelu_clt_module.model.encoder.n_layers * 2 + len(list(save_dir.glob("*.safetensors"))) == jumprelu_clt.encoder.n_layers * 2 ) assert (save_dir / "config.yaml").exists() diff --git a/tests/conftest.py b/tests/conftest.py index 85d0fba..639763c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,10 +2,8 @@ @pytest.fixture(scope="session") -def jumprelu_clt_module(): - from crosslayer_transcoder.metrics.dead_features import DeadFeatures +def jumprelu_clt(): from crosslayer_transcoder.model.clt import CrossLayerTranscoder - from crosslayer_transcoder.model.clt_lightning import CrossLayerTranscoderModule model_config = { "class_path": "crosslayer_transcoder.model.clt.CrossLayerTranscoder", @@ -40,23 +38,4 @@ def jumprelu_clt_module(): model = CrossLayerTranscoder.from_config(model_config) - dead_features = DeadFeatures( - n_features=10_000, - n_layers=12, - return_per_layer=True, - return_log_freqs=True, - return_neuron_indices=True, - ) - - clt_module = CrossLayerTranscoderModule( - model=model, - dead_features=dead_features, - learning_rate=1e-4, - compile=True, - lr_decay_step=80_000, - lr_decay_factor=0.1, - compute_dead_features=True, - compute_dead_features_every=500, - ) - - return clt_module + return model diff --git a/tests/serializable-module/test_from_config_and_checkpoint.py b/tests/serializable-module/test_from_config_and_checkpoint.py deleted file mode 100644 index 99087ca..0000000 --- a/tests/serializable-module/test_from_config_and_checkpoint.py +++ /dev/null @@ -1,98 +0,0 @@ -from pathlib import Path - -import pytest -import yaml -from safetensors.torch import save_file - -from crosslayer_transcoder.model.clt import CrossLayerTranscoder - - -def test_missing_checkpoint(config_dict, tmp_model_dir): - config_path = Path(tmp_model_dir) / "config.yaml" - with open(config_path, "w") as f: - yaml.dump({"model": config_dict}, f) - - with pytest.raises(FileNotFoundError, match="Checkpoint file not found"): - CrossLayerTranscoder.from_config_and_checkpoint( - config_path, Path(tmp_model_dir) / "checkpoint.safetensors" - ) - - -def test_missing_config(config_dict, tmp_model_dir): - model = CrossLayerTranscoder.from_config(config_dict) - checkpoint_path = Path(tmp_model_dir) / "checkpoint.safetensors" - save_file(model.state_dict(), checkpoint_path) - - with pytest.raises(FileNotFoundError, match="Config file not found"): - CrossLayerTranscoder.from_config_and_checkpoint( - Path(tmp_model_dir) / "config.yaml", checkpoint_path - ) - - -def test_missing_model_key_in_config(config_dict, tmp_model_dir): - model = CrossLayerTranscoder.from_config(config_dict) - dir_path = Path(tmp_model_dir) - config_path = dir_path / "config.yaml" - checkpoint_path = dir_path / "checkpoint.safetensors" - - with open(config_path, "w") as f: - yaml.dump({"wrong_key": config_dict}, f) - save_file(model.state_dict(), checkpoint_path) - - with pytest.raises(ValueError, match="Model config not found"): - CrossLayerTranscoder.from_config_and_checkpoint(config_path, checkpoint_path) - - -def test_is_folded_true(config_dict, tmp_model_dir): - model = CrossLayerTranscoder.from_config(config_dict) - dir_path = Path(tmp_model_dir) - config_path = dir_path / "config.yaml" - checkpoint_path = dir_path / "checkpoint.safetensors" - - config_with_folded = config_dict.copy() - config_with_folded["is_folded"] = True - with open(config_path, "w") as f: - yaml.dump({"model": config_with_folded}, f) - save_file(model.state_dict(), checkpoint_path) - - loaded = CrossLayerTranscoder.from_config_and_checkpoint( - config_path, checkpoint_path - ) - - assert loaded._is_folded is True - - -def test_is_folded_false(config_dict, tmp_model_dir): - model = CrossLayerTranscoder.from_config(config_dict) - dir_path = Path(tmp_model_dir) - config_path = dir_path / "config.yaml" - checkpoint_path = dir_path / "checkpoint.safetensors" - - config_with_folded = config_dict.copy() - config_with_folded["is_folded"] = False - with open(config_path, "w") as f: - yaml.dump({"model": config_with_folded}, f) - save_file(model.state_dict(), checkpoint_path) - - loaded = CrossLayerTranscoder.from_config_and_checkpoint( - config_path, checkpoint_path - ) - - assert loaded._is_folded is False - - -def test_is_folded_defaults_false_when_missing(config_dict, tmp_model_dir): - model = CrossLayerTranscoder.from_config(config_dict) - dir_path = Path(tmp_model_dir) - config_path = dir_path / "config.yaml" - checkpoint_path = dir_path / "checkpoint.safetensors" - - with open(config_path, "w") as f: - yaml.dump({"model": config_dict}, f) - save_file(model.state_dict(), checkpoint_path) - - loaded = CrossLayerTranscoder.from_config_and_checkpoint( - config_path, checkpoint_path - ) - - assert loaded._is_folded is False diff --git a/tests/serializable-module/test_from_pretrained.py b/tests/serializable-module/test_from_pretrained.py deleted file mode 100644 index 82d23e6..0000000 --- a/tests/serializable-module/test_from_pretrained.py +++ /dev/null @@ -1,28 +0,0 @@ -from pathlib import Path - -import torch - -from crosslayer_transcoder.model.clt import CrossLayerTranscoder - - -def test_round_trip(config_dict, tmp_model_dir): - original = CrossLayerTranscoder.from_config(config_dict) - original.save_pretrained(Path(tmp_model_dir)) - - loaded = CrossLayerTranscoder.from_pretrained(tmp_model_dir) - - assert isinstance(loaded, CrossLayerTranscoder) - original_state = original.state_dict() - loaded_state = loaded.state_dict() - assert original_state.keys() == loaded_state.keys() - for key in original_state: - assert torch.allclose(original_state[key], loaded_state[key], equal_nan=True) - - -def test_accepts_string_path(config_dict, tmp_model_dir): - original = CrossLayerTranscoder.from_config(config_dict) - original.save_pretrained(Path(tmp_model_dir)) - - loaded = CrossLayerTranscoder.from_pretrained(str(tmp_model_dir)) - - assert isinstance(loaded, CrossLayerTranscoder) From 1893c1178cacc3cf7ce534a1309bd1d250185c33 Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 5 Feb 2026 22:58:38 +0000 Subject: [PATCH 97/99] use IOI prompt --- .../utils/replacement_score.ipynb | 146 +++--------------- 1 file changed, 22 insertions(+), 124 deletions(-) diff --git a/crosslayer_transcoder/utils/replacement_score.ipynb b/crosslayer_transcoder/utils/replacement_score.ipynb index c8fdd61..15a1003 100644 --- a/crosslayer_transcoder/utils/replacement_score.ipynb +++ b/crosslayer_transcoder/utils/replacement_score.ipynb @@ -43,7 +43,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "8e3de157afec4833b82d7e98ae88a658", + "model_id": "ea4d424e20614d70823decee70cbdc5b", "version_major": 2, "version_minor": 0 }, @@ -84,7 +84,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "Converting CLT encoder: 100%|██████████| 12/12 [00:33<00:00, 2.77s/it]\n" + "Converting CLT encoder: 100%|██████████| 12/12 [00:33<00:00, 2.79s/it]\n" ] } ], @@ -139,20 +139,6 @@ "id": "1bcce2aa", "metadata": {}, "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "462db96b956a4063996a865c840c3ec7", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "config.json: 0%| | 0.00/665 [00:00= 0.8\n", @@ -425,7 +331,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "id": "50185332", "metadata": {}, "outputs": [ @@ -433,7 +339,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Use the IFrame below, or open your graph here: f'http://localhost:8048/index.html'\n" + "Open your graph here: f'http://localhost:8048/index.html'\n" ] } ], @@ -449,14 +355,6 @@ " f\"Open your graph here: f'http://localhost:{port}/index.html'\"\n", ")\n" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9873d294", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { From 542149c3994cbd44998a276013b5c7e3ada36f49 Mon Sep 17 00:00:00 2001 From: jiito Date: Thu, 5 Feb 2026 22:59:39 +0000 Subject: [PATCH 98/99] cleanup test --- tests/circuit_tracer/test_circuit_tracer_integration.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/circuit_tracer/test_circuit_tracer_integration.py b/tests/circuit_tracer/test_circuit_tracer_integration.py index cc0fcd7..9859d9a 100644 --- a/tests/circuit_tracer/test_circuit_tracer_integration.py +++ b/tests/circuit_tracer/test_circuit_tracer_integration.py @@ -1,9 +1,8 @@ import pathlib import shutil -from unittest.mock import MagicMock + import yaml from circuit_tracer.transcoder.cross_layer_transcoder import load_clt -import pytest from crosslayer_transcoder.model.clt import CrossLayerTranscoder from crosslayer_transcoder.utils.model_converters.circuit_tracer import ( From b3a3af08568577a0a5b1f1f712be422a61960e45 Mon Sep 17 00:00:00 2001 From: jiito Date: Fri, 6 Feb 2026 02:22:29 +0000 Subject: [PATCH 99/99] initial refactor of model saving --- crosslayer_transcoder/model/clt.py | 61 ++++ .../utils/model_converters/circuit_tracer.py | 151 +++++----- .../utils/replacement_score.ipynb | 265 ++++++++++++++++-- .../utils/sanity_check_model.ipynb | 2 +- .../test_circuit_tracer_integration.py | 2 +- .../test_convert_to_circuit_tracer.py | 2 +- 6 files changed, 395 insertions(+), 88 deletions(-) diff --git a/crosslayer_transcoder/model/clt.py b/crosslayer_transcoder/model/clt.py index eb13339..fb91d5d 100644 --- a/crosslayer_transcoder/model/clt.py +++ b/crosslayer_transcoder/model/clt.py @@ -1,6 +1,7 @@ from pathlib import Path from typing import Any, Dict, Optional, Tuple, Union +import einops import torch import torch.nn as nn import yaml @@ -194,6 +195,17 @@ def to_config(self) -> Dict[str, Any]: }, } + def to_circuit_tracer(self): + W = einops.rearrange( + self.get_parameter("W"), + "n_layers d_acts d_features -> n_layers d_features d_acts", + ).contiguous() + b = self.get_parameter("b") + return { + "W": W, + "b": b, + } + class Decoder(SerializableModule): def __init__(self, d_acts: int, d_features: int, n_layers: int): @@ -275,6 +287,12 @@ def to_config(self) -> Dict[str, Any]: }, } + def to_circuit_tracer(self): + return { + "W": self.W, + "b": self.b, + } + class CrosslayerDecoder(SerializableModule): def __init__(self, d_acts: int, d_features: int, n_layers: int): @@ -369,6 +387,32 @@ def to_config(self) -> Dict[str, Any]: }, } + def to_circuit_tracer(self): + output_decs = [] + for source_layer in range(self.n_layers): + output_dec_i = torch.zeros( + [self.d_features, self.n_layers - source_layer, self.d_acts], + ) + + for k in range(source_layer, self.n_layers): + # get decoder mat for layer i --> k + decoder_w_k = self.get_parameter(f"W_{k}") + + dec_i_k = decoder_w_k[source_layer, ...] + assert dec_i_k.shape == ( + self.d_features, + self.d_acts, + ) + + output_dec_i[:, k - source_layer, ...] = dec_i_k + + output_decs.append(output_dec_i) + + return { + "W": output_decs, + "b": self.b, + } + class CrossLayerTranscoder(SerializableModule): def __init__( @@ -465,3 +509,20 @@ def save_pretrained(self, directory: Path, fold_standardizers: bool = True): yaml.dump({"model": config}, f) save_file(self.state_dict(), directory / "checkpoint.safetensors") + + def to_circuit_tracer(self): + # NOTE: this mutates the model in-place. Potentially bad, but a tradeoff for copying a huge model. + self.fold() + + encoder = self.encoder.to_circuit_tracer() + decoder = self.decoder.to_circuit_tracer() + + is_per_layer_decoder = isinstance(self.decoder, Decoder) + + config = { + "is_per_layer_decoder": is_per_layer_decoder, + "encoder": encoder, + "decoder": decoder, + } + + return config diff --git a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py index 9d216e5..5c6b2e3 100644 --- a/crosslayer_transcoder/utils/model_converters/circuit_tracer.py +++ b/crosslayer_transcoder/utils/model_converters/circuit_tracer.py @@ -1,24 +1,19 @@ +import logging from pathlib import Path -import einops -from tqdm import tqdm import torch import yaml from safetensors.torch import save_file from crosslayer_transcoder.model import ( - BatchTopK, CrossLayerTranscoder, - PerLayerBatchTopK, PerLayerTopK, ) -from crosslayer_transcoder.model.topk import TopK +from crosslayer_transcoder.model.clt import Decoder +from crosslayer_transcoder.model.jumprelu import JumpReLU from crosslayer_transcoder.utils.model_converters.model_converter import ( ModelConverter, ) -from crosslayer_transcoder.model.jumprelu import JumpReLU - -import logging logger = logging.getLogger(__name__) @@ -36,80 +31,102 @@ def __init__( self.save_dir.mkdir(parents=True, exist_ok=True) - def convert_and_save( - self, model: CrossLayerTranscoder, dtype: torch.dtype = torch.bfloat16 - ) -> None: - if isinstance(model.nonlinearity, (BatchTopK, PerLayerBatchTopK)): - logger.warning( - "TopK nonlinearity is not supported by circuit-tracer. Skipping conversion." - ) - raise ValueError("TopK nonlinearity is not supported by circuit-tracer.") - - # NOTE: this mutates the model in-place. Potentially bad, but a tradeoff for copying a huge model. - model.fold() - - encoder = model.encoder - decoder = model.decoder - nonlinearity = model.nonlinearity - n_layers = encoder.n_layers - d_acts = encoder.d_acts # -> circuit-tracer.d_model - d_features = encoder.d_features # -> circuit-tracer.d_transcoder - - rearranged_W_enc = einops.rearrange( - encoder.get_parameter("W").to(dtype), - "n_layers d_acts d_features -> n_layers d_features d_acts", - ).contiguous() - - for source_layer in tqdm( - range(encoder.n_layers), desc="Converting CLT encoder" - ): - layer_encoder_dict = { - f"W_enc_{source_layer}": rearranged_W_enc[source_layer].cpu().to(dtype), - f"b_enc_{source_layer}": encoder.get_parameter("b")[source_layer] - .cpu() - .to(dtype), - f"b_dec_{source_layer}": decoder.get_parameter("b")[source_layer] - .cpu() - .to(dtype), + def _create_plt_files(self, encoder, decoder, nonlinearity, n_layers): + # decoder shape: d_transcoder, d_model + + file_dicts = [] + + for source_layer in range(n_layers): + layer_dict = { + "W_dec": decoder["W"][source_layer], + "W_enc": encoder["W"][source_layer], + "b_dec": decoder["b"][source_layer], + "b_enc": encoder["b"][source_layer], } if isinstance(nonlinearity, JumpReLU): - layer_encoder_dict[f"threshold_{source_layer}"] = ( - nonlinearity.theta[:, source_layer, :].cpu().to(dtype) - ) - if isinstance(nonlinearity, PerLayerTopK): - layer_encoder_dict[f"k_{source_layer}"] = torch.tensor( - [nonlinearity.k], dtype=torch.int - ) - - save_file( - layer_encoder_dict, f"{self.save_dir}/W_enc_{source_layer}.safetensors" + layer_dict["activation_function.threshold"] = nonlinearity.theta[ + :, source_layer, : + ] + elif isinstance(nonlinearity, PerLayerTopK): + layer_dict["activation_function.k"] = torch.tensor(nonlinearity.k) + file_dicts.append( + (layer_dict, f"{self.save_dir}/layer_{source_layer}.safetensors") ) - output_dec_i = torch.zeros([d_features, n_layers - source_layer, d_acts]) + return file_dicts + + def _create_clt_files( + self, + encoder, + decoder, + nonlinearity, + n_layers, + ): + file_dicts = [] + + for source_layer in range(n_layers): + layer_encoder_dict = { + f"W_enc_{source_layer}": encoder["W"][source_layer], + f"b_enc_{source_layer}": encoder["b"][source_layer], + f"b_dec_{source_layer}": decoder["b"][source_layer], + } - for k in range(source_layer, n_layers): - # get decoder mat for layer i --> k - decoder_w_k = decoder.get_parameter(f"W_{k}") + if isinstance(nonlinearity, JumpReLU): + layer_encoder_dict[f"threshold_{source_layer}"] = nonlinearity.theta[ + :, source_layer, : + ] + if isinstance(nonlinearity, PerLayerTopK): + layer_encoder_dict[f"k_{source_layer}"] = torch.tensor(nonlinearity.k) - dec_i_k = decoder_w_k.to(dtype)[source_layer, ...] - assert dec_i_k.shape == ( - d_features, - d_acts, + file_dicts.append( + ( + layer_encoder_dict, + f"{self.save_dir}/W_enc_{source_layer}.safetensors", ) - output_dec_i[:, k - source_layer, ...] = dec_i_k.cpu().to(dtype) + ) - decoder_dict = {f"W_dec_{source_layer}": output_dec_i} + decoder_dict = {f"W_dec_{source_layer}": decoder["W"][source_layer]} - save_file( - decoder_dict, - f"{self.save_dir}/W_dec_{source_layer}.safetensors", + file_dicts.append( + (decoder_dict, f"{self.save_dir}/W_dec_{source_layer}.safetensors") ) + return file_dicts + + def export(self, model: CrossLayerTranscoder, dtype: torch.dtype = torch.bfloat16): + is_per_layer_decoder = isinstance(model.decoder, Decoder) config = { - "model_kind": "cross_layer_transcoder", + "model_name": "PLACEHOLDER MODEL_NAME", "feature_input_hook": self.feature_input_hook, "feature_output_hook": self.feature_output_hook, + "model_kind": "transcoder_set" + if is_per_layer_decoder + else "cross_layer_transcoder", } + model_dict = model.to_circuit_tracer() + + n_layers = model.encoder.n_layers + + if model_dict["is_per_layer_decoder"]: + file_dicts = self._create_plt_files( + model_dict["encoder"], + model_dict["decoder"], + model.nonlinearity, + n_layers, + ) + else: + file_dicts = self._create_clt_files( + model_dict["encoder"], + model_dict["decoder"], + model.nonlinearity, + n_layers, + ) + + # TODO: convert to dtype and CPU (?) + + for file_dict, file_path in file_dicts: + save_file(file_dict, file_path) + with open(self.save_dir / "config.yaml", "w") as f: yaml.dump(config, f, default_flow_style=False) diff --git a/crosslayer_transcoder/utils/replacement_score.ipynb b/crosslayer_transcoder/utils/replacement_score.ipynb index 15a1003..45286e5 100644 --- a/crosslayer_transcoder/utils/replacement_score.ipynb +++ b/crosslayer_transcoder/utils/replacement_score.ipynb @@ -43,7 +43,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "ea4d424e20614d70823decee70cbdc5b", + "model_id": "a830fddc58ed4a328535348f7137e6bc", "version_major": 2, "version_minor": 0 }, @@ -79,15 +79,7 @@ "execution_count": 4, "id": "f259397a", "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Converting CLT encoder: 100%|██████████| 12/12 [00:33<00:00, 2.79s/it]\n" - ] - } - ], + "outputs": [], "source": [ "from crosslayer_transcoder.utils.model_converters.circuit_tracer import (\n", " CircuitTracerConverter,\n", @@ -198,22 +190,28 @@ "name": "stderr", "output_type": "stream", "text": [ - "Phase 0: Precomputing activations and vectors\n", - "Precomputation completed in 0.38s\n", + "Phase 0: Precomputing activations and vectors\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Precomputation completed in 0.44s\n", "Found 2496 active features\n", "Phase 1: Running forward pass\n", - "Forward pass completed in 0.03s\n", + "Forward pass completed in 0.04s\n", "Phase 2: Building input vectors\n", "Selected 10 logits with cumulative probability 0.7510\n", "Will include 2496 of 2496 feature nodes\n", - "Input vectors built in 0.04s\n", + "Input vectors built in 0.02s\n", "Phase 3: Computing logit attributions\n", "sys:1: UserWarning: Full backward hook is firing when gradients are computed with respect to module outputs since no inputs require gradients. See https://docs.pytorch.org/docs/main/generated/torch.nn.Module.html#torch.nn.Module.register_full_backward_hook for more details.\n", - "Logit attributions completed in 0.14s\n", + "Logit attributions completed in 0.10s\n", "Phase 4: Computing feature attributions\n", - "Feature influence computation: 100%|██████████| 2496/2496 [00:01<00:00, 2007.91it/s]\n", - "Feature attributions completed in 1.32s\n", - "Attribution completed in 2.25s\n" + "Feature influence computation: 100%|██████████| 2496/2496 [00:01<00:00, 2354.52it/s]\n", + "Feature attributions completed in 1.06s\n", + "Attribution completed in 2.07s\n" ] } ], @@ -355,6 +353,237 @@ " f\"Open your graph here: f'http://localhost:{port}/index.html'\"\n", ")\n" ] + }, + { + "cell_type": "markdown", + "id": "395d0c43", + "metadata": {}, + "source": [ + "## Repeat with a PLT" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "0a35d063", + "metadata": {}, + "outputs": [], + "source": [ + "huggingface_plt_path = \"georglange/crosslayer-transcoder-topk-plt-16k\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "677ef6dd", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "e12840b235dd45cb85c1da48eb229a53", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Fetching 2 files: 0%| | 0/2 [00:00