diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/_distutils_hack/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/_distutils_hack/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9580b42f8469f62543b9fedd57a953c56c66659e
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/_distutils_hack/__pycache__/__init__.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/_distutils_hack/__pycache__/override.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/_distutils_hack/__pycache__/override.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9b0ed80a116c8302f2f16114225693c8eeef1f2b
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/_distutils_hack/__pycache__/override.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/commands/tpu.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/commands/tpu.py
new file mode 100644
index 0000000000000000000000000000000000000000..fc0f07bf8697bfdb6484d3bf817f2e18b1313b00
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/commands/tpu.py
@@ -0,0 +1,157 @@
+#!/usr/bin/env python
+
+# Copyright 2022 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import argparse
+import os
+import subprocess
+
+from packaging.version import Version, parse
+
+from accelerate.commands.config.config_args import default_config_file, load_config_from_file
+
+
+_description = "Run commands across TPU VMs for initial setup before running `accelerate launch`."
+
+
+def tpu_command_parser(subparsers=None):
+ if subparsers is not None:
+ parser = subparsers.add_parser("tpu-config", description=_description)
+ else:
+ parser = argparse.ArgumentParser("Accelerate tpu-config command", description=_description)
+ # Core arguments
+ config_args = parser.add_argument_group(
+ "Config Arguments", "Arguments that can be configured through `accelerate config`."
+ )
+ config_args.add_argument(
+ "--config_file",
+ type=str,
+ default=None,
+ help="Path to the config file to use for accelerate.",
+ )
+ config_args.add_argument(
+ "--tpu_name",
+ default=None,
+ help="The name of the TPU to use. If not specified, will use the TPU specified in the config file.",
+ )
+ config_args.add_argument(
+ "--tpu_zone",
+ default=None,
+ help="The zone of the TPU to use. If not specified, will use the zone specified in the config file.",
+ )
+ pod_args = parser.add_argument_group("TPU Arguments", "Arguments for options ran inside the TPU.")
+ pod_args.add_argument(
+ "--use_alpha",
+ action="store_true",
+ help="Whether to use `gcloud alpha` when running the TPU training script instead of `gcloud`.",
+ )
+ pod_args.add_argument(
+ "--command_file",
+ default=None,
+ help="The path to the file containing the commands to run on the pod on startup.",
+ )
+ pod_args.add_argument(
+ "--command",
+ action="append",
+ nargs="+",
+ help="A command to run on the pod. Can be passed multiple times.",
+ )
+ pod_args.add_argument(
+ "--install_accelerate",
+ action="store_true",
+ help="Whether to install accelerate on the pod. Defaults to False.",
+ )
+ pod_args.add_argument(
+ "--accelerate_version",
+ default="latest",
+ help="The version of accelerate to install on the pod. If not specified, will use the latest pypi version. Specify 'dev' to install from GitHub.",
+ )
+ pod_args.add_argument(
+ "--debug", action="store_true", help="If set, will print the command that would be run instead of running it."
+ )
+
+ if subparsers is not None:
+ parser.set_defaults(func=tpu_command_launcher)
+ return parser
+
+
+def tpu_command_launcher(args):
+ defaults = None
+
+ # Get the default from the config file if it exists.
+ if args.config_file is not None or os.path.isfile(default_config_file):
+ defaults = load_config_from_file(args.config_file)
+ if not args.command_file and defaults.command_file is not None and not args.command:
+ args.command_file = defaults.command_file
+ if not args.command and defaults.commands is not None:
+ args.command = defaults.commands
+ if not args.tpu_name:
+ args.tpu_name = defaults.tpu_name
+ if not args.tpu_zone:
+ args.tpu_zone = defaults.tpu_zone
+ if args.accelerate_version == "dev":
+ args.accelerate_version = "git+https://github.com/huggingface/accelerate.git"
+ elif args.accelerate_version == "latest":
+ args.accelerate_version = "accelerate -U"
+ elif isinstance(parse(args.accelerate_version), Version):
+ args.accelerate_version = f"accelerate=={args.accelerate_version}"
+
+ if not args.command_file and not args.command:
+ raise ValueError("You must specify either a command file or a command to run on the pod.")
+
+ if args.command_file:
+ with open(args.command_file) as f:
+ args.command = [f.read().splitlines()]
+
+ # To turn list of lists into list of strings
+ if isinstance(args.command[0], list):
+ args.command = [line for cmd in args.command for line in cmd]
+ # Default to the shared folder and install accelerate
+ new_cmd = ["cd /usr/share"]
+ if args.install_accelerate:
+ new_cmd += [f"pip install {args.accelerate_version}"]
+ new_cmd += args.command
+ args.command = "; ".join(new_cmd)
+
+ # Then send it to gcloud
+ # Eventually try to use google-api-core to do this instead of subprocess
+ cmd = ["gcloud"]
+ if args.use_alpha:
+ cmd += ["alpha"]
+ cmd += [
+ "compute",
+ "tpus",
+ "tpu-vm",
+ "ssh",
+ args.tpu_name,
+ "--zone",
+ args.tpu_zone,
+ "--command",
+ args.command,
+ "--worker",
+ "all",
+ ]
+ if args.debug:
+ print(f"Running {' '.join(cmd)}")
+ return
+ subprocess.run(cmd)
+ print("Successfully setup pod.")
+
+
+def main():
+ parser = tpu_command_parser()
+ args = parser.parse_args()
+
+ tpu_command_launcher(args)
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/test_utils/scripts/external_deps/__pycache__/test_ds_multiple_model.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/test_utils/scripts/external_deps/__pycache__/test_ds_multiple_model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d2b407ec2c1fbc198c3b7a949c5b401c78bc7d5d
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/test_utils/scripts/external_deps/__pycache__/test_ds_multiple_model.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..d9696b1bb2aa5f944e8df4f54b3f4e9201d0d9ba
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/__init__.py
@@ -0,0 +1,306 @@
+# Copyright 2022 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+from ..parallelism_config import ParallelismConfig
+from .ao import convert_model_to_fp8_ao, filter_first_and_last_linear_layers, has_ao_layers
+from .constants import (
+ MITA_PROFILING_AVAILABLE_PYTORCH_VERSION,
+ MODEL_NAME,
+ OPTIMIZER_NAME,
+ PROFILE_PATTERN_NAME,
+ RNG_STATE_NAME,
+ SAFE_MODEL_NAME,
+ SAFE_WEIGHTS_INDEX_NAME,
+ SAFE_WEIGHTS_NAME,
+ SAFE_WEIGHTS_PATTERN_NAME,
+ SAMPLER_NAME,
+ SCALER_NAME,
+ SCHEDULER_NAME,
+ TORCH_DISTRIBUTED_OPERATION_TYPES,
+ TORCH_LAUNCH_PARAMS,
+ WEIGHTS_INDEX_NAME,
+ WEIGHTS_NAME,
+ WEIGHTS_PATTERN_NAME,
+ XPU_PROFILING_AVAILABLE_PYTORCH_VERSION,
+)
+from .dataclasses import (
+ AORecipeKwargs,
+ AutocastKwargs,
+ BnbQuantizationConfig,
+ ComputeEnvironment,
+ CustomDtype,
+ DataLoaderConfiguration,
+ DDPCommunicationHookType,
+ DeepSpeedPlugin,
+ DeepSpeedSequenceParallelConfig,
+ DistributedDataParallelKwargs,
+ DistributedType,
+ DynamoBackend,
+ FP8RecipeKwargs,
+ FullyShardedDataParallelPlugin,
+ GradientAccumulationPlugin,
+ GradScalerKwargs,
+ InitProcessGroupKwargs,
+ KwargsHandler,
+ LoggerType,
+ MegatronLMPlugin,
+ MSAMPRecipeKwargs,
+ PrecisionType,
+ ProfileKwargs,
+ ProjectConfiguration,
+ RNGType,
+ SageMakerDistributedType,
+ TensorInformation,
+ TERecipeKwargs,
+ TorchContextParallelConfig,
+ TorchDynamoPlugin,
+ TorchTensorParallelConfig,
+ TorchTensorParallelPlugin,
+ add_model_config_to_megatron_parser,
+)
+from .environment import (
+ are_libraries_initialized,
+ check_cuda_fp8_capability,
+ check_cuda_p2p_ib_support,
+ clear_environment,
+ convert_dict_to_env_variables,
+ get_cpu_distributed_information,
+ get_current_device_type,
+ get_gpu_info,
+ get_int_from_env,
+ parse_choice_from_env,
+ parse_flag_from_env,
+ patch_environment,
+ purge_accelerate_environment,
+ set_numa_affinity,
+ str_to_bool,
+)
+from .imports import (
+ deepspeed_required,
+ get_ccl_version,
+ is_4bit_bnb_available,
+ is_8bit_bnb_available,
+ is_aim_available,
+ is_bf16_available,
+ is_bitsandbytes_multi_backend_available,
+ is_bnb_available,
+ is_boto3_available,
+ is_ccl_available,
+ is_clearml_available,
+ is_comet_ml_available,
+ is_cuda_available,
+ is_datasets_available,
+ is_deepspeed_available,
+ is_dvclive_available,
+ is_fp8_available,
+ is_fp16_available,
+ is_habana_gaudi1,
+ is_hpu_available,
+ is_import_timer_available,
+ is_ipex_available,
+ is_lomo_available,
+ is_matplotlib_available,
+ is_megatron_lm_available,
+ is_mlflow_available,
+ is_mlu_available,
+ is_mps_available,
+ is_msamp_available,
+ is_musa_available,
+ is_npu_available,
+ is_pandas_available,
+ is_peft_available,
+ is_pippy_available,
+ is_pynvml_available,
+ is_pytest_available,
+ is_rich_available,
+ is_sagemaker_available,
+ is_schedulefree_available,
+ is_sdaa_available,
+ is_swanlab_available,
+ is_tensorboard_available,
+ is_timm_available,
+ is_torch_xla_available,
+ is_torchao_available,
+ is_torchdata_available,
+ is_torchdata_stateful_dataloader_available,
+ is_torchvision_available,
+ is_trackio_available,
+ is_transformer_engine_available,
+ is_transformer_engine_mxfp8_available,
+ is_transformers_available,
+ is_triton_available,
+ is_wandb_available,
+ is_weights_only_available,
+ is_xccl_available,
+ is_xpu_available,
+ torchao_required,
+)
+from .modeling import (
+ align_module_device,
+ calculate_maximum_sizes,
+ check_device_map,
+ check_tied_parameters_in_config,
+ check_tied_parameters_on_same_device,
+ compute_module_sizes,
+ convert_file_size_to_int,
+ dtype_byte_size,
+ find_tied_parameters,
+ get_balanced_memory,
+ get_grad_scaler,
+ get_max_layer_size,
+ get_max_memory,
+ get_mixed_precision_context_manager,
+ has_offloaded_params,
+ id_tensor_storage,
+ infer_auto_device_map,
+ is_peft_model,
+ load_checkpoint_in_model,
+ load_offloaded_weights,
+ load_state_dict,
+ named_module_tensors,
+ retie_parameters,
+ set_module_tensor_to_device,
+)
+from .offload import (
+ OffloadedWeightsLoader,
+ PrefixedDataset,
+ extract_submodules_state_dict,
+ load_offloaded_weight,
+ offload_state_dict,
+ offload_weight,
+ save_offload_index,
+)
+from .operations import (
+ CannotPadNestedTensorWarning,
+ GatheredParameters,
+ broadcast,
+ broadcast_object_list,
+ concatenate,
+ convert_outputs_to_fp32,
+ convert_to_fp32,
+ copy_tensor_to_devices,
+ find_batch_size,
+ find_device,
+ gather,
+ gather_object,
+ get_data_structure,
+ honor_type,
+ ignorant_find_batch_size,
+ initialize_tensors,
+ is_namedtuple,
+ is_tensor_information,
+ is_torch_tensor,
+ listify,
+ pad_across_processes,
+ pad_input_tensors,
+ recursively_apply,
+ reduce,
+ send_to_device,
+ slice_tensors,
+)
+from .versions import compare_versions, is_torch_version
+
+
+if is_deepspeed_available():
+ from .deepspeed import (
+ DeepSpeedEngineWrapper,
+ DeepSpeedOptimizerWrapper,
+ DeepSpeedSchedulerWrapper,
+ DummyOptim,
+ DummyScheduler,
+ HfDeepSpeedConfig,
+ get_active_deepspeed_plugin,
+ map_pytorch_optim_to_deepspeed,
+ )
+
+from .bnb import has_4bit_bnb_layers, load_and_quantize_model
+from .fsdp_utils import (
+ disable_fsdp_ram_efficient_loading,
+ enable_fsdp_ram_efficient_loading,
+ ensure_weights_retied,
+ fsdp2_apply_ac,
+ fsdp2_canonicalize_names,
+ fsdp2_load_full_state_dict,
+ fsdp2_prepare_model,
+ fsdp2_switch_optimizer_parameters,
+ get_fsdp2_grad_scaler,
+ load_fsdp_model,
+ load_fsdp_optimizer,
+ merge_fsdp_weights,
+ save_fsdp_model,
+ save_fsdp_optimizer,
+)
+from .launch import (
+ PrepareForLaunch,
+ _filter_args,
+ prepare_deepspeed_cmd_env,
+ prepare_multi_gpu_env,
+ prepare_sagemager_args_inputs,
+ prepare_simple_launcher_cmd_env,
+ prepare_tpu,
+)
+
+# For docs
+from .megatron_lm import (
+ AbstractTrainStep,
+ BertTrainStep,
+ GPTTrainStep,
+ MegatronLMDummyDataLoader,
+ MegatronLMDummyScheduler,
+ T5TrainStep,
+ avg_losses_across_data_parallel_group,
+)
+
+
+if is_megatron_lm_available():
+ from .megatron_lm import (
+ MegatronEngine,
+ MegatronLMOptimizerWrapper,
+ MegatronLMSchedulerWrapper,
+ gather_across_data_parallel_groups,
+ )
+ from .megatron_lm import initialize as megatron_lm_initialize
+ from .megatron_lm import prepare_data_loader as megatron_lm_prepare_data_loader
+ from .megatron_lm import prepare_model_optimizer_scheduler as megatron_lm_prepare_model_optimizer_scheduler
+ from .megatron_lm import prepare_optimizer as megatron_lm_prepare_optimizer
+ from .megatron_lm import prepare_scheduler as megatron_lm_prepare_scheduler
+from .memory import find_executable_batch_size, release_memory
+from .other import (
+ check_os_kernel,
+ clean_state_dict_for_safetensors,
+ compile_regions,
+ compile_regions_deepspeed,
+ convert_bytes,
+ extract_model_from_parallel,
+ get_module_children_bottom_up,
+ get_pretty_name,
+ has_compiled_regions,
+ is_compiled_module,
+ is_port_in_use,
+ load,
+ merge_dicts,
+ model_has_dtensor,
+ recursive_getattr,
+ save,
+ wait_for_everyone,
+ write_basic_config,
+)
+from .random import set_seed, synchronize_rng_state, synchronize_rng_states
+from .torch_xla import install_xla
+from .tqdm import tqdm
+from .transformer_engine import (
+ apply_fp8_autowrap,
+ contextual_fp8_autocast,
+ convert_model,
+ has_transformer_engine_layers,
+)
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/ao.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/ao.py
new file mode 100644
index 0000000000000000000000000000000000000000..73155615b768a01f709bb8e0857617ba58a6ec83
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/ao.py
@@ -0,0 +1,140 @@
+# Copyright 2025 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Needed utilities for torchao FP8 training.
+"""
+
+from functools import partial
+from typing import TYPE_CHECKING, Callable, Optional
+
+import torch
+
+from .imports import is_torchao_available, torchao_required
+
+
+if TYPE_CHECKING:
+ if is_torchao_available():
+ from torchao.float8.float8_linear import Float8LinearConfig
+
+
+def find_first_last_linear_layers(model: torch.nn.Module):
+ """
+ Finds the first and last linear layer names in a model.
+
+ This is needed during FP8 to avoid issues with instability by keeping the first and last layers unquantized.
+
+ Ref: https://x.com/xariusrke/status/1826669142604141052
+ """
+ first_linear, last_linear = None, None
+ for name, module in model.named_modules():
+ if isinstance(module, torch.nn.Linear):
+ if first_linear is None:
+ first_linear = name
+ last_linear = name
+ return first_linear, last_linear
+
+
+def filter_linear_layers(module, fqn: str, layers_to_filter: list[str]) -> bool:
+ """
+ A function which will check if `module` is:
+ - a `torch.nn.Linear` layer
+ - has in_features and out_features divisible by 16
+ - is not part of `layers_to_filter`
+
+ Args:
+ module (`torch.nn.Module`):
+ The module to check.
+ fqn (`str`):
+ The fully qualified name of the layer.
+ layers_to_filter (`List[str]`):
+ The list of layers to filter.
+ """
+ if isinstance(module, torch.nn.Linear):
+ if module.in_features % 16 != 0 or module.out_features % 16 != 0:
+ return False
+ if fqn in layers_to_filter:
+ return False
+ return True
+
+
+def filter_first_and_last_linear_layers(module, fqn: str) -> bool:
+ """
+ A filter function which will filter out all linear layers except the first and last.
+
+
+
+ For stability reasons, we skip the first and last linear layers Otherwise can lead to the model not training or
+ converging properly
+
+
+
+ Args:
+ module (`torch.nn.Module`):
+ The module to check.
+ fqn (`str`):
+ The fully qualified name of the layer.
+ """
+ first_linear, last_linear = find_first_last_linear_layers(module)
+ return filter_linear_layers(module, fqn, layers_to_filter=[first_linear, last_linear])
+
+
+@torchao_required
+def has_ao_layers(model: torch.nn.Module):
+ from torchao.float8.float8_linear import Float8Linear
+
+ for name, module in model.named_modules():
+ if isinstance(module, Float8Linear):
+ return True
+ return False
+
+
+@torchao_required
+def convert_model_to_fp8_ao(
+ model: torch.nn.Module,
+ config: Optional["Float8LinearConfig"] = None,
+ module_filter_func: Optional[Callable] = filter_first_and_last_linear_layers,
+):
+ """
+ Converts all `nn.Linear` layers in the model (except the first and last) to torchao's `Float8Linear` layer inplace.
+
+ Args:
+ model (`torch.nn.Module`):
+ The model to convert.
+ config (`torchao.float8.Float8LinearConfig`, *optional*):
+ The configuration for the FP8 training. Recommended to utilize
+ `torchao.float8.recipe_name_to_linear_config` to generate this. In general, the default config should be
+ sufficient (what is passed when set to `None`).
+ module_filter_func (`Callable`, *optional*, defaults to `filter_linear_layers`):
+ Optional function that must take in a module and layer name, and returns a boolean indicating whether the
+ module should be converted to FP8. Defaults to `filter_linear_layers`. See it for an example.
+
+ Example:
+
+ ```python
+ from accelerate.utils.ao import convert_model_to_fp8_ao
+
+ model = MyModel()
+ model.to("cuda")
+ convert_to_float8_training(model)
+
+ model.train()
+ ```
+ """
+ from torchao.float8 import convert_to_float8_training
+
+ first_linear, last_linear = find_first_last_linear_layers(model)
+ if module_filter_func is None:
+ module_filter_func = partial(filter_linear_layers, layers_to_filter=[first_linear, last_linear])
+ convert_to_float8_training(model, module_filter_fn=module_filter_func, config=config)
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/bnb.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/bnb.py
new file mode 100644
index 0000000000000000000000000000000000000000..5fbd46eb2f1a3cb07adb2ffb1f15e8f63f26fcff
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/bnb.py
@@ -0,0 +1,469 @@
+# Copyright 2023 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging
+import os
+from copy import deepcopy
+from typing import Optional, Union
+
+import torch
+import torch.nn as nn
+
+from accelerate.utils.imports import (
+ is_4bit_bnb_available,
+ is_8bit_bnb_available,
+)
+
+from ..big_modeling import dispatch_model, init_empty_weights
+from .dataclasses import BnbQuantizationConfig
+from .modeling import (
+ find_tied_parameters,
+ get_balanced_memory,
+ infer_auto_device_map,
+ load_checkpoint_in_model,
+ offload_weight,
+ set_module_tensor_to_device,
+)
+
+
+logger = logging.getLogger(__name__)
+
+
+def load_and_quantize_model(
+ model: torch.nn.Module,
+ bnb_quantization_config: BnbQuantizationConfig,
+ weights_location: Optional[Union[str, os.PathLike]] = None,
+ device_map: Optional[dict[str, Union[int, str, torch.device]]] = None,
+ no_split_module_classes: Optional[list[str]] = None,
+ max_memory: Optional[dict[Union[int, str], Union[int, str]]] = None,
+ offload_folder: Optional[Union[str, os.PathLike]] = None,
+ offload_state_dict: bool = False,
+):
+ """
+ This function will quantize the input model with the associated config passed in `bnb_quantization_config`. If the
+ model is in the meta device, we will load and dispatch the weights according to the `device_map` passed. If the
+ model is already loaded, we will quantize the model and put the model on the GPU,
+
+ Args:
+ model (`torch.nn.Module`):
+ Input model. The model can be already loaded or on the meta device
+ bnb_quantization_config (`BnbQuantizationConfig`):
+ The bitsandbytes quantization parameters
+ weights_location (`str` or `os.PathLike`):
+ The folder weights_location to load. It can be:
+ - a path to a file containing a whole model state dict
+ - a path to a `.json` file containing the index to a sharded checkpoint
+ - a path to a folder containing a unique `.index.json` file and the shards of a checkpoint.
+ - a path to a folder containing a unique pytorch_model.bin file.
+ device_map (`Dict[str, Union[int, str, torch.device]]`, *optional*):
+ A map that specifies where each submodule should go. It doesn't need to be refined to each parameter/buffer
+ name, once a given module name is inside, every submodule of it will be sent to the same device.
+ no_split_module_classes (`List[str]`, *optional*):
+ A list of layer class names that should never be split across device (for instance any layer that has a
+ residual connection).
+ max_memory (`Dict`, *optional*):
+ A dictionary device identifier to maximum memory. Will default to the maximum memory available if unset.
+ offload_folder (`str` or `os.PathLike`, *optional*):
+ If the `device_map` contains any value `"disk"`, the folder where we will offload weights.
+ offload_state_dict (`bool`, *optional*, defaults to `False`):
+ If `True`, will temporarily offload the CPU state dict on the hard drive to avoid getting out of CPU RAM if
+ the weight of the CPU state dict + the biggest shard does not fit.
+
+ Returns:
+ `torch.nn.Module`: The quantized model
+ """
+
+ load_in_4bit = bnb_quantization_config.load_in_4bit
+ load_in_8bit = bnb_quantization_config.load_in_8bit
+
+ if load_in_8bit and not is_8bit_bnb_available():
+ raise ImportError(
+ "You have a version of `bitsandbytes` that is not compatible with 8bit quantization,"
+ " make sure you have the latest version of `bitsandbytes` installed."
+ )
+ if load_in_4bit and not is_4bit_bnb_available():
+ raise ValueError(
+ "You have a version of `bitsandbytes` that is not compatible with 4bit quantization,"
+ "make sure you have the latest version of `bitsandbytes` installed."
+ )
+
+ modules_on_cpu = []
+ # custom device map
+ if isinstance(device_map, dict) and len(device_map.keys()) > 1:
+ modules_on_cpu = [key for key, value in device_map.items() if value in ["disk", "cpu"]]
+
+ # We keep some modules such as the lm_head in their original dtype for numerical stability reasons
+ if bnb_quantization_config.skip_modules is None:
+ bnb_quantization_config.skip_modules = get_keys_to_not_convert(model)
+
+ # add cpu modules to skip modules only for 4-bit modules
+ if load_in_4bit:
+ bnb_quantization_config.skip_modules.extend(modules_on_cpu)
+ modules_to_not_convert = bnb_quantization_config.skip_modules
+
+ # We add the modules we want to keep in full precision
+ if bnb_quantization_config.keep_in_fp32_modules is None:
+ bnb_quantization_config.keep_in_fp32_modules = []
+ keep_in_fp32_modules = bnb_quantization_config.keep_in_fp32_modules
+ modules_to_not_convert.extend(keep_in_fp32_modules)
+
+ # compatibility with peft
+ model.is_loaded_in_4bit = load_in_4bit
+ model.is_loaded_in_8bit = load_in_8bit
+
+ model_device = get_parameter_device(model)
+ if model_device.type != "meta":
+ # quantization of an already loaded model
+ logger.warning(
+ "It is not recommended to quantize a loaded model. "
+ "The model should be instantiated under the `init_empty_weights` context manager."
+ )
+ model = replace_with_bnb_layers(model, bnb_quantization_config, modules_to_not_convert=modules_to_not_convert)
+ # convert param to the right dtype
+ dtype = bnb_quantization_config.torch_dtype
+ for name, param in model.state_dict().items():
+ if any(module_to_keep_in_fp32 in name for module_to_keep_in_fp32 in keep_in_fp32_modules):
+ param.to(torch.float32)
+ if param.dtype != torch.float32:
+ name = name.replace(".weight", "").replace(".bias", "")
+ param = getattr(model, name, None)
+ if param is not None:
+ param.to(torch.float32)
+ elif torch.is_floating_point(param):
+ param.to(dtype)
+ if model_device.type == "cuda":
+ model.cuda(torch.cuda.current_device())
+ torch.cuda.empty_cache()
+ elif torch.cuda.is_available():
+ model.to(torch.cuda.current_device())
+ elif torch.xpu.is_available():
+ model.to(torch.xpu.current_device())
+ else:
+ raise RuntimeError("No GPU or Intel XPU found. A GPU or Intel XPU is needed for quantization.")
+ logger.info(
+ f"The model device type is {model_device.type}. However, gpu or intel xpu is needed for quantization."
+ "We move the model to it."
+ )
+ return model
+
+ elif weights_location is None:
+ raise RuntimeError(
+ f"`weights_location` needs to be the folder path containing the weights of the model, but we found {weights_location} "
+ )
+
+ else:
+ with init_empty_weights():
+ model = replace_with_bnb_layers(
+ model, bnb_quantization_config, modules_to_not_convert=modules_to_not_convert
+ )
+ device_map = get_quantized_model_device_map(
+ model,
+ bnb_quantization_config,
+ device_map,
+ max_memory=max_memory,
+ no_split_module_classes=no_split_module_classes,
+ )
+ if offload_state_dict is None and device_map is not None and "disk" in device_map.values():
+ offload_state_dict = True
+
+ offload = any(x in list(device_map.values()) for x in ["cpu", "disk"])
+
+ load_checkpoint_in_model(
+ model,
+ weights_location,
+ device_map,
+ dtype=bnb_quantization_config.torch_dtype,
+ offload_folder=offload_folder,
+ offload_state_dict=offload_state_dict,
+ keep_in_fp32_modules=bnb_quantization_config.keep_in_fp32_modules,
+ offload_8bit_bnb=load_in_8bit and offload,
+ )
+ return dispatch_model(model, device_map=device_map, offload_dir=offload_folder)
+
+
+def get_quantized_model_device_map(
+ model, bnb_quantization_config, device_map=None, max_memory=None, no_split_module_classes=None
+):
+ if device_map is None:
+ if torch.cuda.is_available():
+ device_map = {"": torch.cuda.current_device()}
+ elif torch.xpu.is_available():
+ device_map = {"": torch.xpu.current_device()}
+ else:
+ raise RuntimeError("No GPU found. A GPU is needed for quantization.")
+ logger.info("The device_map was not initialized.Setting device_map to `{'':torch.cuda.current_device()}`.")
+
+ if isinstance(device_map, str):
+ if device_map not in ["auto", "balanced", "balanced_low_0", "sequential"]:
+ raise ValueError(
+ "If passing a string for `device_map`, please choose 'auto', 'balanced', 'balanced_low_0' or "
+ "'sequential'."
+ )
+
+ special_dtypes = {}
+ special_dtypes.update(
+ {
+ name: bnb_quantization_config.torch_dtype
+ for name, _ in model.named_parameters()
+ if any(m in name for m in bnb_quantization_config.skip_modules)
+ }
+ )
+ special_dtypes.update(
+ {
+ name: torch.float32
+ for name, _ in model.named_parameters()
+ if any(m in name for m in bnb_quantization_config.keep_in_fp32_modules)
+ }
+ )
+
+ kwargs = {}
+ kwargs["special_dtypes"] = special_dtypes
+ kwargs["no_split_module_classes"] = no_split_module_classes
+ kwargs["dtype"] = bnb_quantization_config.target_dtype
+
+ # get max_memory for each device.
+ if device_map != "sequential":
+ max_memory = get_balanced_memory(
+ model,
+ low_zero=(device_map == "balanced_low_0"),
+ max_memory=max_memory,
+ **kwargs,
+ )
+
+ kwargs["max_memory"] = max_memory
+ device_map = infer_auto_device_map(model, **kwargs)
+
+ if isinstance(device_map, dict):
+ # check if don't have any quantized module on the cpu
+ modules_not_to_convert = bnb_quantization_config.skip_modules + bnb_quantization_config.keep_in_fp32_modules
+
+ device_map_without_some_modules = {
+ key: device_map[key] for key in device_map.keys() if key not in modules_not_to_convert
+ }
+ for device in ["cpu", "disk"]:
+ if device in device_map_without_some_modules.values():
+ if bnb_quantization_config.load_in_4bit:
+ raise ValueError(
+ """
+ Some modules are dispatched on the CPU or the disk. Make sure you have enough GPU RAM to fit
+ the quantized model. If you want to dispatch the model on the CPU or the disk while keeping
+ these modules in `torch_dtype`, you need to pass a custom `device_map` to
+ `load_and_quantize_model`. Check
+ https://huggingface.co/docs/accelerate/main/en/usage_guides/quantization#offload-modules-to-cpu-and-disk
+ for more details.
+ """
+ )
+ else:
+ logger.info(
+ "Some modules are are offloaded to the CPU or the disk. Note that these modules will be converted to 8-bit"
+ )
+ del device_map_without_some_modules
+ return device_map
+
+
+def replace_with_bnb_layers(model, bnb_quantization_config, modules_to_not_convert=None, current_key_name=None):
+ """
+ A helper function to replace all `torch.nn.Linear` modules by `bnb.nn.Linear8bit` modules or by `bnb.nn.Linear4bit`
+ modules from the `bitsandbytes`library. The function will be run recursively and replace `torch.nn.Linear` modules.
+
+ Parameters:
+ model (`torch.nn.Module`):
+ Input model or `torch.nn.Module` as the function is run recursively.
+ modules_to_not_convert (`List[str]`):
+ Names of the modules to not quantize convert. In practice we keep the `lm_head` in full precision for
+ numerical stability reasons.
+ current_key_name (`List[str]`, *optional*):
+ An array to track the current key of the recursion. This is used to check whether the current key (part of
+ it) is not in the list of modules to not convert.
+ """
+
+ if modules_to_not_convert is None:
+ modules_to_not_convert = []
+
+ model, has_been_replaced = _replace_with_bnb_layers(
+ model, bnb_quantization_config, modules_to_not_convert, current_key_name
+ )
+ if not has_been_replaced:
+ logger.warning(
+ "You are loading your model in 8bit or 4bit but no linear modules were found in your model."
+ " this can happen for some architectures such as gpt2 that uses Conv1D instead of Linear layers."
+ " Please double check your model architecture, or submit an issue on github if you think this is"
+ " a bug."
+ )
+ return model
+
+
+def _replace_with_bnb_layers(
+ model,
+ bnb_quantization_config,
+ modules_to_not_convert=None,
+ current_key_name=None,
+):
+ """
+ Private method that wraps the recursion for module replacement.
+
+ Returns the converted model and a boolean that indicates if the conversion has been successful or not.
+ """
+ # bitsandbytes will initialize CUDA on import, so it needs to be imported lazily
+ import bitsandbytes as bnb
+
+ has_been_replaced = False
+ for name, module in model.named_children():
+ if current_key_name is None:
+ current_key_name = []
+ current_key_name.append(name)
+ if isinstance(module, nn.Linear) and name not in modules_to_not_convert:
+ # Check if the current key is not in the `modules_to_not_convert`
+ current_key_name_str = ".".join(current_key_name)
+ proceed = True
+ for key in modules_to_not_convert:
+ if (
+ (key in current_key_name_str) and (key + "." in current_key_name_str)
+ ) or key == current_key_name_str:
+ proceed = False
+ break
+ if proceed:
+ # Load bnb module with empty weight and replace ``nn.Linear` module
+ if bnb_quantization_config.load_in_8bit:
+ bnb_module = bnb.nn.Linear8bitLt(
+ module.in_features,
+ module.out_features,
+ module.bias is not None,
+ has_fp16_weights=False,
+ threshold=bnb_quantization_config.llm_int8_threshold,
+ )
+ elif bnb_quantization_config.load_in_4bit:
+ bnb_module = bnb.nn.Linear4bit(
+ module.in_features,
+ module.out_features,
+ module.bias is not None,
+ bnb_quantization_config.bnb_4bit_compute_dtype,
+ compress_statistics=bnb_quantization_config.bnb_4bit_use_double_quant,
+ quant_type=bnb_quantization_config.bnb_4bit_quant_type,
+ )
+ else:
+ raise ValueError("load_in_8bit and load_in_4bit can't be both False")
+ bnb_module.weight.data = module.weight.data
+ if module.bias is not None:
+ bnb_module.bias.data = module.bias.data
+ bnb_module.requires_grad_(False)
+ setattr(model, name, bnb_module)
+ has_been_replaced = True
+ if len(list(module.children())) > 0:
+ _, _has_been_replaced = _replace_with_bnb_layers(
+ module, bnb_quantization_config, modules_to_not_convert, current_key_name
+ )
+ has_been_replaced = has_been_replaced | _has_been_replaced
+ # Remove the last key for recursion
+ current_key_name.pop(-1)
+ return model, has_been_replaced
+
+
+def get_keys_to_not_convert(model):
+ r"""
+ An utility function to get the key of the module to keep in full precision if any For example for CausalLM modules
+ we may want to keep the lm_head in full precision for numerical stability reasons. For other architectures, we want
+ to keep the tied weights of the model. The function will return a list of the keys of the modules to not convert in
+ int8.
+
+ Parameters:
+ model (`torch.nn.Module`):
+ Input model
+ """
+ # Create a copy of the model
+ with init_empty_weights():
+ tied_model = deepcopy(model) # this has 0 cost since it is done inside `init_empty_weights` context manager`
+
+ tied_params = find_tied_parameters(tied_model)
+ # For compatibility with Accelerate < 0.18
+ if isinstance(tied_params, dict):
+ tied_keys = sum(list(tied_params.values()), []) + list(tied_params.keys())
+ else:
+ tied_keys = sum(tied_params, [])
+ has_tied_params = len(tied_keys) > 0
+
+ # Check if it is a base model
+ is_base_model = False
+ if hasattr(model, "base_model_prefix"):
+ is_base_model = not hasattr(model, model.base_model_prefix)
+
+ # Ignore this for base models (BertModel, GPT2Model, etc.)
+ if (not has_tied_params) and is_base_model:
+ return []
+
+ # otherwise they have an attached head
+ list_modules = list(model.named_children())
+ list_last_module = [list_modules[-1][0]]
+
+ # add last module together with tied weights
+ intersection = set(list_last_module) - set(tied_keys)
+ list_untouched = list(set(tied_keys)) + list(intersection)
+
+ # remove ".weight" from the keys
+ names_to_remove = [".weight", ".bias"]
+ filtered_module_names = []
+ for name in list_untouched:
+ for name_to_remove in names_to_remove:
+ if name_to_remove in name:
+ name = name.replace(name_to_remove, "")
+ filtered_module_names.append(name)
+
+ return filtered_module_names
+
+
+def has_4bit_bnb_layers(model):
+ """Check if we have `bnb.nn.Linear4bit` or `bnb.nn.Linear8bitLt` layers inside our model"""
+ # bitsandbytes will initialize CUDA on import, so it needs to be imported lazily
+ import bitsandbytes as bnb
+
+ for m in model.modules():
+ if isinstance(m, bnb.nn.Linear4bit):
+ return True
+ return False
+
+
+def get_parameter_device(parameter: nn.Module):
+ return next(parameter.parameters()).device
+
+
+def quantize_and_offload_8bit(model, param, param_name, new_dtype, offload_folder, offload_index, fp16_statistics):
+ # if it is not quantized, we quantize and offload the quantized weights and the SCB stats
+ if fp16_statistics is None:
+ set_module_tensor_to_device(model, param_name, 0, dtype=new_dtype, value=param)
+ tensor_name = param_name
+ module = model
+ if "." in tensor_name:
+ splits = tensor_name.split(".")
+ for split in splits[:-1]:
+ new_module = getattr(module, split)
+ if new_module is None:
+ raise ValueError(f"{module} has no attribute {split}.")
+ module = new_module
+ tensor_name = splits[-1]
+ # offload weights
+ module._parameters[tensor_name].requires_grad = False
+ offload_weight(module._parameters[tensor_name], param_name, offload_folder, index=offload_index)
+ if hasattr(module._parameters[tensor_name], "SCB"):
+ offload_weight(
+ module._parameters[tensor_name].SCB,
+ param_name.replace("weight", "SCB"),
+ offload_folder,
+ index=offload_index,
+ )
+ else:
+ offload_weight(param, param_name, offload_folder, index=offload_index)
+ offload_weight(fp16_statistics, param_name.replace("weight", "SCB"), offload_folder, index=offload_index)
+
+ set_module_tensor_to_device(model, param_name, "meta", dtype=new_dtype, value=torch.empty(*param.size()))
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/constants.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/constants.py
new file mode 100644
index 0000000000000000000000000000000000000000..10a381309f9aed121f8e17e1a7464aa58657a785
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/constants.py
@@ -0,0 +1,106 @@
+# Copyright 2022 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import operator as op
+
+import torch
+
+
+SCALER_NAME = "scaler.pt"
+MODEL_NAME = "pytorch_model"
+SAFE_MODEL_NAME = "model"
+RNG_STATE_NAME = "random_states"
+OPTIMIZER_NAME = "optimizer"
+SCHEDULER_NAME = "scheduler"
+SAMPLER_NAME = "sampler"
+PROFILE_PATTERN_NAME = "profile_{suffix}.json"
+WEIGHTS_NAME = f"{MODEL_NAME}.bin"
+WEIGHTS_PATTERN_NAME = "pytorch_model{suffix}.bin"
+WEIGHTS_INDEX_NAME = f"{WEIGHTS_NAME}.index.json"
+SAFE_WEIGHTS_NAME = f"{SAFE_MODEL_NAME}.safetensors"
+SAFE_WEIGHTS_PATTERN_NAME = "model{suffix}.safetensors"
+SAFE_WEIGHTS_INDEX_NAME = f"{SAFE_WEIGHTS_NAME}.index.json"
+SAGEMAKER_PYTORCH_VERSION = "1.10.2"
+SAGEMAKER_PYTHON_VERSION = "py38"
+SAGEMAKER_TRANSFORMERS_VERSION = "4.17.0"
+SAGEMAKER_PARALLEL_EC2_INSTANCES = ["ml.p3.16xlarge", "ml.p3dn.24xlarge", "ml.p4dn.24xlarge"]
+FSDP_SHARDING_STRATEGY = ["FULL_SHARD", "SHARD_GRAD_OP", "NO_SHARD", "HYBRID_SHARD", "HYBRID_SHARD_ZERO2"]
+FSDP_AUTO_WRAP_POLICY = ["TRANSFORMER_BASED_WRAP", "SIZE_BASED_WRAP", "NO_WRAP"]
+FSDP_BACKWARD_PREFETCH = ["BACKWARD_PRE", "BACKWARD_POST", "NO_PREFETCH"]
+FSDP_STATE_DICT_TYPE = ["FULL_STATE_DICT", "LOCAL_STATE_DICT", "SHARDED_STATE_DICT"]
+FSDP2_STATE_DICT_TYPE = ["SHARDED_STATE_DICT", "FULL_STATE_DICT"]
+FSDP_PYTORCH_VERSION = (
+ "2.1.0.a0+32f93b1" # Technically should be 2.1.0, but MS-AMP uses this specific prerelease in their Docker image.
+)
+FSDP2_PYTORCH_VERSION = "2.6.0"
+FSDP_MODEL_NAME = "pytorch_model_fsdp"
+DEEPSPEED_MULTINODE_LAUNCHERS = ["pdsh", "standard", "openmpi", "mvapich", "mpich", "nossh", "slurm"]
+TORCH_DYNAMO_MODES = ["default", "reduce-overhead", "max-autotune"]
+ELASTIC_LOG_LINE_PREFIX_TEMPLATE_PYTORCH_VERSION = "2.2.0"
+XPU_PROFILING_AVAILABLE_PYTORCH_VERSION = "2.4.0"
+MITA_PROFILING_AVAILABLE_PYTORCH_VERSION = "2.1.0"
+BETA_TP_AVAILABLE_PYTORCH_VERSION = "2.3.0"
+
+BETA_TP_AVAILABLE_TRANSFORMERS_VERSION = "4.52.0"
+BETA_CP_AVAILABLE_PYTORCH_VERSION = "2.6.0"
+BETA_SP_AVAILABLE_DEEPSPEED_VERSION = "0.18.2"
+
+STR_OPERATION_TO_FUNC = {">": op.gt, ">=": op.ge, "==": op.eq, "!=": op.ne, "<=": op.le, "<": op.lt}
+
+# These are the args for `torch.distributed.launch` for pytorch < 1.9
+TORCH_LAUNCH_PARAMS = [
+ "nnodes",
+ "nproc_per_node",
+ "rdzv_backend",
+ "rdzv_endpoint",
+ "rdzv_id",
+ "rdzv_conf",
+ "standalone",
+ "max_restarts",
+ "monitor_interval",
+ "start_method",
+ "role",
+ "module",
+ "m",
+ "no_python",
+ "run_path",
+ "log_dir",
+ "r",
+ "redirects",
+ "t",
+ "tee",
+ "node_rank",
+ "master_addr",
+ "master_port",
+]
+
+CUDA_DISTRIBUTED_TYPES = ["DEEPSPEED", "MULTI_GPU", "FSDP", "MEGATRON_LM", "TP"]
+TORCH_DISTRIBUTED_OPERATION_TYPES = CUDA_DISTRIBUTED_TYPES + [
+ "MULTI_NPU",
+ "MULTI_MLU",
+ "MULTI_SDAA",
+ "MULTI_MUSA",
+ "MULTI_XPU",
+ "MULTI_CPU",
+ "MULTI_HPU",
+]
+SUPPORTED_PYTORCH_LAYERS_FOR_UPCASTING = (
+ torch.nn.Conv1d,
+ torch.nn.Conv2d,
+ torch.nn.Conv3d,
+ torch.nn.ConvTranspose1d,
+ torch.nn.ConvTranspose2d,
+ torch.nn.ConvTranspose3d,
+ torch.nn.Linear,
+)
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/dataclasses.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/dataclasses.py
new file mode 100644
index 0000000000000000000000000000000000000000..b226c25d312fe18022714dcd9af8ac7a90ab2775
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/dataclasses.py
@@ -0,0 +1,2985 @@
+# Copyright 2022 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+General namespace and dataclass related classes
+"""
+
+import argparse
+import copy
+import enum
+import functools
+import logging
+import os
+import warnings
+from collections.abc import Iterable
+from contextlib import contextmanager
+from dataclasses import dataclass, field
+from datetime import timedelta
+from typing import TYPE_CHECKING, Any, Callable, Literal, Optional, Union, get_args
+
+import torch
+
+from .constants import (
+ BETA_CP_AVAILABLE_PYTORCH_VERSION,
+ BETA_TP_AVAILABLE_PYTORCH_VERSION,
+ BETA_TP_AVAILABLE_TRANSFORMERS_VERSION,
+ FSDP2_PYTORCH_VERSION,
+ FSDP_AUTO_WRAP_POLICY,
+ FSDP_BACKWARD_PREFETCH,
+ FSDP_SHARDING_STRATEGY,
+ MITA_PROFILING_AVAILABLE_PYTORCH_VERSION,
+ XPU_PROFILING_AVAILABLE_PYTORCH_VERSION,
+)
+from .environment import parse_flag_from_env, str_to_bool
+from .imports import (
+ is_cuda_available,
+ is_hpu_available,
+ is_mlu_available,
+ is_msamp_available,
+ is_musa_available,
+ is_npu_available,
+ is_transformer_engine_available,
+ is_xpu_available,
+)
+from .versions import compare_versions, is_torch_version
+
+
+if TYPE_CHECKING:
+ # Mock imports for type checking
+ from torchao.float8 import Float8LinearConfig
+
+
+logger = logging.getLogger(__name__)
+
+
+class KwargsHandler:
+ """
+ Internal mixin that implements a `to_kwargs()` method for a dataclass.
+ """
+
+ def to_dict(self):
+ return copy.deepcopy(self.__dict__)
+
+ def to_kwargs(self):
+ """
+ Returns a dictionary containing the attributes with values different from the default of this class.
+ """
+ # import clear_environment here to avoid circular import problem
+ from .environment import clear_environment
+
+ with clear_environment():
+ default_dict = self.__class__().to_dict()
+ this_dict = self.to_dict()
+ return {k: v for k, v in this_dict.items() if default_dict[k] != v}
+
+
+class EnumWithContains(enum.EnumMeta):
+ "A metaclass that adds the ability to check if `self` contains an item with the `in` operator"
+
+ def __contains__(cls, item):
+ try:
+ cls(item)
+ except ValueError:
+ return False
+ return True
+
+
+class BaseEnum(enum.Enum, metaclass=EnumWithContains):
+ "An enum class that can get the value of an item with `str(Enum.key)`"
+
+ def __str__(self):
+ return self.value
+
+ @classmethod
+ def list(cls):
+ "Method to list all the possible items in `cls`"
+ return list(map(str, cls))
+
+
+@dataclass
+class AutocastKwargs(KwargsHandler):
+ """
+ Use this object in your [`Accelerator`] to customize how `torch.autocast` behaves. Please refer to the
+ documentation of this [context manager](https://pytorch.org/docs/stable/amp.html#torch.autocast) for more
+ information on each argument.
+
+ Example:
+
+ ```python
+ from accelerate import Accelerator
+ from accelerate.utils import AutocastKwargs
+
+ kwargs = AutocastKwargs(cache_enabled=True)
+ accelerator = Accelerator(kwargs_handlers=[kwargs])
+ ```
+ """
+
+ enabled: bool = True
+ cache_enabled: Optional[bool] = None
+
+
+class DDPCommunicationHookType(BaseEnum):
+ """
+ Represents a type of communication hook used in DDP.
+
+ Values:
+
+ - **NO** -- no communication hook
+ - **FP16** -- DDP communication hook to compress the gradients in FP16
+ - **BF16** -- DDP communication hook to compress the gradients in BF16
+ - **POWER_SGD** -- DDP communication hook to use PowerSGD
+ - **BATCHED_POWER_SGD** -- DDP communication hook to use batched PowerSGD
+ """
+
+ NO = "no"
+ FP16 = "fp16"
+ BF16 = "bf16"
+ POWER_SGD = "power_sgd"
+ BATCHED_POWER_SGD = "batched_power_sgd"
+
+
+@dataclass
+class DistributedDataParallelKwargs(KwargsHandler):
+ """
+ Use this object in your [`Accelerator`] to customize how your model is wrapped in a
+ `torch.nn.parallel.DistributedDataParallel`. Please refer to the documentation of this
+ [wrapper](https://pytorch.org/docs/stable/generated/torch.nn.parallel.DistributedDataParallel.html) for more
+ information on each argument.
+
+
+
+ `gradient_as_bucket_view` is only available in PyTorch 1.7.0 and later versions.
+
+ `static_graph` is only available in PyTorch 1.11.0 and later versions.
+
+
+
+ Example:
+
+ ```python
+ from accelerate import Accelerator
+ from accelerate.utils import DistributedDataParallelKwargs
+
+ kwargs = DistributedDataParallelKwargs(find_unused_parameters=True)
+ accelerator = Accelerator(kwargs_handlers=[kwargs])
+ ```
+ """
+
+ dim: int = 0
+ broadcast_buffers: bool = True
+ bucket_cap_mb: int = 25
+ find_unused_parameters: bool = False
+ check_reduction: bool = False
+ gradient_as_bucket_view: bool = False
+ static_graph: bool = False
+
+ comm_hook: DDPCommunicationHookType = DDPCommunicationHookType.NO
+ comm_wrapper: Literal[
+ DDPCommunicationHookType.NO,
+ DDPCommunicationHookType.FP16,
+ DDPCommunicationHookType.BF16,
+ ] = DDPCommunicationHookType.NO
+ comm_state_option: dict = field(default_factory=dict)
+
+ def to_dict(self, ignore_keys=("comm_hook", "comm_wrapper", "comm_state_option")):
+ return {k: v for k, v in super().to_dict().items() if k not in ignore_keys}
+
+ def register_comm_hook(self, model):
+ from torch.distributed.algorithms.ddp_comm_hooks import (
+ default_hooks,
+ powerSGD_hook,
+ )
+
+ hook_map: dict[DDPCommunicationHookType, Callable] = {
+ DDPCommunicationHookType.FP16: default_hooks.fp16_compress_hook,
+ DDPCommunicationHookType.BF16: default_hooks.bf16_compress_hook,
+ DDPCommunicationHookType.POWER_SGD: powerSGD_hook.powerSGD_hook,
+ DDPCommunicationHookType.BATCHED_POWER_SGD: powerSGD_hook.batched_powerSGD_hook,
+ }
+
+ wrapper_map: dict[DDPCommunicationHookType, Callable] = {
+ DDPCommunicationHookType.FP16: default_hooks.fp16_compress_wrapper,
+ DDPCommunicationHookType.BF16: default_hooks.bf16_compress_wrapper,
+ }
+
+ hook: Optional[Callable] = hook_map.get(self.comm_hook)
+ wrapper: Optional[Callable] = wrapper_map.get(self.comm_wrapper)
+
+ if hook and wrapper:
+ hook = wrapper(hook)
+
+ if hook:
+ state = (
+ powerSGD_hook.PowerSGDState(None, **self.comm_state_option)
+ if self.comm_hook
+ in (
+ DDPCommunicationHookType.POWER_SGD,
+ DDPCommunicationHookType.BATCHED_POWER_SGD,
+ )
+ else None
+ )
+ model.register_comm_hook(
+ state=state,
+ hook=hook,
+ )
+
+
+@dataclass
+class GradScalerKwargs(KwargsHandler):
+ """
+ Use this object in your [`Accelerator`] to customize the behavior of mixed precision, specifically how the
+ `torch.amp.GradScaler` or `torch.cuda.amp.GradScaler` used is created. Please refer to the documentation of this
+ [scaler](https://pytorch.org/docs/stable/amp.html?highlight=gradscaler) for more information on each argument.
+
+
+
+ `torch.cuda.amp.GradScaler` is only available in PyTorch 1.5.0 and later versions, and `torch.amp.GradScaler` is
+ only available in PyTorch 2.4.0 and later versions.
+
+
+
+ Example:
+
+ ```python
+ from accelerate import Accelerator
+ from accelerate.utils import GradScalerKwargs
+
+ kwargs = GradScalerKwargs(backoff_factor=0.25)
+ accelerator = Accelerator(kwargs_handlers=[kwargs])
+ ```
+ """
+
+ init_scale: float = 65536.0
+ growth_factor: float = 2.0
+ backoff_factor: float = 0.5
+ growth_interval: int = 2000
+ enabled: bool = True
+
+
+@dataclass
+class InitProcessGroupKwargs(KwargsHandler):
+ """
+ Use this object in your [`Accelerator`] to customize the initialization of the distributed processes. Please refer
+ to the documentation of this
+ [method](https://pytorch.org/docs/stable/distributed.html#torch.distributed.init_process_group) for more
+ information on each argument.
+
+ Note: If `timeout` is set to `None`, the default will be based upon how `backend` is set.
+
+ ```python
+ from datetime import timedelta
+ from accelerate import Accelerator
+ from accelerate.utils import InitProcessGroupKwargs
+
+ kwargs = InitProcessGroupKwargs(timeout=timedelta(seconds=800))
+ accelerator = Accelerator(kwargs_handlers=[kwargs])
+ ```
+ """
+
+ backend: Optional[str] = "nccl"
+ init_method: Optional[str] = None
+ timeout: Optional[timedelta] = None
+
+ def __post_init__(self):
+ if self.timeout is None:
+ seconds = 1800 if self.backend != "nccl" else 600
+ self.timeout = timedelta(seconds=seconds)
+
+
+# Literals
+Backend = Literal["MSAMP", "TE"]
+OptLevel = Literal["O1", "O2"]
+FP8Format = Literal["HYBRID", "E4M3", "E5M2"]
+AmaxComputeAlgorithm = Literal["max", "most_recent"]
+
+
+# FP8 training recipe kwargs
+@dataclass
+class AORecipeKwargs(KwargsHandler):
+ """
+ Use this object in your [`Accelerator`] to customize the initialization of the recipe for FP8 mixed precision
+ training with `torchao` FP8.
+
+ Args:
+ config (`torchao.float8.Float8LinearConfig`, *optional*, default to `None`):
+ The configuration for the FP8 training. In general, the default config should be sufficient.
+ module_filter_func (`Callable`, *optional*, default to `None`):
+ Optional function that must take in a module and layer name, and returns a boolean indicating whether the
+ module should be converted to FP8. Defaults to `accelerate.utils.ao.filter_linear_layers`. See it for an
+ example.
+ """
+
+ config: Optional["Float8LinearConfig"] = None
+ module_filter_func: Optional[Callable] = None
+
+
+@dataclass
+class TERecipeKwargs(KwargsHandler):
+ """
+ Use this object in your [`Accelerator`] to customize the initialization of the recipe for FP8 mixed precision
+ training with `transformer-engine`.
+
+
+
+ For more information on the args, please refer to the API
+ [documentation](https://docs.nvidia.com/deeplearning/transformer-engine/user-guide/api/common.html).
+
+
+
+ ```python
+ from accelerate import Accelerator
+ from accelerate.utils import TERecipeKwargs
+
+ kwargs = TERecipeKwargs(fp8_format="HYBRID")
+ accelerator = Accelerator(mixed_precision="fp8", kwargs_handlers=[kwargs])
+ ```
+
+ Args:
+ use_autocast_during_eval (`bool`, *optional*, default to `False`):
+ Whether to use FP8 autocast during eval mode. Generally better metrics are found when this is `False`.
+ margin (`int`, *optional*, default to 0):
+ The margin to use for the gradient scaling.
+ interval (`int`, *optional*, default to 1):
+ The interval to use for how often the scaling factor is recomputed.
+ fp8_format (`str`, *optional*, default to "HYBRID"):
+ The format to use for the FP8 recipe. Must be one of `HYBRID`, `E4M3` or `E5M2`. (Generally `HYBRID` for
+ training, `E4M3` or `E5M2` for evaluation)
+ amax_history_len (`int`, *optional*, default to 1024):
+ The length of the history to use for the scaling factor computation
+ amax_compute_algo (`str`, *optional*, default to "most_recent"):
+ The algorithm to use for the scaling factor computation. Must be one of `max` or `most_recent`.
+ override_linear_precision (`tuple` of three `bool`, *optional*, default to `(False, False, False)`):
+ Whether or not to execute `fprop`, `dgrad`, and `wgrad` GEMMS in higher precision.
+ """
+
+ use_autocast_during_eval: Optional[bool] = None
+ margin: Optional[int] = None
+ interval: Optional[int] = None
+ fp8_format: FP8Format = None
+ amax_history_len: Optional[int] = None
+ amax_compute_algo: AmaxComputeAlgorithm = None
+ override_linear_precision: tuple[bool, bool, bool] = None
+ use_mxfp8_block_scaling: Optional[bool] = None
+
+ def __post_init__(self):
+ env_prefix = "ACCELERATE_FP8_"
+ if not is_transformer_engine_available():
+ raise ImportError("TransformerEngine is not available. Please install it or use a different backend.")
+ if self.use_autocast_during_eval is None:
+ self.use_autocast_during_eval = parse_flag_from_env(env_prefix + "USE_AUTOCAST_DURING_EVAL")
+ if self.margin is None:
+ self.margin = int(os.environ.get(env_prefix + "MARGIN", 0))
+ if self.interval is None:
+ self.interval = int(os.environ.get(env_prefix + "INTERVAL", 1))
+ if self.fp8_format is None:
+ self.fp8_format = os.environ.get(env_prefix + "FORMAT", "HYBRID")
+ self.fp8_format = self.fp8_format.upper()
+ if self.fp8_format not in get_args(FP8Format):
+ raise ValueError(f"`fp8_format` must be one of {' or '.join(get_args(FP8Format))}.")
+ if self.amax_compute_algo is None:
+ self.amax_compute_algo = os.environ.get(env_prefix + "AMAX_COMPUTE_ALGO", "most_recent")
+ self.amax_compute_algo = self.amax_compute_algo.lower()
+ if self.amax_compute_algo not in get_args(AmaxComputeAlgorithm):
+ raise ValueError(f"`amax_compute_algo` must be one of {' or '.join(get_args(AmaxComputeAlgorithm))}")
+ if self.amax_history_len is None:
+ self.amax_history_len = int(os.environ.get(env_prefix + "AMAX_HISTORY_LEN", 1024))
+ if self.override_linear_precision is None:
+ fprop = parse_flag_from_env(env_prefix + "OVERRIDE_FPROP")
+ dgrad = parse_flag_from_env(env_prefix + "OVERRIDE_DGRAD")
+ wgrad = parse_flag_from_env(env_prefix + "OVERRIDE_WGRAD")
+ self.override_linear_precision = (fprop, dgrad, wgrad)
+ if self.use_mxfp8_block_scaling is None:
+ self.use_mxfp8_block_scaling = parse_flag_from_env(env_prefix + "USE_MXFP8_BLOCK_SCALING")
+
+
+@dataclass
+class MSAMPRecipeKwargs(KwargsHandler):
+ """
+ Use this object in your [`Accelerator`] to customize the initialization of the recipe for FP8 mixed precision
+ training with `ms-amp`.
+ """
+
+ opt_level: OptLevel = None
+
+ def __post_init__(self):
+ env_prefix = "ACCELERATE_FP8_"
+ if self.opt_level is None:
+ self.opt_level = os.environ.get(env_prefix + "OPT_LEVEL", "O2")
+ if self.opt_level not in get_args(OptLevel):
+ raise ValueError(f"`opt_level` must be one of {' or '.join(get_args(OptLevel))}")
+
+
+@dataclass
+class FP8RecipeKwargs(TERecipeKwargs, MSAMPRecipeKwargs):
+ """
+ Deprecated. Please use one of the proper FP8 recipe kwargs classes such as `TERecipeKwargs` or `MSAMPRecipeKwargs`
+ instead.
+ """
+
+ backend: Backend = None
+
+ def __post_init__(self):
+ env_prefix = "ACCELERATE_FP8_"
+ warnings.warn(
+ "FP8RecipeKwargs is deprecated and will be removed in Accelerate v2.0.0. "
+ "Please use one of the proper FP8 recipe kwargs classes such as TERecipeKwargs or MSAMPRecipeKwargs instead.",
+ FutureWarning,
+ )
+ default_backend = "msamp" if is_msamp_available() else "te"
+ if self.backend is None:
+ self.backend = os.environ.get(env_prefix + "BACKEND", default_backend)
+ self.backend = self.backend.upper()
+ if self.backend not in get_args(Backend):
+ raise ValueError("`backend` must be 'MSAMP' or 'TE' (TransformerEngine) to use `FP8RecipeKwargs`.")
+ super().__post_init__()
+
+
+# Literal
+ProfilerActivity = Literal["cpu", "xpu", "mtia", "cuda", "hpu"]
+
+
+@dataclass
+class ProfileKwargs(KwargsHandler):
+ """
+ Use this object in your [`Accelerator`] to customize the initialization of the profiler. Please refer to the
+ documentation of this [context manager](https://pytorch.org/docs/stable/profiler.html#torch.profiler.profile) for
+ more information on each argument.
+
+
+
+ `torch.profiler` is only available in PyTorch 1.8.1 and later versions.
+
+
+
+ Example:
+
+ ```python
+ from accelerate import Accelerator
+ from accelerate.utils import ProfileKwargs
+
+ kwargs = ProfileKwargs(activities=["cpu", "cuda"])
+ accelerator = Accelerator(kwargs_handlers=[kwargs])
+ ```
+
+ Args:
+ activities (`List[str]`, *optional*, default to `None`):
+ The list of activity groups to use in profiling. Must be one of `"cpu"`, `"xpu"`, `"mtia"`, "hpu" or
+ `"cuda"`.
+ schedule_option (`Dict[str, int]`, *optional*, default to `None`):
+ The schedule option to use for the profiler. Available keys are `wait`, `warmup`, `active`, `repeat` and
+ `skip_first`. The profiler will skip the first `skip_first` steps, then wait for `wait` steps, then do the
+ warmup for the next `warmup` steps, then do the active recording for the next `active` steps and then
+ repeat the cycle starting with `wait` steps. The optional number of cycles is specified with the `repeat`
+ parameter, the zero value means that the cycles will continue until the profiling is finished.
+ on_trace_ready (`Callable`, *optional*, default to `None`):
+ Callable that is called at each step when schedule returns `ProfilerAction.RECORD_AND_SAVE` during the
+ profiling.
+ record_shapes (`bool`, *optional*, default to `False`):
+ Save information about operator’s input shapes.
+ profile_memory (`bool`, *optional*, default to `False`):
+ Track tensor memory allocation/deallocation
+ with_stack (`bool`, *optional*, default to `False`):
+ Record source information (file and line number) for the ops.
+ with_flops (`bool`, *optional*, default to `False`):
+ Use formula to estimate the FLOPS of specific operators
+ with_modules (`bool`, *optional*, default to `False`):
+ Record module hierarchy (including function names) corresponding to the callstack of the op.
+ output_trace_dir (`str`, *optional*, default to `None`):
+ Exports the collected trace in Chrome JSON format. Chrome use 'chrome://tracing' view json file. Defaults
+ to None, which means profiling does not store json files.
+ """
+
+ activities: Optional[list[ProfilerActivity]] = None
+ schedule_option: Optional[dict[str, int]] = None
+ on_trace_ready: Optional[Callable] = None
+ record_shapes: bool = False
+ profile_memory: bool = False
+ with_stack: bool = False
+ with_flops: bool = False
+ with_modules: bool = False
+ output_trace_dir: Optional[str] = None
+
+ def _get_profiler_activity(self, activity: ProfilerActivity) -> torch.profiler.ProfilerActivity:
+ """Get the profiler activity from the string.
+
+ Args:
+ activity (str): The profiler activity name.
+
+ Returns:
+ torch.profiler.ProfilerActivity: The profiler activity.
+ """
+
+ profiler_activity_map: dict[str, torch.profiler.ProfilerActivity] = {
+ "cpu": torch.profiler.ProfilerActivity.CPU,
+ "cuda": torch.profiler.ProfilerActivity.CUDA,
+ }
+
+ if is_hpu_available():
+ profiler_activity_map["hpu"] = torch.profiler.ProfilerActivity.HPU
+
+ if is_torch_version(">=", XPU_PROFILING_AVAILABLE_PYTORCH_VERSION):
+ if torch.xpu.is_available():
+ profiler_activity_map["xpu"] = torch.profiler.ProfilerActivity.XPU
+
+ if is_torch_version(">=", MITA_PROFILING_AVAILABLE_PYTORCH_VERSION):
+ if torch.mtia.is_available():
+ profiler_activity_map["mtia"] = torch.profiler.ProfilerActivity.MTIA
+
+ if activity not in profiler_activity_map:
+ raise ValueError(f"Invalid profiler activity: {activity}. Must be one of {list(profiler_activity_map)}.")
+ return profiler_activity_map[activity]
+
+ def build(self) -> torch.profiler.profile:
+ """
+ Build a profiler object with the current configuration.
+
+ Returns:
+ torch.profiler.profile: The profiler object.
+ """
+ activities: Optional[list[ProfilerActivity]] = None
+ if self.activities is not None:
+ activities = [self._get_profiler_activity(activity) for activity in self.activities]
+ schedule: Optional[torch.profiler.schedule] = None
+ if self.schedule_option is not None:
+ schedule = torch.profiler.schedule(**self.schedule_option)
+
+ return torch.profiler.profile(
+ activities=activities,
+ schedule=schedule,
+ on_trace_ready=self.on_trace_ready,
+ record_shapes=self.record_shapes,
+ profile_memory=self.profile_memory,
+ with_stack=self.with_stack,
+ with_flops=self.with_flops,
+ with_modules=self.with_modules,
+ )
+
+
+class DistributedType(str, enum.Enum):
+ """
+ Represents a type of distributed environment.
+
+ Values:
+
+ - **NO** -- Not a distributed environment, just a single process.
+ - **MULTI_CPU** -- Distributed on multiple CPU nodes.
+ - **MULTI_GPU** -- Distributed on multiple GPUs.
+ - **MULTI_MLU** -- Distributed on multiple MLUs.
+ - **MULTI_SDAA** -- Distributed on multiple SDAAs.
+ - **MULTI_MUSA** -- Distributed on multiple MUSAs.
+ - **MULTI_NPU** -- Distributed on multiple NPUs.
+ - **MULTI_XPU** -- Distributed on multiple XPUs.
+ - **MULTI_HPU** -- Distributed on multiple HPUs.
+ - **DEEPSPEED** -- Using DeepSpeed.
+ - **XLA** -- Using TorchXLA.
+ """
+
+ # Subclassing str as well as Enum allows the `DistributedType` to be JSON-serializable out of the box.
+ NO = "NO"
+ MULTI_CPU = "MULTI_CPU"
+ MULTI_GPU = "MULTI_GPU"
+ MULTI_NPU = "MULTI_NPU"
+ MULTI_MLU = "MULTI_MLU"
+ MULTI_SDAA = "MULTI_SDAA"
+ MULTI_MUSA = "MULTI_MUSA"
+ MULTI_XPU = "MULTI_XPU"
+ DEEPSPEED = "DEEPSPEED"
+ FSDP = "FSDP"
+ XLA = "XLA"
+ MEGATRON_LM = "MEGATRON_LM"
+ MULTI_HPU = "MULTI_HPU"
+
+
+class SageMakerDistributedType(str, enum.Enum):
+ """
+ Represents a type of distributed environment.
+
+ Values:
+
+ - **NO** -- Not a distributed environment, just a single process.
+ - **DATA_PARALLEL** -- using sagemaker distributed data parallelism.
+ - **MODEL_PARALLEL** -- using sagemaker distributed model parallelism.
+ """
+
+ # Subclassing str as well as Enum allows the `SageMakerDistributedType` to be JSON-serializable out of the box.
+ NO = "NO"
+ DATA_PARALLEL = "DATA_PARALLEL"
+ MODEL_PARALLEL = "MODEL_PARALLEL"
+
+
+class FP8BackendType(str, enum.Enum):
+ """
+ Represents the backend used for FP8.
+
+ Values:
+
+ - **TE** -- using TransformerEngine.
+ - **MSAMP** -- using msamp.
+ """
+
+ # Subclassing str as well as Enum allows the `FP8BackendType` to be JSON-serializable out of the box.
+ NO = "NO"
+ TE = "TE"
+ MSAMP = "MSAMP"
+ AO = "AO"
+
+
+class ComputeEnvironment(str, enum.Enum):
+ """
+ Represents a type of the compute environment.
+
+ Values:
+
+ - **LOCAL_MACHINE** -- private/custom cluster hardware.
+ - **AMAZON_SAGEMAKER** -- Amazon SageMaker as compute environment.
+ """
+
+ # Subclassing str as well as Enum allows the `ComputeEnvironment` to be JSON-serializable out of the box.
+ LOCAL_MACHINE = "LOCAL_MACHINE"
+ AMAZON_SAGEMAKER = "AMAZON_SAGEMAKER"
+
+
+class DynamoBackend(str, BaseEnum):
+ """
+ Represents a dynamo backend (see https://pytorch.org/docs/stable/torch.compiler.html).
+
+ Values:
+
+ - **NO** -- Do not use torch dynamo.
+ - **EAGER** -- Uses PyTorch to run the extracted GraphModule. This is quite useful in debugging TorchDynamo
+ issues.
+ - **AOT_EAGER** -- Uses AotAutograd with no compiler, i.e, just using PyTorch eager for the AotAutograd's
+ extracted forward and backward graphs. This is useful for debugging, and unlikely to give speedups.
+ - **INDUCTOR** -- Uses TorchInductor backend with AotAutograd and cudagraphs by leveraging codegened Triton
+ kernels. [Read
+ more](https://dev-discuss.pytorch.org/t/torchinductor-a-pytorch-native-compiler-with-define-by-run-ir-and-symbolic-shapes/747)
+ - **AOT_TS_NVFUSER** -- nvFuser with AotAutograd/TorchScript. [Read
+ more](https://dev-discuss.pytorch.org/t/tracing-with-primitives-update-1-nvfuser-and-its-primitives/593)
+ - **NVPRIMS_NVFUSER** -- nvFuser with PrimTorch. [Read
+ more](https://dev-discuss.pytorch.org/t/tracing-with-primitives-update-1-nvfuser-and-its-primitives/593)
+ - **CUDAGRAPHS** -- cudagraphs with AotAutograd. [Read more](https://github.com/pytorch/torchdynamo/pull/757)
+ - **OFI** -- Uses Torchscript optimize_for_inference. Inference only. [Read
+ more](https://pytorch.org/docs/stable/generated/torch.jit.optimize_for_inference.html)
+ - **FX2TRT** -- Uses Nvidia TensorRT for inference optimizations. Inference only. [Read
+ more](https://github.com/pytorch/TensorRT/blob/master/docsrc/tutorials/getting_started_with_fx_path.rst)
+ - **ONNXRT** -- Uses ONNXRT for inference on CPU/GPU. Inference only. [Read more](https://onnxruntime.ai/)
+ - **TENSORRT** -- Uses ONNXRT to run TensorRT for inference optimizations. [Read
+ more](https://github.com/onnx/onnx-tensorrt)
+ - **AOT_TORCHXLA_TRACE_ONCE** -- Uses Pytorch/XLA with TorchDynamo optimization, for training. [Read
+ more](https://github.com/pytorch/xla/blob/r2.0/docs/dynamo.md)
+ - **TORCHXLA_TRACE_ONCE** -- Uses Pytorch/XLA with TorchDynamo optimization, for inference. [Read
+ more](https://github.com/pytorch/xla/blob/r2.0/docs/dynamo.md)
+ - **IPEX** -- Uses IPEX for inference on CPU. Inference only. [Read
+ more](https://github.com/intel/intel-extension-for-pytorch).
+ - **TVM** -- Uses Apache TVM for inference optimizations. [Read more](https://tvm.apache.org/)
+ - **HPU_BACKEND** -- Uses HPU backend for inference optimizations.
+
+ """
+
+ # Subclassing str as well as Enum allows the `SageMakerDistributedType` to be JSON-serializable out of the box.
+ NO = "NO"
+ EAGER = "EAGER"
+ AOT_EAGER = "AOT_EAGER"
+ INDUCTOR = "INDUCTOR"
+ AOT_TS_NVFUSER = "AOT_TS_NVFUSER"
+ NVPRIMS_NVFUSER = "NVPRIMS_NVFUSER"
+ CUDAGRAPHS = "CUDAGRAPHS"
+ OFI = "OFI"
+ FX2TRT = "FX2TRT"
+ ONNXRT = "ONNXRT"
+ TENSORRT = "TENSORRT"
+ AOT_TORCHXLA_TRACE_ONCE = "AOT_TORCHXLA_TRACE_ONCE"
+ TORCHXLA_TRACE_ONCE = "TORCHXLA_TRACE_ONCE"
+ IPEX = "IPEX"
+ TVM = "TVM"
+ HPU_BACKEND = "HPU_BACKEND"
+
+
+class LoggerType(BaseEnum):
+ """Represents a type of supported experiment tracker
+
+ Values:
+
+ - **ALL** -- all available trackers in the environment that are supported
+ - **TENSORBOARD** -- TensorBoard as an experiment tracker
+ - **WANDB** -- wandb as an experiment tracker
+ - **TRACKIO** -- trackio as an experiment tracker
+ - **COMETML** -- comet_ml as an experiment tracker
+ - **MLFLOW** -- mlflow as an experiment tracker
+ - **CLEARML** -- clearml as an experiment tracker
+ - **DVCLIVE** -- dvclive as an experiment tracker
+ - **SWANLAB** -- swanlab as an experiment tracker
+ """
+
+ ALL = "all"
+ AIM = "aim"
+ TENSORBOARD = "tensorboard"
+ WANDB = "wandb"
+ TRACKIO = "trackio"
+ COMETML = "comet_ml"
+ MLFLOW = "mlflow"
+ CLEARML = "clearml"
+ DVCLIVE = "dvclive"
+ SWANLAB = "swanlab"
+
+
+class PrecisionType(str, BaseEnum):
+ """Represents a type of precision used on floating point values
+
+ Values:
+
+ - **NO** -- using full precision (FP32)
+ - **FP16** -- using half precision
+ - **BF16** -- using brain floating point precision
+ """
+
+ NO = "no"
+ FP8 = "fp8"
+ FP16 = "fp16"
+ BF16 = "bf16"
+
+
+class RNGType(BaseEnum):
+ TORCH = "torch"
+ CUDA = "cuda"
+ MLU = "mlu"
+ SDAA = "sdaa"
+ MUSA = "musa"
+ NPU = "npu"
+ XLA = "xla"
+ XPU = "xpu"
+ HPU = "hpu"
+ GENERATOR = "generator"
+
+
+class CustomDtype(enum.Enum):
+ r"""
+ An enum that contains multiple custom dtypes that can be used for `infer_auto_device_map`.
+ """
+
+ FP8 = "fp8"
+ INT4 = "int4"
+ INT2 = "int2"
+
+
+# data classes
+
+
+@dataclass
+class TensorInformation:
+ shape: torch.Size
+ dtype: torch.dtype
+
+
+@dataclass
+class DataLoaderConfiguration:
+ """
+ Configuration for dataloader-related items when calling `accelerator.prepare`.
+
+ Args:
+ split_batches (`bool`, defaults to `False`):
+ Whether or not the accelerator should split the batches yielded by the dataloaders across the devices. If
+ `True`, the actual batch size used will be the same on any kind of distributed processes, but it must be a
+ round multiple of `num_processes` you are using. If `False`, actual batch size used will be the one set in
+ your script multiplied by the number of processes.
+ dispatch_batches (`bool`, defaults to `None`):
+ If set to `True`, the dataloader prepared by the Accelerator is only iterated through on the main process
+ and then the batches are split and broadcast to each process. Will default to `True` for `DataLoader` whose
+ underlying dataset is an `IterableDataset`, `False` otherwise.
+ even_batches (`bool`, defaults to `True`):
+ If set to `True`, in cases where the total batch size across all processes does not exactly divide the
+ dataset, samples at the start of the dataset will be duplicated so the batch can be divided equally among
+ all workers.
+ use_seedable_sampler (`bool`, defaults to `False`):
+ Whether or not use a fully seedable random sampler ([`data_loader.SeedableRandomSampler`]). Ensures
+ training results are fully reproducible using a different sampling technique. While seed-to-seed results
+ may differ, on average the differences are negligible when using multiple different seeds to compare.
+ Should also be ran with [`~utils.set_seed`] for the best results.
+ data_seed (`int`, defaults to `None`):
+ The seed to use for the underlying generator when using `use_seedable_sampler`. If `None`, the generator
+ will use the current default seed from torch.
+ non_blocking (`bool`, defaults to `False`):
+ If set to `True`, the dataloader prepared by the Accelerator will utilize non-blocking host-to-device
+ transfers, allowing for better overlap between dataloader communication and computation. Recommended that
+ the prepared dataloader has `pin_memory` set to `True` to work properly.
+ use_stateful_dataloader (`bool`, defaults to `False`):
+ If set to `True`, the dataloader prepared by the Accelerator will be backed by
+ [torchdata.StatefulDataLoader](https://github.com/pytorch/data/tree/main/torchdata/stateful_dataloader).
+ This requires `torchdata` version 0.8.0 or higher that supports StatefulDataLoader to be installed.
+ """
+
+ split_batches: bool = field(
+ default=False,
+ metadata={
+ "help": "Whether or not the accelerator should split the batches yielded by the dataloaders across the devices. If"
+ " `True` the actual batch size used will be the same on any kind of distributed processes, but it must be a"
+ " round multiple of the `num_processes` you are using. If `False`, actual batch size used will be the one set"
+ " in your script multiplied by the number of processes."
+ },
+ )
+ dispatch_batches: bool = field(
+ default=None,
+ metadata={
+ "help": "If set to `True`, the dataloader prepared by the Accelerator is only iterated through on the main process"
+ " and then the batches are split and broadcast to each process. Will default to `True` for `DataLoader` whose"
+ " underlying dataset is an `IterableDataset`, `False` otherwise."
+ },
+ )
+ even_batches: bool = field(
+ default=True,
+ metadata={
+ "help": "If set to `True`, in cases where the total batch size across all processes does not exactly divide the"
+ " dataset, samples at the start of the dataset will be duplicated so the batch can be divided equally among"
+ " all workers."
+ },
+ )
+ use_seedable_sampler: bool = field(
+ default=False,
+ metadata={
+ "help": "Whether or not use a fully seedable random sampler ([`data_loader.SeedableRandomSampler`])."
+ "Ensures training results are fully reproducible using a different sampling technique. "
+ "While seed-to-seed results may differ, on average the differences are negligible when using"
+ "multiple different seeds to compare. Should also be ran with [`~utils.set_seed`] for the best results."
+ },
+ )
+ data_seed: int = field(
+ default=None,
+ metadata={
+ "help": "The seed to use for the underlying generator when using `use_seedable_sampler`. If `None`, the generator"
+ " will use the current default seed from torch."
+ },
+ )
+ non_blocking: bool = field(
+ default=False,
+ metadata={
+ "help": "If set to `True`, the dataloader prepared by the Accelerator will utilize non-blocking host-to-device"
+ " transfers, allowing for better overlap between dataloader communication and computation. Recommended that the"
+ " prepared dataloader has `pin_memory` set to `True` to work properly."
+ },
+ )
+ use_stateful_dataloader: bool = field(
+ default=False,
+ metadata={
+ "help": "If set to `True`, the dataloader prepared by the Accelerator will be backed by "
+ "[torchdata.StatefulDataLoader](https://github.com/pytorch/data/tree/main/torchdata/stateful_dataloader). This requires `torchdata` version 0.8.0 or higher that supports StatefulDataLoader to be installed."
+ },
+ )
+
+
+@dataclass
+class ProjectConfiguration:
+ """
+ Configuration for the Accelerator object based on inner-project needs.
+
+ Args:
+ project_dir (`str`, defaults to `None`):
+ A path to a directory for storing data.
+ logging_dir (`str`, defaults to `None`):
+ A path to a directory for storing logs of locally-compatible loggers. If None, defaults to `project_dir`.
+ automatic_checkpoint_naming (`bool`, defaults to `False`):
+ Whether saved states should be automatically iteratively named.
+ total_limit (`int`, defaults to `None`):
+ The maximum number of total saved states to keep.
+ iteration (`int`, defaults to `0`):
+ The current save iteration.
+ save_on_each_node (`bool`, defaults to `False`):
+ When doing multi-node distributed training, whether to save models and checkpoints on each node, or only on
+ the main one.
+ """
+
+ project_dir: str = field(default=None, metadata={"help": "A path to a directory for storing data."})
+ logging_dir: str = field(
+ default=None,
+ metadata={
+ "help": "A path to a directory for storing logs of locally-compatible loggers. If None, defaults to `project_dir`."
+ },
+ )
+ automatic_checkpoint_naming: bool = field(
+ default=False,
+ metadata={"help": "Whether saved states should be automatically iteratively named."},
+ )
+
+ total_limit: int = field(
+ default=None,
+ metadata={"help": "The maximum number of total saved states to keep."},
+ )
+
+ iteration: int = field(
+ default=0,
+ metadata={"help": "The current save iteration."},
+ )
+
+ save_on_each_node: bool = field(
+ default=False,
+ metadata={
+ "help": (
+ "When doing multi-node distributed training, whether to save models and checkpoints on each node, or"
+ " only on the main one"
+ )
+ },
+ )
+
+ def set_directories(self, project_dir: Optional[str] = None):
+ "Sets `self.project_dir` and `self.logging_dir` to the appropriate values."
+ self.project_dir = project_dir
+ if self.logging_dir is None:
+ self.logging_dir = project_dir
+
+ def __post_init__(self):
+ self.set_directories(self.project_dir)
+
+
+@dataclass
+class GradientAccumulationPlugin(KwargsHandler):
+ """
+ A plugin to configure gradient accumulation behavior. You can only pass one of `gradient_accumulation_plugin` or
+ `gradient_accumulation_steps` to [`Accelerator`]. Passing both raises an error.
+
+ Parameters:
+ num_steps (`int`):
+ The number of steps to accumulate gradients for.
+ adjust_scheduler (`bool`, *optional*, defaults to `True`):
+ Whether to adjust the scheduler steps to account for the number of steps being accumulated. Should be
+ `True` if the used scheduler was not adjusted for gradient accumulation.
+ sync_with_dataloader (`bool`, *optional*, defaults to `True`):
+ Whether to synchronize setting the gradients when at the end of the dataloader.
+ sync_each_batch (`bool`, *optional*):
+ Whether to synchronize setting the gradients at each data batch. Setting to `True` may reduce memory
+ requirements when using gradient accumulation with distributed training, at expense of speed.
+
+ Example:
+
+ ```python
+ from accelerate.utils import GradientAccumulationPlugin
+
+ gradient_accumulation_plugin = GradientAccumulationPlugin(num_steps=2)
+ accelerator = Accelerator(gradient_accumulation_plugin=gradient_accumulation_plugin)
+ ```
+ """
+
+ num_steps: int = field(
+ default=None,
+ metadata={"help": "The number of steps to accumulate gradients for."},
+ )
+ adjust_scheduler: bool = field(
+ default=True,
+ metadata={
+ "help": "Whether to adjust the scheduler steps to account for the number of steps being accumulated. Should be `True` if the used scheduler was not adjusted for gradient accumulation."
+ },
+ )
+ sync_with_dataloader: bool = field(
+ default=True,
+ metadata={
+ "help": "Whether to synchronize setting the gradients when at the end of the dataloader. Should only be set to `False` if you know what you're doing."
+ },
+ )
+ sync_each_batch: bool = field(
+ default=False,
+ metadata={
+ "help": "Whether to synchronize setting the gradients at each data batch. Setting to `True` may reduce memory requirements when using gradient accumulation with distributed training, at expense of speed."
+ },
+ )
+
+
+@dataclass
+class TorchDynamoPlugin(KwargsHandler):
+ """
+ This plugin is used to compile a model with PyTorch 2.0
+
+ Args:
+ backend (`DynamoBackend`, defaults to `None`):
+ A valid Dynamo backend. See https://pytorch.org/docs/stable/torch.compiler.html for more details.
+ mode (`str`, defaults to `None`):
+ Possible options are 'default', 'reduce-overhead' or 'max-autotune'.
+ fullgraph (`bool`, defaults to `None`):
+ Whether it is ok to break model into several subgraphs.
+ dynamic (`bool`, defaults to `None`):
+ Whether to use dynamic shape for tracing.
+ options (`Any`, defaults to `None`):
+ A dictionary of options to pass to the backend.
+ disable (`bool`, defaults to `False`):
+ Turn torch.compile() into a no-op for testing
+ use_regional_compilation (`bool`, defaults to `None`):
+ Use it to reduce the cold start compilation time of torch.compile() by targeting repeated blocks of the
+ same class and compiling them sequentially to hit the compiler's cache. For example, in `GPT2LMHeadModel`,
+ the repeated block/class is `GPT2Block`, and can be accessed as `model.transformer.h[0]`. The rest of the
+ model (e.g model.lm_head) is compiled separately.
+ """
+
+ backend: DynamoBackend = field(
+ default=None,
+ metadata={"help": f"Possible options are {[b.value.lower() for b in DynamoBackend]}"},
+ )
+ mode: str = field(
+ default=None,
+ metadata={"help": "Possible options are 'default', 'reduce-overhead' or 'max-autotune'"},
+ )
+ fullgraph: bool = field(
+ default=None,
+ metadata={"help": "Whether it is ok to break model into several subgraphs"},
+ )
+ dynamic: bool = field(default=None, metadata={"help": "Whether to use dynamic shape for tracing"})
+ options: Any = field(
+ default=None,
+ metadata={"help": "A dictionary of options to pass to the backend."},
+ )
+ disable: bool = field(
+ default=False,
+ metadata={"help": "Turn torch.compile() into a no-op for testing"},
+ )
+
+ use_regional_compilation: bool = field(
+ default=None,
+ metadata={
+ "help": (
+ # https://pytorch.org/tutorials/recipes/regional_compilation.html
+ "Use it to reduce the cold start compilation time of torch.compile() by targeting repeated "
+ "blocks of the same class and compiling them sequentially to hit the compiler's cache. For "
+ "example, in `GPT2LMHeadModel`, the repeated block/class is `GPT2Block`, and can be accessed "
+ "as `model.transformer.h[0]`. The rest of the model (e.g model.lm_head) is compiled separately."
+ )
+ },
+ )
+
+ def __post_init__(self):
+ prefix = "ACCELERATE_DYNAMO_"
+ if self.backend is None:
+ self.backend = os.environ.get(prefix + "BACKEND", "no")
+ self.backend = DynamoBackend(self.backend.upper())
+
+ if self.mode is None:
+ self.mode = os.environ.get(prefix + "MODE", "default")
+ if self.fullgraph is None:
+ self.fullgraph = str_to_bool(os.environ.get(prefix + "USE_FULLGRAPH", "False")) == 1
+ if self.use_regional_compilation is None:
+ self.use_regional_compilation = (
+ str_to_bool(os.environ.get(prefix + "USE_REGIONAL_COMPILATION", "False")) == 1
+ )
+
+ if self.dynamic is None and os.environ.get(prefix + "USE_DYNAMIC", None) is not None:
+ self.dynamic = str_to_bool(os.environ.get(prefix + "USE_DYNAMIC", "False")) == 1
+
+ def to_dict(self):
+ dynamo_config = copy.deepcopy(self.__dict__)
+ dynamo_config["backend"] = dynamo_config["backend"].value.lower()
+ return dynamo_config
+
+ def to_kwargs(self):
+ kwargs = super().to_kwargs()
+ kwargs.pop("use_regional_compilation", None)
+ return kwargs
+
+
+@dataclass
+class DeepSpeedPlugin:
+ """
+ This plugin is used to integrate DeepSpeed.
+
+ Args:
+ hf_ds_config (`Any`, defaults to `None`):
+ Path to DeepSpeed config file or dict or an object of class `accelerate.utils.deepspeed.HfDeepSpeedConfig`.
+ gradient_accumulation_steps (`int`, defaults to `None`):
+ Number of steps to accumulate gradients before updating optimizer states. If not set, will use the value
+ from the `Accelerator` directly.
+ gradient_clipping (`float`, defaults to `None`):
+ Enable gradient clipping with value.
+ zero_stage (`int`, defaults to `None`):
+ Possible options are 0, 1, 2, 3. Default will be taken from environment variable.
+ is_train_batch_min (`bool`, defaults to `True`):
+ If both train & eval dataloaders are specified, this will decide the `train_batch_size`.
+ offload_optimizer_device (`str`, defaults to `None`):
+ Possible options are none|cpu|nvme. Only applicable with ZeRO Stages 2 and 3.
+ offload_param_device (`str`, defaults to `None`):
+ Possible options are none|cpu|nvme. Only applicable with ZeRO Stage 3.
+ offload_optimizer_nvme_path (`str`, defaults to `None`):
+ Possible options are /nvme|/local_nvme. Only applicable with ZeRO Stage 3.
+ offload_param_nvme_path (`str`, defaults to `None`):
+ Possible options are /nvme|/local_nvme. Only applicable with ZeRO Stage 3.
+ zero3_init_flag (`bool`, defaults to `None`):
+ Flag to indicate whether to save 16-bit model. Only applicable with ZeRO Stage-3.
+ zero3_save_16bit_model (`bool`, defaults to `None`):
+ Flag to indicate whether to save 16-bit model. Only applicable with ZeRO Stage-3.
+ transformer_moe_cls_names (`str`, defaults to `None`):
+ Comma-separated list of Transformers MoE layer class names (case-sensitive). For example,
+ `MixtralSparseMoeBlock`, `Qwen2MoeSparseMoeBlock`, `JetMoEAttention`, `JetMoEBlock`, etc.
+ enable_msamp (`bool`, defaults to `None`):
+ Flag to indicate whether to enable MS-AMP backend for FP8 training.
+ msasmp_opt_level (`Optional[Literal["O1", "O2"]]`, defaults to `None`):
+ Optimization level for MS-AMP (defaults to 'O1'). Only applicable if `enable_msamp` is True. Should be one
+ of ['O1' or 'O2'].
+ """
+
+ hf_ds_config: Any = field(
+ default=None,
+ metadata={
+ "help": "path to DeepSpeed config file or dict or an object of class `accelerate.utils.deepspeed.HfDeepSpeedConfig`."
+ },
+ )
+ gradient_accumulation_steps: int = field(
+ default=None,
+ metadata={
+ "help": "Number of steps to accumulate gradients before updating optimizer states. If not set, will use the value from the `Accelerator` directly."
+ },
+ )
+ gradient_clipping: float = field(default=None, metadata={"help": "Enable gradient clipping with value"})
+ zero_stage: int = field(
+ default=None,
+ metadata={"help": "Possible options are 0,1,2,3; Default will be taken from environment variable"},
+ )
+ is_train_batch_min: bool = field(
+ default=True,
+ metadata={"help": "If both train & eval dataloaders are specified, this will decide the train_batch_size"},
+ )
+ offload_optimizer_device: str = field(
+ default=None,
+ metadata={"help": "Possible options are none|cpu|nvme. Only applicable with ZeRO Stages 2 and 3."},
+ )
+ offload_param_device: str = field(
+ default=None,
+ metadata={"help": "Possible options are none|cpu|nvme. Only applicable with ZeRO Stage 3."},
+ )
+ offload_optimizer_nvme_path: str = field(
+ default=None,
+ metadata={"help": "Possible options are /nvme|/local_nvme. Only applicable with ZeRO Stage 3."},
+ )
+ offload_param_nvme_path: str = field(
+ default=None,
+ metadata={"help": "Possible options are /nvme|/local_nvme. Only applicable with ZeRO Stage 3."},
+ )
+ zero3_init_flag: bool = field(
+ default=None,
+ metadata={
+ "help": "Flag to indicate whether to enable `deepspeed.zero.Init` for constructing massive models."
+ "Only applicable with ZeRO Stage-3."
+ },
+ )
+ zero3_save_16bit_model: bool = field(
+ default=None,
+ metadata={"help": "Flag to indicate whether to save 16-bit model. Only applicable with ZeRO Stage-3."},
+ )
+ transformer_moe_cls_names: str = field(
+ default=None,
+ metadata={
+ "help": "comma-separated list of transformers MoE layer class names (case-sensitive), e.g : "
+ " `MixtralSparseMoeBlock`, `Qwen2MoeSparseMoeBlock`, `JetMoEAttention,JetMoEBlock` ..."
+ },
+ )
+ enable_msamp: bool = field(
+ default=None,
+ metadata={"help": "Flag to indicate whether to enable MS-AMP backend for FP8 training."},
+ )
+ msamp_opt_level: Optional[Literal["O1", "O2"]] = field(
+ default=None,
+ metadata={
+ "help": "Optimization level for MS-AMP (defaults to 'O1'). Only applicable if `enable_msamp` is True. Should be one of ['O1' or 'O2']."
+ },
+ )
+
+ def __post_init__(self):
+ from .deepspeed import HfDeepSpeedConfig
+
+ if self.gradient_accumulation_steps is None:
+ gas = os.environ.get("ACCELERATE_GRADIENT_ACCUMULATION_STEPS", "auto")
+ self.gradient_accumulation_steps = int(gas) if gas.isdigit() else gas
+
+ if self.gradient_clipping is None:
+ gradient_clipping = os.environ.get("ACCELERATE_GRADIENT_CLIPPING", "auto")
+ self.gradient_clipping = gradient_clipping if gradient_clipping == "auto" else float(gradient_clipping)
+
+ if self.zero_stage is None:
+ self.zero_stage = int(os.environ.get("ACCELERATE_DEEPSPEED_ZERO_STAGE", 2))
+
+ if self.offload_optimizer_device is None:
+ self.offload_optimizer_device = os.environ.get("ACCELERATE_DEEPSPEED_OFFLOAD_OPTIMIZER_DEVICE", "none")
+
+ if self.offload_param_device is None:
+ self.offload_param_device = os.environ.get("ACCELERATE_DEEPSPEED_OFFLOAD_PARAM_DEVICE", "none")
+
+ if self.offload_optimizer_nvme_path is None:
+ self.offload_optimizer_nvme_path = os.environ.get(
+ "ACCELERATE_DEEPSPEED_OFFLOAD_OPTIMIZER_NVME_PATH", "none"
+ )
+
+ if self.offload_param_nvme_path is None:
+ self.offload_param_nvme_path = os.environ.get("ACCELERATE_DEEPSPEED_OFFLOAD_PARAM_NVME_PATH", "none")
+
+ if self.zero3_save_16bit_model is None:
+ self.zero3_save_16bit_model = (
+ os.environ.get("ACCELERATE_DEEPSPEED_ZERO3_SAVE_16BIT_MODEL", "false").lower() == "true"
+ )
+ if self.enable_msamp is None:
+ self.enable_msamp = os.environ.get("ACCELERATE_FP8_BACKEND", None) == "MSAMP"
+
+ if self.msamp_opt_level is None:
+ self.msamp_opt_level = os.environ.get("ACCELERATE_FP8_OPT_LEVEL", "O1")
+
+ if self.hf_ds_config is None:
+ self.hf_ds_config = os.environ.get("ACCELERATE_DEEPSPEED_CONFIG_FILE", "none")
+
+ if (
+ isinstance(self.hf_ds_config, dict)
+ or (isinstance(self.hf_ds_config, str) and self.hf_ds_config != "none")
+ or isinstance(self.hf_ds_config, HfDeepSpeedConfig)
+ ):
+ if not isinstance(self.hf_ds_config, HfDeepSpeedConfig):
+ self.hf_ds_config = HfDeepSpeedConfig(self.hf_ds_config)
+ if "gradient_accumulation_steps" not in self.hf_ds_config.config:
+ self.hf_ds_config.config["gradient_accumulation_steps"] = 1
+ if "zero_optimization" not in self.hf_ds_config.config:
+ raise ValueError("Please specify the ZeRO optimization config in the DeepSpeed config.")
+
+ self._deepspeed_config_checks()
+ plugin_to_config_mapping = {
+ "gradient_accumulation_steps": "gradient_accumulation_steps",
+ "gradient_clipping": "gradient_clipping",
+ "zero_stage": "zero_optimization.stage",
+ "offload_optimizer_device": "zero_optimization.offload_optimizer.device",
+ "offload_param_device": "zero_optimization.offload_param.device",
+ "offload_param_nvme_path": "zero_optimization.offload_param.nvme_path",
+ "offload_optimizer_nvme_path": "zero_optimization.offload_optimizer.nvme_path",
+ "zero3_save_16bit_model": "zero_optimization.stage3_gather_16bit_weights_on_model_save",
+ }
+ kwargs = {v: getattr(self, k) for k, v in plugin_to_config_mapping.items() if getattr(self, k) is not None}
+ for key in kwargs.keys():
+ self.fill_match(key, **kwargs, must_match=False)
+ self.hf_ds_config.set_stage_and_offload()
+
+ # filling the missing values in the class attributes from the DeepSpeed config
+ # when using the DeepSpeed config file.
+ for key, value in plugin_to_config_mapping.items():
+ config_value = self.hf_ds_config.get_value(value)
+ if config_value is not None and config_value != "auto":
+ setattr(self, key, config_value)
+ else:
+ config = {
+ "train_batch_size": "auto",
+ "train_micro_batch_size_per_gpu": "auto",
+ "gradient_accumulation_steps": self.gradient_accumulation_steps,
+ "zero_optimization": {
+ "stage": self.zero_stage,
+ "offload_optimizer": {
+ "device": self.offload_optimizer_device,
+ "nvme_path": (
+ self.offload_optimizer_nvme_path if self.offload_optimizer_device == "nvme" else None
+ ),
+ },
+ "offload_param": {
+ "device": self.offload_param_device,
+ "nvme_path": (self.offload_param_nvme_path if self.offload_param_device == "nvme" else None),
+ },
+ "stage3_gather_16bit_weights_on_model_save": self.zero3_save_16bit_model,
+ },
+ }
+ if self.gradient_clipping:
+ config["gradient_clipping"] = self.gradient_clipping
+ self.hf_ds_config = HfDeepSpeedConfig(config)
+
+ self.deepspeed_config = self.hf_ds_config.config
+ self.deepspeed_config["steps_per_print"] = float("inf") # this will stop deepspeed from logging @ stdout
+ if self.zero3_init_flag is None:
+ self.zero3_init_flag = (
+ str_to_bool(
+ os.environ.get(
+ "ACCELERATE_DEEPSPEED_ZERO3_INIT",
+ str(self.hf_ds_config.is_zero3()),
+ )
+ )
+ == 1
+ )
+ if self.zero3_init_flag and not self.hf_ds_config.is_zero3():
+ warnings.warn("DeepSpeed Zero3 Init flag is only applicable for ZeRO Stage 3. Setting it to False.")
+ self.zero3_init_flag = False
+ # NOTE: Set to False by default, will be set to `True` automatically if it's the first plugin passed
+ # to the `Accelerator`'s `deepspeed_plugin` param, *or* `AcceleratorState().enable_deepspeed_plugin(plugin_key)` is manually called
+ self._set_selected(False)
+
+ # Ignore if it's already set
+ if self.enable_msamp and "msamp" not in self.deepspeed_config:
+ if self.zero_stage == 3:
+ raise NotImplementedError(
+ "MS-AMP is not supported for ZeRO Stage 3. Please use ZeRO Stage 0, 1, or 2 instead."
+ )
+ if self.msamp_opt_level not in ["O1", "O2"]:
+ raise ValueError("Invalid optimization level for MS-AMP. Please use one of ['O1' or'O2'].")
+ self.deepspeed_config["msamp"] = {
+ "enabled": True,
+ "opt_level": self.msamp_opt_level,
+ }
+
+ def fill_match(self, ds_key_long, mismatches=None, must_match=True, **kwargs):
+ mismatches = [] if mismatches is None else mismatches
+ config, ds_key = self.hf_ds_config.find_config_node(ds_key_long)
+ if config is None:
+ return
+
+ if config.get(ds_key) == "auto":
+ if ds_key_long in kwargs:
+ config[ds_key] = kwargs[ds_key_long]
+ return
+ else:
+ raise ValueError(
+ f"`{ds_key_long}` not found in kwargs. "
+ f"Please specify `{ds_key_long}` without `auto` (set to correct value) in the DeepSpeed config file or "
+ "pass it in kwargs."
+ )
+
+ if not must_match:
+ return
+
+ ds_val = config.get(ds_key)
+ if ds_val is not None and ds_key_long in kwargs:
+ if ds_val != kwargs[ds_key_long]:
+ mismatches.append(f"- ds {ds_key_long}={ds_val} vs arg {ds_key_long}={kwargs[ds_key_long]}")
+
+ def is_auto(self, ds_key_long):
+ val = self.hf_ds_config.get_value(ds_key_long)
+ if val is None:
+ return False
+ else:
+ return val == "auto"
+
+ def get_value(self, ds_key_long, default=None):
+ return self.hf_ds_config.get_value(ds_key_long, default)
+
+ def deepspeed_config_process(self, prefix="", mismatches=None, config=None, must_match=True, **kwargs):
+ """Process the DeepSpeed config with the values from the kwargs."""
+ mismatches = [] if mismatches is None else mismatches
+ if config is None:
+ config = self.deepspeed_config
+ for key, value in config.items():
+ if isinstance(value, dict):
+ self.deepspeed_config_process(
+ prefix=prefix + key + ".",
+ mismatches=mismatches,
+ config=value,
+ must_match=must_match,
+ **kwargs,
+ )
+ else:
+ self.fill_match(prefix + key, mismatches, must_match=must_match, **kwargs)
+ if len(mismatches) > 0 and prefix == "":
+ mismatches_msg = "\n".join(mismatches)
+ raise ValueError(
+ "Please correct the following DeepSpeed config values that mismatch kwargs "
+ f" values:\n{mismatches_msg}\nThe easiest method is to set these DeepSpeed config values to 'auto'."
+ )
+
+ def set_mixed_precision(self, mixed_precision):
+ ds_config = self.deepspeed_config
+ kwargs = {
+ "fp16.enabled": mixed_precision == "fp16",
+ # When training in fp8, we still rely on bf16 autocast for the core mixed precision
+ "bf16.enabled": mixed_precision in ("bf16", "fp8"),
+ }
+ if mixed_precision == "fp16":
+ if "fp16" not in ds_config:
+ ds_config["fp16"] = {"enabled": True, "auto_cast": True}
+ elif mixed_precision in ("bf16", "fp8"):
+ if "bf16" not in ds_config:
+ ds_config["bf16"] = {"enabled": True}
+
+ if mixed_precision == "fp8" and self.enable_msamp:
+ if "msamp" not in ds_config:
+ ds_config["msamp"] = {
+ "enabled": True,
+ "opt_level": self.msamp_opt_level,
+ }
+
+ if mixed_precision != "no":
+ diff_dtype = "bf16" if mixed_precision == "fp16" else "fp16"
+ if str(ds_config.get(diff_dtype, {}).get("enabled", "False")).lower() == "true":
+ raise ValueError(
+ f"`--mixed_precision` arg cannot be set to `{mixed_precision}` when `{diff_dtype}` is set in the DeepSpeed config file."
+ )
+ for dtype in ["fp16", "bf16"]:
+ if dtype not in ds_config:
+ ds_config[dtype] = {"enabled": False}
+ self.fill_match("fp16.enabled", must_match=False, **kwargs)
+ self.fill_match("bf16.enabled", must_match=False, **kwargs)
+
+ def set_deepspeed_weakref(self):
+ from .imports import is_transformers_available
+
+ ds_config = copy.deepcopy(self.deepspeed_config)
+ if self.zero3_init_flag:
+ if not is_transformers_available():
+ raise Exception(
+ "When `zero3_init_flag` is set, it requires Transformers to be installed. "
+ "Please run `pip install transformers`."
+ )
+ if "gradient_accumulation_steps" not in ds_config or ds_config["gradient_accumulation_steps"] == "auto":
+ ds_config["gradient_accumulation_steps"] = 1
+ if "train_micro_batch_size_per_gpu" not in ds_config or ds_config["train_micro_batch_size_per_gpu"] == "auto":
+ ds_config["train_micro_batch_size_per_gpu"] = 1
+ if ds_config.get("train_batch_size", None) == "auto":
+ del ds_config["train_batch_size"]
+
+ if compare_versions("transformers", "<", "4.46"):
+ from transformers.deepspeed import (
+ HfDeepSpeedConfig,
+ unset_hf_deepspeed_config,
+ )
+ else:
+ from transformers.integrations import (
+ HfDeepSpeedConfig,
+ unset_hf_deepspeed_config,
+ )
+
+ unset_hf_deepspeed_config()
+ self.dschf = HfDeepSpeedConfig(ds_config) # keep this object alive # noqa
+
+ def is_zero3_init_enabled(self):
+ return self.zero3_init_flag
+
+ @contextmanager
+ def zero3_init_context_manager(self, enable=False):
+ old = self.zero3_init_flag
+ if old == enable:
+ yield
+ else:
+ self.zero3_init_flag = enable
+ self.dschf = None
+ self.set_deepspeed_weakref()
+ yield
+ self.zero3_init_flag = old
+ self.dschf = None
+ self.set_deepspeed_weakref()
+
+ def _deepspeed_config_checks(self):
+ env_variable_names_to_ignore = [
+ "ACCELERATE_GRADIENT_ACCUMULATION_STEPS",
+ "ACCELERATE_GRADIENT_CLIPPING",
+ "ACCELERATE_DEEPSPEED_ZERO_STAGE",
+ "ACCELERATE_DEEPSPEED_OFFLOAD_OPTIMIZER_DEVICE",
+ "ACCELERATE_DEEPSPEED_OFFLOAD_PARAM_DEVICE",
+ "ACCELERATE_DEEPSPEED_OFFLOAD_PARAM_NVME_PATH",
+ "ACCELERATE_DEEPSPEED_OFFLOAD_OPTIMIZER_NVME_PATH",
+ "ACCELERATE_DEEPSPEED_ZERO3_SAVE_16BIT_MODEL",
+ "ACCELERATE_MIXED_PRECISION",
+ ]
+ env_variable_names_to_ignore = [
+ name.replace("ACCELERATE_", "").replace("DEEPSPEED_", "").lower() for name in env_variable_names_to_ignore
+ ]
+
+ deepspeed_fields_from_accelerate_config = os.environ.get("ACCELERATE_CONFIG_DS_FIELDS", "").split(",")
+
+ if any(name in env_variable_names_to_ignore for name in deepspeed_fields_from_accelerate_config):
+ raise ValueError(
+ f"When using `deepspeed_config_file`, the following accelerate config variables will be ignored: {env_variable_names_to_ignore}.\n"
+ "Please specify them appropriately in the DeepSpeed config file.\n"
+ "If you are using an accelerate config file, remove others config variables mentioned in the above specified list.\n"
+ "The easiest method is to create a new config following the questionnaire via `accelerate config`.\n"
+ "It will only ask for the necessary config variables when using `deepspeed_config_file`."
+ )
+
+ def set_moe_leaf_modules(self, model):
+ if self.transformer_moe_cls_names is None:
+ self.transformer_moe_cls_names = os.environ.get("ACCELERATE_DEEPSPEED_MOE_LAYER_CLS_NAMES", None)
+ if self.transformer_moe_cls_names is not None:
+ if compare_versions("deepspeed", "<", "0.14.0"):
+ raise ImportError("DeepSpeed version must be >= 0.14.0 to use MOE support. Please update DeepSpeed.")
+ from deepspeed.utils import set_z3_leaf_modules
+
+ class_names = self.transformer_moe_cls_names.split(",")
+ transformer_moe_cls = []
+ for layer_class in class_names:
+ transformer_cls = get_module_class_from_name(model, layer_class)
+ if transformer_cls is None:
+ raise Exception(
+ f"Could not find a transformer layer class called '{layer_class}' to wrap in the model."
+ )
+ else:
+ transformer_moe_cls.append(transformer_cls)
+ set_z3_leaf_modules(model, transformer_moe_cls) # z3_leaf
+
+ def select(self, _from_accelerator_state: bool = False):
+ """
+ Sets the HfDeepSpeedWeakref to use the current deepspeed plugin configuration
+ """
+ if not _from_accelerator_state:
+ raise ValueError(
+ "A `DeepSpeedPlugin` object must be enabled manually by calling `AcceleratorState().enable_deepspeed_plugin(plugin_key)`."
+ )
+ self.set_deepspeed_weakref()
+ self._set_selected(True)
+
+ def _unselect(self):
+ self._set_selected(False)
+
+ def _set_selected(self, value: bool):
+ """
+ Private setter for the 'enabled' attribute.
+ """
+ self._selected = value
+
+ @property
+ def selected(self):
+ return self._selected
+
+ @selected.setter
+ def selected(self, value):
+ raise NotImplementedError(
+ "'enabled' can only be set through calling 'AcceleratorState().enable_deepspeed_plugin(key)'."
+ )
+
+
+@dataclass
+class FullyShardedDataParallelPlugin:
+ """
+ This plugin is used to enable fully sharded data parallelism.
+
+ Args:
+ fsdp_version (`int`, defaults to `1`):
+ The version of FSDP to use. Defaults to 1. If set to 2, launcher expects the config to be converted to
+ FSDP2 format.
+ sharding_strategy (`Union[str, torch.distributed.fsdp.ShardingStrategy]`, defaults to `'FULL_SHARD'`):
+ Sharding strategy to use. Should be either a `str` or an instance of
+ `torch.distributed.fsdp.fully_sharded_data_parallel.ShardingStrategy`. Is deprecated in favor of
+ `reshard_after_forward`.
+ reshard_after_forward (`Union[str, torch.distributed.fsdp.ShardingStrategy, bool]`, defaults to `'FULL_SHARD'` for `fsdp_version=1` and `True` for `fsdp_version=2`):
+ Sharding strategy to use. Should be a bool if `fsdp_version` is set to 2 else a `str` or an instance of
+ `torch.distributed.fsdp.fully_sharded_data_parallel.ShardingStrategy`.
+ backward_prefetch (`Union[str, torch.distributed.fsdp.BackwardPrefetch]`, defaults to `'NO_PREFETCH'`):
+ Backward prefetch strategy to use. Should be either a `str` or an instance of
+ `torch.distributed.fsdp.fully_sharded_data_parallel.BackwardPrefetch`.
+ mixed_precision_policy (`Optional[Union[dict, str, torch.distributed.fsdp.MixedPrecision, torch.distributed.fsdp.MixedPrecisionPolicy]]`, defaults to `None`):
+ A config to enable mixed precision training with FullyShardedDataParallel. If passing in a `dict`, it
+ should have the following keys: `param_dtype`, `reduce_dtype`, and `buffer_dtype`, can be an instance of
+ `torch.distributed.fsdp.MixedPrecisionPolicy` if `fsdp_version` is set to 2. If passing in a `str`, it
+ should be one of the following values: fp8, fp16, bf16, fp32, and used to set `param_dtype`,
+ `reduce_dtype`, and `buffer_dtype`.
+ auto_wrap_policy (`Optional(Union[Callable, Literal["transformer_based_wrap", "size_based_wrap", "no_wrap"]]), defaults to `NO_WRAP`):
+ A callable or string specifying a policy to recursively wrap layers with FSDP. If a string, it must be one
+ of `transformer_based_wrap`, `size_based_wrap`, or `no_wrap`. See
+ `torch.distributed.fsdp.wrap.size_based_wrap_policy` for a direction on what it should look like.
+ cpu_offload (`Union[bool, torch.distributed.fsdp.CPUOffload, torch.distributed.fsdp.CPUOffloadPolicy]`, defaults to `False`):
+ Whether to offload parameters to CPU. Should be either a `bool` or an instance of
+ `torch.distributed.fsdp.fully_sharded_data_parallel.CPUOffload` or
+ `torch.distributed.fsdp.fully_sharded_data_parallel.CPUOffloadPolicy` if `fsdp_version` is set to 2.
+ ignored_modules (`Optional[Union[Iterable[torch.nn.Module], str]]`, defaults to `None`):
+ A list of modules to ignore when wrapping with FSDP. When passing a string, will match the modules by name
+ using regex fullmatch. If `fsdp_version` is set to 2, the modules are converted to parameters and used.
+ state_dict_type (`Union[str, torch.distributed.fsdp.StateDictType]`, defaults to `'FULL_STATE_DICT'`):
+ State dict type to use. If a string, it must be one of `full_state_dict`, `local_state_dict`, or
+ `sharded_state_dict`.
+ state_dict_config (`Optional[Union[torch.distributed.fsdp.FullStateDictConfig, torch.distributed.fsdp.ShardedStateDictConfig]`, defaults to `None`):
+ State dict config to use. Is determined based on the `state_dict_type` if not passed in.
+ optim_state_dict_config (`Optional[Union[torch.distributed.fsdp.FullOptimStateDictConfig, torch.distributed.fsdp.ShardedOptimStateDictConfig]`, defaults to `None`):
+ Optim state dict config to use. Is determined based on the `state_dict_type` if not passed in.
+ limit_all_gathers (`bool`, defaults to `True`):
+ Whether to have FSDP explicitly synchronizes the CPU thread to prevent too many in-flight all-gathers. This
+ bool only affects the sharded strategies that schedule all-gathers. Enabling this can help lower the number
+ of CUDA malloc retries.
+ use_orig_params (`bool`, defaults to `False`):
+ Whether to use the original parameters for the optimizer.
+ param_init_fn (`Optional[Callable[[torch.nn.Module], None]`, defaults to `None`):
+ A `Callable[torch.nn.Module] -> None` that specifies how modules that are currently on the meta device
+ should be initialized onto an actual device. Only applicable when `sync_module_states` is `True`. By
+ default is a `lambda` which calls `to_empty` on the module.
+ sync_module_states (`bool`, defaults to `False`):
+ Whether each individually wrapped FSDP unit should broadcast module parameters from rank 0 to ensure they
+ are the same across all ranks after initialization. Defaults to `False` unless `cpu_ram_efficient_loading`
+ is `True`, then will be forcibly enabled.
+ forward_prefetch (`bool`, defaults to `False`):
+ Whether to have FSDP explicitly prefetches the next upcoming all-gather while executing in the forward
+ pass. only use with Static graphs.
+ activation_checkpointing (`bool`, defaults to `False`):
+ A technique to reduce memory usage by clearing activations of certain layers and recomputing them during a
+ backward pass. Effectively, this trades extra computation time for reduced memory usage.
+ cpu_ram_efficient_loading (`bool`, defaults to `None`):
+ If True, only the first process loads the pretrained model checkoint while all other processes have empty
+ weights. Only applicable for Transformers. When using this, `sync_module_states` needs to be `True`.
+ transformer_cls_names_to_wrap (`Optional[List[str]]`, defaults to `None`):
+ A list of transformer layer class names to wrap. Only applicable when `auto_wrap_policy` is
+ `transformer_based_wrap`.
+ min_num_params (`Optional[int]`, defaults to `None`):
+ The minimum number of parameters a module must have to be wrapped. Only applicable when `auto_wrap_policy`
+ is `size_based_wrap`.
+ """
+
+ fsdp_version: int = field(
+ default=None,
+ metadata={
+ "help": "The version of FSDP to use. Defaults to 1. If set to 2, launcher expects the config to be converted to FSDP2 format."
+ },
+ )
+
+ sharding_strategy: Union[str, "torch.distributed.fsdp.ShardingStrategy"] = field(
+ default=None,
+ metadata={
+ "help": "Sharding strategy to use. Should be either a `str` or an instance of `torch.distributed.fsdp.fully_sharded_data_parallel.ShardingStrategy`. Defaults to 'FULL_SHARD'. Is deprecated in favor of `reshard_after_forward` "
+ },
+ )
+
+ reshard_after_forward: Union[str, "torch.distributed.fsdp.ShardingStrategy", bool] = field(
+ default=None,
+ metadata={
+ "help": "Sharding strategy to use. Should be a bool if `fsdp_version` is set to 2 else a `str` or an instance of `torch.distributed.fsdp.fully_sharded_data_parallel.ShardingStrategy`. Defaults to 'FULL_SHARD'"
+ },
+ )
+ backward_prefetch: Optional[Union[str, "torch.distributed.fsdp.BackwardPrefetch"]] = field(
+ default=None,
+ metadata={
+ "help": "Backward prefetch strategy to use. Should be either a `str` or an instance of `torch.distributed.fsdp.fully_sharded_data_parallel.BackwardPrefetch`. Defaults to 'NO_PREFETCH'. This becomes obsolete in FSDP2."
+ },
+ )
+ mixed_precision_policy: Optional[
+ Union[
+ dict,
+ str,
+ "torch.distributed.fsdp.MixedPrecision",
+ "torch.distributed.fsdp.MixedPrecisionPolicy",
+ ]
+ ] = field(
+ default=None,
+ metadata={
+ "help": "A config to enable mixed precision training with FullyShardedDataParallel. "
+ "If passing in a `dict`, it should have the following keys: `param_dtype`, `reduce_dtype`, and `buffer_dtype`."
+ "Can also be an instance of `torch.distributed.fsdp.MixedPrecisionPolicy` if `fsdp_version` is set to 2."
+ },
+ )
+ auto_wrap_policy: Optional[Union[Callable, Literal["transformer_based_wrap", "size_based_wrap", "no_wrap"]]] = (
+ field(
+ default=None,
+ metadata={
+ "help": "A callable or string specifying a policy to recursively wrap layers with FSDP. If a string, it must be one of `transformer_based_wrap`, `size_based_wrap`, or `no_wrap`. "
+ "Defaults to `NO_WRAP`. See `torch.distributed.fsdp.wrap.size_based_wrap_policy` for a direction on what it should look like"
+ },
+ )
+ )
+ cpu_offload: Union[
+ bool,
+ "torch.distributed.fsdp.CPUOffload",
+ "torch.distributed.fsdp.CPUOffloadPolicy",
+ ] = field(
+ default=None,
+ metadata={
+ "help": "Whether to offload parameters to CPU. Should be either a `bool` or an instance of `torch.distributed.fsdp.fully_sharded_data_parallel.CPUOffload` or `torch.distributed.fsdp.fully_sharded_data_parallel.CPUOffloadPolicy` if `fsdp_version` is set to 2. Defaults to `False`"
+ },
+ )
+ ignored_modules: Optional[Union[Iterable[torch.nn.Module], str]] = field(
+ default=None,
+ metadata={"help": "A list of modules to ignore when wrapping with FSDP."},
+ )
+
+ state_dict_type: Union[str, "torch.distributed.fsdp.StateDictType"] = field(
+ default=None,
+ metadata={
+ "help": "State dict type to use. If a string, it must be one of `full_state_dict`, `local_state_dict`, or `sharded_state_dict`. Defaults to `FULL_STATE_DICT`"
+ },
+ )
+ state_dict_config: Optional[
+ Union[
+ "torch.distributed.fsdp.FullStateDictConfig",
+ "torch.distributed.fsdp.ShardedStateDictConfig",
+ ]
+ ] = field(
+ default=None,
+ metadata={"help": "State dict config to use. Is determined based on the `state_dict_type` if not passed in."},
+ )
+ optim_state_dict_config: Optional[
+ Union[
+ "torch.distributed.fsdp.FullOptimStateDictConfig",
+ "torch.distributed.fsdp.ShardedOptimStateDictConfig",
+ ]
+ ] = field(
+ default=None,
+ metadata={
+ "help": "Optim state dict config to use. Is determined based on the `state_dict_type` if not passed in."
+ },
+ )
+ limit_all_gathers: bool = field(
+ default=True,
+ metadata={
+ "help": "Whether to have FSDP explicitly synchronizes the CPU thread to prevent "
+ "too many in-flight all-gathers. This bool only affects the sharded strategies that schedule all-gathers. "
+ "Enabling this can help lower the number of CUDA malloc retries."
+ },
+ )
+ use_orig_params: Optional[bool] = field(
+ default=None,
+ metadata={
+ "help": "Whether to use the original parameters for the optimizer. Defaults to `False`. This becomes obsolete in FSDP2."
+ },
+ )
+ param_init_fn: Optional[Callable[[torch.nn.Module], None]] = field(
+ default=None,
+ metadata={
+ "help": "A Callable[torch.nn.Module] -> None that specifies how modules "
+ "that are currently on the meta device should be initialized onto an actual device. "
+ "Only applicable when `sync_module_states` is `True`. By default is a `lambda` which calls `to_empty` on the module."
+ },
+ )
+ sync_module_states: Optional[bool] = field(
+ default=None,
+ metadata={
+ "help": "Whether each individually wrapped FSDP unit should broadcast module parameters from rank 0 "
+ "to ensure they are the same across all ranks after initialization. Defaults to `False` unless "
+ "`cpu_ram_efficient_loading` is `True`, then will be forcibly enabled. This becomes obsolete in FSDP2."
+ },
+ )
+ forward_prefetch: bool = field(
+ default=None,
+ metadata={
+ "help": "Whether to have FSDP explicitly prefetches the next upcoming "
+ "all-gather while executing in the forward pass. only use with Static graphs. Defaults to `False`"
+ },
+ )
+ activation_checkpointing: bool = field(
+ default=None,
+ metadata={
+ "help": "A technique to reduce memory usage by clearing activations of "
+ "certain layers and recomputing them during a backward pass. Effectively, this trades extra computation time "
+ "for reduced memory usage. Defaults to `False`"
+ },
+ )
+ cpu_ram_efficient_loading: bool = field(
+ default=None,
+ metadata={
+ "help": "If True, only the first process loads the pretrained model checkoint while all other processes have empty weights. "
+ "Only applicable for 🤗 Transformers. When using this, `sync_module_states` needs to be `True`. Defaults to `False`."
+ },
+ )
+ transformer_cls_names_to_wrap: Optional[list[str]] = field(
+ default=None,
+ metadata={
+ "help": "A list of transformer layer class names to wrap. Only applicable when `auto_wrap_policy` is `transformer_based_wrap`."
+ },
+ )
+ min_num_params: Optional[int] = field(
+ default=None,
+ metadata={
+ "help": "The minimum number of parameters a module must have to be wrapped. Only applicable when `auto_wrap_policy` is `size_based_wrap`."
+ },
+ )
+
+ def __post_init__(self):
+ from torch.distributed.fsdp import BackwardPrefetch, ShardingStrategy
+
+ _fsdp2_warnings = set()
+
+ env_prefix = "FSDP_"
+ # Strategy: By default we should always assume that values are passed in, else we check the environment variables
+ if self.fsdp_version is None:
+ self.fsdp_version = int(os.environ.get(env_prefix + "VERSION", "1"))
+
+ if self.fsdp_version == 2:
+ if not is_torch_version(">=", FSDP2_PYTORCH_VERSION):
+ raise ImportError(f"FSDP2 requires PyTorch >= {FSDP2_PYTORCH_VERSION}")
+
+ if self.sharding_strategy is not None:
+ # We cannot properly detect all of the cases, as by default `args.fsdp_sharding_strategy` is set to `fully_shard`
+ # Therefore we issue a warning only if the user has explicitly set it inside their plugin
+ _fsdp2_warnings.add(
+ "sharding_strategy is deprecated in favor of reshard_after_forward. "
+ "This will be removed in a future version of Accelerate."
+ )
+ if self.fsdp_version == 1:
+ if self.sharding_strategy is None:
+ self.sharding_strategy = os.environ.get(env_prefix + "SHARDING_STRATEGY", "FULL_SHARD")
+ if isinstance(self.sharding_strategy, str):
+ if self.sharding_strategy.upper() in FSDP_SHARDING_STRATEGY:
+ self.sharding_strategy = FSDP_SHARDING_STRATEGY.index(self.sharding_strategy.upper()) + 1
+ if isinstance(self.sharding_strategy, int) or self.sharding_strategy.isdigit():
+ self.sharding_strategy = ShardingStrategy(int(self.sharding_strategy))
+ else:
+ self.sharding_strategy = ShardingStrategy[self.sharding_strategy.upper()]
+
+ # Fallback to `reshard_after_forward` in FSDP1 if `sharding_strategy` is not set
+ if self.reshard_after_forward is None and self.sharding_strategy is None:
+ reshard_after_forward = os.environ.get(
+ env_prefix + "RESHARD_AFTER_FORWARD",
+ "true" if self.fsdp_version == 2 else "FULL_SHARD",
+ )
+ if self.fsdp_version == 2:
+ self.reshard_after_forward = str_to_bool(reshard_after_forward.lower(), to_bool=True)
+ else:
+ self.reshard_after_forward = reshard_after_forward
+ if isinstance(self.reshard_after_forward, str):
+ if self.fsdp_version == 2:
+ self.reshard_after_forward = str_to_bool(self.reshard_after_forward.lower(), to_bool=True)
+ else:
+ # We need to remap based on custom enum values for user readability
+ if self.reshard_after_forward.upper() in FSDP_SHARDING_STRATEGY:
+ self.reshard_after_forward = FSDP_SHARDING_STRATEGY.index(self.reshard_after_forward.upper()) + 1
+ if isinstance(self.reshard_after_forward, int) or self.reshard_after_forward.isdigit():
+ self.reshard_after_forward = ShardingStrategy(int(self.reshard_after_forward))
+ else:
+ self.reshard_after_forward = ShardingStrategy[self.reshard_after_forward.upper()]
+
+ if self.fsdp_version == 2 and not isinstance(self.reshard_after_forward, bool):
+ raise ValueError(
+ f"reshard_after_forward set to {self.reshard_after_forward}. This is not supported with FSDP2, please set to a `bool`"
+ )
+ if self.fsdp_version == 1 and isinstance(self.reshard_after_forward, bool):
+ raise ValueError(
+ f"reshard_after_forward set to {self.reshard_after_forward}. This is not supported with FSDP1, please set to a `str` or an instance of `torch.distributed.fsdp.fully_sharded_data_parallel.ShardingStrategy`"
+ )
+
+ if self.cpu_offload is None:
+ self.cpu_offload = str_to_bool(os.environ.get(env_prefix + "OFFLOAD_PARAMS", "False")) == 1
+
+ self.set_cpu_offload() # abstracted away to hide imports due to version checks
+ self.validate_cpu_offload()
+
+ if self.backward_prefetch is None:
+ self.backward_prefetch = os.environ.get(env_prefix + "BACKWARD_PREFETCH", None)
+ if isinstance(self.backward_prefetch, str) and self.backward_prefetch.upper() == "NO_PREFETCH":
+ self.backward_prefetch = None
+ if self.backward_prefetch is not None and not isinstance(self.backward_prefetch, BackwardPrefetch):
+ if isinstance(self.backward_prefetch, str) and self.backward_prefetch.upper() in FSDP_BACKWARD_PREFETCH:
+ self.backward_prefetch = FSDP_BACKWARD_PREFETCH.index(self.backward_prefetch.upper()) + 1
+ if isinstance(self.backward_prefetch, int) or self.backward_prefetch.isdigit():
+ self.backward_prefetch = BackwardPrefetch(int(self.backward_prefetch))
+ else:
+ self.backward_prefetch = BackwardPrefetch[self.backward_prefetch.upper()]
+ if self.fsdp_version == 2 and self.backward_prefetch is not None:
+ _fsdp2_warnings.add("backward_prefetch is not supported in FSDP2. Setting backward prefetch to None.")
+ self.backward_prefetch = None
+
+ self.set_state_dict_type()
+
+ if self.auto_wrap_policy is None:
+ self.auto_wrap_policy = os.environ.get(env_prefix + "AUTO_WRAP_POLICY", "NO_WRAP")
+ if isinstance(self.auto_wrap_policy, str):
+ if self.auto_wrap_policy.upper() not in FSDP_AUTO_WRAP_POLICY:
+ raise ValueError(
+ f"Invalid auto wrap policy: {self.auto_wrap_policy}. Must be one of {FSDP_AUTO_WRAP_POLICY}"
+ )
+ from torch.distributed.fsdp.wrap import (
+ size_based_auto_wrap_policy,
+ transformer_auto_wrap_policy,
+ )
+
+ if self.auto_wrap_policy.upper() == "TRANSFORMER_BASED_WRAP":
+ self.auto_wrap_policy = transformer_auto_wrap_policy
+ if self.transformer_cls_names_to_wrap is None:
+ self.transformer_cls_names_to_wrap = os.environ.get(env_prefix + "TRANSFORMER_CLS_TO_WRAP", None)
+ if isinstance(self.transformer_cls_names_to_wrap, str):
+ self.transformer_cls_names_to_wrap = self.transformer_cls_names_to_wrap.split(",")
+ elif self.auto_wrap_policy.upper() == "SIZE_BASED_WRAP":
+ self.auto_wrap_policy = size_based_auto_wrap_policy
+ if self.min_num_params is None:
+ self.min_num_params = int(os.environ.get(env_prefix + "MIN_NUM_PARAMS", 0))
+ elif not isinstance(self.min_num_params, int):
+ raise ValueError(
+ f"`min_num_params` must be an integer. Got {self.min_num_params} of type {type(self.min_num_params)}"
+ )
+ elif self.auto_wrap_policy.upper() == "NO_WRAP":
+ self.auto_wrap_policy = None
+
+ if self.use_orig_params is None and self.fsdp_version == 1:
+ self.use_orig_params = str_to_bool(os.environ.get(env_prefix + "USE_ORIG_PARAMS", "False")) == 1
+ if self.fsdp_version == 2 and self.use_orig_params is not None:
+ _fsdp2_warnings.add("use_orig_params is obsolete in FSDP2, as FSDP2 always uses the original parameters.")
+ self.use_orig_params = None
+
+ if self.sync_module_states is None and self.fsdp_version == 1:
+ self.sync_module_states = str_to_bool(os.environ.get(env_prefix + "SYNC_MODULE_STATES", "False")) == 1
+ if self.fsdp_version == 2 and self.sync_module_states is not None:
+ _fsdp2_warnings.add(
+ "sync_module_states is obsolete in FSDP2, as it is not needed anymore."
+ "Setting sync_module_states to None."
+ )
+ self.sync_module_states = None
+
+ if self.forward_prefetch is None and self.fsdp_version == 1:
+ self.forward_prefetch = str_to_bool(os.environ.get(env_prefix + "FORWARD_PREFETCH", "False")) == 1
+ if self.fsdp_version == 2 and self.forward_prefetch is not None:
+ raise ValueError("forward_prefetch is not yet implemented in FSDP2, set to None or use `fsdp_version=1`")
+
+ if self.activation_checkpointing is None:
+ self.activation_checkpointing = (
+ str_to_bool(os.environ.get(env_prefix + "ACTIVATION_CHECKPOINTING", "False")) == 1
+ )
+
+ if self.ignored_modules is None:
+ self.ignored_modules = os.environ.get(env_prefix + "IGNORED_MODULES", None)
+
+ if self.cpu_ram_efficient_loading is None:
+ self.cpu_ram_efficient_loading = (
+ str_to_bool(os.environ.get(env_prefix + "CPU_RAM_EFFICIENT_LOADING", "False")) == 1
+ )
+ else:
+ # We still need to set it for transformers
+ os.environ[env_prefix + "CPU_RAM_EFFICIENT_LOADING"] = str(self.cpu_ram_efficient_loading)
+ # There's no need to specify sync_module_states in FSDP2
+ if self.fsdp_version == 1 and self.cpu_ram_efficient_loading and not self.sync_module_states:
+ warnings.warn(
+ "sync_module_states cannot be False since efficient cpu ram loading enabled. "
+ "Setting sync_module_states to True."
+ )
+ self.sync_module_states = True
+ if isinstance(self.mixed_precision_policy, str):
+ # override is True since self.mixed_precision_policy is not None
+ # has to be overwritten with the correct mixed precision object
+ self.set_mixed_precision(self.mixed_precision_policy, override=True)
+ elif isinstance(self.mixed_precision_policy, dict):
+ self.set_mixed_precision(self.mixed_precision_policy)
+ if self.mixed_precision_policy is not None:
+ self.validate_mixed_precision_policy()
+
+ if self.sync_module_states:
+ if is_npu_available():
+ device = torch.npu.current_device()
+ elif is_mlu_available():
+ device = torch.mlu.current_device()
+ elif is_musa_available():
+ device = torch.musa.current_device()
+ elif is_cuda_available():
+ device = torch.cuda.current_device()
+ elif is_xpu_available():
+ device = torch.xpu.current_device()
+ elif is_hpu_available():
+ device = torch.hpu.current_device()
+ else:
+ raise RuntimeError(
+ "There are currently no available devices found, must be one of 'XPU', 'CUDA', 'MLU', 'NPU', 'MUSA', or 'HPU'."
+ )
+ # Create a function that will be used to initialize the parameters of the model
+ # when using `sync_module_states`
+ self.param_init_fn = lambda x: x.to_empty(device=device, recurse=False)
+ if is_torch_version("<", "2.7.0") and self.fsdp_version == 2 and self.ignored_modules is not None:
+ _fsdp2_warnings.add(
+ "FSDP2 ignored_params/ignored_modules is not available for torch version < 2.7.0"
+ "Setting ignored_modules to None."
+ )
+ self.ignored_modules = None
+ # Single warning for all deprecation warnings due to FSDP2 conversion
+ if _fsdp2_warnings:
+ logger.warning("Multiple deprecation warnings due to FSDP2 conversion:\n".join(_fsdp2_warnings))
+
+ def set_state_dict_type(self, state_dict_type=None):
+ """
+ Set the state dict config based on the `StateDictType`.
+ """
+ from torch.distributed.fsdp.fully_sharded_data_parallel import (
+ FullOptimStateDictConfig,
+ FullStateDictConfig,
+ ShardedOptimStateDictConfig,
+ ShardedStateDictConfig,
+ StateDictType,
+ )
+
+ # Override the state_dict_type if provided, typical use case:
+ # user trains with sharded, but final save is with full
+ if state_dict_type is not None:
+ self.state_dict_type = state_dict_type
+
+ if self.state_dict_type is None:
+ self.state_dict_type = os.environ.get(
+ "FSDP_STATE_DICT_TYPE",
+ "FULL_STATE_DICT" if self.fsdp_version == 1 else "SHARDED_STATE_DICT",
+ )
+ if isinstance(self.state_dict_type, str):
+ if self.state_dict_type.isdigit():
+ self.state_dict_type = StateDictType(int(self.state_dict_type))
+ else:
+ self.state_dict_type = StateDictType[self.state_dict_type.upper()]
+
+ if self.state_dict_type == StateDictType.FULL_STATE_DICT:
+ if self.state_dict_config is None:
+ self.state_dict_config = FullStateDictConfig(offload_to_cpu=True, rank0_only=True)
+ if self.optim_state_dict_config is None:
+ self.optim_state_dict_config = FullOptimStateDictConfig(offload_to_cpu=True, rank0_only=True)
+ elif self.state_dict_type == StateDictType.SHARDED_STATE_DICT:
+ if self.state_dict_config is None:
+ self.state_dict_config = ShardedStateDictConfig(offload_to_cpu=True)
+ if self.optim_state_dict_config is None:
+ self.optim_state_dict_config = ShardedOptimStateDictConfig(offload_to_cpu=True)
+
+ if self.fsdp_version == 2 and self.state_dict_type == StateDictType.LOCAL_STATE_DICT:
+ raise ValueError(
+ "FSDP2 does not support LOCAL_STATE_DICT. "
+ "Please set `fsdp_state_dict_type` to `SHARDED_STATE_DICT` or `FULL_STATE_DICT`."
+ )
+
+ def set_auto_wrap_policy(self, model):
+ """
+ Given `model`, creates an `auto_wrap_policy` based on the passed in policy and if we can use the
+ `transformer_cls_to_wrap`
+ """
+ from torch.distributed.fsdp.wrap import (
+ size_based_auto_wrap_policy,
+ transformer_auto_wrap_policy,
+ )
+
+ # First base off of `_no_split_modules`
+ no_split_modules = getattr(model, "_no_split_modules", None)
+ default_transformer_cls_names_to_wrap = list(no_split_modules) if no_split_modules is not None else []
+ if self.auto_wrap_policy == transformer_auto_wrap_policy:
+ if self.transformer_cls_names_to_wrap is None:
+ self.transformer_cls_names_to_wrap = default_transformer_cls_names_to_wrap
+ transformer_cls_to_wrap = set()
+ for layer_class in self.transformer_cls_names_to_wrap:
+ transformer_cls = get_module_class_from_name(model, layer_class)
+ if transformer_cls is None:
+ raise ValueError(f"Could not find the transformer layer class {layer_class} in the model.")
+ transformer_cls_to_wrap.add(transformer_cls)
+ # Finally we set the auto_wrap_policy to a callable
+ self.auto_wrap_policy = functools.partial(
+ self.auto_wrap_policy, transformer_layer_cls=transformer_cls_to_wrap
+ )
+
+ elif self.auto_wrap_policy == size_based_auto_wrap_policy:
+ # If zero, we silently ignore it.
+ if self.min_num_params > 0:
+ self.auto_wrap_policy = functools.partial(self.auto_wrap_policy, min_num_params=self.min_num_params)
+ else:
+ self.auto_wrap_policy = None
+
+ def set_mixed_precision(self, mixed_precision, buffer_autocast=False, override=False):
+ "Sets the mixed precision policy for FSDP"
+ mixed_precision_mapping = {
+ "fp8": torch.bfloat16,
+ "fp16": torch.float16,
+ "bf16": torch.bfloat16,
+ "fp32": torch.float32,
+ }
+ dtype = mixed_precision
+ if isinstance(mixed_precision, str):
+ dtype = mixed_precision_mapping.get(mixed_precision, None)
+ if dtype is None:
+ raise ValueError(
+ f"Invalid mixed precision: {mixed_precision}. Must be one of {list(mixed_precision_mapping.keys())}"
+ )
+ elif isinstance(mixed_precision, torch.dtype) and mixed_precision not in mixed_precision_mapping.values():
+ raise ValueError(
+ f"Invalid mixed precision: {mixed_precision}. Must be one of {list(mixed_precision_mapping.values())}"
+ )
+
+ buffer_type = torch.float32 if buffer_autocast else dtype
+
+ if self.fsdp_version == 1:
+ from torch.distributed.fsdp import MixedPrecision
+ elif self.fsdp_version == 2:
+ from torch.distributed.fsdp import MixedPrecisionPolicy as MixedPrecision
+
+ if override or self.mixed_precision_policy is None:
+ dtype_args = {"param_dtype": dtype, "reduce_dtype": dtype}
+ if self.fsdp_version == 1:
+ dtype_args["buffer_dtype"] = buffer_type
+ else:
+ dtype_args["output_dtype"] = dtype
+ # TODO(s1ro1): `cast_forward_inputs` for FSDP2?
+ self.mixed_precision_policy = MixedPrecision(**dtype_args)
+ elif isinstance(self.mixed_precision_policy, dict):
+ # Check for incompatible types
+ valid_keys = ["param_dtype", "reduce_dtype"] + (
+ ["buffer_dtype"] if self.fsdp_version == 1 else ["output_dtype"]
+ )
+ missing_keys = [k for k in valid_keys if k not in self.mixed_precision_policy]
+ invalid_values = [
+ k for k, v in self.mixed_precision_policy.items() if v not in mixed_precision_mapping.values()
+ ]
+ if missing_keys or invalid_values:
+ raise ValueError(
+ f"Invalid mixed precision policy: {self.mixed_precision_policy}. "
+ f"Must be a `dict` with keys {valid_keys}."
+ f"Values must be one of {list(mixed_precision_mapping.values())}"
+ )
+ self.mixed_precision_policy = MixedPrecision(**self.mixed_precision_policy)
+
+ def validate_mixed_precision_policy(self):
+ """
+ Validates the mixed precision policy, abstracted away to not bring in the imports if not needed.
+ """
+ if self.fsdp_version == 2:
+ from torch.distributed.fsdp import MixedPrecisionPolicy as MixedPrecision
+ else:
+ from torch.distributed.fsdp import MixedPrecision
+
+ if not isinstance(self.mixed_precision_policy, MixedPrecision):
+ required_type = (
+ "`torch.distributed.fsdp.MixedPrecisionPolicy`"
+ if self.fsdp_version == 2
+ else "`torch.distributed.fsdp.MixedPrecision`"
+ )
+ raise ValueError(f"mixed_precision_policy must be an instance of {required_type}.")
+
+ def set_cpu_offload(self):
+ if self.fsdp_version == 2:
+ from torch.distributed.fsdp import CPUOffloadPolicy, OffloadPolicy
+ else:
+ from torch.distributed.fsdp import CPUOffload
+
+ if isinstance(self.cpu_offload, bool):
+ if self.fsdp_version == 2:
+ if not self.cpu_offload:
+ self.cpu_offload = OffloadPolicy()
+ else:
+ self.cpu_offload = CPUOffloadPolicy()
+ else:
+ self.cpu_offload = CPUOffload(offload_params=self.cpu_offload)
+
+ def validate_cpu_offload(self):
+ if self.fsdp_version == 2:
+ from torch.distributed.fsdp import OffloadPolicy
+ else:
+ from torch.distributed.fsdp import CPUOffload
+
+ if self.fsdp_version == 2 and not isinstance(self.cpu_offload, OffloadPolicy):
+ raise ValueError(
+ f"`cpu_offload` must be an instance of `torch.distributed.fsdp.OffloadPolicy` in FSDP2, got {self.cpu_offload}"
+ )
+ if self.fsdp_version == 1 and not isinstance(self.cpu_offload, CPUOffload):
+ raise ValueError(
+ f"`cpu_offload` must be an instance of `torch.distributed.fsdp.CPUOffload` in FSDP1, got {self.cpu_offload}"
+ )
+
+
+@dataclass
+class TorchTensorParallelPlugin:
+ """
+ This plugin is used to enable tensor parallelism using PyTorch >= 2.0.
+ """
+
+ tp_size: int = field(
+ default=1,
+ metadata={"help": "tensor parallel size will be used in the device mesh preparation"},
+ )
+
+ # torch_device_mesh is of type "torch.distributed.DeviceMesh"
+ torch_device_mesh: Optional["torch.distributed.DeviceMesh"] = field(default=None)
+
+
+@dataclass
+class TorchContextParallelConfig:
+ """
+ This class holds the configuration for context parallelism in PyTorch.
+ """
+
+ cp_comm_strategy: Optional[str] = field(
+ default=None,
+ metadata={
+ "help": "Communication strategy for context parallelism. Can be one of 'allgather' or 'alltoall'. Defaults to 'allgather'."
+ },
+ )
+
+ def __post_init__(self):
+ if not is_torch_version(">=", BETA_CP_AVAILABLE_PYTORCH_VERSION):
+ raise ValueError(
+ f"FSDP2-based Context parallelism is only available in PyTorch {BETA_CP_AVAILABLE_PYTORCH_VERSION} and later versions. "
+ "Please upgrade your PyTorch version."
+ )
+
+ if self.cp_comm_strategy is None:
+ self.cp_comm_strategy = os.environ.get("PARALLELISM_CONFIG_CP_COMM_STRATEGY", "allgather")
+ if self.cp_comm_strategy not in ["allgather", "alltoall"]:
+ raise ValueError(
+ f"Invalid cp_comm_strategy: {self.cp_comm_strategy}. Must be one of 'allgather' or 'alltoall'."
+ )
+
+
+@dataclass
+class DeepSpeedSequenceParallelConfig:
+ sp_seq_length: Optional[int] = field(
+ default=None,
+ metadata={
+ "help": "Sequence length for when batches are all of the same length. For variable sequence lengths across batches set `sp_seq_length_is_variable=True` and leave this field unset"
+ },
+ )
+ sp_seq_length_is_variable: Optional[bool] = field(
+ default=None,
+ metadata={
+ "help": "If `True` will work with a sequence length that may change between batches, in which case `sp_seq_length` value can be set to anything divisible by cp size or remain unset. If `False` then `sp_seq_length` needs to match the batch's sequence length dimension. The default is `True`."
+ },
+ )
+ sp_attn_implementation: Optional[str] = field(
+ default=None,
+ metadata={
+ "help": "Attention implementation to use. Can be one of 'flash_attention_2', 'flash_attention_3' or 'sdpa'. Defaults to `sdpa`."
+ },
+ )
+
+ def __post_init__(self):
+ # sp_seq_length_is_variable and sp_seq_length are interconnected
+ if self.sp_seq_length_is_variable is None:
+ self.sp_seq_length_is_variable = (
+ os.environ.get("PARALLELISM_CONFIG_SP_SEQ_LENGTH_IS_VARIABLE", "true").lower() == "true"
+ )
+
+ if not self.sp_seq_length_is_variable and self.sp_seq_length is None:
+ if "PARALLELISM_CONFIG_SP_SEQ_LENGTH" not in os.environ:
+ raise ValueError(
+ "when `sp_seq_length_is_variable` is `False` `sp_seq_length` must be provided either through the constructor or the environment variable PARALLELISM_CONFIG_SP_SEQ_LENGTH"
+ )
+ else:
+ self.sp_seq_length = os.environ.get("PARALLELISM_CONFIG_SP_SEQ_LENGTH")
+ self.sp_seq_length = None if self.sp_seq_length == "None" else int(self.sp_seq_length)
+
+ if self.sp_attn_implementation is None:
+ self.sp_attn_implementation = os.environ.get("PARALLELISM_CONFIG_SP_ATTN_IMPLEMENTATION", None)
+
+ if self.sp_attn_implementation is not None and self.sp_attn_implementation not in [
+ "flash_attention_2",
+ "flash_attention_3",
+ "sdpa",
+ ]:
+ raise ValueError(
+ f"Invalid sp_attn_implementation: {self.sp_attn_implementation}. Must be one of 'flash_attention_2', 'flash_attention_3' or 'sdpa'."
+ )
+
+
+@dataclass
+class TorchTensorParallelConfig:
+ """
+ Use this object in your [`Accelerator`] to customize your torch tensor parallelism.
+ """
+
+ enable_async_tp: bool = False
+
+ def __post_init__(self):
+ if not is_torch_version(">=", BETA_TP_AVAILABLE_PYTORCH_VERSION):
+ raise ValueError(
+ f"Torch tensor parallelism is only available in PyTorch {BETA_TP_AVAILABLE_PYTORCH_VERSION} and later versions. "
+ "Please upgrade your PyTorch version."
+ )
+
+ if not compare_versions("transformers", ">=", BETA_TP_AVAILABLE_TRANSFORMERS_VERSION):
+ raise ValueError(f"TP requires transformers >= {BETA_TP_AVAILABLE_TRANSFORMERS_VERSION}")
+
+ if self.enable_async_tp:
+ warnings.warn("Async tensor parallelism is currently not supported, ignoring this option.")
+
+
+@dataclass
+class MegatronLMPlugin:
+ """
+ Plugin for Megatron-LM to enable tensor, pipeline, sequence and data parallelism. Also to enable selective
+ activation recomputation and optimized fused kernels.
+
+ Args:
+ tp_degree (`int`, defaults to `None`):
+ Tensor parallelism degree.
+ pp_degree (`int`, defaults to `None`):
+ Pipeline parallelism degree.
+ num_micro_batches (`int`, defaults to `None`):
+ Number of micro-batches.
+ gradient_clipping (`float`, defaults to `None`):
+ Gradient clipping value based on global L2 Norm (0 to disable).
+ sequence_parallelism (`bool`, defaults to `None`):
+ Enable sequence parallelism.
+ recompute_activations (`bool`, defaults to `None`):
+ Enable selective activation recomputation.
+ use_distributed_optimizr (`bool`, defaults to `None`):
+ Enable distributed optimizer.
+ pipeline_model_parallel_split_rank (`int`, defaults to `None`):
+ Rank where encoder and decoder should be split.
+ num_layers_per_virtual_pipeline_stage (`int`, defaults to `None`):
+ Number of layers per virtual pipeline stage.
+ is_train_batch_min (`str`, defaults to `True`):
+ If both tran & eval dataloaders are specified, this will decide the `micro_batch_size`.
+ train_iters (`int`, defaults to `None`):
+ Total number of samples to train over all training runs. Note that either train-iters or train-samples
+ should be provided when using `MegatronLMDummyScheduler`.
+ train_samples (`int`, defaults to `None`):
+ Total number of samples to train over all training runs. Note that either train-iters or train-samples
+ should be provided when using `MegatronLMDummyScheduler`.
+ weight_decay_incr_style (`str`, defaults to `'constant'`):
+ Weight decay increment function. choices=["constant", "linear", "cosine"].
+ start_weight_decay (`float`, defaults to `None`):
+ Initial weight decay coefficient for L2 regularization.
+ end_weight_decay (`float`, defaults to `None`):
+ End of run weight decay coefficient for L2 regularization.
+ lr_decay_style (`str`, defaults to `'linear'`):
+ Learning rate decay function. choices=['constant', 'linear', 'cosine'].
+ lr_decay_iters (`int`, defaults to `None`):
+ Number of iterations for learning rate decay. If None defaults to `train_iters`.
+ lr_decay_samples (`int`, defaults to `None`):
+ Number of samples for learning rate decay. If None defaults to `train_samples`.
+ lr_warmup_iters (`int`, defaults to `None`):
+ Number of iterations to linearly warmup learning rate over.
+ lr_warmup_samples (`int`, defaults to `None`):
+ Number of samples to linearly warmup learning rate over.
+ lr_warmup_fraction (`float`, defaults to `None`):
+ Fraction of lr-warmup-(iters/samples) to linearly warmup learning rate over.
+ min_lr (`float`, defaults to `0`):
+ Minimum value for learning rate. The scheduler clip values below this threshold.
+ consumed_samples (`List`, defaults to `None`):
+ Number of samples consumed in the same order as the dataloaders to `accelerator.prepare` call.
+ no_wd_decay_cond (`Optional`, defaults to `None`):
+ Condition to disable weight decay.
+ scale_lr_cond (`Optional`, defaults to `None`):
+ Condition to scale learning rate.
+ lr_mult (`float`, defaults to `1.0`):
+ Learning rate multiplier.
+ megatron_dataset_flag (`bool`, defaults to `False`):
+ Whether the format of dataset follows Megatron-LM Indexed/Cached/MemoryMapped format.
+ seq_length (`int`, defaults to `None`):
+ Maximum sequence length to process.
+ encoder_seq_length (`int`, defaults to `None`):
+ Maximum sequence length to process for the encoder.
+ decoder_seq_length (`int`, defaults to `None`):
+ Maximum sequence length to process for the decoder.
+ tensorboard_dir (`str`, defaults to `None`):
+ Path to save tensorboard logs.
+ set_all_logging_options (`bool`, defaults to `False`):
+ Whether to set all logging options.
+ eval_iters (`int`, defaults to `100`):
+ Number of iterations to run for evaluation validation/test for.
+ eval_interval (`int`, defaults to `1000`):
+ Interval between running evaluation on validation set.
+ return_logits (`bool`, defaults to `False`):
+ Whether to return logits from the model.
+ custom_train_step_class (`Optional`, defaults to `None`):
+ Custom train step class.
+ custom_train_step_kwargs (`Optional`, defaults to `None`):
+ Custom train step kwargs.
+ custom_model_provider_function (`Optional`, defaults to `None`):
+ Custom model provider function.
+ custom_prepare_model_function (`Optional`, defaults to `None`):
+ Custom prepare model function.
+ custom_megatron_datasets_provider_function (`Optional`, defaults to `None`):
+ Custom megatron train_valid_test datasets provider function.
+ custom_get_batch_function (`Optional`, defaults to `None`):
+ Custom get batch function.
+ custom_loss_function (`Optional`, defaults to `None`):
+ Custom loss function.
+ other_megatron_args (`Optional`, defaults to `None`):
+ Other Megatron-LM arguments. Please refer Megatron-LM.
+ """
+
+ tp_degree: int = field(default=None, metadata={"help": "tensor parallelism degree."})
+ pp_degree: int = field(default=None, metadata={"help": "pipeline parallelism degree."})
+ num_micro_batches: int = field(default=None, metadata={"help": "number of micro-batches."})
+ gradient_clipping: float = field(
+ default=None,
+ metadata={"help": "gradient clipping value based on global L2 Norm (0 to disable)"},
+ )
+ sequence_parallelism: bool = field(
+ default=None,
+ metadata={"help": "enable sequence parallelism"},
+ )
+ recompute_activations: bool = field(
+ default=None,
+ metadata={"help": "enable selective activation recomputation"},
+ )
+ use_distributed_optimizer: bool = field(
+ default=None,
+ metadata={"help": "enable distributed optimizer"},
+ )
+ pipeline_model_parallel_split_rank: int = field(
+ default=None,
+ metadata={"help": "Rank where encoder and decoder should be split."},
+ )
+ num_layers_per_virtual_pipeline_stage: int = field(
+ default=None, metadata={"help": "Number of layers per virtual pipeline stage."}
+ )
+ is_train_batch_min: str = field(
+ default=True,
+ metadata={"help": "If both train & eval dataloaders are specified, this will decide the micro_batch_size"},
+ )
+ train_iters: int = field(
+ default=None,
+ metadata={
+ "help": "Total number of iterations to train over all training runs. "
+ "Note that either train-iters or train-samples should be provided when using `MegatronLMDummyScheduler`"
+ },
+ )
+ train_samples: int = field(
+ default=None,
+ metadata={
+ "help": "Total number of samples to train over all training runs. "
+ "Note that either train-iters or train-samples should be provided when using `MegatronLMDummyScheduler`"
+ },
+ )
+ weight_decay_incr_style: str = field(
+ default="constant",
+ metadata={"help": 'Weight decay increment function. choices=["constant", "linear", "cosine"]. '},
+ )
+ start_weight_decay: float = field(
+ default=None,
+ metadata={"help": "Initial weight decay coefficient for L2 regularization."},
+ )
+ end_weight_decay: float = field(
+ default=None,
+ metadata={"help": "End of run weight decay coefficient for L2 regularization."},
+ )
+ lr_decay_style: str = field(
+ default="linear",
+ metadata={"help": "Learning rate decay function. choices=['constant', 'linear', 'cosine']."},
+ )
+ lr_decay_iters: int = field(
+ default=None,
+ metadata={"help": "Number of iterations for learning rate decay. If None defaults to `train_iters`."},
+ )
+ lr_decay_samples: int = field(
+ default=None,
+ metadata={"help": "Number of samples for learning rate decay. If None defaults to `train_samples`."},
+ )
+ lr_warmup_iters: int = field(
+ default=None,
+ metadata={"help": "number of iterations to linearly warmup learning rate over."},
+ )
+ lr_warmup_samples: int = field(
+ default=None,
+ metadata={"help": "number of samples to linearly warmup learning rate over."},
+ )
+ lr_warmup_fraction: float = field(
+ default=None,
+ metadata={"help": "fraction of lr-warmup-(iters/samples) to linearly warmup learning rate over."},
+ )
+ min_lr: float = field(
+ default=0,
+ metadata={"help": "Minimum value for learning rate. The scheduler clip values below this threshold."},
+ )
+ consumed_samples: list[int] = field(
+ default=None,
+ metadata={
+ "help": "Number of samples consumed in the same order as the dataloaders to `accelerator.prepare` call."
+ },
+ )
+ no_wd_decay_cond: Optional[Callable] = field(default=None, metadata={"help": "Condition to disable weight decay."})
+ scale_lr_cond: Optional[Callable] = field(default=None, metadata={"help": "Condition to scale learning rate."})
+ lr_mult: float = field(default=1.0, metadata={"help": "Learning rate multiplier."})
+ megatron_dataset_flag: bool = field(
+ default=False,
+ metadata={"help": "Whether the format of dataset follows Megatron-LM Indexed/Cached/MemoryMapped format."},
+ )
+ seq_length: int = field(
+ default=None,
+ metadata={"help": "Maximum sequence length to process."},
+ )
+ encoder_seq_length: int = field(
+ default=None,
+ metadata={"help": "Maximum sequence length to process for the encoder."},
+ )
+ decoder_seq_length: int = field(
+ default=None,
+ metadata={"help": "Maximum sequence length to process for the decoder."},
+ )
+ tensorboard_dir: str = field(
+ default=None,
+ metadata={"help": "Path to save tensorboard logs."},
+ )
+ set_all_logging_options: bool = field(
+ default=False,
+ metadata={"help": "Whether to set all logging options."},
+ )
+ eval_iters: int = field(
+ default=100,
+ metadata={"help": "Number of iterations to run for evaluation validation/test for."},
+ )
+ eval_interval: int = field(
+ default=1000,
+ metadata={"help": "Interval between running evaluation on validation set."},
+ )
+ return_logits: bool = field(
+ default=False,
+ metadata={"help": "Whether to return logits from the model."},
+ )
+
+ # custom train step args
+ custom_train_step_class: Optional[Any] = field(
+ default=None,
+ metadata={"help": "Custom train step class."},
+ )
+ custom_train_step_kwargs: Optional[dict[str, Any]] = field(
+ default=None,
+ metadata={"help": "Custom train step kwargs."},
+ )
+
+ # custom model args
+ custom_model_provider_function: Optional[Callable] = field(
+ default=None,
+ metadata={"help": "Custom model provider function."},
+ )
+ custom_prepare_model_function: Optional[Callable] = field(
+ default=None,
+ metadata={"help": "Custom prepare model function."},
+ )
+ custom_megatron_datasets_provider_function: Optional[Callable] = field(
+ default=None,
+ metadata={"help": "Custom megatron train_valid_test datasets provider function."},
+ )
+ custom_get_batch_function: Optional[Callable] = field(
+ default=None,
+ metadata={"help": "Custom get batch function."},
+ )
+ custom_loss_function: Optional[Callable] = field(
+ default=None,
+ metadata={"help": "Custom loss function."},
+ )
+
+ # remaining args such as enabling Alibi/ROPE positional embeddings,
+ # wandb logging, Multi-Query Attention, etc.
+ other_megatron_args: Optional[dict[str, Any]] = field(
+ default=None,
+ metadata={"help": "Other Megatron-LM arguments. Please refer Megatron-LM"},
+ )
+
+ def __post_init__(self):
+ prefix = "MEGATRON_LM_"
+ if self.tp_degree is None:
+ self.tp_degree = int(os.environ.get(prefix + "TP_DEGREE", 1))
+ if self.pp_degree is None:
+ self.pp_degree = int(os.environ.get(prefix + "PP_DEGREE", 1))
+ if self.num_micro_batches is None:
+ self.num_micro_batches = int(os.environ.get(prefix + "NUM_MICRO_BATCHES", 1))
+ if self.gradient_clipping is None:
+ self.gradient_clipping = float(os.environ.get(prefix + "GRADIENT_CLIPPING", 1.0))
+ if self.recompute_activations is None:
+ self.recompute_activations = str_to_bool(os.environ.get(prefix + "RECOMPUTE_ACTIVATIONS", "False")) == 1
+ if self.use_distributed_optimizer is None:
+ self.use_distributed_optimizer = (
+ str_to_bool(os.environ.get(prefix + "USE_DISTRIBUTED_OPTIMIZER", "False")) == 1
+ )
+ if self.sequence_parallelism is None:
+ self.sequence_parallelism = str_to_bool(os.environ.get(prefix + "SEQUENCE_PARALLELISM", "False")) == 1
+
+ if self.pp_degree > 1 or self.use_distributed_optimizer:
+ self.DDP_impl = "local"
+ else:
+ self.DDP_impl = "torch"
+
+ if self.consumed_samples is not None:
+ if len(self.consumed_samples) == 1:
+ self.consumed_samples.extend([0, 0])
+ elif len(self.consumed_samples) == 2:
+ self.consumed_samples.append(0)
+
+ self.megatron_lm_default_args = {
+ "tensor_model_parallel_size": self.tp_degree,
+ "pipeline_model_parallel_size": self.pp_degree,
+ "pipeline_model_parallel_split_rank": self.pipeline_model_parallel_split_rank,
+ "num_layers_per_virtual_pipeline_stage": self.num_layers_per_virtual_pipeline_stage,
+ "DDP_impl": self.DDP_impl,
+ "use_distributed_optimizer": self.use_distributed_optimizer,
+ "sequence_parallel": self.sequence_parallelism,
+ "clip_grad": self.gradient_clipping,
+ "num_micro_batches": self.num_micro_batches,
+ "consumed_samples": self.consumed_samples,
+ "no_wd_decay_cond": self.no_wd_decay_cond,
+ "scale_lr_cond": self.scale_lr_cond,
+ "lr_mult": self.lr_mult,
+ "megatron_dataset_flag": self.megatron_dataset_flag,
+ "eval_iters": self.eval_iters,
+ "eval_interval": self.eval_interval,
+ }
+ if self.recompute_activations:
+ self.megatron_lm_default_args["recompute_granularity"] = "selective"
+ if self.tensorboard_dir is not None:
+ self.megatron_lm_default_args["tensorboard_dir"] = self.tensorboard_dir
+ if self.set_all_logging_options:
+ self.set_tensorboard_logging_options()
+ if self.other_megatron_args is not None:
+ self.megatron_lm_default_args.update(self.other_megatron_args)
+
+ def set_network_size_args(self, model, batch_data=None):
+ model_config_type = model.config.model_type.lower()
+ for model_type in MODEL_CONFIGS_TO_MEGATRON_PARSERS.keys():
+ if model_type in model_config_type:
+ MODEL_CONFIGS_TO_MEGATRON_PARSERS[model_type](self, model, batch_data)
+ return
+ raise ValueError(
+ f"Accelerate Megatron-LM integration not supports {model_config_type} model. "
+ "You can add your own model config parser."
+ )
+
+ def set_mixed_precision(self, mixed_precision):
+ if mixed_precision == "fp16":
+ self.megatron_lm_default_args["fp16"] = True
+ elif mixed_precision == "bf16":
+ self.megatron_lm_default_args["bf16"] = True
+ self.DDP_impl = "local"
+ self.megatron_lm_default_args["DDP_impl"] = self.DDP_impl
+
+ def set_training_args(self, micro_batch_size, dp_degree):
+ self.data_parallel_size = dp_degree
+ self.micro_batch_size = micro_batch_size
+ self.global_batch_size = dp_degree * micro_batch_size * self.num_micro_batches
+ self.megatron_lm_default_args["data_parallel_size"] = self.data_parallel_size
+ self.megatron_lm_default_args["micro_batch_size"] = self.micro_batch_size
+ self.megatron_lm_default_args["global_batch_size"] = self.global_batch_size
+
+ def set_optimizer_type(self, optimizer):
+ optimizer_name = optimizer.__class__.__name__.lower()
+ if "adam" in optimizer_name:
+ self.megatron_lm_default_args["optimizer"] = "adam"
+ self.megatron_lm_default_args["adam_beta1"] = optimizer.defaults["betas"][0]
+ self.megatron_lm_default_args["adam_beta2"] = optimizer.defaults["betas"][1]
+ self.megatron_lm_default_args["adam_eps"] = optimizer.defaults["eps"]
+ elif "sgd" in optimizer_name:
+ self.megatron_lm_default_args["optimizer"] = "sgd"
+ self.megatron_lm_default_args["sgd_momentum"] = optimizer.defaults["momentum"]
+ else:
+ raise ValueError(f"Optimizer {optimizer_name} is not supported by Megatron-LM")
+
+ self.megatron_lm_default_args["lr"] = optimizer.defaults["lr"]
+ self.megatron_lm_default_args["weight_decay"] = optimizer.defaults["weight_decay"]
+
+ def set_scheduler_args(self, scheduler):
+ if self.train_iters is None:
+ self.train_iters = scheduler.total_num_steps // self.megatron_lm_default_args["data_parallel_size"]
+ if self.train_samples is not None:
+ self.train_samples = None
+ warnings.warn(
+ "Ignoring `train_samples` as `train_iters` based on scheduler is being used for training."
+ )
+ if self.lr_warmup_iters is None:
+ self.lr_warmup_iters = scheduler.warmup_num_steps // self.megatron_lm_default_args["data_parallel_size"]
+ if self.lr_warmup_samples is not None:
+ warnings.warn(
+ "Ignoring `lr_warmup_samples` as `lr_warmup_iters` based on scheduler is being used for training."
+ )
+ self.lr_warmup_samples = 0
+
+ self.megatron_lm_default_args["train_iters"] = self.train_iters
+ self.megatron_lm_default_args["lr_warmup_iters"] = self.lr_warmup_iters
+ self.megatron_lm_default_args["train_samples"] = self.train_samples
+ self.megatron_lm_default_args["lr_warmup_samples"] = self.lr_warmup_samples
+ self.megatron_lm_default_args["lr_decay_iters"] = self.lr_decay_iters
+ self.megatron_lm_default_args["lr_decay_samples"] = self.lr_decay_samples
+ self.megatron_lm_default_args["lr_warmup_fraction"] = self.lr_warmup_fraction
+ self.megatron_lm_default_args["lr_decay_style"] = self.lr_decay_style
+ self.megatron_lm_default_args["weight_decay_incr_style"] = self.weight_decay_incr_style
+ self.megatron_lm_default_args["start_weight_decay"] = self.start_weight_decay
+ self.megatron_lm_default_args["end_weight_decay"] = self.end_weight_decay
+ self.megatron_lm_default_args["min_lr"] = self.min_lr
+
+ def set_tensorboard_logging_options(self):
+ from megatron.training.arguments import _add_logging_args
+
+ parser = argparse.ArgumentParser()
+ parser = _add_logging_args(parser)
+ logging_args = parser.parse_known_args()
+ self.dataset_args = vars(logging_args[0])
+ for key, value in self.dataset_args.items():
+ if key.startswith("log_"):
+ self.megatron_lm_default_args[key] = True
+ elif key.startswith("no_log_"):
+ self.megatron_lm_default_args[key.replace("no_", "")] = True
+
+
+MODEL_CONFIGS_TO_MEGATRON_PARSERS = {}
+
+
+def add_model_config_to_megatron_parser(model_type: str):
+ def add_model_config_parser_helper(func):
+ @functools.wraps(func)
+ def wrapper(*args, **kwargs):
+ return func(*args, **kwargs)
+
+ MODEL_CONFIGS_TO_MEGATRON_PARSERS[model_type] = func
+ return wrapper
+
+ return add_model_config_parser_helper
+
+
+@add_model_config_to_megatron_parser("megatron-bert")
+def parse_bert_config(megatron_lm_plugin, model, batch_data):
+ model_type_name = "bert"
+ num_layers = model.config.num_hidden_layers
+ hidden_size = model.config.hidden_size
+ num_attention_heads = model.config.num_attention_heads
+ max_position_embeddings = model.config.max_position_embeddings
+ num_labels = model.config.num_labels
+ orig_vocab_size = model.config.vocab_size
+ pretraining_flag = False
+ if "maskedlm" in model.__class__.__name__.lower():
+ pretraining_flag = True
+ if megatron_lm_plugin.seq_length is not None:
+ if megatron_lm_plugin.encoder_seq_length is not None:
+ warnings.warn("Both `seq_length` and `encoder_seq_length` are set. Using `encoder_seq_length`.")
+ megatron_lm_plugin.seq_length = megatron_lm_plugin.encoder_seq_length
+ elif megatron_lm_plugin.encoder_seq_length is not None:
+ megatron_lm_plugin.seq_length = megatron_lm_plugin.encoder_seq_length
+ elif batch_data is not None:
+ megatron_lm_plugin.seq_length = batch_data["input_ids"].shape[1]
+ else:
+ megatron_lm_plugin.seq_length = max_position_embeddings
+ megatron_lm_plugin.megatron_lm_default_args["seq_length"] = megatron_lm_plugin.seq_length
+ megatron_lm_plugin.megatron_lm_default_args["model_type_name"] = model_type_name
+ megatron_lm_plugin.megatron_lm_default_args["num_layers"] = num_layers
+ megatron_lm_plugin.megatron_lm_default_args["hidden_size"] = hidden_size
+ megatron_lm_plugin.megatron_lm_default_args["num_attention_heads"] = num_attention_heads
+ megatron_lm_plugin.megatron_lm_default_args["max_position_embeddings"] = max_position_embeddings
+ megatron_lm_plugin.megatron_lm_default_args["pretraining_flag"] = pretraining_flag
+ megatron_lm_plugin.megatron_lm_default_args["orig_vocab_size"] = orig_vocab_size
+ megatron_lm_plugin.megatron_lm_default_args["model_return_dict"] = model.config.return_dict
+ megatron_lm_plugin.megatron_lm_default_args["num_labels"] = num_labels
+
+
+@add_model_config_to_megatron_parser("gpt2")
+def parse_gpt2_config(megatron_lm_plugin, model, batch_data):
+ model_type_name = "gpt"
+ num_layers = model.config.n_layer
+ hidden_size = model.config.n_embd
+ num_attention_heads = model.config.n_head
+ max_position_embeddings = model.config.n_positions
+ orig_vocab_size = model.config.vocab_size
+ pretraining_flag = True
+ if megatron_lm_plugin.seq_length is not None:
+ if megatron_lm_plugin.decoder_seq_length is not None:
+ warnings.warn("Both `seq_length` and `decoder_seq_length` are set. Using `decoder_seq_length`.")
+ megatron_lm_plugin.seq_length = megatron_lm_plugin.decoder_seq_length
+ elif megatron_lm_plugin.decoder_seq_length is not None:
+ megatron_lm_plugin.seq_length = megatron_lm_plugin.decoder_seq_length
+ elif batch_data is not None:
+ megatron_lm_plugin.seq_length = batch_data["input_ids"].shape[1]
+ else:
+ megatron_lm_plugin.seq_length = max_position_embeddings
+ megatron_lm_plugin.megatron_lm_default_args["seq_length"] = megatron_lm_plugin.seq_length
+ megatron_lm_plugin.megatron_lm_default_args["return_logits"] = megatron_lm_plugin.return_logits
+ megatron_lm_plugin.megatron_lm_default_args["tokenizer_type"] = "GPT2BPETokenizer"
+ megatron_lm_plugin.megatron_lm_default_args["model_type_name"] = model_type_name
+ megatron_lm_plugin.megatron_lm_default_args["num_layers"] = num_layers
+ megatron_lm_plugin.megatron_lm_default_args["hidden_size"] = hidden_size
+ megatron_lm_plugin.megatron_lm_default_args["num_attention_heads"] = num_attention_heads
+ megatron_lm_plugin.megatron_lm_default_args["max_position_embeddings"] = max_position_embeddings
+ megatron_lm_plugin.megatron_lm_default_args["pretraining_flag"] = pretraining_flag
+ megatron_lm_plugin.megatron_lm_default_args["orig_vocab_size"] = orig_vocab_size
+ megatron_lm_plugin.megatron_lm_default_args["model_return_dict"] = model.config.return_dict
+
+
+@add_model_config_to_megatron_parser("t5")
+def parse_t5_config(megatron_lm_plugin, model, batch_data):
+ model_type_name = "t5"
+ num_layers = model.config.num_layers
+ hidden_size = model.config.d_model
+ num_attention_heads = model.config.num_heads
+ max_position_embeddings = model.config.n_positions if hasattr(model.config, "n_positions") else 1024
+ orig_vocab_size = model.config.vocab_size
+ pretraining_flag = True
+ if megatron_lm_plugin.encoder_seq_length is None:
+ if batch_data is not None:
+ megatron_lm_plugin.encoder_seq_length = batch_data["input_ids"].shape[1]
+ else:
+ megatron_lm_plugin.encoder_seq_length = max_position_embeddings
+ if megatron_lm_plugin.decoder_seq_length is None:
+ if batch_data is not None:
+ megatron_lm_plugin.decoder_seq_length = batch_data["labels"].shape[1]
+ else:
+ megatron_lm_plugin.decoder_seq_length = max_position_embeddings
+ megatron_lm_plugin.megatron_lm_default_args["encoder_seq_length"] = megatron_lm_plugin.encoder_seq_length
+ megatron_lm_plugin.megatron_lm_default_args["decoder_seq_length"] = megatron_lm_plugin.decoder_seq_length
+ megatron_lm_plugin.megatron_lm_default_args["model_type_name"] = model_type_name
+ megatron_lm_plugin.megatron_lm_default_args["num_layers"] = num_layers
+ megatron_lm_plugin.megatron_lm_default_args["hidden_size"] = hidden_size
+ megatron_lm_plugin.megatron_lm_default_args["num_attention_heads"] = num_attention_heads
+ megatron_lm_plugin.megatron_lm_default_args["max_position_embeddings"] = max_position_embeddings
+ megatron_lm_plugin.megatron_lm_default_args["pretraining_flag"] = pretraining_flag
+ megatron_lm_plugin.megatron_lm_default_args["orig_vocab_size"] = orig_vocab_size
+ megatron_lm_plugin.megatron_lm_default_args["model_return_dict"] = model.config.return_dict
+
+
+@add_model_config_to_megatron_parser("llama")
+def parse_llama_config(megatron_lm_plugin, model, batch_data):
+ model_type_name = "gpt"
+ num_layers = model.config.num_hidden_layers
+ pretraining_flag = True
+ hidden_size = model.config.hidden_size
+ num_attention_heads = model.config.num_attention_heads
+ orig_vocab_size = model.config.vocab_size
+
+ max_position_embeddings = model.config.max_position_embeddings
+ seq_length = getattr(model.config, "max_sequence_length", None)
+ if megatron_lm_plugin.seq_length is None:
+ if seq_length is not None:
+ megatron_lm_plugin.seq_length = seq_length
+ elif megatron_lm_plugin.decoder_seq_length is not None:
+ megatron_lm_plugin.seq_length = megatron_lm_plugin.decoder_seq_length
+ elif batch_data is not None:
+ megatron_lm_plugin.seq_length = batch_data["input_ids"].shape[1]
+ else:
+ megatron_lm_plugin.seq_length = max_position_embeddings
+
+ megatron_lm_plugin.megatron_lm_default_args["return_logits"] = megatron_lm_plugin.return_logits
+ megatron_lm_plugin.megatron_lm_default_args["tokenizer_type"] = "Llama2Tokenizer"
+ megatron_lm_plugin.megatron_lm_default_args["model_type_name"] = model_type_name
+ megatron_lm_plugin.megatron_lm_default_args["num_layers"] = num_layers
+ megatron_lm_plugin.megatron_lm_default_args["pretraining_flag"] = pretraining_flag
+ megatron_lm_plugin.megatron_lm_default_args["hidden_size"] = hidden_size
+ megatron_lm_plugin.megatron_lm_default_args["num_attention_heads"] = num_attention_heads
+ megatron_lm_plugin.megatron_lm_default_args["orig_vocab_size"] = orig_vocab_size
+ megatron_lm_plugin.megatron_lm_default_args["max_position_embeddings"] = max_position_embeddings
+ megatron_lm_plugin.megatron_lm_default_args["seq_length"] = megatron_lm_plugin.seq_length
+ megatron_lm_plugin.megatron_lm_default_args["model_return_dict"] = model.config.return_dict
+
+
+@dataclass
+class BnbQuantizationConfig:
+ """
+ A plugin to enable BitsAndBytes 4bit and 8bit quantization
+
+ Args:
+ load_in_8bit (`bool`, defaults to `False`):
+ Enable 8bit quantization.
+ llm_int8_threshold (`float`, defaults to `6.0`):
+ Value of the outliner threshold. Only relevant when `load_in_8bit=True`.
+ load_in_4bit (`bool`, defaults to `False`):
+ Enable 4bit quantization.
+ bnb_4bit_quant_type (`str`, defaults to `fp4`):
+ Set the quantization data type in the `bnb.nn.Linear4Bit` layers. Options are {'fp4','np4'}.
+ bnb_4bit_use_double_quant (`bool`, defaults to `False`):
+ Enable nested quantization where the quantization constants from the first quantization are quantized
+ again.
+ bnb_4bit_compute_dtype (`bool`, defaults to `fp16`):
+ This sets the computational type which might be different than the input time. For example, inputs might be
+ fp32, but computation can be set to bf16 for speedups. Options are {'fp32','fp16','bf16'}.
+ torch_dtype (`torch.dtype`, defaults to `None`):
+ This sets the dtype of the remaining non quantized layers. `bitsandbytes` library suggests to set the value
+ to `torch.float16` for 8 bit model and use the same dtype as the compute dtype for 4 bit model.
+ skip_modules (`List[str]`, defaults to `None`):
+ An explicit list of the modules that we don't quantize. The dtype of these modules will be `torch_dtype`.
+ keep_in_fp32_modules (`List`, defaults to `None`):
+ An explicit list of the modules that we don't quantize. We keep them in `torch.float32`.
+ """
+
+ load_in_8bit: bool = field(default=False, metadata={"help": "enable 8bit quantization."})
+
+ llm_int8_threshold: float = field(
+ default=6.0,
+ metadata={"help": "value of the outliner threshold. only relevant when load_in_8bit=True"},
+ )
+
+ load_in_4bit: bool = field(default=False, metadata={"help": "enable 4bit quantization."})
+
+ bnb_4bit_quant_type: str = field(
+ default="fp4",
+ metadata={
+ "help": "set the quantization data type in the `bnb.nn.Linear4Bit` layers. Options are {'fp4','nf4'}."
+ },
+ )
+
+ bnb_4bit_use_double_quant: bool = field(
+ default=False,
+ metadata={
+ "help": "enable nested quantization where the quantization constants from the first quantization are quantized again."
+ },
+ )
+
+ bnb_4bit_compute_dtype: str = field(
+ default="fp16",
+ metadata={
+ "help": "This sets the computational type which might be different than the input time. For example, inputs might be "
+ "fp32, but computation can be set to bf16 for speedups. Options are {'fp32','fp16','bf16'}."
+ },
+ )
+
+ torch_dtype: torch.dtype = field(
+ default=None,
+ metadata={
+ "help": "this sets the dtype of the remaining non quantized layers. `bitsandbytes` library suggests to set the value"
+ "to `torch.float16` for 8 bit model and use the same dtype as the compute dtype for 4 bit model "
+ },
+ )
+
+ skip_modules: list[str] = field(
+ default=None,
+ metadata={
+ "help": "an explicit list of the modules that we don't quantize. The dtype of these modules will be `torch_dtype`."
+ },
+ )
+
+ keep_in_fp32_modules: list[str] = field(
+ default=None,
+ metadata={"help": "an explicit list of the modules that we don't quantize. We keep them in `torch.float32`."},
+ )
+
+ def __post_init__(self):
+ """
+ Safety checker that arguments are correct - also replaces some NoneType arguments with their default values.
+ """
+ if not isinstance(self.load_in_8bit, bool):
+ raise ValueError("load_in_8bit must be a boolean")
+
+ if not isinstance(self.load_in_4bit, bool):
+ raise ValueError("load_in_4bit must be a boolean")
+
+ if self.load_in_4bit and self.load_in_8bit:
+ raise ValueError("load_in_4bit and load_in_8bit can't be both True")
+
+ if not self.load_in_4bit and not self.load_in_8bit:
+ raise ValueError("load_in_4bit and load_in_8bit can't be both False")
+
+ if not isinstance(self.llm_int8_threshold, (int, float)):
+ raise ValueError("llm_int8_threshold must be a float or an int")
+
+ if not isinstance(self.bnb_4bit_quant_type, str):
+ raise ValueError("bnb_4bit_quant_type must be a string")
+ elif self.bnb_4bit_quant_type not in ["fp4", "nf4"]:
+ raise ValueError(f"bnb_4bit_quant_type must be in ['fp4','nf4'] but found {self.bnb_4bit_quant_type}")
+
+ if not isinstance(self.bnb_4bit_use_double_quant, bool):
+ raise ValueError("bnb_4bit_use_double_quant must be a boolean")
+
+ if isinstance(self.bnb_4bit_compute_dtype, str):
+ if self.bnb_4bit_compute_dtype == "fp32":
+ self.bnb_4bit_compute_dtype = torch.float32
+ elif self.bnb_4bit_compute_dtype == "fp16":
+ self.bnb_4bit_compute_dtype = torch.float16
+ elif self.bnb_4bit_compute_dtype == "bf16":
+ self.bnb_4bit_compute_dtype = torch.bfloat16
+ else:
+ raise ValueError(
+ f"bnb_4bit_compute_dtype must be in ['fp32','fp16','bf16'] but found {self.bnb_4bit_compute_dtype}"
+ )
+ elif not isinstance(self.bnb_4bit_compute_dtype, torch.dtype):
+ raise ValueError("bnb_4bit_compute_dtype must be a string or a torch.dtype")
+
+ if self.skip_modules is not None and not isinstance(self.skip_modules, list):
+ raise ValueError("skip_modules must be a list of strings")
+
+ if self.keep_in_fp32_modules is not None and not isinstance(self.keep_in_fp32_modules, list):
+ raise ValueError("keep_in_fp_32_modules must be a list of strings")
+
+ if self.load_in_4bit:
+ self.target_dtype = CustomDtype.INT4
+
+ if self.load_in_8bit:
+ self.target_dtype = torch.int8
+
+ if self.load_in_4bit and self.llm_int8_threshold != 6.0:
+ warnings.warn("llm_int8_threshold can only be used for model loaded in 8bit")
+
+ if isinstance(self.torch_dtype, str):
+ if self.torch_dtype == "fp32":
+ self.torch_dtype = torch.float32
+ elif self.torch_dtype == "fp16":
+ self.torch_dtype = torch.float16
+ elif self.torch_dtype == "bf16":
+ self.torch_dtype = torch.bfloat16
+ else:
+ raise ValueError(f"torch_dtype must be in ['fp32','fp16','bf16'] but found {self.torch_dtype}")
+ if self.load_in_8bit and self.torch_dtype is None:
+ self.torch_dtype = torch.float16
+
+ if self.load_in_4bit and self.torch_dtype is None:
+ self.torch_dtype = self.bnb_4bit_compute_dtype
+
+ if not isinstance(self.torch_dtype, torch.dtype):
+ raise ValueError("torch_dtype must be a torch.dtype")
+
+
+def get_module_class_from_name(module, name):
+ """
+ Gets a class from a module by its name.
+
+ Args:
+ module (`torch.nn.Module`): The module to get the class from.
+ name (`str`): The name of the class.
+ """
+ modules_children = list(module.children())
+ if module.__class__.__name__ == name:
+ return module.__class__
+ elif len(modules_children) == 0:
+ return
+ else:
+ for child_module in modules_children:
+ module_class = get_module_class_from_name(child_module, name)
+ if module_class is not None:
+ return module_class
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/deepspeed.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/deepspeed.py
new file mode 100644
index 0000000000000000000000000000000000000000..22db891c63d9bd48691acd87a15a206c270017a9
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/deepspeed.py
@@ -0,0 +1,385 @@
+# Copyright 2021 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import base64
+import json
+import os
+from copy import deepcopy
+
+from torch import optim
+
+from ..optimizer import AcceleratedOptimizer
+from ..scheduler import AcceleratedScheduler
+from .dataclasses import DistributedType
+from .imports import is_bnb_available
+from .versions import compare_versions
+
+
+def map_pytorch_optim_to_deepspeed(optimizer):
+ """
+ Args:
+ optimizer: torch.optim.Optimizer
+
+ Returns the DeepSeedCPUOptimizer (deepspeed.ops) version of the optimizer.
+ """
+
+ defaults = {k: v for k, v in optimizer.defaults.items() if k in ["lr", "weight_decay"]}
+
+ # Select the DeepSpeedCPUOptimizer based on the original optimizer class.
+ # DeepSpeedCPUAdam is the default
+ from deepspeed.ops.adam import DeepSpeedCPUAdam
+
+ optimizer_class = DeepSpeedCPUAdam
+
+ # For DeepSpeedCPUAdam (adamw_mode)
+ if compare_versions("deepspeed", ">=", "0.3.1"):
+ defaults["adamw_mode"] = False
+ is_adaw = isinstance(optimizer, optim.AdamW)
+
+ if is_bnb_available() and not is_adaw:
+ import bitsandbytes.optim as bnb_opt
+
+ if isinstance(optimizer, (bnb_opt.AdamW, bnb_opt.AdamW32bit)):
+ try:
+ is_adaw = optimizer.optim_bits == 32
+ except AttributeError:
+ is_adaw = optimizer.args.optim_bits == 32
+ else:
+ is_adaw = False
+
+ if is_adaw:
+ defaults["adamw_mode"] = True
+
+ # For DeepSpeedCPUAdagrad
+ if compare_versions("deepspeed", ">=", "0.5.5"):
+ # Check if the optimizer is PyTorch's Adagrad.
+ is_ada = isinstance(optimizer, optim.Adagrad)
+ # If not, and bitsandbytes is available,
+ # # check if the optimizer is the 32-bit bitsandbytes Adagrad.
+ if is_bnb_available() and not is_ada:
+ import bitsandbytes.optim as bnb_opt
+
+ if isinstance(optimizer, (bnb_opt.Adagrad, bnb_opt.Adagrad32bit)):
+ try:
+ is_ada = optimizer.optim_bits == 32
+ except AttributeError:
+ is_ada = optimizer.args.optim_bits == 32
+ if is_ada:
+ from deepspeed.ops.adagrad import DeepSpeedCPUAdagrad
+
+ optimizer_class = DeepSpeedCPUAdagrad
+
+ # For DeepSpeedCPULion
+ if is_bnb_available(min_version="0.38.0") and compare_versions("deepspeed", ">=", "0.11.0"):
+ from bitsandbytes.optim import Lion, Lion32bit
+
+ if isinstance(optimizer, (Lion, Lion32bit)):
+ try:
+ is_bnb_32bits = optimizer.optim_bits == 32
+ except AttributeError:
+ is_bnb_32bits = optimizer.args.optim_bits == 32
+ if is_bnb_32bits:
+ from deepspeed.ops.lion import DeepSpeedCPULion
+
+ optimizer_class = DeepSpeedCPULion
+
+ return optimizer_class(optimizer.param_groups, **defaults)
+
+
+def get_active_deepspeed_plugin(state):
+ """
+ Returns the currently active DeepSpeedPlugin.
+
+ Raises:
+ ValueError: If DeepSpeed was not enabled and this function is called.
+ """
+ if state.distributed_type != DistributedType.DEEPSPEED:
+ raise ValueError(
+ "Couldn't retrieve the active `DeepSpeedPlugin` as none were enabled. "
+ "Please make sure that either `Accelerator` is configured for `deepspeed` "
+ "or make sure that the desired `DeepSpeedPlugin` has been enabled (`AcceleratorState().select_deepspeed_plugin(name)`) "
+ "before calling this function."
+ )
+ if not isinstance(state.deepspeed_plugins, dict):
+ return state.deepspeed_plugins
+ return next(plugin for plugin in state.deepspeed_plugins.values() if plugin.selected)
+
+
+class HfDeepSpeedConfig:
+ """
+ This object contains a DeepSpeed configuration dictionary and can be quickly queried for things like zero stage.
+
+ A `weakref` of this object is stored in the module's globals to be able to access the config from areas where
+ things like the Trainer object is not available (e.g. `from_pretrained` and `_get_resized_embeddings`). Therefore
+ it's important that this object remains alive while the program is still running.
+
+ [`Trainer`] uses the `HfTrainerDeepSpeedConfig` subclass instead. That subclass has logic to sync the configuration
+ with values of [`TrainingArguments`] by replacing special placeholder values: `"auto"`. Without this special logic
+ the DeepSpeed configuration is not modified in any way.
+
+ Args:
+ config_file_or_dict (`Union[str, Dict]`): path to DeepSpeed config file or dict.
+
+ """
+
+ def __init__(self, config_file_or_dict):
+ if isinstance(config_file_or_dict, dict):
+ # Don't modify user's data should they want to reuse it (e.g. in tests), because once we
+ # modified it, it will not be accepted here again, since `auto` values would have been overridden
+ config = deepcopy(config_file_or_dict)
+ elif os.path.exists(config_file_or_dict):
+ with open(config_file_or_dict, encoding="utf-8") as f:
+ config = json.load(f)
+ else:
+ try:
+ try:
+ # First try parsing as JSON directly
+ config = json.loads(config_file_or_dict)
+ except json.JSONDecodeError:
+ # If that fails, try base64 decoding
+ config_decoded = base64.urlsafe_b64decode(config_file_or_dict).decode("utf-8")
+ config = json.loads(config_decoded)
+ except (UnicodeDecodeError, AttributeError, ValueError):
+ raise ValueError(
+ f"Expected a string path to an existing deepspeed config, or a dictionary, or a base64 encoded string. Received: {config_file_or_dict}"
+ )
+
+ self.config = config
+
+ self.set_stage_and_offload()
+
+ def set_stage_and_offload(self):
+ # zero stage - this is done as early as possible, before model is created, to allow
+ # ``is_deepspeed_zero3_enabled`` query and getting to the early deepspeed config object
+ # during ``zero.Init()`` which needs to know the dtype, and some other hparams.
+ self._stage = self.get_value("zero_optimization.stage", -1)
+
+ # offload
+ self._offload = False
+ if self.is_zero2() or self.is_zero3():
+ offload_devices_valid = set(["cpu", "nvme"])
+ offload_devices = set(
+ [
+ self.get_value("zero_optimization.offload_optimizer.device"),
+ self.get_value("zero_optimization.offload_param.device"),
+ ]
+ )
+ if len(offload_devices & offload_devices_valid) > 0:
+ self._offload = True
+
+ def find_config_node(self, ds_key_long):
+ config = self.config
+
+ # find the config node of interest if it exists
+ nodes = ds_key_long.split(".")
+ ds_key = nodes.pop()
+ for node in nodes:
+ config = config.get(node)
+ if config is None:
+ return None, ds_key
+
+ return config, ds_key
+
+ def get_value(self, ds_key_long, default=None):
+ """
+ Returns the set value or `default` if no value is set
+ """
+ config, ds_key = self.find_config_node(ds_key_long)
+ if config is None:
+ return default
+ return config.get(ds_key, default)
+
+ def del_config_sub_tree(self, ds_key_long, must_exist=False):
+ """
+ Deletes a sub-section of the config file if it's found.
+
+ Unless `must_exist` is `True` the section doesn't have to exist.
+ """
+ config = self.config
+
+ # find the config node of interest if it exists
+ nodes = ds_key_long.split(".")
+ for node in nodes:
+ parent_config = config
+ config = config.get(node)
+ if config is None:
+ if must_exist:
+ raise ValueError(f"Can't find {ds_key_long} entry in the config: {self.config}")
+ else:
+ return
+
+ # if found remove it
+ if parent_config is not None:
+ parent_config.pop(node)
+
+ def is_true(self, ds_key_long):
+ """
+ Returns `True`/``False` only if the value is set, always `False` otherwise. So use this method to ask the very
+ specific question of whether the value is set to `True` (and it's not set to `False`` or isn't set).
+
+ """
+ value = self.get_value(ds_key_long)
+ return False if value is None else bool(value)
+
+ def is_false(self, ds_key_long):
+ """
+ Returns `True`/``False` only if the value is set, always `False` otherwise. So use this method to ask the very
+ specific question of whether the value is set to `False` (and it's not set to `True`` or isn't set).
+ """
+ value = self.get_value(ds_key_long)
+ return False if value is None else not bool(value)
+
+ def is_zero2(self):
+ return self._stage == 2
+
+ def is_zero3(self):
+ return self._stage == 3
+
+ def is_offload(self):
+ return self._offload
+
+
+class DeepSpeedEngineWrapper:
+ """
+ Internal wrapper for deepspeed.runtime.engine.DeepSpeedEngine. This is used to follow conventional training loop.
+
+ Args:
+ engine (deepspeed.runtime.engine.DeepSpeedEngine): deepspeed engine to wrap
+ """
+
+ def __init__(self, engine):
+ self.engine = engine
+
+ def backward(self, loss, sync_gradients=True, **kwargs):
+ # Set gradient accumulation boundary based on Accelerate's sync_gradients state
+ # This tells DeepSpeed whether this is the final micro-batch before gradient sync
+ self.engine.set_gradient_accumulation_boundary(is_boundary=sync_gradients)
+
+ # runs backpropagation and handles mixed precision
+ self.engine.backward(loss, **kwargs)
+
+ # Only perform step and related operations at gradient accumulation boundaries
+ if sync_gradients:
+ # Deepspeed's `engine.step` performs the following operations:
+ # - gradient accumulation check
+ # - gradient clipping
+ # - optimizer step
+ # - zero grad
+ # - checking overflow
+ # - lr_scheduler step (only if engine.lr_scheduler is not None)
+ self.engine.step()
+ # and this plugin overrides the above calls with no-ops when Accelerate runs under
+ # Deepspeed, but allows normal functionality for non-Deepspeed cases thus enabling a simple
+ # training loop that works transparently under many training regimes.
+
+ def get_global_grad_norm(self):
+ """Get the global gradient norm from DeepSpeed engine."""
+ grad_norm = self.engine.get_global_grad_norm()
+ # Convert to scalar if it's a tensor
+ if hasattr(grad_norm, "item"):
+ return grad_norm.item()
+ return grad_norm
+
+
+class DeepSpeedOptimizerWrapper(AcceleratedOptimizer):
+ """
+ Internal wrapper around a deepspeed optimizer.
+
+ Args:
+ optimizer (`torch.optim.optimizer.Optimizer`):
+ The optimizer to wrap.
+ """
+
+ def __init__(self, optimizer):
+ super().__init__(optimizer, device_placement=False, scaler=None)
+ self.__has_overflow__ = hasattr(self.optimizer, "overflow")
+
+ def zero_grad(self, set_to_none=None):
+ pass # `accelerator.backward(loss)` is doing that automatically. Therefore, its implementation is not needed
+
+ def step(self):
+ pass # `accelerator.backward(loss)` is doing that automatically. Therefore, its implementation is not needed
+
+ @property
+ def step_was_skipped(self):
+ """Whether or not the optimizer step was done, or skipped because of gradient overflow."""
+ if self.__has_overflow__:
+ return self.optimizer.overflow
+ return False
+
+
+class DeepSpeedSchedulerWrapper(AcceleratedScheduler):
+ """
+ Internal wrapper around a deepspeed scheduler.
+
+ Args:
+ scheduler (`torch.optim.lr_scheduler.LambdaLR`):
+ The scheduler to wrap.
+ optimizers (one or a list of `torch.optim.Optimizer`):
+ """
+
+ def __init__(self, scheduler, optimizers):
+ super().__init__(scheduler, optimizers)
+
+ def step(self):
+ pass # `accelerator.backward(loss)` is doing that automatically. Therefore, its implementation is not needed
+
+
+class DummyOptim:
+ """
+ Dummy optimizer presents model parameters or param groups, this is primarily used to follow conventional training
+ loop when optimizer config is specified in the deepspeed config file.
+
+ Args:
+ lr (float):
+ Learning rate.
+ params (iterable): iterable of parameters to optimize or dicts defining
+ parameter groups
+ weight_decay (float):
+ Weight decay.
+ **kwargs (additional keyword arguments, *optional*):
+ Other arguments.
+ """
+
+ def __init__(self, params, lr=0.001, weight_decay=0, **kwargs):
+ self.params = params
+ self.lr = lr
+ self.weight_decay = weight_decay
+ self.kwargs = kwargs
+
+
+class DummyScheduler:
+ """
+ Dummy scheduler presents model parameters or param groups, this is primarily used to follow conventional training
+ loop when scheduler config is specified in the deepspeed config file.
+
+ Args:
+ optimizer (`torch.optim.optimizer.Optimizer`):
+ The optimizer to wrap.
+ total_num_steps (int, *optional*):
+ Total number of steps.
+ warmup_num_steps (int, *optional*):
+ Number of steps for warmup.
+ lr_scheduler_callable (callable, *optional*):
+ A callable function that creates an LR Scheduler. It accepts only one argument `optimizer`.
+ **kwargs (additional keyword arguments, *optional*):
+ Other arguments.
+ """
+
+ def __init__(self, optimizer, total_num_steps=None, warmup_num_steps=0, lr_scheduler_callable=None, **kwargs):
+ self.optimizer = optimizer
+ self.total_num_steps = total_num_steps
+ self.warmup_num_steps = warmup_num_steps
+ self.lr_scheduler_callable = lr_scheduler_callable
+ self.kwargs = kwargs
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/environment.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/environment.py
new file mode 100644
index 0000000000000000000000000000000000000000..faa3be2d336ad8674fdbdfd3d5504645b25f2b79
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/environment.py
@@ -0,0 +1,471 @@
+# Copyright 2022 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging
+import math
+import os
+import platform
+import subprocess
+import sys
+from contextlib import contextmanager
+from dataclasses import dataclass, field
+from functools import lru_cache, wraps
+from shutil import which
+from typing import Optional, Union
+
+import torch
+from packaging.version import parse
+
+
+logger = logging.getLogger(__name__)
+
+
+def convert_dict_to_env_variables(current_env: dict):
+ """
+ Verifies that all keys and values in `current_env` do not contain illegal keys or values, and returns a list of
+ strings as the result.
+
+ Example:
+ ```python
+ >>> from accelerate.utils.environment import verify_env
+
+ >>> env = {"ACCELERATE_DEBUG_MODE": "1", "BAD_ENV_NAME": ">> valid_env_items = verify_env(env)
+ >>> print(valid_env_items)
+ ["ACCELERATE_DEBUG_MODE=1\n", "OTHER_ENV=2\n"]
+ ```
+ """
+ forbidden_chars = [";", "\n", "<", ">", " "]
+ valid_env_items = []
+ for key, value in current_env.items():
+ if all(char not in (key + value) for char in forbidden_chars) and len(key) >= 1 and len(value) >= 1:
+ valid_env_items.append(f"{key}={value}\n")
+ else:
+ logger.warning(f"WARNING: Skipping {key}={value} as it contains forbidden characters or missing values.")
+ return valid_env_items
+
+
+def str_to_bool(value, to_bool: bool = False) -> Union[int, bool]:
+ """
+ Converts a string representation of truth to `True` (1) or `False` (0).
+
+ True values are `y`, `yes`, `t`, `true`, `on`, and `1`; False value are `n`, `no`, `f`, `false`, `off`, and `0`;
+ """
+ value = value.lower()
+ if value in ("y", "yes", "t", "true", "on", "1"):
+ return 1 if not to_bool else True
+ elif value in ("n", "no", "f", "false", "off", "0"):
+ return 0 if not to_bool else False
+ else:
+ raise ValueError(f"invalid truth value {value}")
+
+
+def get_int_from_env(env_keys, default):
+ """Returns the first positive env value found in the `env_keys` list or the default."""
+ for e in env_keys:
+ val = int(os.environ.get(e, -1))
+ if val >= 0:
+ return val
+ return default
+
+
+def parse_flag_from_env(key, default=False):
+ """Returns truthy value for `key` from the env if available else the default."""
+ value = os.environ.get(key, str(default))
+ return str_to_bool(value) == 1 # As its name indicates `str_to_bool` actually returns an int...
+
+
+def parse_choice_from_env(key, default="no"):
+ value = os.environ.get(key, str(default))
+ return value
+
+
+def are_libraries_initialized(*library_names: str) -> list[str]:
+ """
+ Checks if any of `library_names` are imported in the environment. Will return any names that are.
+ """
+ return [lib_name for lib_name in library_names if lib_name in sys.modules.keys()]
+
+
+def get_current_device_type() -> tuple[str, str]:
+ """
+ Determines the current device type and distributed type without initializing any device.
+
+ This is particularly important when using fork-based multiprocessing, as device initialization
+ before forking can cause errors.
+
+ The device detection order follows the same priority as state.py:_prepare_backend():
+ MLU -> SDAA -> MUSA -> NPU -> HPU -> CUDA -> XPU
+
+ Returns:
+ tuple[str, str]: A tuple of (device_type, distributed_type)
+ - device_type: The device string (e.g., "cuda", "npu", "xpu")
+ - distributed_type: The distributed type string (e.g., "MULTI_GPU", "MULTI_NPU")
+
+ Example:
+ ```python
+ >>> device_type, distributed_type = get_current_device_type()
+ >>> print(device_type) # "cuda"
+ >>> print(distributed_type) # "MULTI_GPU"
+ ```
+ """
+ from .imports import (
+ is_hpu_available,
+ is_mlu_available,
+ is_musa_available,
+ is_npu_available,
+ is_sdaa_available,
+ is_xpu_available,
+ )
+
+ if is_mlu_available():
+ return "mlu", "MULTI_MLU"
+ elif is_sdaa_available():
+ return "sdaa", "MULTI_SDAA"
+ elif is_musa_available():
+ return "musa", "MULTI_MUSA"
+ elif is_npu_available():
+ return "npu", "MULTI_NPU"
+ elif is_hpu_available():
+ return "hpu", "MULTI_HPU"
+ elif torch.cuda.is_available():
+ return "cuda", "MULTI_GPU"
+ elif is_xpu_available():
+ return "xpu", "MULTI_XPU"
+ else:
+ # Default to CUDA even if not available (for CPU-only scenarios where CUDA code paths are still used)
+ return "cuda", "MULTI_GPU"
+
+
+def _nvidia_smi():
+ """
+ Returns the right nvidia-smi command based on the system.
+ """
+ if platform.system() == "Windows":
+ # If platform is Windows and nvidia-smi can't be found in path
+ # try from systemd drive with default installation path
+ command = which("nvidia-smi")
+ if command is None:
+ command = f"{os.environ['systemdrive']}\\Program Files\\NVIDIA Corporation\\NVSMI\\nvidia-smi.exe"
+ else:
+ command = "nvidia-smi"
+ return command
+
+
+def get_gpu_info():
+ """
+ Gets GPU count and names using `nvidia-smi` instead of torch to not initialize CUDA.
+
+ Largely based on the `gputil` library.
+ """
+ # Returns as list of `n` GPUs and their names
+ output = subprocess.check_output(
+ [_nvidia_smi(), "--query-gpu=count,name", "--format=csv,noheader"], universal_newlines=True
+ )
+ output = output.strip()
+ gpus = output.split(os.linesep)
+ # Get names from output
+ gpu_count = len(gpus)
+ gpu_names = [gpu.split(",")[1].strip() for gpu in gpus]
+ return gpu_names, gpu_count
+
+
+def get_driver_version():
+ """
+ Returns the driver version
+
+ In the case of multiple GPUs, will return the first.
+ """
+ output = subprocess.check_output(
+ [_nvidia_smi(), "--query-gpu=driver_version", "--format=csv,noheader"], universal_newlines=True
+ )
+ output = output.strip()
+ return output.split(os.linesep)[0]
+
+
+def check_cuda_p2p_ib_support():
+ """
+ Checks if the devices being used have issues with P2P and IB communications, namely any consumer GPU hardware after
+ the 3090.
+
+ Notably uses `nvidia-smi` instead of torch to not initialize CUDA.
+ """
+ try:
+ device_names, device_count = get_gpu_info()
+ # As new consumer GPUs get released, add them to `unsupported_devices``
+ unsupported_devices = {"RTX 40"}
+ if device_count > 1:
+ if any(
+ unsupported_device in device_name
+ for device_name in device_names
+ for unsupported_device in unsupported_devices
+ ):
+ # Check if they have the right driver version
+ acceptable_driver_version = "550.40.07"
+ current_driver_version = get_driver_version()
+ if parse(current_driver_version) < parse(acceptable_driver_version):
+ return False
+ return True
+ except Exception:
+ pass
+ return True
+
+
+@lru_cache
+def check_cuda_fp8_capability():
+ """
+ Checks if the current GPU available supports FP8.
+
+ Notably might initialize `torch.cuda` to check.
+ """
+
+ try:
+ # try to get the compute capability from nvidia-smi
+ output = subprocess.check_output(
+ [_nvidia_smi(), "--query-gpu=compute_capability", "--format=csv,noheader"], universal_newlines=True
+ )
+ output = output.strip()
+ # we take the first GPU's compute capability
+ compute_capability = tuple(map(int, output.split(os.linesep)[0].split(".")))
+ except Exception:
+ compute_capability = torch.cuda.get_device_capability()
+
+ return compute_capability >= (8, 9)
+
+
+@dataclass
+class CPUInformation:
+ """
+ Stores information about the CPU in a distributed environment. It contains the following attributes:
+ - rank: The rank of the current process.
+ - world_size: The total number of processes in the world.
+ - local_rank: The rank of the current process on the local node.
+ - local_world_size: The total number of processes on the local node.
+ """
+
+ rank: int = field(default=0, metadata={"help": "The rank of the current process."})
+ world_size: int = field(default=1, metadata={"help": "The total number of processes in the world."})
+ local_rank: int = field(default=0, metadata={"help": "The rank of the current process on the local node."})
+ local_world_size: int = field(default=1, metadata={"help": "The total number of processes on the local node."})
+
+
+def get_cpu_distributed_information() -> CPUInformation:
+ """
+ Returns various information about the environment in relation to CPU distributed training as a `CPUInformation`
+ dataclass.
+ """
+ information = {}
+ information["rank"] = get_int_from_env(["RANK", "PMI_RANK", "OMPI_COMM_WORLD_RANK", "MV2_COMM_WORLD_RANK"], 0)
+ information["world_size"] = get_int_from_env(
+ ["WORLD_SIZE", "PMI_SIZE", "OMPI_COMM_WORLD_SIZE", "MV2_COMM_WORLD_SIZE"], 1
+ )
+ information["local_rank"] = get_int_from_env(
+ ["LOCAL_RANK", "MPI_LOCALRANKID", "OMPI_COMM_WORLD_LOCAL_RANK", "MV2_COMM_WORLD_LOCAL_RANK"], 0
+ )
+ information["local_world_size"] = get_int_from_env(
+ ["LOCAL_WORLD_SIZE", "MPI_LOCALNRANKS", "OMPI_COMM_WORLD_LOCAL_SIZE", "MV2_COMM_WORLD_LOCAL_SIZE"],
+ 1,
+ )
+ return CPUInformation(**information)
+
+
+def override_numa_affinity(local_process_index: int, verbose: Optional[bool] = None) -> None:
+ """
+ Overrides whatever NUMA affinity is set for the current process. This is very taxing and requires recalculating the
+ affinity to set, ideally you should use `utils.environment.set_numa_affinity` instead.
+
+ Args:
+ local_process_index (int):
+ The index of the current process on the current server.
+ verbose (bool, *optional*):
+ Whether to log out the assignment of each CPU. If `ACCELERATE_DEBUG_MODE` is enabled, will default to True.
+ """
+ if verbose is None:
+ verbose = parse_flag_from_env("ACCELERATE_DEBUG_MODE", False)
+ if torch.cuda.is_available():
+ from accelerate.utils import is_pynvml_available
+
+ if not is_pynvml_available():
+ raise ImportError(
+ "To set CPU affinity on CUDA GPUs the `nvidia-ml-py` package must be available. (`pip install nvidia-ml-py`)"
+ )
+ import pynvml as nvml
+
+ # The below code is based on https://github.com/NVIDIA/DeepLearningExamples/blob/master/TensorFlow2/LanguageModeling/BERT/gpu_affinity.py
+ nvml.nvmlInit()
+ num_elements = math.ceil(os.cpu_count() / 64)
+ handle = nvml.nvmlDeviceGetHandleByIndex(local_process_index)
+ affinity_string = ""
+ for j in nvml.nvmlDeviceGetCpuAffinity(handle, num_elements):
+ # assume nvml returns list of 64 bit ints
+ affinity_string = f"{j:064b}{affinity_string}"
+ affinity_list = [int(x) for x in affinity_string]
+ affinity_list.reverse() # so core 0 is the 0th element
+ affinity_to_set = [i for i, e in enumerate(affinity_list) if e != 0]
+ os.sched_setaffinity(0, affinity_to_set)
+ if verbose:
+ cpu_cores = os.sched_getaffinity(0)
+ logger.info(f"Assigning {len(cpu_cores)} cpu cores to process {local_process_index}: {cpu_cores}")
+
+
+@lru_cache
+def set_numa_affinity(local_process_index: int, verbose: Optional[bool] = None) -> None:
+ """
+ Assigns the current process to a specific NUMA node. Ideally most efficient when having at least 2 cpus per node.
+
+ This result is cached between calls. If you want to override it, please use
+ `accelerate.utils.environment.override_numa_afifnity`.
+
+ Args:
+ local_process_index (int):
+ The index of the current process on the current server.
+ verbose (bool, *optional*):
+ Whether to print the new cpu cores assignment for each process. If `ACCELERATE_DEBUG_MODE` is enabled, will
+ default to True.
+ """
+ override_numa_affinity(local_process_index=local_process_index, verbose=verbose)
+
+
+@contextmanager
+def clear_environment():
+ """
+ A context manager that will temporarily clear environment variables.
+
+ When this context exits, the previous environment variables will be back.
+
+ Example:
+
+ ```python
+ >>> import os
+ >>> from accelerate.utils import clear_environment
+
+ >>> os.environ["FOO"] = "bar"
+ >>> with clear_environment():
+ ... print(os.environ)
+ ... os.environ["FOO"] = "new_bar"
+ ... print(os.environ["FOO"])
+ {}
+ new_bar
+
+ >>> print(os.environ["FOO"])
+ bar
+ ```
+ """
+ _old_os_environ = os.environ.copy()
+ os.environ.clear()
+
+ try:
+ yield
+ finally:
+ os.environ.clear() # clear any added keys,
+ os.environ.update(_old_os_environ) # then restore previous environment
+
+
+@contextmanager
+def patch_environment(**kwargs):
+ """
+ A context manager that will add each keyword argument passed to `os.environ` and remove them when exiting.
+
+ Will convert the values in `kwargs` to strings and upper-case all the keys.
+
+ Example:
+
+ ```python
+ >>> import os
+ >>> from accelerate.utils import patch_environment
+
+ >>> with patch_environment(FOO="bar"):
+ ... print(os.environ["FOO"]) # prints "bar"
+ >>> print(os.environ["FOO"]) # raises KeyError
+ ```
+ """
+ existing_vars = {}
+ for key, value in kwargs.items():
+ key = key.upper()
+ if key in os.environ:
+ existing_vars[key] = os.environ[key]
+ os.environ[key] = str(value)
+
+ try:
+ yield
+ finally:
+ for key in kwargs:
+ key = key.upper()
+ if key in existing_vars:
+ # restore previous value
+ os.environ[key] = existing_vars[key]
+ else:
+ os.environ.pop(key, None)
+
+
+def purge_accelerate_environment(func_or_cls):
+ """Decorator to clean up accelerate environment variables set by the decorated class or function.
+
+ In some circumstances, calling certain classes or functions can result in accelerate env vars being set and not
+ being cleaned up afterwards. As an example, when calling:
+
+ TrainingArguments(fp16=True, ...)
+
+ The following env var will be set:
+
+ ACCELERATE_MIXED_PRECISION=fp16
+
+ This can affect subsequent code, since the env var takes precedence over TrainingArguments(fp16=False). This is
+ especially relevant for unit testing, where we want to avoid the individual tests to have side effects on one
+ another. Decorate the unit test function or whole class with this decorator to ensure that after each test, the env
+ vars are cleaned up. This works for both unittest.TestCase and normal classes (pytest); it also works when
+ decorating the parent class.
+
+ """
+ prefix = "ACCELERATE_"
+
+ @contextmanager
+ def env_var_context():
+ # Store existing accelerate env vars
+ existing_vars = {k: v for k, v in os.environ.items() if k.startswith(prefix)}
+ try:
+ yield
+ finally:
+ # Restore original env vars or remove new ones
+ for key in [k for k in os.environ if k.startswith(prefix)]:
+ if key in existing_vars:
+ os.environ[key] = existing_vars[key]
+ else:
+ os.environ.pop(key, None)
+
+ def wrap_function(func):
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ with env_var_context():
+ return func(*args, **kwargs)
+
+ wrapper._accelerate_is_purged_environment_wrapped = True
+ return wrapper
+
+ if not isinstance(func_or_cls, type):
+ return wrap_function(func_or_cls)
+
+ # Handle classes by wrapping test methods
+ def wrap_test_methods(test_class_instance):
+ for name in dir(test_class_instance):
+ if name.startswith("test"):
+ method = getattr(test_class_instance, name)
+ if callable(method) and not hasattr(method, "_accelerate_is_purged_environment_wrapped"):
+ setattr(test_class_instance, name, wrap_function(method))
+ return test_class_instance
+
+ # Handle inheritance
+ wrap_test_methods(func_or_cls)
+ func_or_cls.__init_subclass__ = classmethod(lambda cls, **kw: wrap_test_methods(cls))
+ return func_or_cls
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/fsdp_utils.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/fsdp_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..b0475cb7d13fb5a6477a93455a9d025b6a582201
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/fsdp_utils.py
@@ -0,0 +1,829 @@
+# Copyright 2023 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import copy
+import functools
+import os
+import re
+import shutil
+import warnings
+from collections import defaultdict
+from collections.abc import Iterable
+from contextlib import nullcontext
+from pathlib import Path
+from typing import Callable, Union
+
+import torch
+
+from ..logging import get_logger
+from .constants import FSDP_MODEL_NAME, OPTIMIZER_NAME, SAFE_WEIGHTS_NAME, WEIGHTS_NAME
+from .dataclasses import get_module_class_from_name
+from .modeling import get_non_persistent_buffers, is_peft_model
+from .other import get_module_children_bottom_up, is_compiled_module, save
+from .versions import is_torch_version
+
+
+logger = get_logger(__name__)
+
+
+def enable_fsdp_ram_efficient_loading():
+ """
+ Enables RAM efficient loading of Hugging Face models for FSDP in the environment.
+ """
+ # Sets values for `transformers.modeling_utils.is_fsdp_enabled`
+ if "ACCELERATE_USE_FSDP" not in os.environ:
+ os.environ["ACCELERATE_USE_FSDP"] = "True"
+ os.environ["FSDP_CPU_RAM_EFFICIENT_LOADING"] = "True"
+
+
+def disable_fsdp_ram_efficient_loading():
+ """
+ Disables RAM efficient loading of Hugging Face models for FSDP in the environment.
+ """
+ os.environ["FSDP_CPU_RAM_EFFICIENT_LOADING"] = "False"
+
+
+def _get_model_state_dict(model, adapter_only=False, sd_options=None):
+ if adapter_only and is_peft_model(model):
+ from peft import get_peft_model_state_dict
+
+ return get_peft_model_state_dict(model, adapter_name=model.active_adapter)
+
+ # Invariant: `sd_options` is not None only for FSDP2
+ if sd_options is not None:
+ from torch.distributed.checkpoint.state_dict import get_model_state_dict
+
+ return get_model_state_dict(model, options=sd_options)
+ else:
+ return model.state_dict()
+
+
+def _set_model_state_dict(model, state_dict, adapter_only=False, sd_options=None):
+ if adapter_only and is_peft_model(model):
+ from peft import set_peft_model_state_dict
+
+ return set_peft_model_state_dict(model, state_dict, adapter_name=model.active_adapter)
+
+ # Invariant: `sd_options` is not None only for FSDP2
+ if sd_options is not None:
+ from torch.distributed.checkpoint.state_dict import set_model_state_dict
+
+ return set_model_state_dict(model, state_dict, options=sd_options)
+ else:
+ return model.load_state_dict(state_dict)
+
+
+def _prepare_sd_options(fsdp_plugin):
+ sd_options = None
+
+ # we use this only for FSDP2, as it requires torch >= 2.6.0 and this api requires torch >= 2.2.0
+ if fsdp_plugin.fsdp_version == 2:
+ from torch.distributed.checkpoint.state_dict import StateDictOptions
+ from torch.distributed.fsdp.fully_sharded_data_parallel import StateDictType
+
+ sd_options = StateDictOptions(
+ full_state_dict=fsdp_plugin.state_dict_type == StateDictType.FULL_STATE_DICT,
+ cpu_offload=getattr(fsdp_plugin.state_dict_config, "offload_to_cpu", False),
+ broadcast_from_rank0=getattr(fsdp_plugin.state_dict_config, "rank0_only", False),
+ )
+
+ return sd_options
+
+
+def save_fsdp_model(fsdp_plugin, accelerator, model, output_dir, model_index=0, adapter_only=False):
+ # Note: We import here to reduce import time from general modules, and isolate outside dependencies
+ import torch.distributed.checkpoint as dist_cp
+ from torch.distributed.checkpoint.default_planner import DefaultSavePlanner
+ from torch.distributed.fsdp.fully_sharded_data_parallel import FullyShardedDataParallel as FSDP
+ from torch.distributed.fsdp.fully_sharded_data_parallel import StateDictType
+
+ os.makedirs(output_dir, exist_ok=True)
+ if fsdp_plugin.state_dict_type == StateDictType.FULL_STATE_DICT:
+ # FSDP raises error when single GPU is used with `offload_to_cpu=True` for FULL_STATE_DICT
+ # so, only enable it when num_processes>1
+ is_multi_process = accelerator.num_processes > 1
+ fsdp_plugin.state_dict_config.offload_to_cpu = is_multi_process
+ fsdp_plugin.state_dict_config.rank0_only = is_multi_process
+
+ ctx = (
+ FSDP.state_dict_type(
+ model, fsdp_plugin.state_dict_type, fsdp_plugin.state_dict_config, fsdp_plugin.optim_state_dict_config
+ )
+ if fsdp_plugin.fsdp_version == 1
+ else nullcontext()
+ )
+ sd_options = _prepare_sd_options(fsdp_plugin)
+
+ with ctx:
+ state_dict = _get_model_state_dict(model, adapter_only=adapter_only, sd_options=sd_options)
+ if fsdp_plugin.state_dict_type == StateDictType.FULL_STATE_DICT:
+ weights_name = f"{FSDP_MODEL_NAME}.bin" if model_index == 0 else f"{FSDP_MODEL_NAME}_{model_index}.bin"
+ output_model_file = os.path.join(output_dir, weights_name)
+ if accelerator.process_index == 0:
+ logger.info(f"Saving model to {output_model_file}")
+ torch.save(state_dict, output_model_file)
+ logger.info(f"Model saved to {output_model_file}")
+ # Invariant: `LOCAL_STATE_DICT` is never possible with `FSDP2`
+ elif fsdp_plugin.state_dict_type == StateDictType.LOCAL_STATE_DICT:
+ weights_name = (
+ f"{FSDP_MODEL_NAME}_rank{accelerator.process_index}.bin"
+ if model_index == 0
+ else f"{FSDP_MODEL_NAME}_{model_index}_rank{accelerator.process_index}.bin"
+ )
+ output_model_file = os.path.join(output_dir, weights_name)
+ logger.info(f"Saving model to {output_model_file}")
+ torch.save(state_dict, output_model_file)
+ logger.info(f"Model saved to {output_model_file}")
+ elif fsdp_plugin.state_dict_type == StateDictType.SHARDED_STATE_DICT:
+ ckpt_dir = os.path.join(output_dir, f"{FSDP_MODEL_NAME}_{model_index}")
+ os.makedirs(ckpt_dir, exist_ok=True)
+ logger.info(f"Saving model to {ckpt_dir}")
+ state_dict = {"model": state_dict}
+
+ dist_cp.save(
+ state_dict=state_dict,
+ storage_writer=dist_cp.FileSystemWriter(ckpt_dir),
+ planner=DefaultSavePlanner(),
+ )
+ logger.info(f"Model saved to {ckpt_dir}")
+
+
+def load_fsdp_model(fsdp_plugin, accelerator, model, input_dir, model_index=0, adapter_only=False):
+ # Note: We import here to reduce import time from general modules, and isolate outside dependencies
+ import torch.distributed.checkpoint as dist_cp
+ from torch.distributed.checkpoint.default_planner import DefaultLoadPlanner
+ from torch.distributed.fsdp.fully_sharded_data_parallel import FullyShardedDataParallel as FSDP
+ from torch.distributed.fsdp.fully_sharded_data_parallel import StateDictType
+
+ accelerator.wait_for_everyone()
+ if fsdp_plugin.state_dict_type == StateDictType.FULL_STATE_DICT:
+ # FSDP raises error when single GPU is used with `offload_to_cpu=True` for FULL_STATE_DICT
+ # so, only enable it when num_processes>1
+ is_multi_process = accelerator.num_processes > 1
+ fsdp_plugin.state_dict_config.offload_to_cpu = is_multi_process
+ fsdp_plugin.state_dict_config.rank0_only = is_multi_process
+
+ ctx = (
+ FSDP.state_dict_type(
+ model, fsdp_plugin.state_dict_type, fsdp_plugin.state_dict_config, fsdp_plugin.optim_state_dict_config
+ )
+ if fsdp_plugin.fsdp_version == 1
+ else nullcontext()
+ )
+ sd_options = _prepare_sd_options(fsdp_plugin)
+ with ctx:
+ if fsdp_plugin.state_dict_type == StateDictType.FULL_STATE_DICT:
+ if type(model) is not FSDP and accelerator.process_index != 0 and not accelerator.is_fsdp2:
+ if not fsdp_plugin.sync_module_states and fsdp_plugin.fsdp_version == 1:
+ raise ValueError(
+ "Set the `sync_module_states` flag to `True` so that model states are synced across processes when "
+ "initializing FSDP object"
+ )
+ return
+ weights_name = f"{FSDP_MODEL_NAME}.bin" if model_index == 0 else f"{FSDP_MODEL_NAME}_{model_index}.bin"
+ input_model_file = os.path.join(input_dir, weights_name)
+ logger.info(f"Loading model from {input_model_file}")
+ # we want an empty state dict for FSDP2 as we use `broadcast_from_rank0`
+ load_model = not accelerator.is_fsdp2 or accelerator.is_main_process
+ if load_model:
+ state_dict = torch.load(input_model_file, weights_only=True)
+ else:
+ state_dict = {}
+ logger.info(f"Model loaded from {input_model_file}")
+ elif fsdp_plugin.state_dict_type == StateDictType.LOCAL_STATE_DICT:
+ weights_name = (
+ f"{FSDP_MODEL_NAME}_rank{accelerator.process_index}.bin"
+ if model_index == 0
+ else f"{FSDP_MODEL_NAME}_{model_index}_rank{accelerator.process_index}.bin"
+ )
+ input_model_file = os.path.join(input_dir, weights_name)
+ logger.info(f"Loading model from {input_model_file}")
+ state_dict = torch.load(input_model_file, weights_only=True)
+ logger.info(f"Model loaded from {input_model_file}")
+ elif fsdp_plugin.state_dict_type == StateDictType.SHARDED_STATE_DICT:
+ ckpt_dir = (
+ os.path.join(input_dir, f"{FSDP_MODEL_NAME}_{model_index}")
+ if f"{FSDP_MODEL_NAME}" not in input_dir
+ else input_dir
+ )
+ logger.info(f"Loading model from {ckpt_dir}")
+ state_dict = {"model": _get_model_state_dict(model, adapter_only=adapter_only, sd_options=sd_options)}
+ dist_cp.load(
+ state_dict=state_dict,
+ storage_reader=dist_cp.FileSystemReader(ckpt_dir),
+ planner=DefaultLoadPlanner(),
+ )
+ state_dict = state_dict["model"]
+ logger.info(f"Model loaded from {ckpt_dir}")
+
+ load_result = _set_model_state_dict(model, state_dict, adapter_only=adapter_only, sd_options=sd_options)
+ return load_result
+
+
+def save_fsdp_optimizer(fsdp_plugin, accelerator, optimizer, model, output_dir, optimizer_index=0):
+ # Note: We import here to reduce import time from general modules, and isolate outside dependencies
+ import torch.distributed.checkpoint as dist_cp
+ from torch.distributed.checkpoint.default_planner import DefaultSavePlanner
+ from torch.distributed.fsdp.fully_sharded_data_parallel import FullyShardedDataParallel as FSDP
+ from torch.distributed.fsdp.fully_sharded_data_parallel import StateDictType
+
+ os.makedirs(output_dir, exist_ok=True)
+
+ ctx = (
+ FSDP.state_dict_type(
+ model, fsdp_plugin.state_dict_type, fsdp_plugin.state_dict_config, fsdp_plugin.optim_state_dict_config
+ )
+ if fsdp_plugin.fsdp_version == 1
+ else nullcontext()
+ )
+
+ sd_options = _prepare_sd_options(fsdp_plugin)
+
+ with ctx:
+ if fsdp_plugin.fsdp_version == 2:
+ from torch.distributed.checkpoint.state_dict import get_optimizer_state_dict
+
+ optim_state = get_optimizer_state_dict(model, optimizer, options=sd_options)
+ else:
+ optim_state = FSDP.optim_state_dict(model, optimizer)
+
+ if fsdp_plugin.state_dict_type == StateDictType.FULL_STATE_DICT:
+ if accelerator.process_index == 0:
+ optim_state_name = (
+ f"{OPTIMIZER_NAME}.bin" if optimizer_index == 0 else f"{OPTIMIZER_NAME}_{optimizer_index}.bin"
+ )
+ output_optimizer_file = os.path.join(output_dir, optim_state_name)
+ logger.info(f"Saving Optimizer state to {output_optimizer_file}")
+ torch.save(optim_state, output_optimizer_file)
+ logger.info(f"Optimizer state saved in {output_optimizer_file}")
+ else:
+ ckpt_dir = os.path.join(output_dir, f"{OPTIMIZER_NAME}_{optimizer_index}")
+ os.makedirs(ckpt_dir, exist_ok=True)
+ logger.info(f"Saving Optimizer state to {ckpt_dir}")
+ dist_cp.save(
+ state_dict={"optimizer": optim_state},
+ storage_writer=dist_cp.FileSystemWriter(ckpt_dir),
+ planner=DefaultSavePlanner(),
+ )
+ logger.info(f"Optimizer state saved in {ckpt_dir}")
+
+
+def load_fsdp_optimizer(fsdp_plugin, accelerator, optimizer, model, input_dir, optimizer_index=0, adapter_only=False):
+ # Note: We import here to reduce import time from general modules, and isolate outside dependencies
+ import torch.distributed.checkpoint as dist_cp
+ from torch.distributed.fsdp.fully_sharded_data_parallel import FullyShardedDataParallel as FSDP
+ from torch.distributed.fsdp.fully_sharded_data_parallel import StateDictType
+
+ accelerator.wait_for_everyone()
+ ctx = (
+ FSDP.state_dict_type(
+ model, fsdp_plugin.state_dict_type, fsdp_plugin.state_dict_config, fsdp_plugin.optim_state_dict_config
+ )
+ if fsdp_plugin.fsdp_version == 1
+ else nullcontext()
+ )
+ sd_options = _prepare_sd_options(fsdp_plugin)
+ with ctx:
+ if fsdp_plugin.state_dict_type == StateDictType.FULL_STATE_DICT:
+ optim_state = None
+ if accelerator.process_index == 0 or not fsdp_plugin.optim_state_dict_config.rank0_only:
+ optimizer_name = (
+ f"{OPTIMIZER_NAME}.bin" if optimizer_index == 0 else f"{OPTIMIZER_NAME}_{optimizer_index}.bin"
+ )
+ input_optimizer_file = os.path.join(input_dir, optimizer_name)
+ logger.info(f"Loading Optimizer state from {input_optimizer_file}")
+ optim_state = torch.load(input_optimizer_file, weights_only=True)
+ logger.info(f"Optimizer state loaded from {input_optimizer_file}")
+ else:
+ ckpt_dir = (
+ os.path.join(input_dir, f"{OPTIMIZER_NAME}_{optimizer_index}")
+ if f"{OPTIMIZER_NAME}" not in input_dir
+ else input_dir
+ )
+ logger.info(f"Loading Optimizer from {ckpt_dir}")
+ optim_state = {"optimizer": optimizer.state_dict()}
+ dist_cp.load(
+ optim_state,
+ checkpoint_id=ckpt_dir,
+ storage_reader=dist_cp.FileSystemReader(ckpt_dir),
+ )
+ optim_state = optim_state["optimizer"]
+ logger.info(f"Optimizer loaded from {ckpt_dir}")
+
+ if fsdp_plugin.fsdp_version == 1:
+ flattened_osd = FSDP.optim_state_dict_to_load(model=model, optim=optimizer, optim_state_dict=optim_state)
+ optimizer.load_state_dict(flattened_osd)
+ else:
+ from torch.distributed.checkpoint.state_dict import set_optimizer_state_dict
+
+ set_optimizer_state_dict(model, optimizer, optim_state, options=sd_options)
+
+
+def _distributed_checkpoint_to_merged_weights(checkpoint_dir: str, save_path: str, safe_serialization: bool = True):
+ """
+ Passthrough to `torch.distributed.checkpoint.format_utils.dcp_to_torch_save`
+
+ Will save under `save_path` as either `model.safetensors` or `pytorch_model.bin`.
+ """
+ # Note: We import here to reduce import time from general modules, and isolate outside dependencies
+ import torch.distributed.checkpoint as dist_cp
+ import torch.distributed.checkpoint.format_utils as dist_cp_format_utils
+
+ state_dict = {}
+ save_path = Path(save_path)
+ save_path.mkdir(exist_ok=True)
+ dist_cp_format_utils._load_state_dict(
+ state_dict,
+ storage_reader=dist_cp.FileSystemReader(checkpoint_dir),
+ planner=dist_cp_format_utils._EmptyStateDictLoadPlanner(),
+ no_dist=True,
+ )
+ save_path = save_path / SAFE_WEIGHTS_NAME if safe_serialization else save_path / WEIGHTS_NAME
+
+ # To handle if state is a dict like {model: {...}}
+ if len(state_dict.keys()) == 1:
+ state_dict = state_dict[list(state_dict)[0]]
+ save(state_dict, save_path, safe_serialization=safe_serialization)
+ return save_path
+
+
+def merge_fsdp_weights(
+ checkpoint_dir: str, output_path: str, safe_serialization: bool = True, remove_checkpoint_dir: bool = False
+):
+ """
+ Merge the weights from sharded FSDP model checkpoints into a single combined checkpoint. Should be used if
+ `SHARDED_STATE_DICT` was used for the model. Weights will be saved to `{output_path}/model.safetensors` if
+ `safe_serialization` else `pytorch_model.bin`.
+
+ Note: this is a CPU-bound process.
+
+ Args:
+ checkpoint_dir (`str`):
+ The directory containing the FSDP checkpoints (can be either the model or optimizer).
+ output_path (`str`):
+ The path to save the merged checkpoint.
+ safe_serialization (`bool`, *optional*, defaults to `True`):
+ Whether to save the merged weights with safetensors (recommended).
+ remove_checkpoint_dir (`bool`, *optional*, defaults to `False`):
+ Whether to remove the checkpoint directory after merging.
+ """
+ checkpoint_dir = Path(checkpoint_dir)
+ from accelerate.state import PartialState
+
+ if not is_torch_version(">=", "2.3.0"):
+ raise ValueError("`merge_fsdp_weights` requires PyTorch >= 2.3.0`")
+
+ # Verify that the checkpoint directory exists
+ if not checkpoint_dir.exists():
+ model_path_exists = (checkpoint_dir / "pytorch_model_fsdp_0").exists()
+ optimizer_path_exists = (checkpoint_dir / "optimizer_0").exists()
+ err = f"Tried to load from {checkpoint_dir} but couldn't find a valid metadata file."
+ if model_path_exists and optimizer_path_exists:
+ err += " However, potential model and optimizer checkpoint directories exist."
+ err += f"Please pass in either {checkpoint_dir}/pytorch_model_fsdp_0 or {checkpoint_dir}/optimizer_0"
+ err += "instead."
+ elif model_path_exists:
+ err += " However, a potential model checkpoint directory exists."
+ err += f"Please try passing in {checkpoint_dir}/pytorch_model_fsdp_0 instead."
+ elif optimizer_path_exists:
+ err += " However, a potential optimizer checkpoint directory exists."
+ err += f"Please try passing in {checkpoint_dir}/optimizer_0 instead."
+ raise ValueError(err)
+
+ # To setup `save` to work
+ state = PartialState()
+ if state.is_main_process:
+ logger.info(f"Merging FSDP weights from {checkpoint_dir}")
+ save_path = _distributed_checkpoint_to_merged_weights(checkpoint_dir, output_path, safe_serialization)
+ logger.info(f"Successfully merged FSDP weights and saved to {save_path}")
+ if remove_checkpoint_dir:
+ logger.info(f"Removing old checkpoint directory {checkpoint_dir}")
+ shutil.rmtree(checkpoint_dir)
+ state.wait_for_everyone()
+
+
+def ensure_weights_retied(param_init_fn, model: torch.nn.Module, device: torch.device):
+ _tied_names = getattr(model, "_tied_weights_keys", None)
+ if not _tied_names:
+ # if no tied names just passthrough
+ return param_init_fn
+
+ # get map of parameter instances to params.
+ # - needed for replacement later
+ _tied_params = {}
+ for name in _tied_names:
+ name = name.split(".")
+ name, param_name = ".".join(name[:-1]), name[-1]
+ mod = model.get_submodule(name)
+ param = getattr(mod, param_name)
+
+ _tied_params[id(param)] = None # placeholder for the param first
+
+ # build param_init_fn for the case with tied params
+ def param_init_fn_tied_param(module: torch.nn.Module):
+ # track which params to tie
+ # - usually only 1, but for completeness consider > 1
+ params_to_tie = defaultdict(list)
+ for n, param in module.named_parameters(recurse=False):
+ if id(param) in _tied_params:
+ params_to_tie[id(param)].append(n)
+
+ # call the param init fn, which potentially re-allocates the
+ # parameters
+ module = param_init_fn(module)
+
+ # search the parameters again and tie them up again
+ for id_key, _param_names in params_to_tie.items():
+ for param_name in _param_names:
+ param = _tied_params[id_key]
+ if param is None:
+ # everything will be tied to the first time the
+ # param is observed
+ _tied_params[id_key] = getattr(module, param_name)
+ else:
+ setattr(module, param_name, param) # tie
+
+ return module
+
+ return param_init_fn_tied_param
+
+
+def fsdp2_load_full_state_dict(accelerator, model: torch.nn.Module, full_sd: dict):
+ """
+ Loads the full state dict (could be only on rank 0) into the sharded model. This is done by broadcasting the
+ parameters from rank 0 to all other ranks. This function modifies the model in-place.
+
+ Args:
+ accelerator (`Accelerator`): The accelerator instance
+ model (`torch.nn.Module`):
+ The model to load the state dict into, expected to be on meta device or a VRAM spike can occur
+ full_sd (`dict`): The full state dict to load, can only be on rank 0
+ """
+ import torch.distributed as dist
+ from torch.distributed.tensor import DTensor, distribute_tensor
+
+ # Model was previously copied to meta device
+ meta_sharded_sd = model.state_dict()
+ sharded_sd = {}
+
+ # Rank 0 distributes the full state dict to other ranks
+ def _infer_parameter_dtype(model, param_name, empty_param):
+ try:
+ old_param = model.get_parameter_or_buffer(param_name)
+ except AttributeError:
+ # Need this for LORA, as there some params are not *parameters* of sorts
+ base_param_name, local_param_name = param_name.rsplit(".", 1)
+ submodule = model.get_submodule(base_param_name)
+ old_param = getattr(submodule, local_param_name)
+
+ is_torch_e4m3fn_available = hasattr(torch, "float8_e4m3fn")
+ casting_dtype = None
+ is_param_float8_e4m3fn = is_torch_e4m3fn_available and empty_param.dtype == torch.float8_e4m3fn
+
+ if empty_param.dtype.is_floating_point and not is_param_float8_e4m3fn:
+ casting_dtype = old_param.dtype
+
+ return old_param is not None and old_param.is_contiguous(), casting_dtype
+
+ def _cast_and_contiguous(tensor, to_contiguous, dtype):
+ if dtype is not None:
+ tensor = tensor.to(dtype=dtype)
+ if to_contiguous:
+ tensor = tensor.contiguous()
+ return tensor
+
+ if accelerator.is_main_process:
+ for (param_name, full_param), sharded_param in zip(full_sd.items(), meta_sharded_sd.values()):
+ device_mesh = sharded_param.device_mesh
+ full_param = full_param.detach().to(device_mesh.device_type)
+ if isinstance(full_param, DTensor):
+ # dist.broadcast() only supports torch.Tensor.
+ # After prepare_tp(), model parameters may become DTensor.
+ # To broadcast such a parameter, convert it to a local tensor first.
+ full_param = full_param.to_local()
+ dist.broadcast(full_param, src=0, group=dist.group.WORLD)
+ sharded_tensor = distribute_tensor(full_param, device_mesh, sharded_param.placements)
+ to_contiguous, casting_dtype = _infer_parameter_dtype(
+ model,
+ param_name,
+ full_param,
+ )
+ sharded_tensor = _cast_and_contiguous(sharded_tensor, to_contiguous, casting_dtype)
+ sharded_sd[param_name] = sharded_tensor
+ # We need this else to have a matching `broadcast` for all of the ranks, else we deadlock
+ else:
+ for param_name, sharded_param in meta_sharded_sd.items():
+ device_mesh = sharded_param.device_mesh
+ full_tensor = torch.empty(sharded_param.size(), device=device_mesh.device_type, dtype=sharded_param.dtype)
+ dist.broadcast(full_tensor, src=0, group=dist.group.WORLD)
+ sharded_tensor = distribute_tensor(full_tensor, device_mesh, sharded_param.placements)
+ to_contiguous, casting_dtype = _infer_parameter_dtype(
+ model,
+ param_name,
+ full_tensor,
+ )
+ sharded_tensor = _cast_and_contiguous(sharded_tensor, to_contiguous, casting_dtype)
+ sharded_sd[param_name] = sharded_tensor
+
+ # we set `assign=True` because our params are on meta device
+ model.load_state_dict(sharded_sd, assign=True)
+ return model
+
+
+def fsdp2_switch_optimizer_parameters(optimizer: torch.optim.Optimizer, mapping: dict):
+ """
+ Switches the parameters of the optimizer to new ones (sharded parameters in usual case). This function modifies the
+ optimizer in-place.
+
+ Args:
+ optimizer (`torch.optim.Optimizer`): Optimizer instance which contains the original model parameters
+ mapping (`dict`): Mapping from the original parameter (specified by `data_ptr`) to the sharded parameter
+
+ Raises:
+ KeyError:
+ If a parameter in the optimizer couldn't be switched to its sharded version. This should never happen and
+ indicates a bug. If we kept the original params instead of raising, the training wouldn't be numerically
+ correct and weights wouldn't get updated.
+ """
+ from torch.distributed.tensor import DTensor
+
+ accessor_mapping = {}
+
+ accessor_mapping[DTensor] = "_local_tensor"
+ try:
+ for param_group in optimizer.param_groups:
+ param_group["params"] = [mapping[p.data_ptr] for p in param_group["params"]]
+ except KeyError:
+ # This shouldn't ever happen, but we want to fail here else training wouldn't be numerically correct
+ # This basically means that we're missing a mapping from the original parameter to the sharded parameter
+ raise KeyError(
+ "A parameter in the optimizer couldn't be switched to its sharded version. This breaks the training. Please raise an issue on GitHub."
+ )
+
+
+def fsdp2_apply_ac(accelerator, model: torch.nn.Module):
+ """
+ Applies the activation checkpointing to the model.
+
+ Args:
+ accelerator (`Accelerator`): The accelerator instance
+ model (`torch.nn.Module`): The model to apply the activation checkpointing to
+
+ Returns:
+ `torch.nn.Module`: The model with the activation checkpointing applied
+ """
+
+ from torch.distributed.algorithms._checkpoint.checkpoint_wrapper import (
+ checkpoint_wrapper,
+ )
+
+ auto_wrap_policy_func = fsdp2_prepare_auto_wrap_policy(accelerator.state.fsdp_plugin, model)
+
+ for layer_name, layer in get_module_children_bottom_up(model, return_fqns=True)[:-1]:
+ if len(layer_name.split(".")) > 1:
+ parent_name, child_name = layer_name.rsplit(".", 1)
+ else:
+ parent_name = None
+ child_name = layer_name
+
+ parent_module = model.get_submodule(parent_name) if parent_name else model
+ if auto_wrap_policy_func(parent_module):
+ layer = checkpoint_wrapper(layer, preserve_rng_state=False)
+ parent_module.register_module(child_name, layer)
+
+ return model
+
+
+def fsdp2_prepare_model(accelerator, model: torch.nn.Module) -> torch.nn.Module:
+ """Prepares the model for FSDP2 in-place. Also returns the model to avoid misuse of the original model.
+
+ Args:
+ accelerator (`Accelerator`): The accelerator instance
+ model (`torch.nn.Module`): The model to prepare
+
+ Returns:
+ `torch.nn.Module`: Prepared model
+ """
+ from torch.distributed.fsdp import FSDPModule, MixedPrecisionPolicy, fully_shard
+
+ is_type_fsdp = isinstance(model, FSDPModule) or (
+ is_compiled_module(model) and isinstance(model._orig_mod, FSDPModule)
+ )
+ if is_type_fsdp:
+ return model
+
+ fsdp2_plugin = accelerator.state.fsdp_plugin
+
+ fsdp2_plugin.set_auto_wrap_policy(model)
+
+ original_sd = model.state_dict()
+ mesh = getattr(accelerator, "torch_device_mesh", None)
+
+ fsdp2_kwargs = {
+ "reshard_after_forward": fsdp2_plugin.reshard_after_forward,
+ "offload_policy": fsdp2_plugin.cpu_offload,
+ # `fully_shard` doesn't accept `None` in case of `MixedPrecisionPolicy`
+ "mp_policy": fsdp2_plugin.mixed_precision_policy or MixedPrecisionPolicy(),
+ "mesh": mesh[tuple(accelerator.parallelism_config.fsdp_dim_names)] if mesh is not None else None,
+ "ignored_params": get_parameters_from_modules(fsdp2_plugin.ignored_modules, model, accelerator.device),
+ }
+
+ model_has_params4bit = False
+ for name, param in model.named_parameters():
+ # this is a temporary fix whereby loading models with bnb params cannot be moved from
+ # GPU to a meta device due with FSDP2 because torch operations don't return the original class type
+ # bypassing the move to meta will still cause the VRAM spike, but at least it still will load
+ if param.__class__.__name__ == "Params4bit":
+ model_has_params4bit = True
+ break
+
+ if fsdp2_plugin.cpu_ram_efficient_loading and not model_has_params4bit:
+ # Context: `fully_shard` moves the model to GPU if it was on CPU, however it can also be on `meta` and then it stays there even after `fully_shard`
+ # For this reason, we need to move the model to `meta` device, as then sharding happens on `meta` device
+ # If we kept the model on CPU (`cpu_ram_efficient_loading` has model be on CPU on all ranks, though non-main ranks only have `torch.empty`), `fully_shard` would move it to GPU
+ # Afterwards, when we call `fsdp2_load_full_state_dict`, us creating the state_dict would result into briefly having two copies of model state_dict on the GPU -> VRAM spike
+
+ # We need to keep the original non-persistent buffers, as those MAY not be in the state_dict, resulting in them staying on meta device
+ # Also, these buffers aren't getting sharded by default
+ # We get the FQNs of all non-persistent buffers, to re-register them after
+ non_persistent_buffer_fqns = get_non_persistent_buffers(model, recurse=True, fqns=True)
+ original_non_persistent_buffers = copy.deepcopy(
+ {k: v for k, v in model.named_buffers() if k in non_persistent_buffer_fqns}
+ )
+ # We move the model to meta device, as then sharding happens on meta device
+ model = model.to(torch.device("meta"))
+ # We need to re-tie the weights, not exactly sure why, but if we don't do this, reference to `lm_head/embed_tokens` stay hanging -> more VRAM usage
+ # We assume `transformers` models have a `tie_weights` method if they support it
+ if hasattr(model, "tie_weights"):
+ model.tie_weights()
+
+ auto_wrap_policy_func = fsdp2_prepare_auto_wrap_policy(fsdp2_plugin, model)
+ if auto_wrap_policy_func is not None:
+ # We skip the model itself, as that one is always wrapped
+ for module in get_module_children_bottom_up(model)[:-1]:
+ if auto_wrap_policy_func(module) and not isinstance(module, FSDPModule):
+ fully_shard(module, **fsdp2_kwargs)
+
+ if not isinstance(model, FSDPModule):
+ fully_shard(model, **fsdp2_kwargs)
+
+ if fsdp2_plugin.cpu_ram_efficient_loading:
+ # If `cpu_ram_efficient_loading` is enabled, only rank 0 loads the weights
+ # Other ranks have an empty model on `meta` device, so we need to distribute the weights properly
+ fsdp2_load_full_state_dict(accelerator, model, original_sd)
+
+ if fsdp2_plugin.cpu_ram_efficient_loading and not model_has_params4bit:
+ # We re-register the buffers, as they may not be in the state_dict
+ for fqn, buffer_tensor in original_non_persistent_buffers.items():
+ buffer_tensor = buffer_tensor.to(accelerator.device)
+
+ if "." in fqn:
+ parent_fqn, local_buffer_name = fqn.rsplit(".", 1)
+ parent_module = model.get_submodule(parent_fqn)
+ else:
+ local_buffer_name = fqn
+ parent_module = model
+
+ parent_module.register_buffer(local_buffer_name, buffer_tensor, persistent=False)
+
+ # We need to tie the weights again, as call to `load_full_state_dict` breaks the tie
+ # Needs to be called both here and above
+ # removing this call makes the have slightly different loss
+ # removing the call above leads to extra memory usage as explained in the comment above
+ if hasattr(model, "tie_weights"):
+ model.tie_weights()
+
+ # There is no `dtype` attribution for nn.Module
+ # Set it to None if it doesn't exist and do the upcast always
+ model_dtype = getattr(model, "dtype", None)
+ if accelerator.mixed_precision != "no" and (model_dtype is None or model_dtype != torch.float32):
+ # We upcast the model according to `deepspeed`'s implementation
+ # More info about this can be found in `accelerator.py:prepare_model`s FSDP1 section
+ model = model.to(torch.float32)
+ if accelerator.is_main_process:
+ # TODO(siro1): Add a warning for each parameter that was upcasted
+ warnings.warn(
+ "FSDP upcast of low precision parameters to fp32 (since mixed_precision != 'no') may affect the precision of model checkpoints."
+ )
+ return model
+
+
+def fsdp2_prepare_auto_wrap_policy(fsdp2_plugin, model: torch.nn.Module) -> Callable[[torch.nn.Module], bool]:
+ """Prepares the auto wrap policy based on its type, done to mimic the behaviour of FSDP1 auto wrap policy.
+
+ Args:
+ fsdp2_plugin (`FullyShardedDataParallelPlugin`):
+ Instance of `FullyShardedDataParallelPlugin` containing the configuration options
+ auto_wrap_policy_type (`str`):
+ Either `transformer` or `size`
+ model (`torch.nn.Module`):
+ The model to wrap
+
+ Returns:
+ `Callable[[torch.nn.Module], bool]`:
+ The auto wrap policy function to be applied to the model
+ """
+ from torch.distributed.fsdp.wrap import size_based_auto_wrap_policy, transformer_auto_wrap_policy
+
+ fn = fsdp2_plugin.auto_wrap_policy
+
+ if isinstance(fn, functools.partial):
+ fn = fn.func
+
+ if fn is transformer_auto_wrap_policy:
+ no_split_modules = getattr(model, "_no_split_modules", None)
+ if no_split_modules is None:
+ no_split_modules = []
+ transformer_cls_names_to_wrap = list(no_split_modules)
+ if fsdp2_plugin.transformer_cls_names_to_wrap is not None:
+ transformer_cls_names_to_wrap = fsdp2_plugin.transformer_cls_names_to_wrap
+ transformer_cls_to_wrap = set()
+
+ for layer_class in transformer_cls_names_to_wrap:
+ transformer_cls = get_module_class_from_name(model, layer_class)
+ if transformer_cls is None:
+ raise ValueError(f"Could not find the transformer layer class {layer_class} in the model.")
+ transformer_cls_to_wrap.add(transformer_cls)
+
+ def policy(module: torch.nn.Module) -> bool:
+ if fsdp2_plugin.transformer_cls_names_to_wrap is None:
+ return False
+ return isinstance(module, tuple(transformer_cls_to_wrap))
+
+ elif fn is size_based_auto_wrap_policy:
+
+ def policy(module: torch.nn.Module) -> bool:
+ module_num_params = sum(p.numel() for p in module.parameters())
+ return module_num_params > fsdp2_plugin.min_num_params
+ else:
+ return None
+
+ return policy
+
+
+def get_fsdp2_grad_scaler(**kwargs):
+ """
+ Returns a `GradScaler` for FSDP2, as the current implementation of `get_grad_scaler` doesn't accept other args. We
+ need this as current `get_grad_scaler` accepts only `distributed_type` as arg, which doesn't differentiate between
+ FSDP1 and FSDP2
+ """
+ from torch.amp.grad_scaler import GradScaler
+
+ return GradScaler(**kwargs)
+
+
+def fsdp2_canonicalize_names(named_params: dict) -> dict:
+ """Removes parameter name modifiers in order to map them back to their original names.
+
+ See huggingface/accelerate#3554 for more context.
+
+ Args:
+ named_params (`dict`): The named parameters dictionary to canonicalize.
+
+ Returns:
+ `dict`: The canonicalized named parameters dictionary
+ """
+ named_params = {k.replace("._checkpoint_wrapped_module", ""): v for k, v in named_params.items()}
+ named_params = {
+ k.replace("_orig_mod.", "") if k.startswith("_orig_mod.") else k: v for k, v in named_params.items()
+ }
+ named_params = {k.replace("._orig_mod", ""): v for k, v in named_params.items()}
+ return named_params
+
+
+def get_parameters_from_modules(
+ modules: Union[Iterable[torch.nn.Module], str], model, device
+) -> set[torch.nn.Parameter]:
+ """Converts modules to parameters where modules can be a string or list of torch.nn.Module
+
+ Args:
+ modules (`Union[Iterable[torch.nn.Module], str]`): List of modules
+
+ Returns:
+ `set[torch.nn.Parameter]`: List of parameters
+ """
+ if modules is None:
+ return set()
+ parameters = []
+ # code taken from accelerate while preparing kwargs for FSDP
+ if isinstance(modules, str):
+ reg = re.compile(modules)
+ mapped_modules = []
+ for name, module in model.named_modules():
+ if reg.fullmatch(name):
+ module.to(device)
+ mapped_modules.append(module)
+ modules = mapped_modules
+ for module in modules:
+ parameters.extend(list(module.parameters()))
+ return set(parameters)
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/imports.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/imports.py
new file mode 100644
index 0000000000000000000000000000000000000000..68cef6b4a4cafd65de5e82de155a316683cee737
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/imports.py
@@ -0,0 +1,564 @@
+# Copyright 2022 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import importlib
+import importlib.metadata
+import os
+import sys
+import warnings
+from functools import lru_cache, wraps
+
+import torch
+from packaging import version
+from packaging.version import parse
+
+from .environment import parse_flag_from_env, patch_environment, str_to_bool
+from .versions import compare_versions, is_torch_version
+
+
+# Try to run Torch native job in an environment with TorchXLA installed by setting this value to 0.
+USE_TORCH_XLA = parse_flag_from_env("USE_TORCH_XLA", default=True)
+
+_torch_xla_available = False
+if USE_TORCH_XLA:
+ try:
+ import torch_xla.core.xla_model as xm # noqa: F401
+ import torch_xla.runtime
+
+ _torch_xla_available = True
+ except ImportError:
+ pass
+
+# Keep it for is_tpu_available. It will be removed along with is_tpu_available.
+_tpu_available = _torch_xla_available
+
+# Cache this result has it's a C FFI call which can be pretty time-consuming
+_torch_distributed_available = torch.distributed.is_available()
+
+
+def _is_package_available(pkg_name, metadata_name=None):
+ # Check we're not importing a "pkg_name" directory somewhere but the actual library by trying to grab the version
+ package_exists = importlib.util.find_spec(pkg_name) is not None
+ if package_exists:
+ try:
+ # Some libraries have different names in the metadata
+ _ = importlib.metadata.metadata(pkg_name if metadata_name is None else metadata_name)
+ return True
+ except importlib.metadata.PackageNotFoundError:
+ return False
+
+
+def is_torch_distributed_available() -> bool:
+ return _torch_distributed_available
+
+
+def is_xccl_available():
+ if is_torch_version(">=", "2.7.0"):
+ return torch.distributed.distributed_c10d.is_xccl_available()
+ if is_ipex_available():
+ return False
+ return False
+
+
+def is_ccl_available():
+ try:
+ pass
+ except ImportError:
+ print(
+ "Intel(R) oneCCL Bindings for PyTorch* is required to run DDP on Intel(R) XPUs, but it is not"
+ " detected. If you see \"ValueError: Invalid backend: 'ccl'\" error, please install Intel(R) oneCCL"
+ " Bindings for PyTorch*."
+ )
+ return importlib.util.find_spec("oneccl_bindings_for_pytorch") is not None
+
+
+def get_ccl_version():
+ return importlib.metadata.version("oneccl_bind_pt")
+
+
+def is_import_timer_available():
+ return _is_package_available("import_timer")
+
+
+def is_pynvml_available():
+ return _is_package_available("pynvml") or _is_package_available("pynvml", "nvidia-ml-py")
+
+
+def is_pytest_available():
+ return _is_package_available("pytest")
+
+
+def is_msamp_available():
+ return _is_package_available("msamp", "ms-amp")
+
+
+def is_schedulefree_available():
+ return _is_package_available("schedulefree")
+
+
+def is_transformer_engine_available():
+ if is_hpu_available():
+ return _is_package_available("intel_transformer_engine", "intel-transformer-engine")
+ else:
+ return _is_package_available("transformer_engine", "transformer-engine")
+
+
+def is_transformer_engine_mxfp8_available():
+ if _is_package_available("transformer_engine", "transformer-engine"):
+ import transformer_engine.pytorch as te
+
+ return te.fp8.check_mxfp8_support()[0]
+ return False
+
+
+def is_lomo_available():
+ return _is_package_available("lomo_optim")
+
+
+def is_cuda_available():
+ """
+ Checks if `cuda` is available via an `nvml-based` check which won't trigger the drivers and leave cuda
+ uninitialized.
+ """
+ with patch_environment(PYTORCH_NVML_BASED_CUDA_CHECK="1"):
+ available = torch.cuda.is_available()
+
+ return available
+
+
+@lru_cache
+def is_torch_xla_available(check_is_tpu=False, check_is_gpu=False):
+ """
+ Check if `torch_xla` is available. To train a native pytorch job in an environment with torch xla installed, set
+ the USE_TORCH_XLA to false.
+ """
+ assert not (check_is_tpu and check_is_gpu), "The check_is_tpu and check_is_gpu cannot both be true."
+
+ if not _torch_xla_available:
+ return False
+ elif check_is_gpu:
+ return torch_xla.runtime.device_type() in ["GPU", "CUDA"]
+ elif check_is_tpu:
+ return torch_xla.runtime.device_type() == "TPU"
+
+ return True
+
+
+def is_torchao_available():
+ package_exists = _is_package_available("torchao")
+ if package_exists:
+ torchao_version = version.parse(importlib.metadata.version("torchao"))
+ return compare_versions(torchao_version, ">=", "0.6.1")
+ return False
+
+
+def is_deepspeed_available():
+ return _is_package_available("deepspeed")
+
+
+def is_pippy_available():
+ return is_torch_version(">=", "2.4.0")
+
+
+def is_bf16_available(ignore_tpu=False):
+ "Checks if bf16 is supported, optionally ignoring the TPU"
+ if is_torch_xla_available(check_is_tpu=True):
+ return not ignore_tpu
+ if is_cuda_available():
+ return torch.cuda.is_bf16_supported()
+ if is_mlu_available():
+ return torch.mlu.is_bf16_supported()
+ if is_xpu_available():
+ return torch.xpu.is_bf16_supported()
+ if is_mps_available():
+ return torch.backends.mps.is_macos_or_newer(14, 0)
+ return True
+
+
+def is_fp16_available():
+ "Checks if fp16 is supported"
+ if is_habana_gaudi1():
+ return False
+
+ return True
+
+
+def is_fp8_available():
+ "Checks if fp8 is supported"
+ return is_msamp_available() or is_transformer_engine_available() or is_torchao_available()
+
+
+def is_4bit_bnb_available():
+ package_exists = _is_package_available("bitsandbytes")
+ if package_exists:
+ bnb_version = version.parse(importlib.metadata.version("bitsandbytes"))
+ return compare_versions(bnb_version, ">=", "0.39.0")
+ return False
+
+
+def is_8bit_bnb_available():
+ package_exists = _is_package_available("bitsandbytes")
+ if package_exists:
+ bnb_version = version.parse(importlib.metadata.version("bitsandbytes"))
+ return compare_versions(bnb_version, ">=", "0.37.2")
+ return False
+
+
+def is_bnb_available(min_version=None):
+ package_exists = _is_package_available("bitsandbytes")
+ if package_exists and min_version is not None:
+ bnb_version = version.parse(importlib.metadata.version("bitsandbytes"))
+ return compare_versions(bnb_version, ">=", min_version)
+ else:
+ return package_exists
+
+
+def is_bitsandbytes_multi_backend_available():
+ if not is_bnb_available():
+ return False
+ import bitsandbytes as bnb
+
+ return "multi_backend" in getattr(bnb, "features", set())
+
+
+def is_torchvision_available():
+ return _is_package_available("torchvision")
+
+
+def is_megatron_lm_available():
+ if str_to_bool(os.environ.get("ACCELERATE_USE_MEGATRON_LM", "False")) == 1:
+ if importlib.util.find_spec("megatron") is not None:
+ try:
+ megatron_version = parse(importlib.metadata.version("megatron-core"))
+ if compare_versions(megatron_version, ">=", "0.8.0"):
+ return importlib.util.find_spec(".training", "megatron")
+ except Exception as e:
+ warnings.warn(f"Parse Megatron version failed. Exception:{e}")
+ return False
+
+
+def is_transformers_available():
+ return _is_package_available("transformers")
+
+
+def is_datasets_available():
+ return _is_package_available("datasets")
+
+
+def is_peft_available():
+ return _is_package_available("peft")
+
+
+def is_timm_available():
+ return _is_package_available("timm")
+
+
+def is_triton_available():
+ if is_xpu_available():
+ return _is_package_available("triton", "pytorch-triton-xpu")
+ return _is_package_available("triton")
+
+
+def is_aim_available():
+ package_exists = _is_package_available("aim")
+ if package_exists:
+ aim_version = version.parse(importlib.metadata.version("aim"))
+ return compare_versions(aim_version, "<", "4.0.0")
+ return False
+
+
+def is_tensorboard_available():
+ return _is_package_available("tensorboard") or _is_package_available("tensorboardX")
+
+
+def is_wandb_available():
+ return _is_package_available("wandb")
+
+
+def is_comet_ml_available():
+ return _is_package_available("comet_ml")
+
+
+def is_swanlab_available():
+ return _is_package_available("swanlab")
+
+
+def is_trackio_available():
+ return sys.version_info >= (3, 10) and _is_package_available("trackio")
+
+
+def is_boto3_available():
+ return _is_package_available("boto3")
+
+
+def is_rich_available():
+ if _is_package_available("rich"):
+ return parse_flag_from_env("ACCELERATE_ENABLE_RICH", False)
+ return False
+
+
+def is_sagemaker_available():
+ return _is_package_available("sagemaker")
+
+
+def is_tqdm_available():
+ return _is_package_available("tqdm")
+
+
+def is_clearml_available():
+ return _is_package_available("clearml")
+
+
+def is_pandas_available():
+ return _is_package_available("pandas")
+
+
+def is_matplotlib_available():
+ return _is_package_available("matplotlib")
+
+
+def is_mlflow_available():
+ if _is_package_available("mlflow"):
+ return True
+
+ if importlib.util.find_spec("mlflow") is not None:
+ try:
+ _ = importlib.metadata.metadata("mlflow-skinny")
+ return True
+ except importlib.metadata.PackageNotFoundError:
+ return False
+ return False
+
+
+def is_mps_available(min_version="1.12"):
+ "Checks if MPS device is available. The minimum version required is 1.12."
+ # With torch 1.12, you can use torch.backends.mps
+ # With torch 2.0.0, you can use torch.mps
+ return is_torch_version(">=", min_version) and torch.backends.mps.is_available() and torch.backends.mps.is_built()
+
+
+def is_ipex_available():
+ "Checks if ipex is installed."
+
+ def get_major_and_minor_from_version(full_version):
+ return str(version.parse(full_version).major) + "." + str(version.parse(full_version).minor)
+
+ _torch_version = importlib.metadata.version("torch")
+ if importlib.util.find_spec("intel_extension_for_pytorch") is None:
+ return False
+ _ipex_version = "N/A"
+ try:
+ _ipex_version = importlib.metadata.version("intel_extension_for_pytorch")
+ except importlib.metadata.PackageNotFoundError:
+ return False
+ torch_major_and_minor = get_major_and_minor_from_version(_torch_version)
+ ipex_major_and_minor = get_major_and_minor_from_version(_ipex_version)
+ if torch_major_and_minor != ipex_major_and_minor:
+ warnings.warn(
+ f"Intel Extension for PyTorch {ipex_major_and_minor} needs to work with PyTorch {ipex_major_and_minor}.*,"
+ f" but PyTorch {_torch_version} is found. Please switch to the matching version and run again."
+ )
+ return False
+ return True
+
+
+@lru_cache
+def is_mlu_available(check_device=False):
+ """
+ Checks if `mlu` is available via an `cndev-based` check which won't trigger the drivers and leave mlu
+ uninitialized.
+ """
+ if importlib.util.find_spec("torch_mlu") is None:
+ return False
+
+ import torch_mlu # noqa: F401
+
+ with patch_environment(PYTORCH_CNDEV_BASED_MLU_CHECK="1"):
+ available = torch.mlu.is_available()
+
+ return available
+
+
+@lru_cache
+def is_musa_available(check_device=False):
+ "Checks if `torch_musa` is installed and potentially if a MUSA is in the environment"
+ if importlib.util.find_spec("torch_musa") is None:
+ return False
+
+ import torch_musa # noqa: F401
+
+ if check_device:
+ try:
+ # Will raise a RuntimeError if no MUSA is found
+ _ = torch.musa.device_count()
+ return torch.musa.is_available()
+ except RuntimeError:
+ return False
+ return hasattr(torch, "musa") and torch.musa.is_available()
+
+
+@lru_cache
+def is_npu_available(check_device=False):
+ "Checks if `torch_npu` is installed and potentially if a NPU is in the environment"
+ if importlib.util.find_spec("torch_npu") is None:
+ return False
+
+ # NOTE: importing torch_npu may raise error in some envs
+ # e.g. inside cpu-only container with torch_npu installed
+ try:
+ import torch_npu # noqa: F401
+ except Exception:
+ return False
+
+ if check_device:
+ try:
+ # Will raise a RuntimeError if no NPU is found
+ _ = torch.npu.device_count()
+ return torch.npu.is_available()
+ except RuntimeError:
+ return False
+ return hasattr(torch, "npu") and torch.npu.is_available()
+
+
+@lru_cache
+def is_sdaa_available(check_device=False):
+ "Checks if `torch_sdaa` is installed and potentially if a SDAA is in the environment"
+ if importlib.util.find_spec("torch_sdaa") is None:
+ return False
+
+ import torch_sdaa # noqa: F401
+
+ if check_device:
+ try:
+ # Will raise a RuntimeError if no NPU is found
+ _ = torch.sdaa.device_count()
+ return torch.sdaa.is_available()
+ except RuntimeError:
+ return False
+ return hasattr(torch, "sdaa") and torch.sdaa.is_available()
+
+
+@lru_cache
+def is_hpu_available(init_hccl=False):
+ "Checks if `torch.hpu` is installed and potentially if a HPU is in the environment"
+ if (
+ importlib.util.find_spec("habana_frameworks") is None
+ or importlib.util.find_spec("habana_frameworks.torch") is None
+ ):
+ return False
+
+ import habana_frameworks.torch # noqa: F401
+
+ if init_hccl:
+ import habana_frameworks.torch.distributed.hccl as hccl # noqa: F401
+
+ return hasattr(torch, "hpu") and torch.hpu.is_available()
+
+
+def is_habana_gaudi1():
+ if is_hpu_available():
+ import habana_frameworks.torch.utils.experimental as htexp # noqa: F401
+
+ if htexp._get_device_type() == htexp.synDeviceType.synDeviceGaudi:
+ return True
+
+ return False
+
+
+@lru_cache
+def is_xpu_available(check_device=False):
+ """
+ Checks if XPU acceleration is available either via `intel_extension_for_pytorch` or via stock PyTorch (>=2.4) and
+ potentially if a XPU is in the environment
+ """
+
+ if is_ipex_available():
+ import intel_extension_for_pytorch # noqa: F401
+ else:
+ if is_torch_version("<=", "2.3"):
+ return False
+
+ if check_device:
+ try:
+ # Will raise a RuntimeError if no XPU is found
+ _ = torch.xpu.device_count()
+ return torch.xpu.is_available()
+ except RuntimeError:
+ return False
+ return hasattr(torch, "xpu") and torch.xpu.is_available()
+
+
+def is_dvclive_available():
+ return _is_package_available("dvclive")
+
+
+def is_torchdata_available():
+ return _is_package_available("torchdata")
+
+
+# TODO: Remove this function once stateful_dataloader is a stable feature in torchdata.
+def is_torchdata_stateful_dataloader_available():
+ package_exists = _is_package_available("torchdata")
+ if package_exists:
+ torchdata_version = version.parse(importlib.metadata.version("torchdata"))
+ return compare_versions(torchdata_version, ">=", "0.8.0")
+ return False
+
+
+def torchao_required(func):
+ """
+ A decorator that ensures the decorated function is only called when torchao is available.
+ """
+
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ if not is_torchao_available():
+ raise ImportError(
+ "`torchao` is not available, please install it before calling this function via `pip install torchao`."
+ )
+ return func(*args, **kwargs)
+
+ return wrapper
+
+
+# TODO: Rework this into `utils.deepspeed` and migrate the "core" chunks into `accelerate.deepspeed`
+def deepspeed_required(func):
+ """
+ A decorator that ensures the decorated function is only called when deepspeed is enabled.
+ """
+
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ from accelerate.state import AcceleratorState
+ from accelerate.utils.dataclasses import DistributedType
+
+ if AcceleratorState._shared_state != {} and AcceleratorState().distributed_type != DistributedType.DEEPSPEED:
+ raise ValueError(
+ "DeepSpeed is not enabled, please make sure that an `Accelerator` is configured for `deepspeed` "
+ "before calling this function."
+ )
+ return func(*args, **kwargs)
+
+ return wrapper
+
+
+def is_weights_only_available():
+ # Weights only with allowlist was added in 2.4.0
+ # ref: https://github.com/pytorch/pytorch/pull/124331
+ return is_torch_version(">=", "2.4.0")
+
+
+def is_numpy_available(min_version="1.25.0"):
+ numpy_version = parse(importlib.metadata.version("numpy"))
+ return compare_versions(numpy_version, ">=", min_version)
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/launch.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/launch.py
new file mode 100644
index 0000000000000000000000000000000000000000..6182bd40d6f29086a0b01816569e147423c46192
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/launch.py
@@ -0,0 +1,781 @@
+# Copyright 2022 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import argparse
+import os
+import subprocess
+import sys
+import warnings
+from ast import literal_eval
+from shutil import which
+from typing import Any
+
+import torch
+
+from ..commands.config.config_args import SageMakerConfig
+from ..utils import (
+ DynamoBackend,
+ PrecisionType,
+ is_ccl_available,
+ is_fp8_available,
+ is_hpu_available,
+ is_ipex_available,
+ is_mlu_available,
+ is_musa_available,
+ is_npu_available,
+ is_sdaa_available,
+ is_torch_xla_available,
+ is_xpu_available,
+)
+from ..utils.constants import DEEPSPEED_MULTINODE_LAUNCHERS
+from ..utils.other import get_free_port, is_port_in_use, merge_dicts
+from ..utils.versions import compare_versions
+from .dataclasses import DistributedType, SageMakerDistributedType
+
+
+def _filter_args(args, parser, default_args=[]):
+ """
+ Filters out all `accelerate` specific args
+ """
+ new_args, _ = parser.parse_known_args(default_args)
+ for key, value in vars(args).items():
+ if key in vars(new_args).keys():
+ setattr(new_args, key, value)
+ return new_args
+
+
+def _get_mpirun_args():
+ """
+ Determines the executable and argument names for mpirun, based on the type of install. The supported MPI programs
+ are: OpenMPI, Intel MPI, or MVAPICH.
+
+ Returns: Program name and arg names for hostfile, num processes, and processes per node
+ """
+ # Find the MPI program name
+ mpi_apps = [x for x in ["mpirun", "mpiexec"] if which(x)]
+
+ if len(mpi_apps) == 0:
+ raise OSError("mpirun or mpiexec were not found. Ensure that Intel MPI, Open MPI, or MVAPICH are installed.")
+
+ # Call the app with the --version flag to determine which MPI app is installed
+ mpi_app = mpi_apps[0]
+ mpirun_version = subprocess.check_output([mpi_app, "--version"])
+
+ if b"Open MPI" in mpirun_version:
+ return mpi_app, "--hostfile", "-n", "--npernode", "--bind-to"
+ else:
+ # Intel MPI and MVAPICH both use the same arg names
+ return mpi_app, "-f", "-n", "-ppn", ""
+
+
+def setup_fp8_env(args: argparse.Namespace, current_env: dict[str, str]):
+ """
+ Setup the FP8 environment variables.
+ """
+ prefix = "ACCELERATE_"
+ for arg in vars(args):
+ if arg.startswith("fp8_"):
+ value = getattr(args, arg)
+ if value is not None:
+ if arg == "fp8_override_linear_precision":
+ current_env[prefix + "FP8_OVERRIDE_FPROP"] = str(value[0])
+ current_env[prefix + "FP8_OVERRIDE_DGRAD"] = str(value[1])
+ current_env[prefix + "FP8_OVERRIDE_WGRAD"] = str(value[2])
+ else:
+ current_env[f"{prefix}{arg.upper()}"] = str(getattr(args, arg))
+ return current_env
+
+
+def prepare_simple_launcher_cmd_env(args: argparse.Namespace) -> tuple[list[str], dict[str, str]]:
+ """
+ Prepares and returns the command list and an environment with the correct simple launcher environment variables.
+ """
+ cmd = []
+ if args.no_python and args.module:
+ raise ValueError("--module and --no_python cannot be used together")
+
+ num_processes = getattr(args, "num_processes", None)
+ num_machines = args.num_machines
+ if args.mpirun_hostfile is not None:
+ mpi_app_name, hostfile_arg, num_proc_arg, proc_per_node_arg, bind_to_arg = _get_mpirun_args()
+ bind_to = getattr(args, "bind-to", "socket")
+ nproc_per_node = str(num_processes // num_machines) if num_processes and num_machines else "1"
+ cmd += [
+ mpi_app_name,
+ hostfile_arg,
+ args.mpirun_hostfile,
+ proc_per_node_arg,
+ nproc_per_node,
+ ]
+ if num_processes:
+ cmd += [num_proc_arg, str(num_processes)]
+ if bind_to_arg:
+ cmd += [bind_to_arg, bind_to]
+ if not args.no_python:
+ cmd.append(sys.executable)
+ if args.module:
+ cmd.append("-m")
+ cmd.append(args.training_script)
+ cmd.extend(args.training_script_args)
+
+ current_env = os.environ.copy()
+ current_env["ACCELERATE_USE_CPU"] = str(args.cpu or args.use_cpu)
+ if args.debug:
+ current_env["ACCELERATE_DEBUG_MODE"] = "true"
+ if args.gpu_ids != "all" and args.gpu_ids is not None:
+ if is_xpu_available():
+ current_env["ZE_AFFINITY_MASK"] = args.gpu_ids
+ elif is_mlu_available():
+ current_env["MLU_VISIBLE_DEVICES"] = args.gpu_ids
+ elif is_sdaa_available():
+ current_env["SDAA_VISIBLE_DEVICES"] = args.gpu_ids
+ elif is_musa_available():
+ current_env["MUSA_VISIBLE_DEVICES"] = args.gpu_ids
+ elif is_npu_available():
+ current_env["ASCEND_RT_VISIBLE_DEVICES"] = args.gpu_ids
+ elif is_hpu_available():
+ current_env["HABANA_VISIBLE_MODULES"] = args.gpu_ids
+ else:
+ current_env["CUDA_VISIBLE_DEVICES"] = args.gpu_ids
+ if num_machines > 1:
+ assert args.main_process_ip is not None, (
+ "When using multiple machines, you need to specify the main process IP."
+ )
+ assert args.main_process_port is not None, (
+ "When using multiple machines, you need to specify the main process port."
+ )
+
+ ccl_worker_count = getattr(args, "mpirun_ccl", 0) if is_ccl_available() else 0
+ if (num_processes is not None and num_processes > 1) or num_machines > 1:
+ current_env["MASTER_ADDR"] = args.main_process_ip if args.main_process_ip is not None else "127.0.0.1"
+ current_env["MASTER_PORT"] = str(args.main_process_port) if args.main_process_port is not None else "29500"
+ current_env["CCL_WORKER_COUNT"] = str(ccl_worker_count)
+ if current_env["ACCELERATE_USE_CPU"]:
+ current_env["KMP_AFFINITY"] = "granularity=fine,compact,1,0"
+ current_env["KMP_BLOCKTIME"] = str(1)
+
+ try:
+ mixed_precision = PrecisionType(args.mixed_precision.lower())
+ except ValueError:
+ raise ValueError(
+ f"Unknown mixed_precision mode: {args.mixed_precision.lower()}. Choose between {PrecisionType.list()}."
+ )
+
+ current_env["ACCELERATE_MIXED_PRECISION"] = str(mixed_precision)
+ if args.mixed_precision.lower() == "fp8":
+ if not is_fp8_available():
+ raise RuntimeError(
+ "FP8 is not available on this machine. Please ensure that either Transformer Engine, MSAMP or torchao is installed."
+ )
+ current_env = setup_fp8_env(args, current_env)
+
+ try:
+ dynamo_backend = DynamoBackend(args.dynamo_backend.upper())
+ except ValueError:
+ raise ValueError(
+ f"Unknown dynamo backend: {args.dynamo_backend.upper()}. Choose between {DynamoBackend.list()}."
+ )
+ current_env["ACCELERATE_DYNAMO_BACKEND"] = dynamo_backend.value
+ current_env["ACCELERATE_DYNAMO_MODE"] = args.dynamo_mode
+ current_env["ACCELERATE_DYNAMO_USE_FULLGRAPH"] = str(args.dynamo_use_fullgraph)
+ current_env["ACCELERATE_DYNAMO_USE_DYNAMIC"] = str(args.dynamo_use_dynamic)
+ current_env["ACCELERATE_DYNAMO_USE_REGIONAL_COMPILATION"] = str(args.dynamo_use_regional_compilation)
+
+ current_env["OMP_NUM_THREADS"] = str(args.num_cpu_threads_per_process)
+ if is_ipex_available():
+ current_env["ACCELERATE_USE_IPEX"] = str(args.ipex).lower()
+ if args.enable_cpu_affinity:
+ current_env["ACCELERATE_CPU_AFFINITY"] = "1"
+ return cmd, current_env
+
+
+def prepare_multi_gpu_env(args: argparse.Namespace) -> dict[str, str]:
+ """
+ Prepares and returns an environment with the correct multi-GPU environment variables.
+ """
+ # get free port and update configurations
+ if args.main_process_port == 0:
+ args.main_process_port = get_free_port()
+
+ elif args.main_process_port is None:
+ args.main_process_port = 29500
+
+ num_processes = args.num_processes
+ num_machines = args.num_machines
+ main_process_ip = args.main_process_ip
+ main_process_port = args.main_process_port
+ if num_machines > 1:
+ args.nproc_per_node = str(num_processes // num_machines)
+ args.nnodes = str(num_machines)
+ args.node_rank = int(args.machine_rank)
+ if getattr(args, "same_network", False):
+ args.master_addr = str(main_process_ip)
+ args.master_port = str(main_process_port)
+ else:
+ args.rdzv_endpoint = f"{main_process_ip}:{main_process_port}"
+ else:
+ args.nproc_per_node = str(num_processes)
+ if main_process_port is not None:
+ args.master_port = str(main_process_port)
+
+ # only need to check port availability in main process, in case we have to start multiple launchers on the same machine
+ # for some reasons like splitting log files.
+ need_port_check = num_machines <= 1 or int(args.machine_rank) == 0
+ if need_port_check and is_port_in_use(main_process_port):
+ if num_machines <= 1:
+ args.standalone = True
+ warnings.warn(
+ f"Port `{main_process_port}` is already in use. "
+ "Accelerate will attempt to launch in a standalone-like mode by finding an open port automatically for this session. "
+ "If this current attempt fails, or for more control in future runs, please specify a different port "
+ "(e.g., `--main_process_port `) or use `--main_process_port 0` for automatic selection "
+ "in your launch command or Accelerate config file."
+ )
+ else:
+ raise ConnectionError(
+ f"Tried to launch distributed communication on port `{main_process_port}`, but another process is utilizing it. "
+ "Please specify a different port (such as using the `--main_process_port` flag or specifying a different `main_process_port` in your config file)"
+ " and rerun your script. To automatically use the next open port (on a single node), you can set this to `0`."
+ )
+
+ if args.module and args.no_python:
+ raise ValueError("--module and --no_python cannot be used together")
+ elif args.module:
+ args.module = True
+ elif args.no_python:
+ args.no_python = True
+
+ current_env = os.environ.copy()
+ if args.debug:
+ current_env["ACCELERATE_DEBUG_MODE"] = "true"
+ gpu_ids = getattr(args, "gpu_ids", "all")
+ if gpu_ids != "all" and args.gpu_ids is not None:
+ if is_xpu_available():
+ current_env["ZE_AFFINITY_MASK"] = gpu_ids
+ elif is_mlu_available():
+ current_env["MLU_VISIBLE_DEVICES"] = gpu_ids
+ elif is_sdaa_available():
+ current_env["SDAA_VISIBLE_DEVICES"] = gpu_ids
+ elif is_musa_available():
+ current_env["MUSA_VISIBLE_DEVICES"] = gpu_ids
+ elif is_npu_available():
+ current_env["ASCEND_RT_VISIBLE_DEVICES"] = gpu_ids
+ elif is_hpu_available():
+ current_env["HABANA_VISIBLE_MODULES"] = gpu_ids
+ else:
+ current_env["CUDA_VISIBLE_DEVICES"] = gpu_ids
+ mixed_precision = args.mixed_precision.lower()
+ try:
+ mixed_precision = PrecisionType(mixed_precision)
+ except ValueError:
+ raise ValueError(f"Unknown mixed_precision mode: {mixed_precision}. Choose between {PrecisionType.list()}.")
+
+ current_env["ACCELERATE_MIXED_PRECISION"] = str(mixed_precision)
+ if args.mixed_precision.lower() == "fp8":
+ if not is_fp8_available():
+ raise RuntimeError(
+ "FP8 is not available on this machine. Please ensure that either Transformer Engine, MSAMP or torchao is installed."
+ )
+ current_env = setup_fp8_env(args, current_env)
+
+ try:
+ dynamo_backend = DynamoBackend(args.dynamo_backend.upper())
+ except ValueError:
+ raise ValueError(
+ f"Unknown dynamo backend: {args.dynamo_backend.upper()}. Choose between {DynamoBackend.list()}."
+ )
+ current_env["ACCELERATE_DYNAMO_BACKEND"] = dynamo_backend.value
+ current_env["ACCELERATE_DYNAMO_MODE"] = args.dynamo_mode
+ current_env["ACCELERATE_DYNAMO_USE_FULLGRAPH"] = str(args.dynamo_use_fullgraph)
+ current_env["ACCELERATE_DYNAMO_USE_DYNAMIC"] = str(args.dynamo_use_dynamic)
+ current_env["ACCELERATE_DYNAMO_USE_REGIONAL_COMPILATION"] = str(args.dynamo_use_regional_compilation)
+
+ if args.use_fsdp:
+ current_env["ACCELERATE_USE_FSDP"] = "true"
+ if args.fsdp_cpu_ram_efficient_loading and not args.fsdp_sync_module_states:
+ raise ValueError("When using `--fsdp_cpu_ram_efficient_loading` set `--fsdp_sync_module_states` to `True`")
+
+ current_env["FSDP_VERSION"] = str(args.fsdp_version) if hasattr(args, "fsdp_version") else "1"
+
+ # For backwards compatibility, we support this in launched scripts,
+ # however, we do not ask users for this in `accelerate config` CLI
+ current_env["FSDP_SHARDING_STRATEGY"] = str(args.fsdp_sharding_strategy)
+
+ current_env["FSDP_RESHARD_AFTER_FORWARD"] = str(args.fsdp_reshard_after_forward).lower()
+ current_env["FSDP_OFFLOAD_PARAMS"] = str(args.fsdp_offload_params).lower()
+ current_env["FSDP_MIN_NUM_PARAMS"] = str(args.fsdp_min_num_params)
+ if args.fsdp_auto_wrap_policy is not None:
+ current_env["FSDP_AUTO_WRAP_POLICY"] = str(args.fsdp_auto_wrap_policy)
+ if args.fsdp_transformer_layer_cls_to_wrap is not None:
+ current_env["FSDP_TRANSFORMER_CLS_TO_WRAP"] = str(args.fsdp_transformer_layer_cls_to_wrap)
+ if args.fsdp_backward_prefetch is not None:
+ current_env["FSDP_BACKWARD_PREFETCH"] = str(args.fsdp_backward_prefetch)
+ if args.fsdp_state_dict_type is not None:
+ current_env["FSDP_STATE_DICT_TYPE"] = str(args.fsdp_state_dict_type)
+ current_env["FSDP_FORWARD_PREFETCH"] = str(args.fsdp_forward_prefetch).lower()
+ current_env["FSDP_USE_ORIG_PARAMS"] = str(args.fsdp_use_orig_params).lower()
+ current_env["FSDP_CPU_RAM_EFFICIENT_LOADING"] = str(args.fsdp_cpu_ram_efficient_loading).lower()
+ current_env["FSDP_SYNC_MODULE_STATES"] = str(args.fsdp_sync_module_states).lower()
+ current_env["FSDP_ACTIVATION_CHECKPOINTING"] = str(args.fsdp_activation_checkpointing).lower()
+ if getattr(args, "fsdp_ignored_modules", None) is not None:
+ current_env["FSDP_IGNORED_MODULES"] = str(args.fsdp_ignored_modules)
+
+ if args.use_megatron_lm:
+ prefix = "MEGATRON_LM_"
+ current_env["ACCELERATE_USE_MEGATRON_LM"] = "true"
+ current_env[prefix + "TP_DEGREE"] = str(args.megatron_lm_tp_degree)
+ current_env[prefix + "PP_DEGREE"] = str(args.megatron_lm_pp_degree)
+ current_env[prefix + "GRADIENT_CLIPPING"] = str(args.megatron_lm_gradient_clipping)
+ if args.megatron_lm_num_micro_batches is not None:
+ current_env[prefix + "NUM_MICRO_BATCHES"] = str(args.megatron_lm_num_micro_batches)
+ if args.megatron_lm_sequence_parallelism is not None:
+ current_env[prefix + "SEQUENCE_PARALLELISM"] = str(args.megatron_lm_sequence_parallelism)
+ if args.megatron_lm_recompute_activations is not None:
+ current_env[prefix + "RECOMPUTE_ACTIVATIONS"] = str(args.megatron_lm_recompute_activations)
+ if args.megatron_lm_use_distributed_optimizer is not None:
+ current_env[prefix + "USE_DISTRIBUTED_OPTIMIZER"] = str(args.megatron_lm_use_distributed_optimizer)
+
+ current_env["OMP_NUM_THREADS"] = str(args.num_cpu_threads_per_process)
+ if args.enable_cpu_affinity:
+ current_env["ACCELERATE_CPU_AFFINITY"] = "1"
+
+ if args.use_parallelism_config:
+ current_env = prepare_extend_env_parallelism_config(args, current_env)
+
+ return current_env
+
+
+def prepare_extend_env_parallelism_config(
+ args: argparse.Namespace, current_env: dict
+) -> tuple[list[str], dict[str, str]]:
+ """
+ Extends `current_env` with context parallelism env vars if any have been set
+ """
+
+ prefix = "PARALLELISM_CONFIG_"
+
+ current_env["ACCELERATE_USE_PARALLELISM_CONFIG"] = "true"
+ current_env[prefix + "DP_REPLICATE_SIZE"] = str(args.parallelism_config_dp_replicate_size)
+ current_env[prefix + "DP_SHARD_SIZE"] = str(args.parallelism_config_dp_shard_size)
+ current_env[prefix + "TP_SIZE"] = str(args.parallelism_config_tp_size)
+ current_env[prefix + "CP_SIZE"] = str(args.parallelism_config_cp_size)
+ current_env[prefix + "CP_BACKEND"] = str(args.parallelism_config_cp_backend)
+ current_env[prefix + "SP_SIZE"] = str(args.parallelism_config_sp_size)
+ current_env[prefix + "SP_BACKEND"] = str(args.parallelism_config_sp_backend)
+ if args.parallelism_config_cp_size > 1:
+ current_env[prefix + "CP_COMM_STRATEGY"] = str(args.parallelism_config_cp_comm_strategy)
+ if args.parallelism_config_sp_size > 1:
+ current_env[prefix + "SP_SEQ_LENGTH"] = str(args.parallelism_config_sp_seq_length)
+ current_env[prefix + "SP_SEQ_LENGTH_IS_VARIABLE"] = str(args.parallelism_config_sp_seq_length_is_variable)
+ current_env[prefix + "SP_ATTN_IMPLEMENTATION"] = str(args.parallelism_config_sp_attn_implementation)
+
+ return current_env
+
+
+def prepare_deepspeed_cmd_env(args: argparse.Namespace) -> tuple[list[str], dict[str, str]]:
+ """
+ Prepares and returns the command list and an environment with the correct DeepSpeed environment variables.
+ """
+ # get free port and update configurations
+ if args.main_process_port == 0:
+ args.main_process_port = get_free_port()
+
+ elif args.main_process_port is None:
+ args.main_process_port = 29500
+
+ num_processes = args.num_processes
+ num_machines = args.num_machines
+ main_process_ip = args.main_process_ip
+ main_process_port = args.main_process_port
+ cmd = None
+
+ # make sure launcher is not None
+ if args.deepspeed_multinode_launcher is None:
+ # set to default pdsh
+ args.deepspeed_multinode_launcher = DEEPSPEED_MULTINODE_LAUNCHERS[0]
+
+ if num_machines > 1 and args.deepspeed_multinode_launcher != DEEPSPEED_MULTINODE_LAUNCHERS[1]:
+ cmd = ["deepspeed"]
+ cmd.extend(["--hostfile", str(args.deepspeed_hostfile)])
+ if args.deepspeed_multinode_launcher == "nossh":
+ if compare_versions("deepspeed", "<", "0.14.5"):
+ raise ValueError("nossh launcher requires DeepSpeed >= 0.14.5")
+ cmd.extend(["--node_rank", str(args.machine_rank), "--no_ssh"])
+ else:
+ cmd.extend(["--no_local_rank", "--launcher", str(args.deepspeed_multinode_launcher)])
+ if args.deepspeed_exclusion_filter is not None:
+ cmd.extend(
+ [
+ "--exclude",
+ str(args.deepspeed_exclusion_filter),
+ ]
+ )
+ elif args.deepspeed_inclusion_filter is not None:
+ cmd.extend(
+ [
+ "--include",
+ str(args.deepspeed_inclusion_filter),
+ ]
+ )
+ else:
+ cmd.extend(["--num_gpus", str(args.num_processes // args.num_machines)])
+ if main_process_ip:
+ cmd.extend(["--master_addr", str(main_process_ip)])
+ cmd.extend(["--master_port", str(main_process_port)])
+ if args.module and args.no_python:
+ raise ValueError("--module and --no_python cannot be used together")
+ elif args.module:
+ cmd.append("--module")
+ elif args.no_python:
+ cmd.append("--no_python")
+ cmd.append(args.training_script)
+ cmd.extend(args.training_script_args)
+ elif num_machines > 1 and args.deepspeed_multinode_launcher == DEEPSPEED_MULTINODE_LAUNCHERS[1]:
+ args.nproc_per_node = str(num_processes // num_machines)
+ args.nnodes = str(num_machines)
+ args.node_rank = int(args.machine_rank)
+ if getattr(args, "same_network", False):
+ args.master_addr = str(main_process_ip)
+ args.master_port = str(main_process_port)
+ else:
+ args.rdzv_endpoint = f"{main_process_ip}:{main_process_port}"
+ else:
+ args.nproc_per_node = str(num_processes)
+ if main_process_port is not None:
+ args.master_port = str(main_process_port)
+
+ # only need to check port availability in main process, in case we have to start multiple launchers on the same machine
+ # for some reasons like splitting log files.
+ need_port_check = num_machines <= 1 or int(args.machine_rank) == 0
+ if need_port_check and is_port_in_use(main_process_port):
+ if num_machines <= 1:
+ args.standalone = True
+ warnings.warn(
+ f"Port `{main_process_port}` is already in use. "
+ "Accelerate will attempt to launch in a standalone-like mode by finding an open port automatically for this session. "
+ "If this current attempt fails, or for more control in future runs, please specify a different port "
+ "(e.g., `--main_process_port `) or use `--main_process_port 0` for automatic selection "
+ "in your launch command or Accelerate config file."
+ )
+ else:
+ raise ConnectionError(
+ f"Tried to launch distributed communication on port `{main_process_port}`, but another process is utilizing it. "
+ "Please specify a different port (such as using the `--main_process_port` flag or specifying a different `main_process_port` in your config file)"
+ " and rerun your script. To automatically use the next open port (on a single node), you can set this to `0`."
+ )
+
+ if args.module and args.no_python:
+ raise ValueError("--module and --no_python cannot be used together")
+ elif args.module:
+ args.module = True
+ elif args.no_python:
+ args.no_python = True
+
+ current_env = os.environ.copy()
+ if args.debug:
+ current_env["ACCELERATE_DEBUG_MODE"] = "true"
+ gpu_ids = getattr(args, "gpu_ids", "all")
+ if gpu_ids != "all" and args.gpu_ids is not None:
+ if is_xpu_available():
+ current_env["ZE_AFFINITY_MASK"] = gpu_ids
+ elif is_mlu_available():
+ current_env["MLU_VISIBLE_DEVICES"] = gpu_ids
+ elif is_sdaa_available():
+ current_env["SDAA_VISIBLE_DEVICES"] = gpu_ids
+ elif is_musa_available():
+ current_env["MUSA_VISIBLE_DEVICES"] = gpu_ids
+ elif is_npu_available():
+ current_env["ASCEND_RT_VISIBLE_DEVICES"] = gpu_ids
+ elif is_hpu_available():
+ current_env["HABANA_VISIBLE_MODULES"] = gpu_ids
+ else:
+ current_env["CUDA_VISIBLE_DEVICES"] = gpu_ids
+ try:
+ mixed_precision = PrecisionType(args.mixed_precision.lower())
+ except ValueError:
+ raise ValueError(
+ f"Unknown mixed_precision mode: {args.mixed_precision.lower()}. Choose between {PrecisionType.list()}."
+ )
+
+ current_env["PYTHONPATH"] = env_var_path_add("PYTHONPATH", os.path.abspath("."))
+ current_env["ACCELERATE_MIXED_PRECISION"] = str(mixed_precision)
+ if args.mixed_precision.lower() == "fp8":
+ if not is_fp8_available():
+ raise RuntimeError(
+ "FP8 is not available on this machine. Please ensure that either Transformer Engine, MSAMP or torchao is installed."
+ )
+ current_env = setup_fp8_env(args, current_env)
+ current_env["ACCELERATE_CONFIG_DS_FIELDS"] = str(args.deepspeed_fields_from_accelerate_config).lower()
+ current_env["ACCELERATE_USE_DEEPSPEED"] = "true"
+ if args.zero_stage is not None:
+ current_env["ACCELERATE_DEEPSPEED_ZERO_STAGE"] = str(args.zero_stage)
+ if args.gradient_accumulation_steps is not None:
+ current_env["ACCELERATE_GRADIENT_ACCUMULATION_STEPS"] = str(args.gradient_accumulation_steps)
+ if args.gradient_clipping is not None:
+ current_env["ACCELERATE_GRADIENT_CLIPPING"] = str(args.gradient_clipping).lower()
+ if args.offload_optimizer_device is not None:
+ current_env["ACCELERATE_DEEPSPEED_OFFLOAD_OPTIMIZER_DEVICE"] = str(args.offload_optimizer_device).lower()
+ if args.offload_param_device is not None:
+ current_env["ACCELERATE_DEEPSPEED_OFFLOAD_PARAM_DEVICE"] = str(args.offload_param_device).lower()
+ if args.zero3_init_flag is not None:
+ current_env["ACCELERATE_DEEPSPEED_ZERO3_INIT"] = str(args.zero3_init_flag).lower()
+ if args.zero3_save_16bit_model is not None:
+ current_env["ACCELERATE_DEEPSPEED_ZERO3_SAVE_16BIT_MODEL"] = str(args.zero3_save_16bit_model).lower()
+ if args.deepspeed_config_file is not None:
+ current_env["ACCELERATE_DEEPSPEED_CONFIG_FILE"] = str(args.deepspeed_config_file)
+ if args.enable_cpu_affinity:
+ current_env["ACCELERATE_CPU_AFFINITY"] = "1"
+ if args.deepspeed_moe_layer_cls_names is not None:
+ current_env["ACCELERATE_DEEPSPEED_MOE_LAYER_CLS_NAMES"] = str(args.deepspeed_moe_layer_cls_names)
+
+ if args.use_parallelism_config:
+ current_env = prepare_extend_env_parallelism_config(args, current_env)
+
+ return cmd, current_env
+
+
+def prepare_tpu(
+ args: argparse.Namespace, current_env: dict[str, str], pod: bool = False
+) -> tuple[argparse.Namespace, dict[str, str]]:
+ """
+ Prepares and returns an environment with the correct TPU environment variables.
+ """
+ if args.mixed_precision == "bf16" and is_torch_xla_available(check_is_tpu=True):
+ if args.downcast_bf16:
+ current_env["XLA_DOWNCAST_BF16"] = "1"
+ else:
+ current_env["XLA_USE_BF16"] = "1"
+ if args.debug:
+ current_env["ACCELERATE_DEBUG_MODE"] = "true"
+ if pod:
+ # Take explicit args and set them up for XLA
+ args.vm = args.tpu_vm
+ args.tpu = args.tpu_name
+ return args, current_env
+
+
+def _convert_nargs_to_dict(nargs: list[str]) -> dict[str, str]:
+ if len(nargs) < 0:
+ return {}
+ # helper function to infer type for argsparser
+
+ def _infer_type(s):
+ try:
+ s = float(s)
+
+ if s // 1 == s:
+ return int(s)
+ return s
+ except ValueError:
+ return s
+
+ parser = argparse.ArgumentParser()
+ _, unknown = parser.parse_known_args(nargs)
+ for index, argument in enumerate(unknown):
+ if argument.startswith(("-", "--")):
+ action = None
+ if index + 1 < len(unknown): # checks if next index would be in list
+ if unknown[index + 1].startswith(("-", "--")): # checks if next element is an key
+ # raise an error if element is store_true or store_false
+ raise ValueError(
+ "SageMaker doesn’t support argparse actions for `store_true` or `store_false`. Please define explicit types"
+ )
+ else: # raise an error if last element is store_true or store_false
+ raise ValueError(
+ "SageMaker doesn’t support argparse actions for `store_true` or `store_false`. Please define explicit types"
+ )
+ # adds argument to parser based on action_store true
+ if action is None:
+ parser.add_argument(argument, type=_infer_type)
+ else:
+ parser.add_argument(argument, action=action)
+
+ return {
+ key: (literal_eval(value) if value in ("True", "False") else value)
+ for key, value in parser.parse_args(nargs).__dict__.items()
+ }
+
+
+def prepare_sagemager_args_inputs(
+ sagemaker_config: SageMakerConfig, args: argparse.Namespace
+) -> tuple[argparse.Namespace, dict[str, Any]]:
+ # configure environment
+ print("Configuring Amazon SageMaker environment")
+ os.environ["AWS_DEFAULT_REGION"] = sagemaker_config.region
+
+ # configure credentials
+ if sagemaker_config.profile is not None:
+ os.environ["AWS_PROFILE"] = sagemaker_config.profile
+ elif args.aws_access_key_id is not None and args.aws_secret_access_key is not None:
+ os.environ["AWS_ACCESS_KEY_ID"] = args.aws_access_key_id
+ os.environ["AWS_SECRET_ACCESS_KEY"] = args.aws_secret_access_key
+ else:
+ raise OSError("You need to provide an aws_access_key_id and aws_secret_access_key when not using aws_profile")
+
+ # extract needed arguments
+ source_dir = os.path.dirname(args.training_script)
+ if not source_dir: # checks if string is empty
+ source_dir = "."
+ entry_point = os.path.basename(args.training_script)
+ if not entry_point.endswith(".py"):
+ raise ValueError(f'Your training script should be a python script and not "{entry_point}"')
+
+ print("Converting Arguments to Hyperparameters")
+ hyperparameters = _convert_nargs_to_dict(args.training_script_args)
+
+ try:
+ mixed_precision = PrecisionType(args.mixed_precision.lower())
+ except ValueError:
+ raise ValueError(
+ f"Unknown mixed_precision mode: {args.mixed_precision.lower()}. Choose between {PrecisionType.list()}."
+ )
+
+ try:
+ dynamo_backend = DynamoBackend(args.dynamo_backend.upper())
+ except ValueError:
+ raise ValueError(
+ f"Unknown dynamo backend: {args.dynamo_backend.upper()}. Choose between {DynamoBackend.list()}."
+ )
+
+ # Environment variables to be set for use during training job
+ environment = {
+ "ACCELERATE_USE_SAGEMAKER": "true",
+ "ACCELERATE_MIXED_PRECISION": str(mixed_precision),
+ "ACCELERATE_DYNAMO_BACKEND": dynamo_backend.value,
+ "ACCELERATE_DYNAMO_MODE": args.dynamo_mode,
+ "ACCELERATE_DYNAMO_USE_FULLGRAPH": str(args.dynamo_use_fullgraph),
+ "ACCELERATE_DYNAMO_USE_DYNAMIC": str(args.dynamo_use_dynamic),
+ "ACCELERATE_DYNAMO_USE_REGIONAL_COMPILATION": str(args.dynamo_use_regional_compilation),
+ "ACCELERATE_SAGEMAKER_DISTRIBUTED_TYPE": sagemaker_config.distributed_type.value,
+ }
+ if args.mixed_precision.lower() == "fp8":
+ if not is_fp8_available():
+ raise RuntimeError(
+ "FP8 is not available on this machine. Please ensure that either Transformer Engine, MSAMP or torchao is installed."
+ )
+ environment = setup_fp8_env(args, environment)
+ # configure distribution set up
+ distribution = None
+ if sagemaker_config.distributed_type == SageMakerDistributedType.DATA_PARALLEL:
+ distribution = {"smdistributed": {"dataparallel": {"enabled": True}}}
+
+ # configure sagemaker inputs
+ sagemaker_inputs = None
+ if sagemaker_config.sagemaker_inputs_file is not None:
+ print(f"Loading SageMaker Inputs from {sagemaker_config.sagemaker_inputs_file} file")
+ sagemaker_inputs = {}
+ with open(sagemaker_config.sagemaker_inputs_file) as file:
+ for i, line in enumerate(file):
+ if i == 0:
+ continue
+ l = line.split("\t")
+ sagemaker_inputs[l[0]] = l[1].strip()
+ print(f"Loaded SageMaker Inputs: {sagemaker_inputs}")
+
+ # configure sagemaker metrics
+ sagemaker_metrics = None
+ if sagemaker_config.sagemaker_metrics_file is not None:
+ print(f"Loading SageMaker Metrics from {sagemaker_config.sagemaker_metrics_file} file")
+ sagemaker_metrics = []
+ with open(sagemaker_config.sagemaker_metrics_file) as file:
+ for i, line in enumerate(file):
+ if i == 0:
+ continue
+ l = line.split("\t")
+ metric_dict = {
+ "Name": l[0],
+ "Regex": l[1].strip(),
+ }
+ sagemaker_metrics.append(metric_dict)
+ print(f"Loaded SageMaker Metrics: {sagemaker_metrics}")
+
+ # configure session
+ print("Creating Estimator")
+ args = {
+ "image_uri": sagemaker_config.image_uri,
+ "entry_point": entry_point,
+ "source_dir": source_dir,
+ "role": sagemaker_config.iam_role_name,
+ "transformers_version": sagemaker_config.transformers_version,
+ "pytorch_version": sagemaker_config.pytorch_version,
+ "py_version": sagemaker_config.py_version,
+ "base_job_name": sagemaker_config.base_job_name,
+ "instance_count": sagemaker_config.num_machines,
+ "instance_type": sagemaker_config.ec2_instance_type,
+ "debugger_hook_config": False,
+ "distribution": distribution,
+ "hyperparameters": hyperparameters,
+ "environment": environment,
+ "metric_definitions": sagemaker_metrics,
+ }
+
+ if sagemaker_config.additional_args is not None:
+ args = merge_dicts(sagemaker_config.additional_args, args)
+ return args, sagemaker_inputs
+
+
+def env_var_path_add(env_var_name, path_to_add):
+ """
+ Extends a path-based environment variable's value with a new path and returns the updated value. It's up to the
+ caller to set it in os.environ.
+ """
+ paths = [p for p in os.environ.get(env_var_name, "").split(":") if len(p) > 0]
+ paths.append(str(path_to_add))
+ return ":".join(paths)
+
+
+class PrepareForLaunch:
+ """
+ Prepare a function that will launched in a distributed setup.
+
+ Args:
+ launcher (`Callable`):
+ The function to launch.
+ distributed_type ([`~state.DistributedType`]):
+ The distributed type to prepare for.
+ debug (`bool`, *optional*, defaults to `False`):
+ Whether or not this is a debug launch.
+ """
+
+ def __init__(self, launcher, distributed_type="NO", debug=False):
+ self.launcher = launcher
+ self.distributed_type = DistributedType(distributed_type)
+ self.debug = debug
+
+ def __call__(self, index, *args):
+ if self.debug:
+ world_size = int(os.environ.get("WORLD_SIZE"))
+ rdv_file = os.environ.get("ACCELERATE_DEBUG_RDV_FILE")
+ torch.distributed.init_process_group(
+ "gloo",
+ rank=index,
+ store=torch.distributed.FileStore(rdv_file, world_size),
+ world_size=world_size,
+ )
+ elif self.distributed_type in (
+ DistributedType.MULTI_GPU,
+ DistributedType.MULTI_MLU,
+ DistributedType.MULTI_MUSA,
+ DistributedType.MULTI_NPU,
+ DistributedType.MULTI_XPU,
+ DistributedType.MULTI_CPU,
+ ):
+ # Prepare the environment for torch.distributed
+ os.environ["LOCAL_RANK"] = str(index)
+ nproc = int(os.environ.get("NPROC", 1))
+ node_rank = int(os.environ.get("NODE_RANK", 0))
+ os.environ["RANK"] = str(nproc * node_rank + index)
+
+ os.environ["FORK_LAUNCHED"] = str(1)
+ self.launcher(*args)
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/megatron_lm.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/megatron_lm.py
new file mode 100644
index 0000000000000000000000000000000000000000..e3754098801102d67b98cebae5bf18b2fd6129d2
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/megatron_lm.py
@@ -0,0 +1,1424 @@
+# Copyright 2022 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import argparse
+import math
+import os
+from abc import ABC
+from functools import partial
+
+import torch
+import torch.nn.functional as F
+from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss
+from torch.nn.parallel.distributed import DistributedDataParallel as torchDDP
+
+from ..optimizer import AcceleratedOptimizer
+from ..scheduler import AcceleratedScheduler
+from .imports import is_megatron_lm_available
+from .operations import recursively_apply, send_to_device
+
+
+if is_megatron_lm_available():
+ from megatron.core import mpu, tensor_parallel
+ from megatron.core.distributed import DistributedDataParallel as LocalDDP
+ from megatron.core.distributed import finalize_model_grads
+ from megatron.core.enums import ModelType
+ from megatron.core.num_microbatches_calculator import get_num_microbatches
+ from megatron.core.optimizer import get_megatron_optimizer
+ from megatron.core.parallel_state import get_tensor_model_parallel_group, get_tensor_model_parallel_src_rank
+ from megatron.core.pipeline_parallel import get_forward_backward_func
+ from megatron.core.utils import get_model_config
+ from megatron.inference.text_generation.communication import broadcast_int_list, broadcast_tensor
+ from megatron.inference.text_generation.generation import (
+ beam_search_and_return_on_first_stage,
+ generate_tokens_probs_and_return_on_first_stage,
+ )
+ from megatron.legacy.data.dataset_utils import build_train_valid_test_datasets
+ from megatron.legacy.model import BertModel, Float16Module, GPTModel, T5Model
+ from megatron.legacy.model.classification import Classification
+ from megatron.training import (
+ get_args,
+ get_tensorboard_writer,
+ get_tokenizer,
+ print_rank_last,
+ )
+ from megatron.training.arguments import (
+ _add_data_args,
+ _add_validation_args,
+ core_transformer_config_from_args,
+ parse_args,
+ validate_args,
+ )
+ from megatron.training.checkpointing import load_args_from_checkpoint, load_checkpoint, save_checkpoint
+ from megatron.training.global_vars import set_global_variables
+ from megatron.training.initialize import (
+ _compile_dependencies,
+ _init_autoresume,
+ _initialize_distributed,
+ _set_random_seed,
+ set_jit_fusion_options,
+ write_args_to_tensorboard,
+ )
+ from megatron.training.tokenizer.tokenizer import _vocab_size_with_padding
+ from megatron.training.training import (
+ build_train_valid_test_data_iterators,
+ get_optimizer_param_scheduler,
+ num_floating_point_operations,
+ setup_model_and_optimizer,
+ train_step,
+ training_log,
+ )
+ from megatron.training.utils import (
+ average_losses_across_data_parallel_group,
+ calc_params_l2_norm,
+ get_ltor_masks_and_position_ids,
+ unwrap_model,
+ )
+
+
+# model utilities
+def model_provider_func(pre_process=True, post_process=True, add_encoder=True, add_decoder=True):
+ """Build the model."""
+ args = get_args()
+ mode = "pre-training" if args.pretraining_flag else "fine-tuning"
+ if args.rank == 0:
+ print(f"Building {args.model_type_name} model in the {mode} mode.")
+ print(
+ "The Megatron LM model weights are initialized at random in `accelerator.prepare`. "
+ "Please use `accelerator.load_checkpoint` to load a pre-trained checkpoint matching the distributed setup."
+ )
+ config = core_transformer_config_from_args(args)
+ if args.model_type_name == "bert":
+ if args.pretraining_flag:
+ num_tokentypes = 2 if args.bert_binary_head else 0
+ model = BertModel(
+ config=config,
+ num_tokentypes=num_tokentypes,
+ add_binary_head=args.bert_binary_head,
+ parallel_output=True,
+ pre_process=pre_process,
+ post_process=post_process,
+ )
+ else:
+ model = Classification(
+ config=config,
+ num_classes=args.num_labels,
+ num_tokentypes=2,
+ pre_process=pre_process,
+ post_process=post_process,
+ )
+ elif args.model_type_name == "gpt":
+ model = GPTModel(
+ config=config,
+ num_tokentypes=0,
+ parallel_output=True,
+ pre_process=pre_process,
+ post_process=post_process,
+ )
+ elif args.model_type_name == "t5":
+ model = T5Model(
+ config=config,
+ num_tokentypes=0,
+ parallel_output=True,
+ pre_process=pre_process,
+ post_process=post_process,
+ add_encoder=add_encoder,
+ add_decoder=add_decoder,
+ )
+ else:
+ raise ValueError(f"Unsupported model type: {args.model_type_name}")
+ return model
+
+
+def prepare_model_optimizer_scheduler(accelerator):
+ accelerator.print("Preparing model optimizer scheduler")
+ args = get_args()
+ if accelerator.state.megatron_lm_plugin.custom_prepare_model_function is not None:
+ if accelerator.state.megatron_lm_plugin.custom_model_provider_function is None:
+ raise ValueError(
+ "You must provide a `custom_model_provider_function` when using a `custom_prepare_model_function`."
+ )
+ custom_model_provider_func = accelerator.state.megatron_lm_plugin.custom_model_provider_function
+ model = accelerator.state.megatron_lm_plugin.custom_prepare_model_function(custom_model_provider_func)
+ optimizer = prepare_optimizer(accelerator, model)
+ scheduler = prepare_scheduler(accelerator, optimizer, scheduler=None)
+ else:
+ model_type = ModelType.encoder_or_decoder
+ if args.model_type_name == "t5":
+ model_type = ModelType.encoder_and_decoder
+ model_provider_func_ = model_provider_func
+ if accelerator.state.megatron_lm_plugin.custom_model_provider_function is not None:
+ model_provider_func_ = accelerator.state.megatron_lm_plugin.custom_model_provider_function
+ (model, optimizer, scheduler) = setup_model_and_optimizer(
+ model_provider_func_,
+ model_type,
+ no_wd_decay_cond=args.no_wd_decay_cond,
+ scale_lr_cond=args.scale_lr_cond,
+ lr_mult=args.lr_mult,
+ )
+ args.model_len = len(model)
+ return model, optimizer, scheduler
+
+
+# dataloader utilities
+class MegatronLMDummyDataLoader:
+ """
+ Dummy dataloader presents model parameters or param groups, this is primarily used to follow conventional training
+
+ Args:
+ **dataset_kwargs: Megatron data arguments.
+ """
+
+ def __init__(self, **dataset_kwargs):
+ parser = argparse.ArgumentParser()
+ parser = _add_data_args(parser)
+ parser = _add_validation_args(parser)
+ data_args = parser.parse_known_args()
+ self.dataset_args = vars(data_args[0])
+ self.dataset_args.update(dataset_kwargs)
+ self.dataset_args["megatron_dataset_flag"] = True
+
+ def set_megatron_data_args(self):
+ args = get_args()
+ for key, value in self.dataset_args.items():
+ old_value = getattr(args, key, "")
+ if old_value != value:
+ print(
+ f"WARNING: MegatronLMDummyDataLoader overriding arguments for {key}:{old_value} with {key}:{value}"
+ )
+ setattr(args, key, value)
+
+ def get_train_valid_test_datasets_provider(self, accelerator):
+ def train_valid_test_datasets_provider(train_val_test_num_samples):
+ """Build train, valid, and test datasets."""
+ args = get_args()
+ dataset_args = {
+ "data_prefix": args.data_path if isinstance(args.data_path, (list, tuple)) else [args.data_path],
+ "splits_string": args.split,
+ "train_valid_test_num_samples": train_val_test_num_samples,
+ "seed": args.seed,
+ }
+ if args.model_type_name == "bert":
+ dataset_args.update(
+ {
+ "max_seq_length": args.seq_length,
+ "binary_head": args.bert_binary_head,
+ }
+ )
+ elif args.model_type_name == "gpt":
+ dataset_args.update(
+ {
+ "max_seq_length": args.seq_length,
+ }
+ )
+ elif args.model_type_name == "t5":
+ dataset_args.update(
+ {
+ "max_seq_length": args.encoder_seq_length,
+ "max_seq_length_dec": args.decoder_seq_length,
+ "dataset_type": "t5",
+ }
+ )
+ else:
+ raise ValueError(f"Unsupported model type: {args.model_type_name}")
+ train_ds, valid_ds, test_ds = build_train_valid_test_datasets(**dataset_args)
+ return train_ds, valid_ds, test_ds
+
+ if accelerator.state.megatron_lm_plugin.custom_megatron_datasets_provider_function is not None:
+ return accelerator.state.megatron_lm_plugin.custom_megatron_datasets_provider_function
+ try:
+ args = get_args()
+ # Use '--no-use-pep517 -e' to pip install nvidia's megatron from source
+ if args.model_type_name == "bert":
+ from pretrain_bert import train_valid_test_datasets_provider
+
+ train_valid_test_datasets_provider.is_distributed = True
+ return train_valid_test_datasets_provider
+ elif args.model_type_name == "gpt":
+ from pretrain_gpt import train_valid_test_datasets_provider
+
+ train_valid_test_datasets_provider.is_distributed = True
+ return train_valid_test_datasets_provider
+ elif args.model_type_name == "t5":
+ from pretrain_t5 import train_valid_test_datasets_provider
+
+ train_valid_test_datasets_provider.is_distributed = True
+ return train_valid_test_datasets_provider
+ except ImportError:
+ pass
+ return train_valid_test_datasets_provider
+
+ def build_train_valid_test_data_iterators(self, accelerator):
+ args = get_args()
+
+ train_valid_test_dataset_provider = self.get_train_valid_test_datasets_provider(accelerator)
+ if args.virtual_pipeline_model_parallel_size is not None:
+ train_data_iterator = []
+ valid_data_iterator = []
+ test_data_iterator = []
+ for i in range(getattr(args, "model_len", 0)):
+ mpu.set_virtual_pipeline_model_parallel_rank(i)
+ iterators = build_train_valid_test_data_iterators(train_valid_test_dataset_provider)
+ train_data_iterator.append(iterators[0])
+ valid_data_iterator.append(iterators[1])
+ test_data_iterator.append(iterators[2])
+ else:
+ train_data_iterator, valid_data_iterator, test_data_iterator = build_train_valid_test_data_iterators(
+ train_valid_test_dataset_provider
+ )
+
+ return train_data_iterator, valid_data_iterator, test_data_iterator
+
+
+def _handle_megatron_data_iterator(accelerator, data_iterator):
+ class DummyMegatronDataloader:
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ return {}
+
+ is_data_iterator_empty = data_iterator is None
+ is_src_data_iterator_empty = torch.tensor(is_data_iterator_empty, dtype=torch.bool, device=accelerator.device)
+ torch.distributed.broadcast(
+ is_src_data_iterator_empty, get_tensor_model_parallel_src_rank(), group=get_tensor_model_parallel_group()
+ )
+ if not is_src_data_iterator_empty and is_data_iterator_empty:
+ return DummyMegatronDataloader()
+ return data_iterator
+
+
+def prepare_data_loader(accelerator, dataloader):
+ accelerator.print("Preparing dataloader")
+ args = get_args()
+ if not args.megatron_dataset_flag:
+ from ..data_loader import _PYTORCH_DATALOADER_KWARGS, prepare_data_loader
+
+ micro_batch_size = args.micro_batch_size * args.num_micro_batches
+ kwargs = {k: getattr(dataloader, k, _PYTORCH_DATALOADER_KWARGS[k]) for k in _PYTORCH_DATALOADER_KWARGS}
+ if kwargs["batch_size"] is None:
+ if isinstance(kwargs["sampler"], torch.utils.data.BatchSampler):
+ kwargs["sampler"].batch_size = micro_batch_size
+ else:
+ del kwargs["sampler"]
+ del kwargs["shuffle"]
+ del kwargs["batch_size"]
+ kwargs["batch_sampler"].batch_size = micro_batch_size
+ else:
+ del kwargs["batch_sampler"]
+ kwargs["batch_size"] = micro_batch_size
+
+ dataloader = torch.utils.data.DataLoader(dataloader.dataset, **kwargs)
+ # split_batches:
+ # Megatron only needs to fetch different data between different dp groups,
+ # and does not need to split the data within the dp group.
+ return prepare_data_loader(
+ dataloader,
+ accelerator.device,
+ num_processes=mpu.get_data_parallel_world_size(),
+ process_index=mpu.get_data_parallel_rank(),
+ split_batches=False,
+ put_on_device=True,
+ rng_types=accelerator.rng_types.copy(),
+ dispatch_batches=accelerator.dispatch_batches,
+ )
+ else:
+ if args.consumed_samples is not None:
+ (
+ args.consumed_train_samples,
+ args.consumed_valid_samples,
+ args.consumed_test_samples,
+ ) = args.consumed_samples
+ else:
+ args.consumed_train_samples, args.consumed_valid_samples, args.consumed_test_samples = 0, 0, 0
+ args.micro_batch_size = args.micro_batch_size * args.num_micro_batches
+ # In order to be compatible with data in transform format,
+ # it needs to increase the size of mbs first,
+ # and then split the large batch data into some mbs.
+ (
+ train_data_iterator,
+ valid_data_iterator,
+ test_data_iterator,
+ ) = dataloader.build_train_valid_test_data_iterators(accelerator)
+ args.micro_batch_size = args.micro_batch_size // args.num_micro_batches
+
+ train_data_iterator = _handle_megatron_data_iterator(
+ accelerator=accelerator, data_iterator=train_data_iterator
+ )
+ valid_data_iterator = _handle_megatron_data_iterator(
+ accelerator=accelerator, data_iterator=valid_data_iterator
+ )
+ test_data_iterator = _handle_megatron_data_iterator(accelerator=accelerator, data_iterator=test_data_iterator)
+
+ return train_data_iterator, valid_data_iterator, test_data_iterator
+
+
+# optimizer utilities
+class MegatronLMOptimizerWrapper(AcceleratedOptimizer):
+ def __init__(self, optimizer):
+ super().__init__(optimizer, device_placement=False, scaler=None)
+
+ def zero_grad(self, set_to_none=None):
+ pass # `model(**batch)` is doing that automatically. Therefore, its implementation is not needed
+
+ def step(self):
+ pass # `model(**batch)` is doing that automatically. Therefore, its implementation is not needed
+
+ @property
+ def step_was_skipped(self):
+ """Whether or not the optimizer step was done, or skipped because of gradient overflow."""
+ return self.optimizer.skipped_iter
+
+
+def prepare_optimizer(accelerator, model):
+ accelerator.print("Preparing optimizer")
+ args = get_args()
+ return get_megatron_optimizer(model, args.no_wd_decay_cond, args.scale_lr_cond, args.lr_mult)
+
+
+# scheduler utilities
+class MegatronLMDummyScheduler:
+ """
+ Dummy scheduler presents model parameters or param groups, this is primarily used to follow conventional training
+ loop when scheduler config is specified in the deepspeed config file.
+
+ Args:
+ optimizer (`torch.optim.optimizer.Optimizer`):
+ The optimizer to wrap.
+ total_num_steps (int):
+ Total number of steps.
+ warmup_num_steps (int):
+ Number of steps for warmup.
+ **kwargs (additional keyword arguments, *optional*):
+ Other arguments.
+ """
+
+ def __init__(self, optimizer, total_num_steps=None, warmup_num_steps=0, **kwargs):
+ self.optimizer = optimizer
+ self.total_num_steps = total_num_steps
+ self.warmup_num_steps = warmup_num_steps
+ self.kwargs = kwargs
+
+
+class MegatronLMSchedulerWrapper(AcceleratedScheduler):
+ def __init__(self, scheduler, optimizers):
+ super().__init__(scheduler, optimizers)
+
+ def step(self, *args, **kwargs):
+ return # `model(**batch)` is doing that automatically. Therefore, its implementation is not needed
+
+
+def prepare_scheduler(accelerator, optimizer, scheduler):
+ accelerator.print("Preparing scheduler")
+ scheduler = get_optimizer_param_scheduler(optimizer)
+ return scheduler
+
+
+class AbstractTrainStep(ABC):
+ """Abstract class for batching, forward pass and loss handler."""
+
+ def __init__(self, name):
+ super().__init__()
+ self.name = name
+
+ def get_batch_func(self, accelerator, megatron_dataset_flag):
+ pass
+
+ def get_forward_step_func(self):
+ pass
+
+ def get_loss_func(self, accelerator):
+ pass
+
+
+class BertTrainStep(AbstractTrainStep):
+ """
+ Bert train step class.
+
+ Args:
+ args (`argparse.Namespace`): Megatron-LM arguments.
+ """
+
+ def __init__(self, accelerator, args):
+ super().__init__("BertTrainStep")
+ self.get_batch = self.get_batch_func(accelerator, args.megatron_dataset_flag)
+ self.loss_func = self.get_loss_func(accelerator, args.pretraining_flag, args.num_labels)
+ self.forward_step = self.get_forward_step_func(args.pretraining_flag, args.bert_binary_head)
+ if not args.model_return_dict:
+ self.model_output_class = None
+ else:
+ from transformers.modeling_outputs import SequenceClassifierOutput
+
+ self.model_output_class = SequenceClassifierOutput
+
+ def get_batch_func(self, accelerator, megatron_dataset_flag):
+ def get_batch_megatron(data_iterator):
+ """Build the batch."""
+
+ # Items and their type.
+ keys = ["text", "types", "labels", "is_random", "loss_mask", "padding_mask"]
+ datatype = torch.int64
+
+ # Broadcast data.
+ if data_iterator is not None:
+ data = next(data_iterator)
+ else:
+ data = None
+ data_b = tensor_parallel.broadcast_data(keys, data, datatype)
+
+ # Unpack.
+ tokens = data_b["text"].long()
+ types = data_b["types"].long()
+ sentence_order = data_b["is_random"].long()
+ loss_mask = data_b["loss_mask"].float()
+ lm_labels = data_b["labels"].long()
+ padding_mask = data_b["padding_mask"].long()
+
+ return tokens, types, sentence_order, loss_mask, lm_labels, padding_mask
+
+ def get_batch_transformer(data_iterator):
+ """Build the batch."""
+ data = next(data_iterator)
+ data = send_to_device(data, torch.cuda.current_device())
+
+ # Unpack.
+ tokens = data["input_ids"].long()
+ padding_mask = data["attention_mask"].long()
+ if "token_type_ids" in data:
+ types = data["token_type_ids"].long()
+ else:
+ types = None
+ if "labels" in data:
+ lm_labels = data["labels"].long()
+ loss_mask = (data["labels"] != -100).to(torch.float)
+ else:
+ lm_labels = None
+ loss_mask = None
+ if "next_sentence_label" in data:
+ sentence_order = data["next_sentence_label"].long()
+ else:
+ sentence_order = None
+
+ return tokens, types, sentence_order, loss_mask, lm_labels, padding_mask
+
+ if accelerator.state.megatron_lm_plugin.custom_get_batch_function is not None:
+ return accelerator.state.megatron_lm_plugin.custom_get_batch_function
+ if megatron_dataset_flag:
+ try:
+ # Use '--no-use-pep517 -e' to pip install nvidia's megatron from source
+ from pretrain_bert import get_batch
+
+ return get_batch
+ except ImportError:
+ pass
+ return get_batch_megatron
+ else:
+ return get_batch_transformer
+
+ def get_loss_func(self, accelerator, pretraining_flag, num_labels):
+ def loss_func_pretrain(loss_mask, sentence_order, output_tensor):
+ lm_loss_, sop_logits = output_tensor
+
+ lm_loss_ = lm_loss_.float()
+ loss_mask = loss_mask.float()
+ lm_loss = torch.sum(lm_loss_.view(-1) * loss_mask.reshape(-1)) / loss_mask.sum()
+
+ if sop_logits is not None:
+ sop_loss = F.cross_entropy(sop_logits.view(-1, 2).float(), sentence_order.view(-1), ignore_index=-1)
+ sop_loss = sop_loss.float()
+ loss = lm_loss + sop_loss
+ averaged_losses = average_losses_across_data_parallel_group([lm_loss, sop_loss])
+ return loss, {"lm loss": averaged_losses[0], "sop loss": averaged_losses[1]}
+
+ else:
+ loss = lm_loss
+ averaged_losses = average_losses_across_data_parallel_group([lm_loss])
+ return loss, {"lm loss": averaged_losses[0]}
+
+ def loss_func_finetune(labels, logits):
+ if num_labels == 1:
+ # We are doing regression
+ loss_fct = MSELoss()
+ loss = loss_fct(logits.view(-1), labels.view(-1))
+ elif self.num_labels > 1 and (labels.dtype in (torch.long, torch.int)):
+ loss_fct = CrossEntropyLoss()
+ loss = loss_fct(logits.view(-1, num_labels), labels.view(-1))
+ else:
+ loss_fct = BCEWithLogitsLoss()
+ loss = loss_fct(logits, labels)
+ averaged_losses = average_losses_across_data_parallel_group([loss])
+ return loss, {"loss": averaged_losses[0]}
+
+ if accelerator.state.megatron_lm_plugin.custom_loss_function is not None:
+ return accelerator.state.megatron_lm_plugin.custom_loss_function
+ if pretraining_flag:
+ return loss_func_pretrain
+ else:
+ return loss_func_finetune
+
+ def get_forward_step_func(self, pretraining_flag, bert_binary_head):
+ def forward_step(data_iterator, model):
+ """Forward step."""
+ tokens, types, sentence_order, loss_mask, labels, padding_mask = self.get_batch(data_iterator)
+ if not bert_binary_head:
+ types = None
+ # Forward pass through the model.
+ if pretraining_flag:
+ output_tensor = model(tokens, padding_mask, tokentype_ids=types, lm_labels=labels)
+ return output_tensor, partial(self.loss_func, loss_mask, sentence_order)
+ else:
+ logits = model(tokens, padding_mask, tokentype_ids=types)
+ return logits, partial(self.loss_func, labels)
+
+ return forward_step
+
+
+class GPTTrainStep(AbstractTrainStep):
+ """
+ GPT train step class.
+
+ Args:
+ args (`argparse.Namespace`): Megatron-LM arguments.
+ """
+
+ def __init__(self, accelerator, args):
+ super().__init__("GPTTrainStep")
+ self.get_batch = self.get_batch_func(accelerator, args.megatron_dataset_flag)
+ self.loss_func = self.get_loss_func(accelerator)
+ self.forward_step = self.get_forward_step_func()
+ self.eod_token = args.padded_vocab_size - 1
+ if args.vocab_file is not None:
+ tokenizer = get_tokenizer()
+ self.eod_token = tokenizer.eod
+ self.reset_position_ids = args.reset_position_ids
+ self.reset_attention_mask = args.reset_attention_mask
+ self.eod_mask_loss = args.eod_mask_loss
+ if not args.model_return_dict:
+ self.model_output_class = None
+ else:
+ from transformers.modeling_outputs import CausalLMOutputWithCrossAttentions
+
+ self.model_output_class = CausalLMOutputWithCrossAttentions
+
+ def get_batch_func(self, accelerator, megatron_dataset_flag):
+ def get_batch_megatron(data_iterator):
+ """Generate a batch"""
+ # Items and their type.
+ keys = ["text"]
+ datatype = torch.int64
+
+ # Broadcast data.
+ if data_iterator is not None:
+ data = next(data_iterator)
+ else:
+ data = None
+ data_b = tensor_parallel.broadcast_data(keys, data, datatype)
+
+ # Unpack.
+ tokens_ = data_b["text"].long()
+ labels = tokens_[:, 1:].contiguous()
+ tokens = tokens_[:, :-1].contiguous()
+
+ # Get the masks and position ids.
+ attention_mask, loss_mask, position_ids = get_ltor_masks_and_position_ids(
+ tokens, self.eod_token, self.reset_position_ids, self.reset_attention_mask, self.eod_mask_loss
+ )
+
+ return tokens, labels, loss_mask, attention_mask, position_ids
+
+ def get_batch_transformer(data_iterator):
+ data = next(data_iterator)
+ data = {"input_ids": data["input_ids"]}
+ data = send_to_device(data, torch.cuda.current_device())
+
+ tokens_ = data["input_ids"].long()
+ padding = torch.zeros((tokens_.shape[0], 1), dtype=tokens_.dtype, device=tokens_.device) + self.eod_token
+ tokens_ = torch.concat([tokens_, padding], dim=1)
+ labels = tokens_[:, 1:].contiguous()
+ tokens = tokens_[:, :-1].contiguous()
+ # Get the masks and position ids.
+ attention_mask, loss_mask, position_ids = get_ltor_masks_and_position_ids(
+ tokens, self.eod_token, self.reset_position_ids, self.reset_attention_mask, True
+ )
+ return tokens, labels, loss_mask, attention_mask, position_ids
+
+ if accelerator.state.megatron_lm_plugin.custom_get_batch_function is not None:
+ return accelerator.state.megatron_lm_plugin.custom_get_batch_function
+ if megatron_dataset_flag:
+ try:
+ # Use '--no-use-pep517 -e' to pip install nvidia's megatron from source
+ from pretrain_gpt import get_batch
+
+ return get_batch
+ except ImportError:
+ pass
+ return get_batch_megatron
+ else:
+ return get_batch_transformer
+
+ def get_loss_func(self, accelerator):
+ args = get_args()
+
+ def loss_func(loss_mask, output_tensor):
+ if args.return_logits:
+ losses, logits = output_tensor
+ else:
+ losses = output_tensor
+ losses = losses.float()
+ loss_mask = loss_mask.view(-1).float()
+ if args.context_parallel_size > 1:
+ loss = torch.cat([torch.sum(losses.view(-1) * loss_mask).view(1), loss_mask.sum().view(1)])
+ torch.distributed.all_reduce(loss, group=mpu.get_context_parallel_group())
+ loss = loss[0] / loss[1]
+ else:
+ loss = torch.sum(losses.view(-1) * loss_mask) / loss_mask.sum()
+
+ # Check individual rank losses are not NaN prior to DP all-reduce.
+ if args.check_for_nan_in_loss_and_grad:
+ global_rank = torch.distributed.get_rank()
+ assert not loss.isnan(), (
+ f"Rank {global_rank}: found NaN in local forward loss calculation. "
+ f"Device: {torch.cuda.current_device()}, node: {os.uname()[1]}"
+ )
+
+ # Reduce loss for logging.
+ averaged_loss = average_losses_across_data_parallel_group([loss])
+
+ output_dict = {"lm loss": averaged_loss[0]}
+ if args.return_logits:
+ output_dict.update({"logits": logits})
+ return loss, output_dict
+
+ if accelerator.state.megatron_lm_plugin.custom_loss_function is not None:
+ return accelerator.state.megatron_lm_plugin.custom_loss_function
+ return loss_func
+
+ def get_forward_step_func(self):
+ def forward_step(data_iterator, model):
+ """Forward step."""
+ # Get the batch.
+ tokens, labels, loss_mask, attention_mask, position_ids = self.get_batch(data_iterator)
+ output_tensor = model(tokens, position_ids, attention_mask, labels=labels)
+
+ return output_tensor, partial(self.loss_func, loss_mask)
+
+ return forward_step
+
+
+class T5TrainStep(AbstractTrainStep):
+ """
+ T5 train step class.
+
+ Args:
+ args (`argparse.Namespace`): Megatron-LM arguments.
+ """
+
+ def __init__(self, accelerator, args):
+ super().__init__("T5TrainStep")
+ self.get_batch = self.get_batch_func(accelerator, args.megatron_dataset_flag)
+ self.loss_func = self.get_loss_func(accelerator)
+ self.forward_step = self.get_forward_step_func()
+ if not args.model_return_dict:
+ self.model_output_class = None
+ else:
+ from transformers.modeling_outputs import Seq2SeqLMOutput
+
+ self.model_output_class = Seq2SeqLMOutput
+
+ @staticmethod
+ def attn_mask_postprocess(attention_mask):
+ # We create a 3D attention mask from a 2D tensor mask.
+ # [b, 1, s]
+ attention_mask_b1s = attention_mask.unsqueeze(1)
+ # [b, s, 1]
+ attention_mask_bs1 = attention_mask.unsqueeze(2)
+ # [b, s, s]
+ attention_mask_bss = attention_mask_b1s * attention_mask_bs1
+ # Convert attention mask to binary:
+ extended_attention_mask = attention_mask_bss < 0.5
+ return extended_attention_mask
+
+ @staticmethod
+ def get_decoder_mask(seq_length, device):
+ attention_mask = torch.tril(torch.ones((1, seq_length, seq_length), device=device))
+ attention_mask = attention_mask < 0.5
+ return attention_mask
+
+ @staticmethod
+ def get_enc_dec_mask(attention_mask, dec_seq_length, device):
+ batch_size, _ = attention_mask.shape
+ # We create a 3D attention mask from a 2D tensor mask.
+ # [b, 1, s]
+ attention_mask_b1s = attention_mask.unsqueeze(1)
+ # [b, s, 1]
+ attention_mask_bs1 = torch.ones((batch_size, dec_seq_length, 1), device=device)
+ attention_mask_bss = attention_mask_bs1 * attention_mask_b1s
+ extended_attention_mask = attention_mask_bss < 0.5
+ return extended_attention_mask
+
+ def get_batch_func(self, accelerator, megatron_dataset_flag):
+ def get_batch_megatron(data_iterator):
+ """Build the batch."""
+
+ keys = ["text_enc", "text_dec", "labels", "loss_mask", "enc_mask", "dec_mask", "enc_dec_mask"]
+ datatype = torch.int64
+
+ # Broadcast data.
+ if data_iterator is not None:
+ data = next(data_iterator)
+ else:
+ data = None
+ data_b = tensor_parallel.broadcast_data(keys, data, datatype)
+
+ # Unpack.
+ tokens_enc = data_b["text_enc"].long()
+ tokens_dec = data_b["text_dec"].long()
+ labels = data_b["labels"].long()
+ loss_mask = data_b["loss_mask"].float()
+
+ enc_mask = data_b["enc_mask"] < 0.5
+ dec_mask = data_b["dec_mask"] < 0.5
+ enc_dec_mask = data_b["enc_dec_mask"] < 0.5
+
+ return tokens_enc, tokens_dec, loss_mask, labels, enc_mask, dec_mask, enc_dec_mask
+
+ def get_batch_transformer(data_iterator):
+ """Build the batch."""
+ data = next(data_iterator)
+ data = send_to_device(data, torch.cuda.current_device())
+
+ tokens_enc = data["input_ids"].long()
+ labels = data["labels"].long()
+ loss_mask = (labels != -100).to(torch.float)
+ if "decoder_input_ids" in data:
+ tokens_dec = data["decoder_input_ids"].long()
+ else:
+ tokens_dec = labels.new_zeros(labels.shape, device=labels.device, dtype=torch.long)
+ tokens_dec[..., 1:] = labels[..., :-1].clone()
+ tokens_dec[..., 0] = 0
+ tokens_dec.masked_fill_(tokens_dec == -100, 0)
+ enc_mask = T5TrainStep.attn_mask_postprocess(data["attention_mask"].long())
+ dec_mask = T5TrainStep.get_decoder_mask(tokens_dec.shape[1], tokens_dec.device)
+ enc_dec_mask = T5TrainStep.get_enc_dec_mask(
+ data["attention_mask"].long(), tokens_dec.shape[1], tokens_dec.device
+ )
+
+ return tokens_enc, tokens_dec, loss_mask, labels, enc_mask, dec_mask, enc_dec_mask
+
+ if accelerator.state.megatron_lm_plugin.custom_get_batch_function is not None:
+ return accelerator.state.megatron_lm_plugin.custom_get_batch_function
+ if megatron_dataset_flag:
+ try:
+ # Use '--no-use-pep517 -e' to pip install nvidia's megatron from source
+ from pretrain_t5 import get_batch
+
+ return get_batch
+ except ImportError:
+ pass
+ return get_batch_megatron
+ else:
+ return get_batch_transformer
+
+ def get_loss_func(self, accelerator):
+ def loss_func(loss_mask, output_tensor):
+ lm_loss_ = output_tensor.float()
+ lm_loss = torch.sum(lm_loss_.view(-1) * loss_mask.reshape(-1)) / loss_mask.sum()
+
+ loss = lm_loss
+ averaged_losses = average_losses_across_data_parallel_group([lm_loss])
+
+ return loss, {"lm loss": averaged_losses[0]}
+
+ if accelerator.state.megatron_lm_plugin.custom_loss_function is not None:
+ return accelerator.state.megatron_lm_plugin.custom_loss_function
+ return loss_func
+
+ def get_forward_step_func(self):
+ def forward_step(data_iterator, model):
+ """Forward step."""
+ # Get the batch.
+ tokens_enc, tokens_dec, loss_mask, lm_labels, enc_mask, dec_mask, enc_dec_mask = self.get_batch(
+ data_iterator
+ )
+ # Forward model lm_labels
+ output_tensor = model(
+ tokens_enc, tokens_dec, enc_mask, dec_mask, enc_dec_mask, tokentype_ids=None, lm_labels=lm_labels
+ )
+
+ return output_tensor, partial(self.loss_func, loss_mask)
+
+ return forward_step
+
+
+def finish_mpu_init():
+ # torch.distributed initialization
+ args = get_args()
+ # Pytorch distributed.
+ _initialize_distributed()
+
+ # Random seeds for reproducibility.
+ if args.rank == 0:
+ print(f"> setting random seeds to {args.seed} ...")
+ _set_random_seed(args.seed, args.data_parallel_random_init)
+
+
+# initialize megatron setup
+def initialize(accelerator, extra_args_provider=None, args_defaults={}):
+ accelerator.print("Initializing Megatron-LM")
+ assert torch.cuda.is_available(), "Megatron requires CUDA."
+
+ # Parse arguments
+ args = parse_args(extra_args_provider, ignore_unknown_args=True)
+
+ # Set defaults
+ for key, value in args_defaults.items():
+ if getattr(args, key, None) is not None:
+ if args.rank == 0:
+ print(
+ f"WARNING: overriding default arguments for {key}:{getattr(args, key)} with {key}:{value}",
+ flush=True,
+ )
+ setattr(args, key, value)
+
+ if args.use_checkpoint_args or args_defaults.get("use_checkpoint_args", False):
+ assert args.load is not None, "--use-checkpoints-args requires --load argument"
+ load_args_from_checkpoint(args)
+
+ validate_args(args)
+
+ # set global args, build tokenizer, and set adlr-autoresume,
+ # tensorboard-writer, and timers.
+ set_global_variables(args)
+
+ # Megatron's MPU is the master. Complete initialization right away.
+ finish_mpu_init()
+
+ # Autoresume.
+ _init_autoresume()
+
+ # Compile dependencies.
+ _compile_dependencies()
+
+ # Set pytorch JIT layer fusion options and warmup JIT functions.
+ set_jit_fusion_options()
+ args = get_args()
+ if getattr(args, "padded_vocab_size", None) is None:
+ args.padded_vocab_size = _vocab_size_with_padding(args.orig_vocab_size, args)
+ if args.model_type_name == "bert" and args.pretraining_flag and args.num_labels == 2:
+ args.bert_binary_head = True
+ else:
+ args.bert_binary_head = False
+ args.iteration = 0
+
+
+class MegatronEngine(torch.nn.Module):
+ """
+ Megatron-LM model wrapper
+
+ Args:
+ accelerator (:class:`~accelerate.Accelerator`): The accelerator object to use.
+ model: Megatron-LM model
+ optimizer: Megatron-LM optimizer
+ lr_scheduler: Megatron-LM lr scheduler
+ """
+
+ def __init__(self, accelerator, model, optimizer, scheduler):
+ super().__init__()
+ self.module = model
+ self.base_model = model[0]
+ self.optimizer = optimizer
+ self.scheduler = scheduler
+ args = get_args()
+ if accelerator.state.megatron_lm_plugin.custom_train_step_class is not None:
+ self.train_step_handler = accelerator.state.megatron_lm_plugin.custom_train_step_class(
+ args, **accelerator.state.megatron_lm_plugin.custom_train_step_kwargs
+ )
+ elif args.model_type_name == "bert":
+ self.train_step_handler = BertTrainStep(accelerator, args)
+ elif args.model_type_name == "gpt":
+ self.train_step_handler = GPTTrainStep(accelerator, args)
+ elif args.model_type_name == "t5":
+ self.train_step_handler = T5TrainStep(accelerator, args)
+ else:
+ raise ValueError(f"Unsupported model type: {args.model_type_name}")
+ self.optimizer.skipped_iter = False
+
+ # Tracking loss.
+ self.total_loss_dict = {}
+ self.eval_total_loss_dict = {}
+ self.iteration = 0
+ self.report_memory_flag = True
+ self.num_floating_point_operations_so_far = 0
+ self.module_config = None
+ if args.tensorboard_dir is not None:
+ write_args_to_tensorboard()
+
+ def get_module_config(self):
+ args = get_args()
+ config = get_model_config(self.module[0])
+ # Setup some training config params
+ config.grad_scale_func = self.optimizer.scale_loss
+ if isinstance(self.module[0], LocalDDP) and args.overlap_grad_reduce:
+ assert config.no_sync_func is None, (
+ "When overlap_grad_reduce is True, config.no_sync_func must be None; "
+ "a custom no_sync_func is not supported when overlapping grad-reduce"
+ )
+ config.no_sync_func = [model_chunk.no_sync for model_chunk in self.module]
+ if len(self.module) == 1:
+ config.no_sync_func = config.no_sync_func[0]
+ if args.delay_grad_reduce:
+ config.grad_sync_func = [model_chunk.start_grad_sync for model_chunk in self.module]
+ if len(self.module) == 1:
+ config.grad_sync_func = config.grad_sync_func[0]
+ if args.overlap_param_gather and args.delay_param_gather:
+ config.param_sync_func = [
+ lambda x: self.optimizer.finish_param_sync(model_index, x) for model_index in range(len(self.module))
+ ]
+ if len(self.module) == 1:
+ config.param_sync_func = config.param_sync_func[0]
+ config.finalize_model_grads_func = finalize_model_grads
+ return config
+
+ def train(self):
+ for model_module in self.module:
+ model_module.train()
+
+ if self.module_config is None:
+ self.module_config = self.get_module_config()
+
+ self.log_eval_results()
+
+ def eval(self):
+ for model_module in self.module:
+ model_module.eval()
+
+ if self.module_config is None:
+ self.module_config = self.get_module_config()
+
+ def get_batch_data_iterator(self, batch_data):
+ args = get_args()
+ data_chunks = []
+ if len(batch_data) > 0:
+ if args.num_micro_batches > 1:
+ for i in range(0, args.num_micro_batches):
+ data_chunks.append(
+ {
+ k: v[i * args.micro_batch_size : (i + 1) * args.micro_batch_size]
+ for k, v in batch_data.items()
+ }
+ )
+ else:
+ data_chunks = [batch_data]
+
+ if len(self.module) > 1:
+ batch_data_iterator = (
+ [iter(data_chunks) for _ in range(len(self.module))]
+ if len(batch_data) > 0
+ else [None] * len(self.module)
+ )
+ else:
+ batch_data_iterator = iter(data_chunks) if len(batch_data) > 0 else None
+ return batch_data_iterator
+
+ def train_step(self, **batch_data):
+ """
+ Training step for Megatron-LM
+
+ Args:
+ batch_data (:obj:`dict`): The batch data to train on.
+ """
+
+ batch_data_iterator = self.get_batch_data_iterator(batch_data)
+
+ loss_reduced, skipped_iter, grad_norm, num_zeros_in_grad = train_step(
+ forward_step_func=self.train_step_handler.forward_step,
+ data_iterator=batch_data_iterator,
+ model=self.module,
+ optimizer=self.optimizer,
+ opt_param_scheduler=self.scheduler,
+ config=self.module_config,
+ )
+
+ self.optimizer.skipped_iter = skipped_iter == 1
+
+ return loss_reduced, skipped_iter, grad_norm, num_zeros_in_grad
+
+ def eval_step(self, **batch_data):
+ """
+ Evaluation step for Megatron-LM
+
+ Args:
+ batch_data (:obj:`dict`): The batch data to evaluate on.
+ """
+
+ args = get_args()
+ batch_data_iterator = self.get_batch_data_iterator(batch_data)
+ forward_backward_func = get_forward_backward_func()
+ loss_dicts = forward_backward_func(
+ forward_step_func=self.train_step_handler.forward_step,
+ data_iterator=batch_data_iterator,
+ model=self.module,
+ num_microbatches=get_num_microbatches(),
+ seq_length=args.seq_length,
+ micro_batch_size=args.micro_batch_size,
+ forward_only=True,
+ )
+ # Empty unused memory
+ if args.empty_unused_memory_level >= 1:
+ torch.cuda.empty_cache()
+
+ args.consumed_valid_samples += (
+ mpu.get_data_parallel_world_size() * args.micro_batch_size * get_num_microbatches()
+ )
+
+ if mpu.is_pipeline_last_stage(ignore_virtual=True):
+ # Average loss across microbatches.
+ loss_reduced = {}
+ for key in loss_dicts[0]:
+ losses_reduced_for_key = [x[key] for x in loss_dicts]
+ if len(losses_reduced_for_key[0].shape) == 0:
+ loss_reduced[key] = sum(losses_reduced_for_key) / len(losses_reduced_for_key)
+ else:
+ loss_reduced[key] = torch.concat(losses_reduced_for_key)
+ return loss_reduced
+ return {}
+
+ def forward(self, **batch_data):
+ # During training, we use train_step()
+ # model(**batch_data) performs following operations by delegating it to `self.train_step`:
+ # 1. Prepare **batch_data for Tendor, Pipeline and Model Parallelism
+ # 2. Set grad to zero.
+ # 3. forward pass and backward pass using Pipeline Parallelism
+ # 4. Empty unused memory.
+ # 5. Reduce gradients.
+ # 6. Update parameters.
+ # 7. Gather params when using Distributed Optimizer (Data Parallelism).
+ # 8. Update learning rate if scheduler is specified.
+ # 9. Empty unused memory.
+ # 10. Average loss across microbatches and across DP ranks.
+ #
+ # During evaluation, we use eval_step()
+ args = get_args()
+ if self.module[0].training:
+ loss_dict, skipped_iter, grad_norm, num_zeros_in_grad = self.train_step(**batch_data)
+ self.iteration += 1
+ batch_size = mpu.get_data_parallel_world_size() * args.micro_batch_size * get_num_microbatches()
+ args.consumed_train_samples += batch_size
+ self.num_floating_point_operations_so_far += num_floating_point_operations(args, batch_size)
+ if args.tensorboard_dir is not None:
+ # Logging.
+ loss_scale = self.optimizer.get_loss_scale().item()
+ params_norm = None
+ if args.log_params_norm:
+ params_norm = calc_params_l2_norm(self.model)
+ self.report_memory_flag = training_log(
+ loss_dict,
+ self.total_loss_dict,
+ self.optimizer.param_groups[0]["lr"],
+ self.iteration,
+ loss_scale,
+ self.report_memory_flag,
+ skipped_iter,
+ grad_norm,
+ params_norm,
+ num_zeros_in_grad,
+ )
+ else:
+ loss_dict = self.eval_step(**batch_data)
+ if args.tensorboard_dir is not None:
+ for key in loss_dict:
+ self.eval_total_loss_dict[key] = (
+ self.eval_total_loss_dict.get(key, torch.cuda.FloatTensor([0.0])) + loss_dict[key]
+ )
+ self.eval_total_loss_dict[key + "_num_iters"] = self.eval_total_loss_dict.get(
+ key + "_num_iters", torch.cuda.FloatTensor([0.0])
+ ) + torch.cuda.FloatTensor([1.0])
+
+ loss = torch.tensor(0.0, device=torch.cuda.current_device())
+ for key in loss_dict:
+ if len(loss_dict[key].shape) == 0:
+ loss += loss_dict[key]
+
+ logits = None
+ if "logits" in loss_dict:
+ logits = loss_dict["logits"]
+ if self.train_step_handler.model_output_class is not None:
+ return self.train_step_handler.model_output_class(loss=loss, logits=logits)
+ return loss
+
+ def log_eval_results(self):
+ args = get_args()
+ if args.tensorboard_dir is None or self.iteration == 0:
+ return
+ args = get_args()
+ writer = get_tensorboard_writer()
+ string = f"validation loss at iteration {self.iteration} | "
+ for key in self.eval_total_loss_dict:
+ if key.endswith("_num_iters"):
+ continue
+ value = self.eval_total_loss_dict[key] / self.eval_total_loss_dict[key + "_num_iters"]
+ string += f"{key} value: {value} | "
+ ppl = math.exp(min(20, value.item()))
+ if args.pretraining_flag:
+ string += f"{key} PPL: {ppl} | "
+ if writer:
+ writer.add_scalar(f"{key} validation", value.item(), self.iteration)
+ if args.pretraining_flag:
+ writer.add_scalar(f"{key} validation ppl", ppl, self.iteration)
+
+ length = len(string) + 1
+ print_rank_last("-" * length)
+ print_rank_last(string)
+ print_rank_last("-" * length)
+ self.eval_total_loss_dict = {}
+
+ def save_checkpoint(self, output_dir):
+ self.log_eval_results()
+ args = get_args()
+ args.save = output_dir
+ torch.distributed.barrier()
+ save_checkpoint(
+ self.iteration,
+ self.module,
+ self.optimizer,
+ self.scheduler,
+ num_floating_point_operations_so_far=self.num_floating_point_operations_so_far,
+ )
+ torch.distributed.barrier()
+
+ def load_checkpoint(self, input_dir):
+ args = get_args()
+ args.load = input_dir
+ args.consumed_train_samples = 0
+ args.consumed_valid_samples = 0
+ torch.distributed.barrier()
+ iteration, num_floating_point_operations_so_far = load_checkpoint(self.module, self.optimizer, self.scheduler)
+ torch.distributed.barrier()
+ self.iteration = iteration
+ self.num_floating_point_operations_so_far = num_floating_point_operations_so_far
+ if args.fp16 and self.iteration == 0:
+ self.optimizer.reload_model_params()
+
+ def megatron_generate(
+ self,
+ inputs,
+ attention_mask=None,
+ max_length=None,
+ max_new_tokens=None,
+ num_beams=None,
+ temperature=None,
+ top_k=None,
+ top_p=None,
+ length_penalty=None,
+ **kwargs,
+ ):
+ """
+ Generate method for GPT2 model. This method is used for inference. Supports both greedy and beam search along
+ with sampling. Refer the Megatron-LM repo for more details
+
+ Args:
+ inputs (torch.Tensor): input ids
+ attention_mask (torch.Tensor, optional): attention mask. Defaults to None.
+ max_length (int, optional): max length of the generated sequence. Defaults to None.
+ Either this or max_new_tokens should be provided.
+ max_new_tokens (int, optional): max number of tokens to be generated. Defaults to None.
+ Either this or max_length should be provided.
+ num_beams (int, optional): number of beams to use for beam search. Defaults to None.
+ temperature (float, optional): temperature for sampling. Defaults to 1.0.
+ top_k (int, optional): top k tokens to consider for sampling. Defaults to 0.0.
+ top_p (float, optional): tokens in top p probability are considered for sampling. Defaults to 0.0.
+ length_penalty (float, optional): length penalty for beam search. Defaults to None.
+ kwargs: additional key-value arguments
+ """
+
+ # checking if required arguments are passed
+ args = get_args()
+ if args.model_type_name != "gpt":
+ raise NotImplementedError("Generate method is not implemented for this model")
+
+ if args.data_parallel_size > 1:
+ raise ValueError("Generate method requires data parallelism to be 1")
+
+ if args.sequence_parallel:
+ raise ValueError("Generate method requires sequence parallelism to be False")
+
+ if args.recompute_granularity is not None:
+ raise ValueError("Checkpoint activations cannot be set for inference")
+
+ if args.vocab_file is None:
+ raise ValueError("Vocab file is required for inference")
+
+ # Prepare inputs
+ if max_length is None and max_new_tokens is None:
+ raise ValueError("`max_length` or `max_new_tokens` are required for inference")
+
+ if temperature is None:
+ temperature = 1.0
+ elif not (0.0 < temperature <= 100.0):
+ raise ValueError("temperature must be a positive number less than or equal to 100.0")
+
+ if top_k is None:
+ top_k = 0
+ elif not (0 <= top_k <= 1000):
+ raise ValueError("top_k must be a positive number less than or equal to 1000")
+
+ if top_p is None:
+ top_p = 0.0
+ elif top_p > 0.0 and top_k > 0.0:
+ raise ValueError("top_p and top_k sampling cannot be set together")
+ else:
+ if not (0.0 <= top_p <= 1.0):
+ raise ValueError("top_p must be less than or equal to 1.0")
+
+ top_p_decay = kwargs.get("top_p_decay", 0.0)
+ if not (0.0 <= top_p_decay <= 1.0):
+ raise ValueError("top_p_decay must be less than or equal to 1.0")
+
+ top_p_bound = kwargs.get("top_p_bound", 0.0)
+ if not (0.0 <= top_p_bound <= 1.0):
+ raise ValueError("top_p_bound must be less than or equal to 1.0")
+
+ add_BOS = kwargs.get("add_BOS", False)
+ if not (isinstance(add_BOS, bool)):
+ raise ValueError("add_BOS must be a boolean")
+
+ beam_width = num_beams
+ if beam_width is not None:
+ if not isinstance(beam_width, int):
+ raise ValueError("beam_width must be an integer")
+ if beam_width < 1:
+ raise ValueError("beam_width must be greater than 0")
+ if inputs.shape[0] > 1:
+ return "When doing beam_search, batch size must be 1"
+
+ tokenizer = get_tokenizer()
+
+ stop_token = kwargs.get("stop_token", tokenizer.eod)
+ if stop_token is not None:
+ if not isinstance(stop_token, int):
+ raise ValueError("stop_token must be an integer")
+
+ if length_penalty is None:
+ length_penalty = 1.0
+
+ sizes_list = None
+ prompts_tokens_tensor = None
+ prompts_length_tensor = None
+ if torch.distributed.get_rank() == 0:
+ # Get the prompts length.
+ if attention_mask is None:
+ prompts_length_tensor = torch.cuda.LongTensor([inputs.shape[1]] * inputs.shape[0])
+ else:
+ prompts_length_tensor = attention_mask.sum(axis=-1).cuda()
+
+ if max_new_tokens is None:
+ max_new_tokens = max_length - inputs.shape[1]
+ if max_new_tokens <= 0:
+ raise ValueError("max_new_tokens must be greater than 0")
+
+ if add_BOS:
+ max_length = max_new_tokens + inputs.shape[1] + 1
+ # making sure that `max_length` is a multiple of 4 to leverage fused kernels
+ max_length = 4 * math.ceil(max_length / 4)
+ max_new_tokens = max_length - (inputs.shape[1] + 1)
+ padding = torch.cuda.LongTensor([[tokenizer.eod] * max_new_tokens] * inputs.shape[0])
+ prompts_tokens_tensor = torch.concat(
+ [torch.unsqueeze(padding[:, 0], axis=-1), inputs.cuda(), padding], axis=-1
+ )
+ else:
+ # making sure that `max_length` is a multiple of 4 to leverage fused kernels
+ max_length = max_new_tokens + inputs.shape[1]
+ max_length = 4 * math.ceil(max_length / 4)
+ max_new_tokens = max_length - inputs.shape[1]
+ padding = torch.cuda.LongTensor([[tokenizer.eod] * max_new_tokens] * inputs.shape[0])
+ prompts_tokens_tensor = torch.concat([inputs.cuda(), padding], axis=-1)
+
+ # We need the sizes of these tensors for the broadcast
+ sizes_list = [
+ prompts_tokens_tensor.size(0), # Batch size
+ prompts_tokens_tensor.size(1),
+ ] # Sequence length
+
+ # First, broadcast the sizes.
+ sizes_tensor = broadcast_int_list(2, int_list=sizes_list, rank=0)
+
+ # Now that we have the sizes, we can broadcast the tokens
+ # and length tensors.
+ sizes = sizes_tensor.tolist()
+ context_tokens_tensor = broadcast_tensor(sizes, torch.int64, tensor=prompts_tokens_tensor, rank=0)
+ context_length_tensor = broadcast_tensor(sizes[0], torch.int64, tensor=prompts_length_tensor, rank=0)
+
+ # Run the inference
+ random_seed = kwargs.get("random_seed", 0)
+ torch.random.manual_seed(random_seed)
+ unwrapped_model = unwrap_model(self.base_model, (torchDDP, LocalDDP, Float16Module))
+ if beam_width is not None:
+ tokens, _ = beam_search_and_return_on_first_stage(
+ unwrapped_model,
+ context_tokens_tensor,
+ context_length_tensor,
+ beam_width,
+ stop_token=stop_token,
+ num_return_gen=1,
+ length_penalty=length_penalty,
+ )
+ else:
+ tokens, _, _ = generate_tokens_probs_and_return_on_first_stage(
+ unwrapped_model,
+ context_tokens_tensor,
+ context_length_tensor,
+ return_output_log_probs=False,
+ top_k=top_k,
+ top_p=top_p,
+ top_p_decay=top_p_decay,
+ top_p_bound=top_p_bound,
+ temperature=temperature,
+ use_eod_token_for_early_termination=True,
+ )
+ return tokens
+
+
+# other utilities
+def avg_losses_across_data_parallel_group(losses):
+ """
+ Average losses across data parallel group.
+
+ Args:
+ losses (List[Tensor]): List of losses to average across data parallel group.
+ """
+
+ return average_losses_across_data_parallel_group(losses)
+
+
+def gather_across_data_parallel_groups(tensor):
+ """
+ Recursively gather tensor in a nested list/tuple/dictionary of tensors from data parallel ranks.
+
+ Args:
+ tensor (nested list/tuple/dictionary of `torch.Tensor`):
+ The data to gather across data parallel ranks.
+
+ """
+
+ def _gpu_gather_one(tensor):
+ if tensor.ndim == 0:
+ tensor = tensor.clone()[None]
+ output_tensors = [
+ torch.empty_like(tensor)
+ for _ in range(torch.distributed.get_world_size(group=mpu.get_data_parallel_group()))
+ ]
+ torch.distributed.all_gather(output_tensors, tensor, group=mpu.get_data_parallel_group())
+ return torch.cat(output_tensors, dim=0)
+
+ return recursively_apply(_gpu_gather_one, tensor, error_on_other_type=True)
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/memory.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/memory.py
new file mode 100644
index 0000000000000000000000000000000000000000..51b71107e5b1c7209e17948cde889f7d82f56b41
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/memory.py
@@ -0,0 +1,210 @@
+# Copyright 2022 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+A collection of utilities for ensuring that training can always occur. Heavily influenced by the
+[toma](https://github.com/BlackHC/toma) library.
+"""
+
+import functools
+import gc
+import importlib
+import inspect
+import warnings
+from typing import Optional
+
+import torch
+from packaging import version
+
+from .imports import (
+ is_cuda_available,
+ is_hpu_available,
+ is_ipex_available,
+ is_mlu_available,
+ is_mps_available,
+ is_musa_available,
+ is_npu_available,
+ is_sdaa_available,
+ is_xpu_available,
+)
+from .versions import compare_versions
+
+
+def clear_device_cache(garbage_collection=False):
+ """
+ Clears the device cache by calling `torch.{backend}.empty_cache`. Can also run `gc.collect()`, but do note that
+ this is a *considerable* slowdown and should be used sparingly.
+ """
+ if garbage_collection:
+ gc.collect()
+
+ if is_xpu_available():
+ torch.xpu.empty_cache()
+ elif is_mlu_available():
+ torch.mlu.empty_cache()
+ elif is_sdaa_available():
+ torch.sdaa.empty_cache()
+ elif is_musa_available():
+ torch.musa.empty_cache()
+ elif is_npu_available():
+ torch.npu.empty_cache()
+ elif is_mps_available(min_version="2.0"):
+ torch.mps.empty_cache()
+ elif is_cuda_available():
+ torch.cuda.empty_cache()
+ elif is_hpu_available():
+ # torch.hpu.empty_cache() # not available on hpu as it reserves all device memory for the current process
+ pass
+
+
+def release_memory(*objects):
+ """
+ Releases memory from `objects` by setting them to `None` and calls `gc.collect()` and `torch.cuda.empty_cache()`.
+ Returned objects should be reassigned to the same variables.
+
+ Args:
+ objects (`Iterable`):
+ An iterable of objects
+ Returns:
+ A list of `None` objects to replace `objects`
+
+ Example:
+
+ ```python
+ >>> import torch
+ >>> from accelerate.utils import release_memory
+
+ >>> a = torch.ones(1000, 1000).cuda()
+ >>> b = torch.ones(1000, 1000).cuda()
+ >>> a, b = release_memory(a, b)
+ ```
+ """
+ if not isinstance(objects, list):
+ objects = list(objects)
+ for i in range(len(objects)):
+ objects[i] = None
+ clear_device_cache(garbage_collection=True)
+ return objects
+
+
+def should_reduce_batch_size(exception: Exception) -> bool:
+ """
+ Checks if `exception` relates to CUDA out-of-memory, XPU out-of-memory, CUDNN not supported, or CPU out-of-memory
+
+ Args:
+ exception (`Exception`):
+ An exception
+ """
+ _statements = [
+ " out of memory.", # OOM for CUDA, HIP, XPU
+ "cuDNN error: CUDNN_STATUS_NOT_SUPPORTED.", # CUDNN SNAFU
+ "DefaultCPUAllocator: can't allocate memory", # CPU OOM
+ "FATAL ERROR :: MODULE:PT_DEVMEM Allocation failed", # HPU OOM
+ ]
+ if isinstance(exception, RuntimeError) and len(exception.args) == 1:
+ return any(err in exception.args[0] for err in _statements)
+ return False
+
+
+def find_executable_batch_size(
+ function: Optional[callable] = None,
+ starting_batch_size: int = 128,
+ reduce_batch_size_fn: Optional[callable] = None,
+):
+ """
+ A basic decorator that will try to execute `function`. If it fails from exceptions related to out-of-memory or
+ CUDNN, the batch size is multiplied by 0.9 and passed to `function`
+
+ `function` must take in a `batch_size` parameter as its first argument.
+
+ Args:
+ function (`callable`, *optional*):
+ A function to wrap
+ starting_batch_size (`int`, *optional*):
+ The batch size to try and fit into memory
+
+ Example:
+
+ ```python
+ >>> from accelerate.utils import find_executable_batch_size
+
+
+ >>> @find_executable_batch_size(starting_batch_size=128)
+ ... def train(batch_size, model, optimizer):
+ ... ...
+
+
+ >>> train(model, optimizer)
+ ```
+ """
+ if function is None:
+ return functools.partial(find_executable_batch_size, starting_batch_size=starting_batch_size)
+
+ batch_size = starting_batch_size
+ if reduce_batch_size_fn is None:
+
+ def reduce_batch_size_fn():
+ nonlocal batch_size
+ batch_size = int(batch_size * 0.9)
+ return batch_size
+
+ def decorator(*args, **kwargs):
+ nonlocal batch_size
+ clear_device_cache(garbage_collection=True)
+ params = list(inspect.signature(function).parameters.keys())
+ # Guard against user error
+ if len(params) < (len(args) + 1):
+ arg_str = ", ".join([f"{arg}={value}" for arg, value in zip(params[1:], args[1:])])
+ raise TypeError(
+ f"Batch size was passed into `{function.__name__}` as the first argument when called."
+ f"Remove this as the decorator already does so: `{function.__name__}({arg_str})`"
+ )
+ while True:
+ if batch_size == 0:
+ raise RuntimeError("No executable batch size found, reached zero.")
+ try:
+ return function(batch_size, *args, **kwargs)
+ except Exception as e:
+ if should_reduce_batch_size(e):
+ clear_device_cache(garbage_collection=True)
+ batch_size = reduce_batch_size_fn()
+ else:
+ raise
+
+ return decorator
+
+
+def get_xpu_available_memory(device_index: int):
+ if version.parse(torch.__version__).release >= version.parse("2.6").release:
+ # torch.xpu.mem_get_info API is available starting from PyTorch 2.6
+ # It further requires PyTorch built with the SYCL runtime which supports API
+ # to query available device memory. If not available, exception will be
+ # raised. Version of SYCL runtime used to build PyTorch is being reported
+ # with print(torch.version.xpu) and corresponds to the version of Intel DPC++
+ # SYCL compiler. First version to support required feature is 20250001.
+ try:
+ return torch.xpu.mem_get_info(device_index)[0]
+ except Exception:
+ pass
+ elif is_ipex_available():
+ ipex_version = version.parse(importlib.metadata.version("intel_extension_for_pytorch"))
+ if compare_versions(ipex_version, ">=", "2.5"):
+ from intel_extension_for_pytorch.xpu import mem_get_info
+
+ return mem_get_info(device_index)[0]
+
+ warnings.warn(
+ "The XPU `mem_get_info` API is available in IPEX version >=2.5 or PyTorch >=2.6. The current returned available memory is incorrect. Please consider upgrading your IPEX or PyTorch version."
+ )
+ return torch.xpu.max_memory_allocated(device_index)
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/modeling.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/modeling.py
new file mode 100644
index 0000000000000000000000000000000000000000..830249ffb1041b6cb29b6e7bdda1d7e47f28bc99
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/modeling.py
@@ -0,0 +1,2186 @@
+# Copyright 2022 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import contextlib
+import gc
+import inspect
+import json
+import logging
+import os
+import re
+import shutil
+import tempfile
+import warnings
+from collections import OrderedDict, defaultdict
+from typing import Optional, Union
+
+import torch
+from torch import distributed as dist
+from torch import nn
+
+from ..state import AcceleratorState
+from .constants import SAFE_WEIGHTS_NAME, WEIGHTS_NAME
+from .dataclasses import AutocastKwargs, CustomDtype, DistributedType
+from .imports import (
+ is_hpu_available,
+ is_mlu_available,
+ is_mps_available,
+ is_musa_available,
+ is_npu_available,
+ is_peft_available,
+ is_sdaa_available,
+ is_torch_xla_available,
+ is_xpu_available,
+)
+from .memory import clear_device_cache, get_xpu_available_memory
+from .offload import load_offloaded_weight, offload_weight, save_offload_index
+from .tqdm import is_tqdm_available, tqdm
+from .versions import is_torch_version
+
+
+if is_npu_available(check_device=False):
+ import torch_npu # noqa: F401
+
+if is_mlu_available(check_device=False):
+ import torch_mlu # noqa: F401
+
+if is_sdaa_available(check_device=False):
+ import torch_sdaa # noqa: F401
+
+if is_musa_available(check_device=False):
+ import torch_musa # noqa: F401
+
+from safetensors import safe_open
+from safetensors.torch import load_file as safe_load_file
+
+
+WEIGHTS_INDEX_NAME = "pytorch_model.bin.index.json"
+
+logger = logging.getLogger(__name__)
+
+
+def is_peft_model(model):
+ from .other import extract_model_from_parallel
+
+ if is_peft_available():
+ from peft import PeftModel
+
+ return is_peft_available() and isinstance(extract_model_from_parallel(model), PeftModel)
+
+
+def check_device_same(first_device, second_device):
+ """
+ Utility method to check if two `torch` devices are similar. When dealing with CUDA devices, torch throws `False`
+ for `torch.device("cuda") == torch.device("cuda:0")` whereas they should be the same
+
+ Args:
+ first_device (`torch.device`):
+ First device to check
+ second_device (`torch.device`):
+ Second device to check
+ """
+ if first_device.type != second_device.type:
+ return False
+
+ if first_device.type != "cpu" and first_device.index is None:
+ # In case the first_device is a cuda device and have
+ # the index attribute set to `None`, default it to `0`
+ first_device = torch.device(first_device.type, index=0)
+
+ if second_device.type != "cpu" and second_device.index is None:
+ # In case the second_device is a cuda device and have
+ # the index attribute set to `None`, default it to `0`
+ second_device = torch.device(second_device.type, index=0)
+
+ return first_device == second_device
+
+
+def convert_file_size_to_int(size: Union[int, str]):
+ """
+ Converts a size expressed as a string with digits an unit (like `"5MB"`) to an integer (in bytes).
+
+ Args:
+ size (`int` or `str`): The size to convert. Will be directly returned if an `int`.
+
+ Example:
+
+ ```py
+ >>> convert_file_size_to_int("1MiB")
+ 1048576
+ ```
+ """
+ mem_size = -1
+ err_msg = (
+ f"`size` {size} is not in a valid format. Use an integer for bytes, or a string with an unit (like '5.0GB')."
+ )
+ try:
+ if isinstance(size, int):
+ mem_size = size
+ elif size.upper().endswith("GIB"):
+ mem_size = int(float(size[:-3]) * (2**30))
+ elif size.upper().endswith("MIB"):
+ mem_size = int(float(size[:-3]) * (2**20))
+ elif size.upper().endswith("KIB"):
+ mem_size = int(float(size[:-3]) * (2**10))
+ elif size.upper().endswith("GB"):
+ int_size = int(float(size[:-2]) * (10**9))
+ mem_size = int_size // 8 if size.endswith("b") else int_size
+ elif size.upper().endswith("MB"):
+ int_size = int(float(size[:-2]) * (10**6))
+ mem_size = int_size // 8 if size.endswith("b") else int_size
+ elif size.upper().endswith("KB"):
+ int_size = int(float(size[:-2]) * (10**3))
+ mem_size = int_size // 8 if size.endswith("b") else int_size
+ except ValueError:
+ raise ValueError(err_msg)
+
+ if mem_size < 0:
+ raise ValueError(err_msg)
+ return mem_size
+
+
+def dtype_byte_size(dtype: torch.dtype):
+ """
+ Returns the size (in bytes) occupied by one parameter of type `dtype`.
+
+ Example:
+
+ ```py
+ >>> dtype_byte_size(torch.float32)
+ 4
+ ```
+ """
+ if dtype == torch.bool:
+ return 1 / 8
+ elif dtype == CustomDtype.INT2:
+ return 1 / 4
+ elif dtype == CustomDtype.INT4:
+ return 1 / 2
+ elif dtype == CustomDtype.FP8:
+ return 1
+ elif is_torch_version(">=", "2.1.0") and dtype in [torch.float8_e4m3fn, torch.float8_e5m2]:
+ return 1
+ bit_search = re.search(r"[^\d](\d+)$", str(dtype))
+ if bit_search is None:
+ raise ValueError(f"`dtype` is not a valid dtype: {dtype}.")
+ bit_size = int(bit_search.groups()[0])
+ return bit_size // 8
+
+
+def id_tensor_storage(tensor: torch.Tensor) -> tuple[torch.device, int, int]:
+ """
+ Unique identifier to a tensor storage. Multiple different tensors can share the same underlying storage. For
+ example, "meta" tensors all share the same storage, and thus their identifier will all be equal. This identifier is
+ guaranteed to be unique and constant for this tensor's storage during its lifetime. Two tensor storages with
+ non-overlapping lifetimes may have the same id.
+ """
+ _SIZE = {
+ torch.int64: 8,
+ torch.float32: 4,
+ torch.int32: 4,
+ torch.bfloat16: 2,
+ torch.float16: 2,
+ torch.int16: 2,
+ torch.uint8: 1,
+ torch.int8: 1,
+ torch.bool: 1,
+ torch.float64: 8,
+ }
+ try:
+ storage_ptr = tensor.untyped_storage().data_ptr()
+ storage_size = tensor.untyped_storage().nbytes()
+ except Exception:
+ try:
+ # Fallback for torch==1.10
+ storage_ptr = tensor.storage().data_ptr()
+ storage_size = tensor.storage().size() * _SIZE[tensor.dtype]
+ except NotImplementedError:
+ # Fallback for meta storage
+ storage_ptr = 0
+ # On torch >=2.0 this is the tensor size
+ storage_size = tensor.nelement() * _SIZE[tensor.dtype]
+
+ return tensor.device, storage_ptr, storage_size
+
+
+def set_module_tensor_to_device(
+ module: nn.Module,
+ tensor_name: str,
+ device: Union[int, str, torch.device],
+ value: Optional[torch.Tensor] = None,
+ dtype: Optional[Union[str, torch.dtype]] = None,
+ fp16_statistics: Optional[torch.HalfTensor] = None,
+ tied_params_map: Optional[dict[int, dict[torch.device, torch.Tensor]]] = None,
+ non_blocking: bool = False,
+ clear_cache: bool = True,
+):
+ """
+ A helper function to set a given tensor (parameter of buffer) of a module on a specific device (note that doing
+ `param.to(device)` creates a new tensor not linked to the parameter, which is why we need this function).
+
+ Args:
+ module (`torch.nn.Module`):
+ The module in which the tensor we want to move lives.
+ tensor_name (`str`):
+ The full name of the parameter/buffer.
+ device (`int`, `str` or `torch.device`):
+ The device on which to set the tensor.
+ value (`torch.Tensor`, *optional*):
+ The value of the tensor (useful when going from the meta device to any other device).
+ dtype (`torch.dtype`, *optional*):
+ If passed along the value of the parameter will be cast to this `dtype`. Otherwise, `value` will be cast to
+ the dtype of the existing parameter in the model.
+ fp16_statistics (`torch.HalfTensor`, *optional*):
+ The list of fp16 statistics to set on the module, used for 8 bit model serialization.
+ tied_params_map (Dict[int, Dict[torch.device, torch.Tensor]], *optional*, defaults to `None`):
+ A map of current data pointers to dictionaries of devices to already dispatched tied weights. For a given
+ execution device, this parameter is useful to reuse the first available pointer of a shared weight on the
+ device for all others, instead of duplicating memory.
+ non_blocking (`bool`, *optional*, defaults to `False`):
+ If `True`, the device transfer will be asynchronous with respect to the host, if possible.
+ clear_cache (`bool`, *optional*, defaults to `True`):
+ Whether or not to clear the device cache after setting the tensor on the device.
+ """
+ # Recurse if needed
+ if "." in tensor_name:
+ splits = tensor_name.split(".")
+ for split in splits[:-1]:
+ new_module = getattr(module, split)
+ if new_module is None:
+ raise ValueError(f"{module} has no attribute {split}.")
+ module = new_module
+ tensor_name = splits[-1]
+
+ if tensor_name not in module._parameters and tensor_name not in module._buffers:
+ raise ValueError(f"{module} does not have a parameter or a buffer named {tensor_name}.")
+ is_buffer = tensor_name in module._buffers
+ old_value = getattr(module, tensor_name)
+
+ # Treat the case where old_value (or a custom `value`, typically offloaded to RAM/disk) belongs to a tied group, and one of the weight
+ # in the tied group has already been dispatched to the device, by avoiding reallocating memory on the device and just copying the pointer.
+ if (
+ value is not None
+ and tied_params_map is not None
+ and value.data_ptr() in tied_params_map
+ and device in tied_params_map[value.data_ptr()]
+ ):
+ module._parameters[tensor_name] = tied_params_map[value.data_ptr()][device]
+ return
+ elif (
+ tied_params_map is not None
+ and old_value.data_ptr() in tied_params_map
+ and device in tied_params_map[old_value.data_ptr()]
+ ):
+ module._parameters[tensor_name] = tied_params_map[old_value.data_ptr()][device]
+ return
+
+ if old_value.device == torch.device("meta") and device not in ["meta", torch.device("meta")] and value is None:
+ raise ValueError(f"{tensor_name} is on the meta device, we need a `value` to put in on {device}.")
+
+ param = module._parameters[tensor_name] if tensor_name in module._parameters else None
+ param_cls = type(param)
+
+ if value is not None:
+ # We can expect mismatches when using bnb 4bit since Params4bit will reshape and pack the weights.
+ # In other cases, we want to make sure we're not loading checkpoints that do not match the config.
+ if old_value.shape != value.shape and param_cls.__name__ != "Params4bit":
+ raise ValueError(
+ f'Trying to set a tensor of shape {value.shape} in "{tensor_name}" (which has shape {old_value.shape}), this looks incorrect.'
+ )
+
+ if dtype is None:
+ # For compatibility with PyTorch load_state_dict which converts state dict dtype to existing dtype in model
+ value = value.to(old_value.dtype, non_blocking=non_blocking)
+ elif not str(value.dtype).startswith(("torch.uint", "torch.int", "torch.bool")):
+ value = value.to(dtype, non_blocking=non_blocking)
+
+ device_quantization = None
+ with torch.no_grad():
+ # leave it on cpu first before moving them to cuda
+ # # fix the case where the device is meta, we don't want to put it on cpu because there is no data =0
+ if (
+ param is not None
+ and param.device.type not in ("cuda", "xpu")
+ and torch.device(device).type in ("cuda", "xpu")
+ and param_cls.__name__ in ["Int8Params", "FP4Params", "Params4bit"]
+ ):
+ device_quantization = device
+ device = "cpu"
+ # `torch.Tensor.to()` is not supported by `torch_npu` (see this [issue](https://github.com/Ascend/pytorch/issues/16)).
+ if isinstance(device, int):
+ if is_npu_available():
+ device = f"npu:{device}"
+ elif is_mlu_available():
+ device = f"mlu:{device}"
+ elif is_sdaa_available():
+ device = f"sdaa:{device}"
+ elif is_musa_available():
+ device = f"musa:{device}"
+ elif is_hpu_available():
+ device = "hpu"
+ if "xpu" in str(device) and not is_xpu_available():
+ raise ValueError(f'{device} is not available, you should use device="cpu" instead')
+ if value is None:
+ new_value = old_value.to(device, non_blocking=non_blocking)
+ if dtype is not None and device in ["meta", torch.device("meta")]:
+ if not str(old_value.dtype).startswith(("torch.uint", "torch.int", "torch.bool")):
+ new_value = new_value.to(dtype, non_blocking=non_blocking)
+
+ if not is_buffer:
+ module._parameters[tensor_name] = param_cls(new_value, requires_grad=old_value.requires_grad)
+ elif isinstance(value, torch.Tensor):
+ new_value = value.to(device, non_blocking=non_blocking)
+ else:
+ new_value = torch.tensor(value, device=device)
+ if device_quantization is not None:
+ device = device_quantization
+ if is_buffer:
+ module._buffers[tensor_name] = new_value
+ elif value is not None or not check_device_same(torch.device(device), module._parameters[tensor_name].device):
+ param_cls = type(module._parameters[tensor_name])
+ kwargs = module._parameters[tensor_name].__dict__
+ if param_cls.__name__ in ["Int8Params", "FP4Params", "Params4bit"]:
+ if param_cls.__name__ == "Int8Params" and new_value.dtype == torch.float32:
+ # downcast to fp16 if any - needed for 8bit serialization
+ new_value = new_value.to(torch.float16, non_blocking=non_blocking)
+ # quantize module that are going to stay on the cpu so that we offload quantized weights
+ if device == "cpu" and param_cls.__name__ == "Int8Params":
+ new_value = param_cls(new_value, requires_grad=old_value.requires_grad, **kwargs).to(0).to("cpu")
+ new_value.CB = new_value.CB.to("cpu")
+ new_value.SCB = new_value.SCB.to("cpu")
+ else:
+ new_value = param_cls(new_value, requires_grad=old_value.requires_grad, **kwargs).to(
+ device, non_blocking=non_blocking
+ )
+ elif param_cls.__name__ in ["QTensor", "QBitsTensor"]:
+ new_value = torch.nn.Parameter(new_value, requires_grad=old_value.requires_grad).to(
+ device, non_blocking=non_blocking
+ )
+ elif param_cls.__name__ in ["AffineQuantizedTensor"]:
+ new_value = new_value.to(device, non_blocking=non_blocking)
+ else:
+ new_value = param_cls(new_value, requires_grad=old_value.requires_grad).to(
+ device, non_blocking=non_blocking
+ )
+
+ module._parameters[tensor_name] = new_value
+ if fp16_statistics is not None:
+ module._parameters[tensor_name].SCB = fp16_statistics.to(device, non_blocking=non_blocking)
+ del fp16_statistics
+ # as we put the weight to meta, it doesn't have SCB attr anymore. make sure that it is not a meta weight
+ if (
+ module.__class__.__name__ == "Linear8bitLt"
+ and getattr(module.weight, "SCB", None) is None
+ and str(module.weight.device) != "meta"
+ ):
+ # quantize only if necessary
+ device_index = torch.device(device).index if torch.device(device).type == "cuda" else None
+ if not getattr(module.weight, "SCB", None) and device_index is not None:
+ if module.bias is not None and module.bias.device.type != "meta":
+ # if a bias exists, we need to wait until the bias is set on the correct device
+ module = module.cuda(device_index)
+ elif module.bias is None:
+ # if no bias exists, we can quantize right away
+ module = module.cuda(device_index)
+ elif (
+ module.__class__.__name__ == "Linear4bit"
+ and getattr(module.weight, "quant_state", None) is None
+ and str(module.weight.device) != "meta"
+ ):
+ # quantize only if necessary
+ device_index = torch.device(device).index if torch.device(device).type == "cuda" else None
+ if not getattr(module.weight, "quant_state", None) and device_index is not None:
+ module.weight = module.weight.cuda(device_index)
+
+ # clean pre and post forward hook
+ if clear_cache and device not in ("cpu", "meta"):
+ clear_device_cache()
+
+ # When handling tied weights, we update tied_params_map to keep track of the tied weights that have already been allocated on the device in
+ # order to avoid duplicating memory, see above.
+ if (
+ tied_params_map is not None
+ and old_value.data_ptr() in tied_params_map
+ and device not in tied_params_map[old_value.data_ptr()]
+ ):
+ tied_params_map[old_value.data_ptr()][device] = new_value
+ elif (
+ value is not None
+ and tied_params_map is not None
+ and value.data_ptr() in tied_params_map
+ and device not in tied_params_map[value.data_ptr()]
+ ):
+ tied_params_map[value.data_ptr()][device] = new_value
+
+
+def named_module_tensors(
+ module: nn.Module, include_buffers: bool = True, recurse: bool = False, remove_non_persistent: bool = False
+):
+ """
+ A helper function that gathers all the tensors (parameters + buffers) of a given module. If `include_buffers=True`
+ it's the same as doing `module.named_parameters(recurse=recurse) + module.named_buffers(recurse=recurse)`.
+
+ Args:
+ module (`torch.nn.Module`):
+ The module we want the tensors on.
+ include_buffer (`bool`, *optional*, defaults to `True`):
+ Whether or not to include the buffers in the result.
+ recurse (`bool`, *optional`, defaults to `False`):
+ Whether or not to go look in every submodule or just return the direct parameters and buffers.
+ remove_non_persistent (`bool`, *optional*, defaults to `False`):
+ Whether or not to remove the non persistent buffer from the buffers. Useful only when include_buffers =
+ True
+ """
+ yield from module.named_parameters(recurse=recurse)
+
+ if include_buffers:
+ non_persistent_buffers = set()
+ if remove_non_persistent:
+ non_persistent_buffers = get_non_persistent_buffers(module, recurse=recurse)
+ for named_buffer in module.named_buffers(recurse=recurse):
+ name, _ = named_buffer
+ if name not in non_persistent_buffers:
+ yield named_buffer
+
+
+def get_non_persistent_buffers(module: nn.Module, recurse: bool = False, fqns: bool = False):
+ """
+ Gather all non persistent buffers of a given modules into a set
+
+ Args:
+ module (`nn.Module`):
+ The module we want the non persistent buffers on.
+ recurse (`bool`, *optional*, defaults to `False`):
+ Whether or not to go look in every submodule or just return the direct non persistent buffers.
+ fqns (`bool`, *optional*, defaults to `False`):
+ Whether or not to return the fully-qualified names of the non persistent buffers.
+ """
+
+ non_persistent_buffers_set = module._non_persistent_buffers_set
+ if recurse:
+ for n, m in module.named_modules():
+ if fqns:
+ non_persistent_buffers_set |= {n + "." + b for b in m._non_persistent_buffers_set}
+ else:
+ non_persistent_buffers_set |= m._non_persistent_buffers_set
+
+ return non_persistent_buffers_set
+
+
+def check_tied_parameters_in_config(model: nn.Module):
+ """
+ Check if there is any indication in the given model that some weights should be tied.
+
+ Args:
+ model (`torch.nn.Module`): The model to inspect
+
+ Returns:
+ bool: True if the model needs to have tied weights
+ """
+
+ # based on model.tie_weights() method
+ has_tied_word_embedding = False
+ has_tied_encoder_decoder = False
+ has_tied_module = False
+
+ if "PreTrainedModel" in [c.__name__ for c in inspect.getmro(model.__class__)]:
+ has_tied_word_embedding = False
+ model_decoder_config = None
+ if hasattr(model, "config"):
+ model_decoder_config = (
+ model.config.get_text_config(decoder=True)
+ if hasattr(model.config, "get_text_config")
+ else model.config
+ )
+ has_tied_word_embedding = (
+ model_decoder_config is not None
+ and getattr(model_decoder_config, "tie_word_embeddings", False)
+ and model.get_output_embeddings()
+ )
+
+ has_tied_encoder_decoder = (
+ hasattr(model, "config")
+ and getattr(model.config, "is_encoder_decoder", False)
+ and getattr(model.config, "tie_encoder_decoder", False)
+ )
+ has_tied_module = any(hasattr(module, "_tie_weights") for module in model.modules())
+ return any([has_tied_word_embedding, has_tied_encoder_decoder, has_tied_module])
+
+
+def _get_param_device(param, device_map):
+ if param in device_map:
+ return device_map[param]
+ parent_param = ".".join(param.split(".")[:-1])
+ if parent_param == param:
+ raise ValueError(f"The `device_map` does not contain the module {param}.")
+ else:
+ return _get_param_device(parent_param, device_map)
+
+
+def check_tied_parameters_on_same_device(tied_params, device_map):
+ """
+ Check if tied parameters are on the same device
+
+ Args:
+ tied_params (`List[List[str]]`):
+ A list of lists of parameter names being all tied together.
+
+ device_map (`Dict[str, Union[int, str, torch.device]]`):
+ A map that specifies where each submodule should go.
+
+ """
+ for tie_param in tied_params:
+ tie_param_devices = {}
+ for param in tie_param:
+ tie_param_devices[param] = _get_param_device(param, device_map)
+ if len(set(tie_param_devices.values())) > 1:
+ logger.warning(
+ f"Tied parameters are on different devices: {tie_param_devices}. "
+ "Please modify your custom device map or set `device_map='auto'`. "
+ )
+
+
+def find_tied_parameters(model: torch.nn.Module, **kwargs) -> list[list[str]]:
+ """
+ Find the tied parameters in a given model.
+
+
+
+ The signature accepts keyword arguments, but they are for the recursive part of this function and you should ignore
+ them.
+
+
+
+ Args:
+ model (`torch.nn.Module`): The model to inspect.
+
+ Returns:
+ List[List[str]]: A list of lists of parameter names being all tied together.
+
+ Example:
+
+ ```py
+ >>> from collections import OrderedDict
+ >>> import torch.nn as nn
+
+ >>> model = nn.Sequential(OrderedDict([("linear1", nn.Linear(4, 4)), ("linear2", nn.Linear(4, 4))]))
+ >>> model.linear2.weight = model.linear1.weight
+ >>> find_tied_parameters(model)
+ [['linear1.weight', 'linear2.weight']]
+ ```
+ """
+
+ # get ALL model parameters and their names
+ all_named_parameters = {name: param for name, param in model.named_parameters(remove_duplicate=False)}
+
+ # get ONLY unique named parameters,
+ # if parameter is tied and have multiple names, it will be included only once
+ no_duplicate_named_parameters = {name: param for name, param in model.named_parameters(remove_duplicate=True)}
+
+ # the difference of the two sets will give us the tied parameters
+ tied_param_names = set(all_named_parameters.keys()) - set(no_duplicate_named_parameters.keys())
+
+ # 'tied_param_names' contains the names of parameters that are tied in the model, but we do not know
+ # which names refer to the same parameter. To identify this, we need to group them together.
+ tied_param_groups = {}
+ for tied_param_name in tied_param_names:
+ tied_param = all_named_parameters[tied_param_name]
+ for param_name, param in no_duplicate_named_parameters.items():
+ # compare if parameters are the same, if so, group their names together
+ if param is tied_param:
+ if param_name not in tied_param_groups:
+ tied_param_groups[param_name] = []
+ tied_param_groups[param_name].append(tied_param_name)
+
+ return [sorted([weight] + list(set(tied))) for weight, tied in tied_param_groups.items()]
+
+
+def retie_parameters(model, tied_params):
+ """
+ Reties tied parameters in a given model if the link was broken (for instance when adding hooks).
+
+ Args:
+ model (`torch.nn.Module`):
+ The model in which to retie parameters.
+ tied_params (`List[List[str]]`):
+ A mapping parameter name to tied parameter name as obtained by `find_tied_parameters`.
+ """
+ for tied_group in tied_params:
+ param_to_tie = None
+ # two loops : the first one to set param_to_tie , the second one to change the values of tied_group
+ for param_name in tied_group:
+ module = model
+ splits = param_name.split(".")
+ for split in splits[:-1]:
+ module = getattr(module, split)
+ param = getattr(module, splits[-1])
+ if param_to_tie is None and param.device != torch.device("meta"):
+ param_to_tie = param
+ break
+ if param_to_tie is not None:
+ for param_name in tied_group:
+ module = model
+ splits = param_name.split(".")
+ for split in splits[:-1]:
+ module = getattr(module, split)
+ setattr(module, splits[-1], param_to_tie)
+
+
+def _get_proper_dtype(dtype: Union[str, torch.device]) -> torch.dtype:
+ """
+ Just does torch.dtype(dtype) if necessary.
+ """
+ if isinstance(dtype, str):
+ # We accept "torch.float16" or just "float16"
+ dtype = dtype.replace("torch.", "")
+ dtype = getattr(torch, dtype)
+ return dtype
+
+
+def compute_module_sizes(
+ model: nn.Module,
+ dtype: Optional[Union[str, torch.device]] = None,
+ special_dtypes: Optional[dict[str, Union[str, torch.device]]] = None,
+ buffers_only: bool = False,
+):
+ """
+ Compute the size of each submodule of a given model.
+ """
+ if dtype is not None:
+ dtype = _get_proper_dtype(dtype)
+ dtype_size = dtype_byte_size(dtype)
+ if special_dtypes is not None:
+ special_dtypes = {key: _get_proper_dtype(dtyp) for key, dtyp in special_dtypes.items()}
+ special_dtypes_size = {key: dtype_byte_size(dtyp) for key, dtyp in special_dtypes.items()}
+ module_sizes = defaultdict(int)
+
+ module_list = []
+
+ if not buffers_only:
+ module_list = named_module_tensors(model, recurse=True)
+ else:
+ module_list = model.named_buffers(recurse=True)
+
+ for name, tensor in module_list:
+ if special_dtypes is not None and name in special_dtypes:
+ size = tensor.numel() * special_dtypes_size[name]
+ elif dtype is None:
+ size = tensor.numel() * dtype_byte_size(tensor.dtype)
+ elif str(tensor.dtype).startswith(("torch.uint", "torch.int", "torch.bool")):
+ # According to the code in set_module_tensor_to_device, these types won't be converted
+ # so use their original size here
+ size = tensor.numel() * dtype_byte_size(tensor.dtype)
+ else:
+ size = tensor.numel() * min(dtype_size, dtype_byte_size(tensor.dtype))
+ name_parts = name.split(".")
+ for idx in range(len(name_parts) + 1):
+ module_sizes[".".join(name_parts[:idx])] += size
+
+ return module_sizes
+
+
+def compute_module_total_buffer_size(
+ model: nn.Module,
+ dtype: Optional[Union[str, torch.device]] = None,
+ special_dtypes: Optional[dict[str, Union[str, torch.device]]] = None,
+):
+ """
+ Compute the total size of buffers in each submodule of a given model.
+ """
+ module_sizes = compute_module_sizes(model, dtype=dtype, special_dtypes=special_dtypes, buffers_only=True)
+ return module_sizes.get("", 0)
+
+
+def get_max_layer_size(
+ modules: list[tuple[str, torch.nn.Module]], module_sizes: dict[str, int], no_split_module_classes: list[str]
+):
+ """
+ Utility function that will scan a list of named modules and return the maximum size used by one full layer. The
+ definition of a layer being:
+ - a module with no direct children (just parameters and buffers)
+ - a module whose class name is in the list `no_split_module_classes`
+
+ Args:
+ modules (`List[Tuple[str, torch.nn.Module]]`):
+ The list of named modules where we want to determine the maximum layer size.
+ module_sizes (`Dict[str, int]`):
+ A dictionary mapping each layer name to its size (as generated by `compute_module_sizes`).
+ no_split_module_classes (`List[str]`):
+ A list of class names for layers we don't want to be split.
+
+ Returns:
+ `Tuple[int, List[str]]`: The maximum size of a layer with the list of layer names realizing that maximum size.
+ """
+ max_size = 0
+ layer_names = []
+ modules_to_treat = modules.copy()
+ while len(modules_to_treat) > 0:
+ module_name, module = modules_to_treat.pop(0)
+ modules_children = list(module.named_children()) if isinstance(module, torch.nn.Module) else []
+ if len(modules_children) == 0 or module.__class__.__name__ in no_split_module_classes:
+ # No splitting this one so we compare to the max_size
+ size = module_sizes[module_name]
+ if size > max_size:
+ max_size = size
+ layer_names = [module_name]
+ elif size == max_size:
+ layer_names.append(module_name)
+ else:
+ modules_to_treat = [(f"{module_name}.{n}", v) for n, v in modules_children] + modules_to_treat
+ return max_size, layer_names
+
+
+def get_max_memory(max_memory: Optional[dict[Union[int, str], Union[int, str]]] = None):
+ """
+ Get the maximum memory available if nothing is passed, converts string to int otherwise.
+ """
+ import psutil
+
+ if max_memory is None:
+ max_memory = {}
+ # Make sure CUDA is initialized on each GPU to have the right memory info.
+ if is_npu_available():
+ for i in range(torch.npu.device_count()):
+ try:
+ _ = torch.tensor(0, device=torch.device("npu", i))
+ max_memory[i] = torch.npu.mem_get_info(i)[0]
+ except Exception:
+ logger.info(f"Device {i} seems unavailable, Proceeding to check subsequent devices.")
+ continue
+ elif is_mlu_available():
+ for i in range(torch.mlu.device_count()):
+ try:
+ _ = torch.tensor(0, device=torch.device("mlu", i))
+ max_memory[i] = torch.mlu.mem_get_info(i)[0]
+ except Exception:
+ logger.info(f"Device {i} seems unavailable, Proceeding to check subsequent devices.")
+ continue
+ elif is_sdaa_available():
+ for i in range(torch.sdaa.device_count()):
+ try:
+ _ = torch.tensor(0, device=torch.device("sdaa", i))
+ max_memory[i] = torch.sdaa.mem_get_info(i)[0]
+ except Exception:
+ logger.info(f"Device {i} seems unavailable, Proceeding to check subsequent devices.")
+ continue
+ elif is_musa_available():
+ for i in range(torch.musa.device_count()):
+ try:
+ _ = torch.tensor(0, device=torch.device("musa", i))
+ max_memory[i] = torch.musa.mem_get_info(i)[0]
+ except Exception:
+ logger.info(f"Device {i} seems unavailable, Proceeding to check subsequent devices.")
+ continue
+ elif is_xpu_available():
+ for i in range(torch.xpu.device_count()):
+ try:
+ _ = torch.tensor(0, device=torch.device("xpu", i))
+ max_memory[i] = get_xpu_available_memory(i)
+ except Exception:
+ logger.info(f"Device {i} seems unavailable, Proceeding to check subsequent devices.")
+ continue
+ elif is_hpu_available():
+ for i in range(torch.hpu.device_count()):
+ try:
+ _ = torch.tensor(0, device=torch.device("hpu", i))
+ max_memory[i] = torch.hpu.mem_get_info(i)[0]
+ except Exception:
+ logger.info(f"Device {i} seems unavailable, Proceeding to check subsequent devices.")
+ continue
+ else:
+ for i in range(torch.cuda.device_count()):
+ try:
+ _ = torch.tensor([0], device=i)
+ max_memory[i] = torch.cuda.mem_get_info(i)[0]
+ except Exception:
+ logger.info(f"Device {i} seems unavailable, Proceeding to check subsequent devices.")
+ continue
+ # allocate everything in the mps device as the RAM is shared
+ if is_mps_available():
+ max_memory["mps"] = psutil.virtual_memory().available
+ else:
+ max_memory["cpu"] = psutil.virtual_memory().available
+ return max_memory
+
+ for key in max_memory:
+ if isinstance(max_memory[key], str):
+ max_memory[key] = convert_file_size_to_int(max_memory[key])
+
+ # Need to sort the device by type to make sure that we allocate the gpu first.
+ # As gpu/npu/xpu are represented by int, we need to sort them first.
+ gpu_devices = [k for k in max_memory.keys() if isinstance(k, int)]
+ gpu_devices.sort()
+ # check if gpu/npu/xpu devices are available and if not, throw a warning
+ if is_npu_available():
+ num_devices = torch.npu.device_count()
+ elif is_mlu_available():
+ num_devices = torch.mlu.device_count()
+ elif is_sdaa_available():
+ num_devices = torch.sdaa.device_count()
+ elif is_musa_available():
+ num_devices = torch.musa.device_count()
+ elif is_xpu_available():
+ num_devices = torch.xpu.device_count()
+ elif is_hpu_available():
+ num_devices = torch.hpu.device_count()
+ else:
+ num_devices = torch.cuda.device_count()
+ for device in gpu_devices:
+ if device >= num_devices or device < 0:
+ logger.warning(f"Device {device} is not available, available devices are {list(range(num_devices))}")
+ # Add the other devices in the preset order if they are available
+ all_devices = gpu_devices + [k for k in ["mps", "cpu", "disk"] if k in max_memory.keys()]
+ # Raise an error if a device is not recognized
+ for k in max_memory.keys():
+ if k not in all_devices:
+ raise ValueError(
+ f"Device {k} is not recognized, available devices are integers(for GPU/XPU), 'mps', 'cpu' and 'disk'"
+ )
+ max_memory = {k: max_memory[k] for k in all_devices}
+
+ return max_memory
+
+
+def clean_device_map(device_map: dict[str, Union[int, str, torch.device]], module_name: str = ""):
+ """
+ Cleans a device_map by grouping all submodules that go on the same device together.
+ """
+ # Get the value of the current module and if there is only one split across several keys, regroup it.
+ prefix = "" if module_name == "" else f"{module_name}."
+ values = [v for k, v in device_map.items() if k.startswith(prefix)]
+ if len(set(values)) == 1 and len(values) > 1:
+ for k in [k for k in device_map if k.startswith(prefix)]:
+ del device_map[k]
+ device_map[module_name] = values[0]
+
+ # Recurse over the children
+ children_modules = [k for k in device_map.keys() if k.startswith(prefix) and len(k) > len(module_name)]
+ idx = len(module_name.split(".")) + 1 if len(module_name) > 0 else 1
+ children_modules = set(".".join(k.split(".")[:idx]) for k in children_modules)
+ for child in children_modules:
+ clean_device_map(device_map, module_name=child)
+
+ return device_map
+
+
+def load_offloaded_weights(model, index, offload_folder):
+ """
+ Loads the weights from the offload folder into the model.
+
+ Args:
+ model (`torch.nn.Module`):
+ The model to load the weights into.
+ index (`dict`):
+ A dictionary containing the parameter name and its metadata for each parameter that was offloaded from the
+ model.
+ offload_folder (`str`):
+ The folder where the offloaded weights are stored.
+ """
+ if index is None or len(index) == 0:
+ # Nothing to do
+ return
+ for param_name, metadata in index.items():
+ if "SCB" in param_name:
+ continue
+ fp16_statistics = None
+ if "weight" in param_name and param_name.replace("weight", "SCB") in index.keys():
+ weight_name = param_name.replace("weight", "SCB")
+ fp16_statistics = load_offloaded_weight(
+ os.path.join(offload_folder, f"{weight_name}.dat"), index[weight_name]
+ )
+ tensor_file = os.path.join(offload_folder, f"{param_name}.dat")
+ weight = load_offloaded_weight(tensor_file, metadata)
+ set_module_tensor_to_device(model, param_name, "cpu", value=weight, fp16_statistics=fp16_statistics)
+
+
+def get_module_leaves(module_sizes):
+ module_children = {}
+ for module in module_sizes:
+ if module == "" or "." not in module:
+ continue
+ parent = module.rsplit(".", 1)[0]
+ module_children[parent] = module_children.get(parent, 0) + 1
+ leaves = [module for module in module_sizes if module_children.get(module, 0) == 0 and module != ""]
+ return leaves
+
+
+def get_balanced_memory(
+ model: nn.Module,
+ max_memory: Optional[dict[Union[int, str], Union[int, str]]] = None,
+ no_split_module_classes: Optional[list[str]] = None,
+ dtype: Optional[Union[str, torch.dtype]] = None,
+ special_dtypes: Optional[dict[str, Union[str, torch.device]]] = None,
+ low_zero: bool = False,
+):
+ """
+ Compute a `max_memory` dictionary for [`infer_auto_device_map`] that will balance the use of each available GPU.
+
+
+
+ All computation is done analyzing sizes and dtypes of the model parameters. As a result, the model can be on the
+ meta device (as it would if initialized within the `init_empty_weights` context manager).
+
+
+
+ Args:
+ model (`torch.nn.Module`):
+ The model to analyze.
+ max_memory (`Dict`, *optional*):
+ A dictionary device identifier to maximum memory. Will default to the maximum memory available if unset.
+ Example: `max_memory={0: "1GB"}`.
+ no_split_module_classes (`List[str]`, *optional*):
+ A list of layer class names that should never be split across device (for instance any layer that has a
+ residual connection).
+ dtype (`str` or `torch.dtype`, *optional*):
+ If provided, the weights will be converted to that type when loaded.
+ special_dtypes (`Dict[str, Union[str, torch.device]]`, *optional*):
+ If provided, special dtypes to consider for some specific weights (will override dtype used as default for
+ all weights).
+ low_zero (`bool`, *optional*):
+ Minimizes the number of weights on GPU 0, which is convenient when it's used for other operations (like the
+ Transformers generate function).
+ """
+ # Get default / clean up max_memory
+ user_not_set_max_memory = max_memory is None
+ max_memory = get_max_memory(max_memory)
+
+ if is_npu_available():
+ expected_device_type = "npu"
+ elif is_mlu_available():
+ expected_device_type = "mlu"
+ elif is_sdaa_available():
+ expected_device_type = "sdaa"
+ elif is_musa_available():
+ expected_device_type = "musa"
+ elif is_xpu_available():
+ expected_device_type = "xpu"
+ elif is_hpu_available():
+ expected_device_type = "hpu"
+ elif is_mps_available():
+ expected_device_type = "mps"
+ else:
+ expected_device_type = "cuda"
+ num_devices = len([d for d in max_memory if torch.device(d).type == expected_device_type and max_memory[d] > 0])
+
+ if num_devices == 0:
+ return max_memory
+
+ if num_devices == 1:
+ # We cannot do low_zero on just one GPU, but we will still reserve some memory for the buffer
+ low_zero = False
+ # If user just asked us to handle memory usage, we should avoid OOM
+ if user_not_set_max_memory:
+ for key in max_memory.keys():
+ if isinstance(key, int):
+ max_memory[key] *= 0.9 # 90% is a good compromise
+ logger.info(
+ f"We will use 90% of the memory on device {key} for storing the model, and 10% for the buffer to avoid OOM. "
+ "You can set `max_memory` in to a higher value to use more memory (at your own risk)."
+ )
+ break # only one device
+
+ module_sizes = compute_module_sizes(model, dtype=dtype, special_dtypes=special_dtypes)
+ per_gpu = module_sizes[""] // (num_devices - 1 if low_zero else num_devices)
+
+ # We can't just set the memory to model_size // num_devices as it will end being too small: each GPU will get
+ # slightly less layers and some layers will end up offload at the end. So this function computes a buffer size to
+ # add which is the biggest of:
+ # - the size of no split block (if applicable)
+ # - the mean of the layer sizes
+ if no_split_module_classes is None:
+ no_split_module_classes = []
+ elif not isinstance(no_split_module_classes, (list, tuple)):
+ no_split_module_classes = [no_split_module_classes]
+
+ # Identify the size of the no_split_block modules
+ if len(no_split_module_classes) > 0:
+ no_split_children = {}
+ for name, size in module_sizes.items():
+ if name == "":
+ continue
+ submodule = model
+ for submodule_name in name.split("."):
+ submodule = getattr(submodule, submodule_name)
+ class_name = submodule.__class__.__name__
+ if class_name in no_split_module_classes and class_name not in no_split_children:
+ no_split_children[class_name] = size
+
+ if set(no_split_children.keys()) == set(no_split_module_classes):
+ break
+ buffer = max(no_split_children.values()) if len(no_split_children) > 0 else 0
+ else:
+ buffer = 0
+
+ # Compute mean of final modules. In the first dict of module sizes, leaves are the parameters
+ leaves = get_module_leaves(module_sizes)
+ leaves_set = set(leaves) # Convert to set for O(1) membership testing
+ module_sizes = {n: v for n, v in module_sizes.items() if n not in leaves_set}
+ # Once removed, leaves are the final modules.
+ leaves = get_module_leaves(module_sizes)
+ mean_leaves = int(sum([module_sizes[n] for n in leaves]) / max(len(leaves), 1))
+ buffer = int(1.25 * max(buffer, mean_leaves))
+ per_gpu += buffer
+
+ # Sorted list of GPUs id (we may have some gpu ids not included in the our max_memory list - let's ignore them)
+ gpus_idx_list = list(
+ sorted(
+ device_id for device_id, device_mem in max_memory.items() if isinstance(device_id, int) and device_mem > 0
+ )
+ )
+ # The last device is left with max_memory just in case the buffer is not enough.
+ for idx in gpus_idx_list[:-1]:
+ max_memory[idx] = min(max_memory[0] if low_zero and idx == 0 else per_gpu, max_memory[idx])
+
+ if low_zero:
+ min_zero = max(0, module_sizes[""] - sum([max_memory[i] for i in range(1, num_devices)]))
+ max_memory[0] = min(min_zero, max_memory[0])
+
+ return max_memory
+
+
+def calculate_maximum_sizes(model: torch.nn.Module):
+ "Computes the total size of the model and its largest layer"
+ sizes = compute_module_sizes(model)
+ # `transformers` models store this information for us
+ no_split_modules = getattr(model, "_no_split_modules", None)
+ if no_split_modules is None:
+ no_split_modules = []
+
+ modules_to_treat = (
+ list(model.named_parameters(recurse=False))
+ + list(model.named_children())
+ + list(model.named_buffers(recurse=False))
+ )
+ largest_layer = get_max_layer_size(modules_to_treat, sizes, no_split_modules)
+ total_size = sizes[""]
+ return total_size, largest_layer
+
+
+def _init_infer_auto_device_map(
+ model: nn.Module,
+ max_memory: Optional[dict[Union[int, str], Union[int, str]]] = None,
+ no_split_module_classes: Optional[list[str]] = None,
+ dtype: Optional[Union[str, torch.dtype]] = None,
+ special_dtypes: Optional[dict[str, Union[str, torch.device]]] = None,
+) -> tuple[
+ list[Union[int, str]],
+ dict[Union[int, str], Union[int, str]],
+ list[Union[int, str]],
+ list[int],
+ dict[str, int],
+ list[list[str]],
+ list[str],
+ list[tuple[str, nn.Module]],
+]:
+ """
+ Initialize variables required for computing the device map for model allocation.
+ """
+ max_memory = get_max_memory(max_memory)
+ if no_split_module_classes is None:
+ no_split_module_classes = []
+ elif not isinstance(no_split_module_classes, (list, tuple)):
+ no_split_module_classes = [no_split_module_classes]
+
+ devices = list(max_memory.keys())
+ if "disk" not in devices:
+ devices.append("disk")
+ gpus = [device for device in devices if device not in ["cpu", "disk"]]
+
+ # Devices that need to keep space for a potential offloaded layer.
+ if "mps" in gpus:
+ main_devices = ["mps"]
+ elif len(gpus) > 0:
+ main_devices = [gpus[0], "cpu"]
+ else:
+ main_devices = ["cpu"]
+
+ module_sizes = compute_module_sizes(model, dtype=dtype, special_dtypes=special_dtypes)
+ tied_parameters = find_tied_parameters(model)
+ if check_tied_parameters_in_config(model) and len(tied_parameters) == 0:
+ logger.warning(
+ "The model weights are not tied. Please use the `tie_weights` method before using the `infer_auto_device` function."
+ )
+
+ # Direct submodules and parameters
+ modules_to_treat = (
+ list(model.named_parameters(recurse=False))
+ + list(model.named_children())
+ + list(model.named_buffers(recurse=False))
+ )
+
+ return (
+ devices,
+ max_memory,
+ main_devices,
+ gpus,
+ module_sizes,
+ tied_parameters,
+ no_split_module_classes,
+ modules_to_treat,
+ )
+
+
+def get_module_size_with_ties(
+ tied_params,
+ module_size,
+ module_sizes,
+ modules_to_treat,
+) -> tuple[int, list[str], list[nn.Module]]:
+ """
+ Calculate the total size of a module, including its tied parameters.
+
+ Args:
+ tied_params (`List[str]`): The list of tied parameters.
+ module_size (`int`): The size of the module without tied parameters.
+ module_sizes (`Dict[str, int]`): A dictionary mapping each layer name to its size.
+ modules_to_treat (`List[Tuple[str, nn.Module]]`): The list of named modules to treat.
+
+ Returns:
+ `Tuple[int, List[str], List[nn.Module]]`: The total size of the module, the names of the tied modules, and the
+ tied modules.
+ """
+ if len(tied_params) < 1:
+ return module_size, [], []
+ tied_module_names = []
+ tied_modules = []
+
+ for tied_param in tied_params:
+ tied_module_index = [i for i, (n, _) in enumerate(modules_to_treat) if tied_param.startswith(n + ".")][0]
+ tied_module_names.append(modules_to_treat[tied_module_index][0])
+ tied_modules.append(modules_to_treat[tied_module_index][1])
+
+ module_size_with_ties = module_size
+ for tied_param, tied_module_name in zip(tied_params, tied_module_names):
+ module_size_with_ties += module_sizes[tied_module_name] - module_sizes[tied_param]
+
+ return module_size_with_ties, tied_module_names, tied_modules
+
+
+def fallback_allocate(
+ modules: list[tuple[str, nn.Module]],
+ module_sizes: dict[str, int],
+ size_limit: Union[int, str],
+ no_split_module_classes: Optional[list[str]] = None,
+ tied_parameters: Optional[list[list[str]]] = None,
+) -> tuple[Optional[str], Optional[nn.Module], list[tuple[str, nn.Module]]]:
+ """
+ Find a module that fits in the size limit using BFS and return it with its name and the remaining modules.
+
+ Args:
+ modules (`List[Tuple[str, nn.Module]]`):
+ The list of named modules to search in.
+ module_sizes (`Dict[str, int]`):
+ A dictionary mapping each layer name to its size (as generated by `compute_module_sizes`).
+ size_limit (`Union[int, str]`):
+ The maximum size a module can have.
+ no_split_module_classes (`Optional[List[str]]`, *optional*):
+ A list of class names for layers we don't want to be split.
+ tied_parameters (`Optional[List[List[str]]`, *optional*):
+ A list of lists of parameter names being all tied together.
+
+ Returns:
+ `Tuple[Optional[str], Optional[nn.Module], List[Tuple[str, nn.Module]]]`: A tuple containing:
+ - The name of the module that fits within the size limit.
+ - The module itself.
+ - The list of remaining modules after the found module is removed.
+ """
+ try:
+ size_limit = convert_file_size_to_int(size_limit)
+ except ValueError:
+ return None, None, modules
+
+ if no_split_module_classes is None:
+ no_split_module_classes = []
+
+ if tied_parameters is None:
+ tied_parameters = []
+
+ modules_to_search = modules.copy()
+ module_found = False
+
+ while modules_to_search:
+ name, module = modules_to_search.pop(0)
+
+ tied_param_groups = [
+ tied_group
+ for tied_group in tied_parameters
+ if any(name + "." in k + "." for k in tied_group) and not all(name + "." in k + "." for k in tied_group)
+ ]
+
+ tied_params = sum(
+ [[p for p in tied_group if name + "." not in p + "."] for tied_group in tied_param_groups], []
+ )
+
+ module_size_with_ties, _, _ = get_module_size_with_ties(
+ tied_params, module_sizes[name], module_sizes, modules_to_search
+ )
+
+ # If the module fits in the size limit, we found it.
+ if module_size_with_ties <= size_limit:
+ module_found = True
+ break
+
+ # The module is too big, we need to split it if possible.
+ modules_children = (
+ []
+ if isinstance(module, nn.Parameter) or isinstance(module, torch.Tensor)
+ else list(module.named_children())
+ )
+
+ # Split fails, move to the next module
+ if len(modules_children) == 0 or module.__class__.__name__ in no_split_module_classes:
+ continue
+
+ # split is possible, add the children to the list of modules to search
+ modules_children = list(module.named_parameters(recurse=False)) + modules_children
+ modules_to_search = [(f"{name}.{n}", v) for n, v in modules_children] + modules_to_search
+
+ if not module_found:
+ return None, None, modules
+
+ # Prepare the module list for removal of the found module
+ current_names = [n for n, _ in modules]
+ dot_idx = [i for i, c in enumerate(name) if c == "."]
+
+ for dot_index in dot_idx:
+ parent_name = name[:dot_index]
+ if parent_name in current_names:
+ parent_module_idx = current_names.index(parent_name)
+ _, parent_module = modules[parent_module_idx]
+ module_children = list(parent_module.named_parameters(recurse=False)) + list(
+ parent_module.named_children()
+ )
+ modules = (
+ modules[:parent_module_idx]
+ + [(f"{parent_name}.{n}", v) for n, v in module_children]
+ + modules[parent_module_idx + 1 :]
+ )
+ current_names = [n for n, _ in modules]
+
+ # Now the target module should be directly in the list
+ target_idx = current_names.index(name)
+ name, module = modules.pop(target_idx)
+
+ return name, module, modules
+
+
+def infer_auto_device_map(
+ model: nn.Module,
+ max_memory: Optional[dict[Union[int, str], Union[int, str]]] = None,
+ no_split_module_classes: Optional[list[str]] = None,
+ dtype: Optional[Union[str, torch.dtype]] = None,
+ special_dtypes: Optional[dict[str, Union[str, torch.dtype]]] = None,
+ verbose: bool = False,
+ clean_result: bool = True,
+ offload_buffers: bool = False,
+ fallback_allocation: bool = False,
+):
+ """
+ Compute a device map for a given model giving priority to GPUs, then offload on CPU and finally offload to disk,
+ such that:
+ - we don't exceed the memory available of any of the GPU.
+ - if offload to the CPU is needed, there is always room left on GPU 0 to put back the layer offloaded on CPU that
+ has the largest size.
+ - if offload to the CPU is needed,we don't exceed the RAM available on the CPU.
+ - if offload to the disk is needed, there is always room left on the CPU to put back the layer offloaded on disk
+ that has the largest size.
+
+
+
+ All computation is done analyzing sizes and dtypes of the model parameters. As a result, the model can be on the
+ meta device (as it would if initialized within the `init_empty_weights` context manager).
+
+
+
+ Args:
+ model (`torch.nn.Module`):
+ The model to analyze.
+ max_memory (`Dict`, *optional*):
+ A dictionary device identifier to maximum memory. Will default to the maximum memory available if unset.
+ Example: `max_memory={0: "1GB"}`.
+ no_split_module_classes (`List[str]`, *optional*):
+ A list of layer class names that should never be split across device (for instance any layer that has a
+ residual connection).
+ dtype (`str` or `torch.dtype`, *optional*):
+ If provided, the weights will be converted to that type when loaded.
+ special_dtypes (`Dict[str, Union[str, torch.device]]`, *optional*):
+ If provided, special dtypes to consider for some specific weights (will override dtype used as default for
+ all weights).
+ verbose (`bool`, *optional*, defaults to `False`):
+ Whether or not to provide debugging statements as the function builds the device_map.
+ clean_result (`bool`, *optional*, defaults to `True`):
+ Clean the resulting device_map by grouping all submodules that go on the same device together.
+ offload_buffers (`bool`, *optional*, defaults to `False`):
+ In the layers that are offloaded on the CPU or the hard drive, whether or not to offload the buffers as
+ well as the parameters.
+ fallback_allocation (`bool`, *optional*, defaults to `False`):
+ When regular allocation fails, try to allocate a module that fits in the size limit using BFS.
+ """
+
+ # Initialize the variables
+ (
+ devices,
+ max_memory,
+ main_devices,
+ gpus,
+ module_sizes,
+ tied_parameters,
+ no_split_module_classes,
+ modules_to_treat,
+ ) = _init_infer_auto_device_map(model, max_memory, no_split_module_classes, dtype, special_dtypes)
+
+ device_map = OrderedDict()
+ current_device = 0
+ device_memory_used = {device: 0 for device in devices}
+ device_buffer_sizes = {}
+ device_minimum_assignment_memory = {}
+
+ # Initialize maximum largest layer, to know which space to keep in memory
+ max_layer_size, max_layer_names = get_max_layer_size(modules_to_treat, module_sizes, no_split_module_classes)
+
+ # Ready ? This is going to be a bit messy.
+ while len(modules_to_treat) > 0:
+ name, module = modules_to_treat.pop(0)
+ if verbose:
+ print(f"\nTreating module {name}.")
+ # Max size in the remaining layers may have changed since we took one, so we maybe update it.
+ max_layer_names = [n for n in max_layer_names if n != name and not n.startswith(name + ".")]
+ if len(max_layer_names) == 0:
+ max_layer_size, max_layer_names = get_max_layer_size(
+ [(n, m) for n, m in modules_to_treat if isinstance(m, torch.nn.Module)],
+ module_sizes,
+ no_split_module_classes,
+ )
+ # Assess size needed
+ module_size = module_sizes[name]
+
+ # We keep relevant tied parameters only: one of the tied parameters in the group is inside the current module
+ # and the other is not.
+ # Note: If we are currently processing the name `compute.weight`, an other parameter named
+ # e.g. `compute.weight_submodule.parameter`
+ # needs to be considered outside the current module, hence the check with additional dots.
+ tied_param_groups = [
+ tied_group
+ for tied_group in tied_parameters
+ if any(name + "." in k + "." for k in tied_group) and not all(name + "." in k + "." for k in tied_group)
+ ]
+
+ if verbose and len(tied_param_groups) > 0:
+ print(f" Found the relevant tied param groups {tied_param_groups}")
+
+ # Then we keep track of all the parameters that are tied to the current module, but not in the current module
+ tied_params = sum(
+ [[p for p in tied_group if name + "." not in p + "."] for tied_group in tied_param_groups], []
+ )
+
+ if verbose and len(tied_params) > 0:
+ print(f" So those parameters need to be taken into account {tied_params}")
+
+ device = devices[current_device]
+ current_max_size = max_memory[device] if device != "disk" else None
+ current_memory_reserved = 0
+ # Reduce max size available by the largest layer.
+ if devices[current_device] in main_devices:
+ current_max_size = current_max_size - max_layer_size
+ current_memory_reserved = max_layer_size
+
+ module_size_with_ties, tied_module_names, tied_modules = get_module_size_with_ties(
+ tied_params, module_size, module_sizes, modules_to_treat
+ )
+
+ # The module and its tied modules fit on the current device.
+ if current_max_size is None or device_memory_used[device] + module_size_with_ties <= current_max_size:
+ if verbose:
+ output = f"Putting {name}"
+
+ if tied_module_names:
+ output += f" and {tied_module_names}"
+ else:
+ output += f" (size={module_size})"
+
+ if current_max_size is not None:
+ output += f" (available={current_max_size - device_memory_used[device]})"
+
+ output += f" on {device}."
+ print(output)
+
+ device_memory_used[device] += module_size_with_ties
+
+ # Assign the primary module to the device.
+ device_map[name] = device
+
+ # Assign tied modules if any.
+ for tied_module_name in tied_module_names:
+ if tied_module_name in [m[0] for m in modules_to_treat]:
+ # Find the index of the tied module in the list
+ tied_module_index = next(i for i, (n, _) in enumerate(modules_to_treat) if n == tied_module_name)
+ # Remove the tied module from the list to prevent reprocessing
+ modules_to_treat.pop(tied_module_index)
+
+ # Assign the tied module to the device
+ device_map[tied_module_name] = device
+
+ # Buffer Handling
+ if not offload_buffers and isinstance(module, nn.Module):
+ # Compute the total buffer size for the module
+ current_buffer_size = compute_module_total_buffer_size(
+ module, dtype=dtype, special_dtypes=special_dtypes
+ )
+ # Update the buffer size on the device
+ device_buffer_sizes[device] = device_buffer_sizes.get(device, 0) + current_buffer_size
+
+ continue
+
+ # The current module itself fits, so we try to split the tied modules.
+ if len(tied_params) > 0 and device_memory_used[device] + module_size <= current_max_size:
+ # can we split one of the tied modules to make it smaller or do we need to go on the next device?
+ if verbose:
+ print(
+ f"Not enough space on {devices[current_device]} to put {name} and {tied_module_names} (space "
+ f"available {current_max_size - device_memory_used[device]}, needed size {module_size_with_ties})."
+ )
+ split_happened = False
+ for tied_module_name, tied_module in zip(tied_module_names, tied_modules):
+ tied_module_children = list(tied_module.named_children())
+ if len(tied_module_children) == 0 or tied_module.__class__.__name__ in no_split_module_classes:
+ # can't break this one.
+ continue
+
+ if verbose:
+ print(f"Splitting {tied_module_name}.")
+ tied_module_children = list(tied_module.named_parameters(recurse=False)) + tied_module_children
+ tied_module_children = [(f"{tied_module_name}.{n}", v) for n, v in tied_module_children]
+ tied_module_index = [i for i, (n, _) in enumerate(modules_to_treat) if n == tied_module_name][0]
+
+ modules_to_treat = (
+ [(name, module)]
+ + modules_to_treat[:tied_module_index]
+ + tied_module_children
+ + modules_to_treat[tied_module_index + 1 :]
+ )
+ # Update the max layer size.
+ max_layer_size, max_layer_names = get_max_layer_size(
+ [(n, m) for n, m in modules_to_treat if isinstance(m, torch.nn.Module)],
+ module_sizes,
+ no_split_module_classes,
+ )
+ split_happened = True
+ break
+
+ if split_happened:
+ continue
+
+ # If the tied module is not split, we go to the next device
+ if verbose:
+ print("None of the tied module can be split, going to the next device.")
+
+ # The current module itself doesn't fit, so we have to split it or go to the next device.
+ if device_memory_used[device] + module_size >= current_max_size:
+ # Split or not split?
+ modules_children = (
+ []
+ if isinstance(module, nn.Parameter) or isinstance(module, torch.Tensor)
+ else list(module.named_children())
+ )
+ if verbose:
+ print(
+ f"Not enough space on {devices[current_device]} to put {name} (space available "
+ f"{current_max_size - device_memory_used[device]}, module size {module_size})."
+ )
+ if len(modules_children) == 0 or module.__class__.__name__ in no_split_module_classes:
+ # -> no split, we go to the next device
+ if verbose:
+ print("This module cannot be split, going to the next device.")
+
+ else:
+ # -> split, we replace the module studied by its children + parameters
+ if verbose:
+ print(f"Splitting {name}.")
+ modules_children = list(module.named_parameters(recurse=False)) + modules_children
+ modules_to_treat = [(f"{name}.{n}", v) for n, v in modules_children] + modules_to_treat
+ # Update the max layer size.
+ max_layer_size, max_layer_names = get_max_layer_size(
+ [(n, m) for n, m in modules_to_treat if isinstance(m, torch.nn.Module)],
+ module_sizes,
+ no_split_module_classes,
+ )
+ continue
+
+ # If no module is assigned to the current device, we attempt to allocate a fallback module
+ # if fallback_allocation is enabled.
+ if device_memory_used[device] == 0 and fallback_allocation and device != "disk":
+ # We try to allocate a module that fits in the size limit using BFS.
+ # Recompute the current max size as we need to consider the current module as well.
+ current_max_size = max_memory[device] - max(max_layer_size, module_size_with_ties)
+
+ fallback_module_name, fallback_module, remaining_modules = fallback_allocate(
+ modules_to_treat,
+ module_sizes,
+ current_max_size - device_memory_used[device],
+ no_split_module_classes,
+ tied_parameters,
+ )
+ # use the next iteration to put the fallback module on the next device to avoid code duplication
+ if fallback_module is not None:
+ modules_to_treat = [(fallback_module_name, fallback_module)] + [(name, module)] + remaining_modules
+ continue
+
+ if device_memory_used[device] == 0:
+ device_minimum_assignment_memory[device] = module_size_with_ties + current_memory_reserved
+
+ # Neither the current module nor any tied modules can be split, so we move to the next device.
+ device_memory_used[device] = device_memory_used[device] + current_memory_reserved
+ current_device += 1
+ modules_to_treat = [(name, module)] + modules_to_treat
+
+ device_memory_used = {device: mem for device, mem in device_memory_used.items() if mem > 0}
+
+ if clean_result:
+ device_map = clean_device_map(device_map)
+
+ non_gpu_buffer_size = device_buffer_sizes.get("cpu", 0) + device_buffer_sizes.get("disk", 0)
+ if non_gpu_buffer_size > 0 and not offload_buffers:
+ is_buffer_fit_any_gpu = False
+ for gpu_device, gpu_max_memory in max_memory.items():
+ if gpu_device == "cpu" or gpu_device == "disk":
+ continue
+
+ if not is_buffer_fit_any_gpu:
+ gpu_memory_used = device_memory_used.get(gpu_device, 0)
+
+ if gpu_max_memory >= non_gpu_buffer_size + gpu_memory_used:
+ is_buffer_fit_any_gpu = True
+
+ if len(gpus) > 0 and not is_buffer_fit_any_gpu:
+ warnings.warn(
+ f"Current model requires {non_gpu_buffer_size} bytes of buffer for offloaded layers, which seems does "
+ f"not fit any GPU's remaining memory. If you are experiencing a OOM later, please consider using "
+ f"offload_buffers=True."
+ )
+
+ if device_minimum_assignment_memory:
+ devices_info = "\n".join(
+ f" - {device}: {mem} bytes required" for device, mem in device_minimum_assignment_memory.items()
+ )
+ logger.info(
+ f"Based on the current allocation process, no modules could be assigned to the following devices due to "
+ f"insufficient memory:\n"
+ f"{devices_info}\n"
+ f"These minimum requirements are specific to this allocation attempt and may vary. Consider increasing "
+ f"the available memory for these devices to at least the specified minimum, or adjusting the model config."
+ )
+ return device_map
+
+
+def check_device_map(model: nn.Module, device_map: dict[str, Union[int, str, torch.device]]):
+ """
+ Checks a device map covers everything in a given model.
+
+ Args:
+ model (`torch.nn.Module`): The model to check the device map against.
+ device_map (`Dict[str, Union[int, str, torch.device]]`): The device map to check.
+ """
+ all_module_names = dict(model.named_modules())
+ invalid_keys = [k for k in device_map if k != "" and k not in all_module_names]
+
+ if invalid_keys:
+ warnings.warn(
+ f"The following device_map keys do not match any submodules in the model: {invalid_keys}", UserWarning
+ )
+
+ all_model_tensors = [name for name, _ in model.state_dict().items()]
+ for module_name in device_map.keys():
+ if module_name == "":
+ all_model_tensors.clear()
+ break
+ else:
+ all_model_tensors = [
+ name
+ for name in all_model_tensors
+ if not name == module_name and not name.startswith(module_name + ".")
+ ]
+ if len(all_model_tensors) > 0:
+ non_covered_params = ", ".join(all_model_tensors)
+ raise ValueError(
+ f"The device_map provided does not give any device for the following parameters: {non_covered_params}"
+ )
+
+
+def load_state_dict(checkpoint_file, device_map=None):
+ """
+ Load a checkpoint from a given file. If the checkpoint is in the safetensors format and a device map is passed, the
+ weights can be fast-loaded directly on the GPU.
+
+ Args:
+ checkpoint_file (`str`): The path to the checkpoint to load.
+ device_map (`Dict[str, Union[int, str, torch.device]]`, *optional*):
+ A map that specifies where each submodule should go. It doesn't need to be refined to each parameter/buffer
+ name, once a given module name is inside, every submodule of it will be sent to the same device.
+ """
+ if checkpoint_file.endswith(".safetensors"):
+ with safe_open(checkpoint_file, framework="pt") as f:
+ metadata = f.metadata()
+ weight_names = f.keys()
+
+ if metadata is None:
+ logger.warning(
+ f"The safetensors archive passed at {checkpoint_file} does not contain metadata. "
+ "Make sure to save your model with the `save_pretrained` method. Defaulting to 'pt' metadata."
+ )
+ metadata = {"format": "pt"}
+
+ if metadata.get("format") not in ["pt", "tf", "flax"]:
+ raise OSError(
+ f"The safetensors archive passed at {checkpoint_file} does not contain the valid metadata. Make sure "
+ "you save your model with the `save_pretrained` method."
+ )
+ elif metadata["format"] != "pt":
+ raise ValueError(f"The checkpoint passed was saved with {metadata['format']}, we need a the pt format.")
+ if device_map is None:
+ return safe_load_file(checkpoint_file)
+ else:
+ # if we only have one device we can load everything directly
+ if len(set(device_map.values())) == 1:
+ device = list(device_map.values())[0]
+ target_device = device
+ if isinstance(device, int):
+ if is_npu_available():
+ target_device = f"npu:{device}"
+ elif is_hpu_available():
+ target_device = "hpu"
+
+ return safe_load_file(checkpoint_file, device=target_device)
+
+ devices = list(set(device_map.values()) - {"disk"})
+ # cpu device should always exist as fallback option
+ if "cpu" not in devices:
+ devices.append("cpu")
+
+ # For each device, get the weights that go there
+ device_weights = {device: [] for device in devices}
+ for module_name, device in device_map.items():
+ if device in devices:
+ device_weights[device].extend(
+ [k for k in weight_names if k == module_name or k.startswith(module_name + ".")]
+ )
+
+ # all weights that haven't defined a device should be loaded on CPU
+ device_weights["cpu"].extend([k for k in weight_names if k not in sum(device_weights.values(), [])])
+ tensors = {}
+ if is_tqdm_available():
+ progress_bar = tqdm(
+ main_process_only=False,
+ total=sum([len(device_weights[device]) for device in devices]),
+ unit="w",
+ smoothing=0,
+ leave=False,
+ )
+ else:
+ progress_bar = None
+ for device in devices:
+ target_device = device
+ if isinstance(device, int):
+ if is_npu_available():
+ target_device = f"npu:{device}"
+ elif is_hpu_available():
+ target_device = "hpu"
+
+ with safe_open(checkpoint_file, framework="pt", device=target_device) as f:
+ for key in device_weights[device]:
+ if progress_bar is not None:
+ progress_bar.set_postfix(dev=device, refresh=False)
+ progress_bar.set_description(key)
+ tensors[key] = f.get_tensor(key)
+ if progress_bar is not None:
+ progress_bar.update()
+ if progress_bar is not None:
+ progress_bar.close()
+
+ return tensors
+ else:
+ return torch.load(checkpoint_file, map_location=torch.device("cpu"), weights_only=True)
+
+
+def get_state_dict_offloaded_model(model: nn.Module):
+ """
+ Returns the state dictionary for an offloaded model via iterative onloading
+
+ Args:
+ model (`torch.nn.Module`):
+ The offloaded model we want to save
+ """
+
+ state_dict = {}
+ placeholders = set()
+ for name, module in model.named_modules():
+ if name == "":
+ continue
+
+ try:
+ with align_module_device(module, "cpu"):
+ module_state_dict = module.state_dict()
+ except MemoryError:
+ raise MemoryError("Offloaded module must fit in CPU memory to call save_model!") from None
+
+ for key in module_state_dict:
+ # ignore placeholder parameters that are still on the meta device
+ if module_state_dict[key].device == torch.device("meta"):
+ placeholders.add(name + f".{key}")
+ continue
+ params = module_state_dict[key]
+ state_dict[name + f".{key}"] = params.to("cpu") # move buffers to cpu
+ for key in placeholders.copy():
+ if key in state_dict:
+ placeholders.remove(key)
+ if placeholders:
+ logger.warning(f"The following tensors were not saved because they were still on meta device: {placeholders}")
+
+ return state_dict
+
+
+def get_state_dict_from_offload(
+ module: nn.Module,
+ module_name: str,
+ state_dict: dict[str, Union[str, torch.tensor]],
+ device_to_put_offload: Union[int, str, torch.device] = "cpu",
+):
+ """
+ Retrieve the state dictionary (with parameters) from an offloaded module and load into a specified device (defaults
+ to cpu).
+
+ Args:
+ module: (`torch.nn.Module`):
+ The module we want to retrieve a state dictionary from
+ module_name: (`str`):
+ The name of the module of interest
+ state_dict (`Dict[str, Union[int, str, torch.device]]`):
+ Dictionary of {module names: parameters}
+ device_to_put_offload (`Union[int, str, torch.device]`):
+ Device to load offloaded parameters into, defaults to the cpu.
+ """
+
+ root = module_name[: module_name.rfind(".")] # module name without .weight or .bias
+
+ # do not move parameters if the module is not offloaded
+ if not has_offloaded_params(module):
+ device_to_put_offload = None
+
+ # assign the device to which the offloaded parameters will be sent
+ with align_module_device(module, device_to_put_offload):
+ for m_key, params in module.state_dict().items():
+ if (root + f".{m_key}") in state_dict:
+ state_dict[root + f".{m_key}"] = params
+
+ return state_dict
+
+
+def load_checkpoint_in_model(
+ model: nn.Module,
+ checkpoint: Union[str, os.PathLike],
+ device_map: Optional[dict[str, Union[int, str, torch.device]]] = None,
+ offload_folder: Optional[Union[str, os.PathLike]] = None,
+ dtype: Optional[Union[str, torch.dtype]] = None,
+ offload_state_dict: bool = False,
+ offload_buffers: bool = False,
+ keep_in_fp32_modules: Optional[list[str]] = None,
+ offload_8bit_bnb: bool = False,
+ strict: bool = False,
+ full_state_dict: bool = True,
+ broadcast_from_rank0: bool = False,
+):
+ """
+ Loads a (potentially sharded) checkpoint inside a model, potentially sending weights to a given device as they are
+ loaded.
+
+
+
+ Once loaded across devices, you still need to call [`dispatch_model`] on your model to make it able to run. To
+ group the checkpoint loading and dispatch in one single call, use [`load_checkpoint_and_dispatch`].
+
+
+
+ Args:
+ model (`torch.nn.Module`):
+ The model in which we want to load a checkpoint.
+ checkpoint (`str` or `os.PathLike`):
+ The folder checkpoint to load. It can be:
+ - a path to a file containing a whole model state dict
+ - a path to a `.json` file containing the index to a sharded checkpoint
+ - a path to a folder containing a unique `.index.json` file and the shards of a checkpoint.
+ - a path to a folder containing a unique pytorch_model.bin or a model.safetensors file.
+ device_map (`Dict[str, Union[int, str, torch.device]]`, *optional*):
+ A map that specifies where each submodule should go. It doesn't need to be refined to each parameter/buffer
+ name, once a given module name is inside, every submodule of it will be sent to the same device.
+ offload_folder (`str` or `os.PathLike`, *optional*):
+ If the `device_map` contains any value `"disk"`, the folder where we will offload weights.
+ dtype (`str` or `torch.dtype`, *optional*):
+ If provided, the weights will be converted to that type when loaded.
+ offload_state_dict (`bool`, *optional*, defaults to `False`):
+ If `True`, will temporarily offload the CPU state dict on the hard drive to avoid getting out of CPU RAM if
+ the weight of the CPU state dict + the biggest shard does not fit.
+ offload_buffers (`bool`, *optional*, defaults to `False`):
+ Whether or not to include the buffers in the weights offloaded to disk.
+ keep_in_fp32_modules(`List[str]`, *optional*):
+ A list of the modules that we keep in `torch.float32` dtype.
+ offload_8bit_bnb (`bool`, *optional*):
+ Whether or not to enable offload of 8-bit modules on cpu/disk.
+ strict (`bool`, *optional*, defaults to `False`):
+ Whether to strictly enforce that the keys in the checkpoint state_dict match the keys of the model's
+ state_dict.
+ full_state_dict (`bool`, *optional*, defaults to `True`): if this is set to `True`, all the tensors in the
+ loaded state_dict will be gathered. No ShardedTensor and DTensor will be in the loaded state_dict.
+ broadcast_from_rank0 (`False`, *optional*, defaults to `False`): when the option is `True`, a distributed
+ `ProcessGroup` must be initialized. rank0 should receive a full state_dict and will broadcast the tensors
+ in the state_dict one by one to other ranks. Other ranks will receive the tensors and shard (if applicable)
+ according to the local shards in the model.
+
+ """
+ if offload_8bit_bnb:
+ from .bnb import quantize_and_offload_8bit
+
+ tied_params = find_tied_parameters(model)
+
+ if check_tied_parameters_in_config(model) and len(tied_params) == 0:
+ logger.warning(
+ "The model weights are not tied. Please use the `tie_weights` method before using the `infer_auto_device` function."
+ )
+ if device_map is not None:
+ check_tied_parameters_on_same_device(tied_params, device_map)
+
+ if offload_folder is None and device_map is not None and "disk" in device_map.values():
+ raise ValueError(
+ "At least one of the model submodule will be offloaded to disk, please pass along an `offload_folder`."
+ )
+ elif offload_folder is not None and device_map is not None and "disk" in device_map.values():
+ os.makedirs(offload_folder, exist_ok=True)
+
+ if isinstance(dtype, str):
+ # We accept "torch.float16" or just "float16"
+ dtype = dtype.replace("torch.", "")
+ dtype = getattr(torch, dtype)
+
+ checkpoint_files = None
+ index_filename = None
+ if os.path.isfile(checkpoint):
+ if str(checkpoint).endswith(".json"):
+ index_filename = checkpoint
+ else:
+ checkpoint_files = [checkpoint]
+ elif os.path.isdir(checkpoint):
+ # check if the whole state dict is present
+ potential_state_bin = [f for f in os.listdir(checkpoint) if f == WEIGHTS_NAME]
+ potential_state_safetensor = [f for f in os.listdir(checkpoint) if f == SAFE_WEIGHTS_NAME]
+ if len(potential_state_bin) == 1:
+ checkpoint_files = [os.path.join(checkpoint, potential_state_bin[0])]
+ elif len(potential_state_safetensor) == 1:
+ checkpoint_files = [os.path.join(checkpoint, potential_state_safetensor[0])]
+ else:
+ # otherwise check for sharded checkpoints
+ potential_index = [f for f in os.listdir(checkpoint) if f.endswith(".index.json")]
+ if len(potential_index) == 0:
+ raise ValueError(
+ f"{checkpoint} is not a folder containing a `.index.json` file or a {WEIGHTS_NAME} or a {SAFE_WEIGHTS_NAME} file"
+ )
+ elif len(potential_index) == 1:
+ index_filename = os.path.join(checkpoint, potential_index[0])
+ else:
+ raise ValueError(
+ f"{checkpoint} containing more than one `.index.json` file, delete the irrelevant ones."
+ )
+ else:
+ raise ValueError(
+ "`checkpoint` should be the path to a file containing a whole state dict, or the index of a sharded "
+ f"checkpoint, or a folder containing a sharded checkpoint or the whole state dict, but got {checkpoint}."
+ )
+
+ if index_filename is not None:
+ checkpoint_folder = os.path.split(index_filename)[0]
+ with open(index_filename) as f:
+ index = json.loads(f.read())
+
+ if "weight_map" in index:
+ index = index["weight_map"]
+ checkpoint_files = sorted(list(set(index.values())))
+ checkpoint_files = [os.path.join(checkpoint_folder, f) for f in checkpoint_files]
+
+ # Logic for missing/unexepected keys goes here.
+
+ offload_index = {}
+ if offload_state_dict:
+ state_dict_folder = tempfile.mkdtemp()
+ state_dict_index = {}
+
+ unexpected_keys = set()
+ model_keys = set(model.state_dict().keys())
+ buffer_names = [name for name, _ in model.named_buffers()]
+ model_devices = {t.device for t in model.state_dict().values() if isinstance(t, torch.Tensor)}
+ model_physical_devices = model_devices - {torch.device("meta")}
+ for checkpoint_file in checkpoint_files:
+ if device_map is None:
+ # exception for multi-device loading was made for the meta device in torch v2.7.0
+ # https://github.com/pytorch/pytorch/blob/v2.6.0/torch/distributed/checkpoint/state_dict.py#L557-L563
+ # https://github.com/pytorch/pytorch/blob/v2.7.0-rc2/torch/distributed/checkpoint/state_dict.py#L575-L587
+ if is_torch_version(">=", "2.2.0") and (
+ (is_torch_version(">=", "2.7.0") and len(model_physical_devices) <= 1) or len(model_devices) <= 1
+ ):
+ from torch.distributed.checkpoint.state_dict import StateDictOptions, set_model_state_dict
+
+ broadcast_from_rank0 &= is_torch_version(">=", "2.4.0")
+ loaded_checkpoint = (
+ load_state_dict(checkpoint_file, device_map=device_map)
+ if not broadcast_from_rank0 or dist.get_rank() == 0
+ else {}
+ )
+ set_model_state_dict(
+ model,
+ loaded_checkpoint,
+ options=StateDictOptions(
+ full_state_dict=full_state_dict,
+ strict=strict,
+ **({"broadcast_from_rank0": broadcast_from_rank0} if is_torch_version(">=", "2.4.0") else {}),
+ ),
+ )
+ else:
+ loaded_checkpoint = load_state_dict(checkpoint_file, device_map=device_map)
+ model.load_state_dict(loaded_checkpoint, strict=strict)
+
+ unexpected_keys.update(set(loaded_checkpoint.keys()) - model_keys)
+ else:
+ loaded_checkpoint = load_state_dict(checkpoint_file, device_map=device_map)
+
+ for param_name, param in loaded_checkpoint.items():
+ # skip SCB parameter (for 8-bit serialization)
+ if "SCB" in param_name:
+ continue
+
+ if param_name not in model_keys:
+ unexpected_keys.add(param_name)
+ if not strict:
+ continue # Skip loading this parameter.
+
+ module_name = param_name
+
+ while len(module_name) > 0 and module_name not in device_map:
+ module_name = ".".join(module_name.split(".")[:-1])
+ if module_name == "" and "" not in device_map:
+ # TODO: group all errors and raise at the end.
+ raise ValueError(f"{param_name} doesn't have any device set.")
+ param_device = device_map[module_name]
+ new_dtype = dtype
+ if dtype is not None and torch.is_floating_point(param):
+ if keep_in_fp32_modules is not None and dtype == torch.float16:
+ proceed = False
+ for key in keep_in_fp32_modules:
+ if ((key in param_name) and (key + "." in param_name)) or key == param_name:
+ proceed = True
+ break
+ if proceed:
+ new_dtype = torch.float32
+
+ if "weight" in param_name and param_name.replace("weight", "SCB") in loaded_checkpoint.keys():
+ if param.dtype == torch.int8:
+ fp16_statistics = loaded_checkpoint[param_name.replace("weight", "SCB")]
+ else:
+ fp16_statistics = None
+
+ if param_device == "disk":
+ if offload_buffers or param_name not in buffer_names:
+ if new_dtype is None:
+ new_dtype = param.dtype
+ if offload_8bit_bnb:
+ quantize_and_offload_8bit(
+ model, param, param_name, new_dtype, offload_folder, offload_index, fp16_statistics
+ )
+ continue
+ else:
+ set_module_tensor_to_device(model, param_name, "meta", dtype=new_dtype)
+ offload_weight(param, param_name, offload_folder, index=offload_index)
+ elif param_device == "cpu" and offload_state_dict:
+ if new_dtype is None:
+ new_dtype = param.dtype
+ if offload_8bit_bnb:
+ quantize_and_offload_8bit(
+ model, param, param_name, new_dtype, state_dict_folder, state_dict_index, fp16_statistics
+ )
+ else:
+ set_module_tensor_to_device(model, param_name, "meta", dtype=new_dtype)
+ offload_weight(param, param_name, state_dict_folder, index=state_dict_index)
+ else:
+ set_module_tensor_to_device(
+ model,
+ param_name,
+ param_device,
+ value=param,
+ dtype=new_dtype,
+ fp16_statistics=fp16_statistics,
+ )
+
+ # Force Python to clean up.
+ del loaded_checkpoint
+ gc.collect()
+
+ if not strict and len(unexpected_keys) > 0:
+ logger.warning(
+ f"Some weights of the model checkpoint at {checkpoint} were not used when"
+ f" initializing {model.__class__.__name__}: {unexpected_keys}. This may or may not be an issue - make sure that the checkpoint does not have unnecessary parameters, or that the model definition correctly corresponds to the checkpoint."
+ )
+
+ save_offload_index(offload_index, offload_folder)
+
+ # Load back offloaded state dict on CPU
+ if offload_state_dict:
+ load_offloaded_weights(model, state_dict_index, state_dict_folder)
+ shutil.rmtree(state_dict_folder)
+
+ retie_parameters(model, tied_params)
+
+
+def get_mixed_precision_context_manager(native_amp: bool = False, autocast_kwargs: AutocastKwargs = None):
+ """
+ Return a context manager for autocasting mixed precision
+
+ Args:
+ native_amp (`bool`, *optional*, defaults to False):
+ Whether mixed precision is actually enabled.
+ cache_enabled (`bool`, *optional*, defaults to True):
+ Whether the weight cache inside autocast should be enabled.
+ """
+ state = AcceleratorState()
+ if autocast_kwargs is None:
+ autocast_kwargs = {}
+ else:
+ autocast_kwargs = autocast_kwargs.to_kwargs()
+ if native_amp:
+ device_type = (
+ "cuda"
+ if (state.distributed_type == DistributedType.XLA and is_torch_xla_available(check_is_gpu=True))
+ else state.device.type
+ )
+ if state.mixed_precision == "fp16":
+ return torch.autocast(device_type=device_type, dtype=torch.float16, **autocast_kwargs)
+ elif state.mixed_precision in ["bf16", "fp8"] and state.distributed_type in [
+ DistributedType.NO,
+ DistributedType.MULTI_CPU,
+ DistributedType.MULTI_GPU,
+ DistributedType.MULTI_MLU,
+ DistributedType.MULTI_SDAA,
+ DistributedType.MULTI_MUSA,
+ DistributedType.MULTI_NPU,
+ DistributedType.MULTI_XPU,
+ DistributedType.MULTI_HPU,
+ DistributedType.FSDP,
+ DistributedType.XLA,
+ ]:
+ return torch.autocast(device_type=device_type, dtype=torch.bfloat16, **autocast_kwargs)
+ else:
+ return torch.autocast(device_type=device_type, **autocast_kwargs)
+ else:
+ return contextlib.nullcontext()
+
+
+def get_grad_scaler(distributed_type: DistributedType = None, **kwargs):
+ """
+ A generic helper which will initialize the correct `GradScaler` implementation based on the environment and return
+ it.
+
+ Args:
+ distributed_type (`DistributedType`, *optional*, defaults to None):
+ The type of distributed environment.
+ kwargs:
+ Additional arguments for the utilized `GradScaler` constructor.
+ """
+ if distributed_type == DistributedType.FSDP:
+ from torch.distributed.fsdp.sharded_grad_scaler import ShardedGradScaler
+
+ return ShardedGradScaler(**kwargs)
+ if is_torch_xla_available(check_is_gpu=True):
+ import torch_xla.amp as xamp
+
+ return xamp.GradScaler(**kwargs)
+ elif is_mlu_available():
+ return torch.mlu.amp.GradScaler(**kwargs)
+ elif is_sdaa_available():
+ return torch.sdaa.amp.GradScaler(**kwargs)
+ elif is_musa_available():
+ return torch.musa.amp.GradScaler(**kwargs)
+ elif is_npu_available():
+ return torch.npu.amp.GradScaler(**kwargs)
+ elif is_hpu_available():
+ return torch.amp.GradScaler("hpu", **kwargs)
+ elif is_xpu_available():
+ return torch.amp.GradScaler("xpu", **kwargs)
+ elif is_mps_available():
+ if not is_torch_version(">=", "2.8.0"):
+ raise ValueError("Grad Scaler with MPS device requires a Pytorch >= 2.8.0")
+ return torch.amp.GradScaler("mps", **kwargs)
+ else:
+ if is_torch_version(">=", "2.3"):
+ return torch.amp.GradScaler("cuda", **kwargs)
+ else:
+ return torch.cuda.amp.GradScaler(**kwargs)
+
+
+def has_offloaded_params(module: torch.nn.Module) -> bool:
+ """
+ Checks if a module has offloaded parameters by checking if the given module has a AlignDevicesHook attached with
+ offloading enabled
+
+ Args:
+ module (`torch.nn.Module`): The module to check for an offload hook.
+
+ Returns:
+ bool: `True` if the module has an offload hook and offloading is enabled, `False` otherwise.
+ """
+ from ..hooks import AlignDevicesHook # avoid circular import
+
+ return hasattr(module, "_hf_hook") and isinstance(module._hf_hook, AlignDevicesHook) and module._hf_hook.offload
+
+
+@contextlib.contextmanager
+def align_module_device(module: torch.nn.Module, execution_device: Optional[torch.device] = None):
+ """
+ Context manager that moves a module's parameters to the specified execution device.
+
+ Args:
+ module (`torch.nn.Module`):
+ Module with parameters to align.
+ execution_device (`torch.device`, *optional*):
+ If provided, overrides the module's execution device within the context. Otherwise, use hook execution
+ device or pass
+ """
+ if has_offloaded_params(module):
+ if execution_device is not None:
+ original_device = module._hf_hook.execution_device
+ module._hf_hook.execution_device = execution_device
+
+ try:
+ module._hf_hook.pre_forward(module)
+ yield
+ finally:
+ module._hf_hook.post_forward(module, None)
+ if execution_device is not None:
+ module._hf_hook.execution_device = original_device
+
+ elif execution_device is not None:
+ devices = {name: param.device for name, param in module.named_parameters(recurse=False)}
+ try:
+ for name in devices:
+ set_module_tensor_to_device(module, name, execution_device)
+ yield
+ finally:
+ for name, device in devices.items():
+ set_module_tensor_to_device(module, name, device)
+
+ else:
+ yield
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/offload.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/offload.py
new file mode 100644
index 0000000000000000000000000000000000000000..da8cfaf3ebf7f2965f408e2b952103ac26868647
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/offload.py
@@ -0,0 +1,213 @@
+# Copyright 2022 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json
+import os
+from collections.abc import Mapping
+from typing import Optional, Union
+
+import numpy as np
+import torch
+from safetensors import safe_open
+
+
+def offload_weight(weight, weight_name, offload_folder, index=None):
+ dtype = None
+ # Check the string instead of the dtype to be compatible with versions of PyTorch that don't have bfloat16.
+ if str(weight.dtype) == "torch.bfloat16":
+ # Need to reinterpret the underlined data as int16 since NumPy does not handle bfloat16s.
+ weight = weight.view(torch.int16)
+ dtype = "bfloat16"
+ array = weight.cpu().numpy()
+ tensor_file = os.path.join(offload_folder, f"{weight_name}.dat")
+ if index is not None:
+ if dtype is None:
+ dtype = str(array.dtype)
+ index[weight_name] = {"dtype": dtype, "shape": list(array.shape)}
+ if array.ndim == 0:
+ array = array[None]
+ file_array = np.memmap(tensor_file, dtype=array.dtype, mode="w+", shape=array.shape)
+ file_array[:] = array[:]
+ file_array.flush()
+ return index
+
+
+def load_offloaded_weight(weight_file, weight_info):
+ shape = tuple(weight_info["shape"])
+ if shape == ():
+ # NumPy memory-mapped arrays can't have 0 dims so it was saved as 1d tensor
+ shape = (1,)
+
+ dtype = weight_info["dtype"]
+ if dtype == "bfloat16":
+ # NumPy does not support bfloat16 so this was saved as a int16
+ dtype = "int16"
+
+ weight = np.memmap(weight_file, dtype=dtype, shape=shape, mode="r")
+
+ if len(weight_info["shape"]) == 0:
+ weight = weight[0]
+ weight = torch.tensor(weight)
+ if weight_info["dtype"] == "bfloat16":
+ weight = weight.view(torch.bfloat16)
+
+ return weight
+
+
+def save_offload_index(index, offload_folder):
+ if index is None or len(index) == 0:
+ # Nothing to save
+ return
+
+ offload_index_file = os.path.join(offload_folder, "index.json")
+ if os.path.isfile(offload_index_file):
+ with open(offload_index_file, encoding="utf-8") as f:
+ current_index = json.load(f)
+ else:
+ current_index = {}
+ current_index.update(index)
+
+ with open(offload_index_file, "w", encoding="utf-8") as f:
+ json.dump(current_index, f, indent=2)
+
+
+def offload_state_dict(save_dir: Union[str, os.PathLike], state_dict: dict[str, torch.Tensor]):
+ """
+ Offload a state dict in a given folder.
+
+ Args:
+ save_dir (`str` or `os.PathLike`):
+ The directory in which to offload the state dict.
+ state_dict (`Dict[str, torch.Tensor]`):
+ The dictionary of tensors to offload.
+ """
+ os.makedirs(save_dir, exist_ok=True)
+ index = {}
+ for name, parameter in state_dict.items():
+ index = offload_weight(parameter, name, save_dir, index=index)
+
+ # Update index
+ save_offload_index(index, save_dir)
+
+
+class PrefixedDataset(Mapping):
+ """
+ Will access keys in a given dataset by adding a prefix.
+
+ Args:
+ dataset (`Mapping`): Any map with string keys.
+ prefix (`str`): A prefix to add when trying to access any element in the underlying dataset.
+ """
+
+ def __init__(self, dataset: Mapping, prefix: str):
+ self.dataset = dataset
+ self.prefix = prefix
+
+ def __getitem__(self, key):
+ return self.dataset[f"{self.prefix}{key}"]
+
+ def __iter__(self):
+ return iter([key for key in self.dataset if key.startswith(self.prefix)])
+
+ def __len__(self):
+ return len(self.dataset)
+
+
+class OffloadedWeightsLoader(Mapping):
+ """
+ A collection that loads weights stored in a given state dict or memory-mapped on disk.
+
+ Args:
+ state_dict (`Dict[str, torch.Tensor]`, *optional*):
+ A dictionary parameter name to tensor.
+ save_folder (`str` or `os.PathLike`, *optional*):
+ The directory in which the weights are stored (by `offload_state_dict` for instance).
+ index (`Dict`, *optional*):
+ A dictionary from weight name to their information (`dtype`/ `shape` or safetensors filename). Will default
+ to the index saved in `save_folder`.
+ """
+
+ def __init__(
+ self,
+ state_dict: Optional[dict[str, torch.Tensor]] = None,
+ save_folder: Optional[Union[str, os.PathLike]] = None,
+ index: Optional[Mapping] = None,
+ device=None,
+ ):
+ if state_dict is None and save_folder is None and index is None:
+ raise ValueError("Need either a `state_dict`, a `save_folder` or an `index` containing offloaded weights.")
+
+ self.state_dict = {} if state_dict is None else state_dict
+ self.save_folder = save_folder
+ if index is None and save_folder is not None:
+ with open(os.path.join(save_folder, "index.json")) as f:
+ index = json.load(f)
+ self.index = {} if index is None else index
+ self.all_keys = list(self.state_dict.keys())
+ self.all_keys.extend([key for key in self.index if key not in self.all_keys])
+ self.device = device
+
+ def __getitem__(self, key: str):
+ # State dict gets priority
+ if key in self.state_dict:
+ return self.state_dict[key]
+ weight_info = self.index[key]
+ if weight_info.get("safetensors_file") is not None:
+ device = "cpu" if self.device is None else self.device
+ tensor = None
+ try:
+ with safe_open(weight_info["safetensors_file"], framework="pt", device=device) as f:
+ tensor = f.get_tensor(weight_info.get("weight_name", key))
+ except TypeError:
+ # if failed to get_tensor on the device, such as bf16 on mps, try to load it on CPU first
+ with safe_open(weight_info["safetensors_file"], framework="pt", device="cpu") as f:
+ tensor = f.get_tensor(weight_info.get("weight_name", key))
+
+ if "dtype" in weight_info:
+ tensor = tensor.to(getattr(torch, weight_info["dtype"]))
+
+ if tensor.device != torch.device(device):
+ tensor = tensor.to(device)
+ return tensor
+
+ weight_file = os.path.join(self.save_folder, f"{key}.dat")
+ return load_offloaded_weight(weight_file, weight_info)
+
+ def __iter__(self):
+ return iter(self.all_keys)
+
+ def __len__(self):
+ return len(self.all_keys)
+
+
+def extract_submodules_state_dict(state_dict: dict[str, torch.Tensor], submodule_names: list[str]):
+ """
+ Extract the sub state-dict corresponding to a list of given submodules.
+
+ Args:
+ state_dict (`Dict[str, torch.Tensor]`): The state dict to extract from.
+ submodule_names (`List[str]`): The list of submodule names we want to extract.
+ """
+ result = {}
+ for module_name in submodule_names:
+ # We want to catch module_name parameter (module_name.xxx) or potentially module_name, but not any of the
+ # submodules that could being like module_name (transformers.h.1 and transformers.h.10 for instance)
+ result.update(
+ {
+ key: param
+ for key, param in state_dict.items()
+ if key == module_name or key.startswith(module_name + ".")
+ }
+ )
+ return result
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/operations.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/operations.py
new file mode 100644
index 0000000000000000000000000000000000000000..2357fdf03ba533714bf517e67269b3be36a78e39
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/operations.py
@@ -0,0 +1,867 @@
+# Copyright 2022 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""
+A set of basic tensor ops compatible with tpu, gpu, and multigpu
+"""
+
+import pickle
+import warnings
+from collections.abc import Mapping
+from contextlib import contextmanager, nullcontext
+from functools import update_wrapper, wraps
+from typing import Any
+
+import torch
+
+from ..state import AcceleratorState, PartialState
+from .constants import TORCH_DISTRIBUTED_OPERATION_TYPES
+from .dataclasses import DistributedType, TensorInformation
+from .imports import (
+ is_npu_available,
+ is_torch_distributed_available,
+ is_torch_xla_available,
+)
+from .versions import is_torch_version
+
+
+if is_torch_xla_available():
+ import torch_xla.core.xla_model as xm
+
+if is_torch_distributed_available():
+ from torch.distributed import ReduceOp
+
+
+def is_torch_tensor(tensor):
+ return isinstance(tensor, torch.Tensor)
+
+
+def is_torch_xpu_tensor(tensor):
+ return isinstance(
+ tensor,
+ torch.xpu.FloatTensor,
+ torch.xpu.ByteTensor,
+ torch.xpu.IntTensor,
+ torch.xpu.LongTensor,
+ torch.xpu.HalfTensor,
+ torch.xpu.DoubleTensor,
+ torch.xpu.BFloat16Tensor,
+ )
+
+
+def is_tensor_information(tensor_info):
+ return isinstance(tensor_info, TensorInformation)
+
+
+def is_namedtuple(data):
+ """
+ Checks if `data` is a `namedtuple` or not. Can have false positives, but only if a user is trying to mimic a
+ `namedtuple` perfectly.
+ """
+ return isinstance(data, tuple) and hasattr(data, "_asdict") and hasattr(data, "_fields")
+
+
+def honor_type(obj, generator):
+ """
+ Cast a generator to the same type as obj (list, tuple, or namedtuple)
+ """
+ # Some objects may not be able to instantiate from a generator directly
+ if is_namedtuple(obj):
+ return type(obj)(*list(generator))
+ else:
+ return type(obj)(generator)
+
+
+def recursively_apply(func, data, *args, test_type=is_torch_tensor, error_on_other_type=False, **kwargs):
+ """
+ Recursively apply a function on a data structure that is a nested list/tuple/dictionary of a given base type.
+
+ Args:
+ func (`callable`):
+ The function to recursively apply.
+ data (nested list/tuple/dictionary of `main_type`):
+ The data on which to apply `func`
+ *args:
+ Positional arguments that will be passed to `func` when applied on the unpacked data.
+ main_type (`type`, *optional*, defaults to `torch.Tensor`):
+ The base type of the objects to which apply `func`.
+ error_on_other_type (`bool`, *optional*, defaults to `False`):
+ Whether to return an error or not if after unpacking `data`, we get on an object that is not of type
+ `main_type`. If `False`, the function will leave objects of types different than `main_type` unchanged.
+ **kwargs (additional keyword arguments, *optional*):
+ Keyword arguments that will be passed to `func` when applied on the unpacked data.
+
+ Returns:
+ The same data structure as `data` with `func` applied to every object of type `main_type`.
+ """
+ if isinstance(data, (tuple, list)):
+ return honor_type(
+ data,
+ (
+ recursively_apply(
+ func, o, *args, test_type=test_type, error_on_other_type=error_on_other_type, **kwargs
+ )
+ for o in data
+ ),
+ )
+ elif isinstance(data, Mapping):
+ return type(data)(
+ {
+ k: recursively_apply(
+ func, v, *args, test_type=test_type, error_on_other_type=error_on_other_type, **kwargs
+ )
+ for k, v in data.items()
+ }
+ )
+ elif test_type(data):
+ return func(data, *args, **kwargs)
+ elif error_on_other_type:
+ raise TypeError(
+ f"Unsupported types ({type(data)}) passed to `{func.__name__}`. Only nested list/tuple/dicts of "
+ f"objects that are valid for `{test_type.__name__}` should be passed."
+ )
+ return data
+
+
+def send_to_device(tensor, device, non_blocking=False, skip_keys=None):
+ """
+ Recursively sends the elements in a nested list/tuple/dictionary of tensors to a given device.
+
+ Args:
+ tensor (nested list/tuple/dictionary of `torch.Tensor`):
+ The data to send to a given device.
+ device (`torch.device`):
+ The device to send the data to.
+
+ Returns:
+ The same data structure as `tensor` with all tensors sent to the proper device.
+ """
+ if is_torch_tensor(tensor) or hasattr(tensor, "to"):
+ # `torch.Tensor.to("npu")` could not find context when called for the first time (see this [issue](https://gitee.com/ascend/pytorch/issues/I8KECW?from=project-issue)).
+ if device == "npu":
+ device = "npu:0"
+ try:
+ return tensor.to(device, non_blocking=non_blocking)
+ except TypeError: # .to() doesn't accept non_blocking as kwarg
+ return tensor.to(device)
+ except AssertionError as error:
+ # `torch.Tensor.to()` is not supported by `torch_npu` (see this [issue](https://github.com/Ascend/pytorch/issues/16)).
+ # This call is inside the try-block since is_npu_available is not supported by torch.compile.
+ if is_npu_available():
+ if isinstance(device, int):
+ device = f"npu:{device}"
+ else:
+ raise error
+ try:
+ return tensor.to(device, non_blocking=non_blocking)
+ except TypeError: # .to() doesn't accept non_blocking as kwarg
+ return tensor.to(device)
+ elif isinstance(tensor, (tuple, list)):
+ return honor_type(
+ tensor, (send_to_device(t, device, non_blocking=non_blocking, skip_keys=skip_keys) for t in tensor)
+ )
+ elif isinstance(tensor, Mapping):
+ if isinstance(skip_keys, str):
+ skip_keys = [skip_keys]
+ elif skip_keys is None:
+ skip_keys = []
+ return type(tensor)(
+ {
+ k: t if k in skip_keys else send_to_device(t, device, non_blocking=non_blocking, skip_keys=skip_keys)
+ for k, t in tensor.items()
+ }
+ )
+ else:
+ return tensor
+
+
+def get_data_structure(data):
+ """
+ Recursively gathers the information needed to rebuild a nested list/tuple/dictionary of tensors.
+
+ Args:
+ data (nested list/tuple/dictionary of `torch.Tensor`):
+ The data to send to analyze.
+
+ Returns:
+ The same data structure as `data` with [`~utils.TensorInformation`] instead of tensors.
+ """
+
+ def _get_data_structure(tensor):
+ return TensorInformation(shape=tensor.shape, dtype=tensor.dtype)
+
+ return recursively_apply(_get_data_structure, data)
+
+
+def get_shape(data):
+ """
+ Recursively gathers the shape of a nested list/tuple/dictionary of tensors as a list.
+
+ Args:
+ data (nested list/tuple/dictionary of `torch.Tensor`):
+ The data to send to analyze.
+
+ Returns:
+ The same data structure as `data` with lists of tensor shapes instead of tensors.
+ """
+
+ def _get_shape(tensor):
+ return list(tensor.shape)
+
+ return recursively_apply(_get_shape, data)
+
+
+def initialize_tensors(data_structure):
+ """
+ Recursively initializes tensors from a nested list/tuple/dictionary of [`~utils.TensorInformation`].
+
+ Returns:
+ The same data structure as `data` with tensors instead of [`~utils.TensorInformation`].
+ """
+
+ def _initialize_tensor(tensor_info):
+ return torch.empty(*tensor_info.shape, dtype=tensor_info.dtype)
+
+ return recursively_apply(_initialize_tensor, data_structure, test_type=is_tensor_information)
+
+
+def find_batch_size(data):
+ """
+ Recursively finds the batch size in a nested list/tuple/dictionary of lists of tensors.
+
+ Args:
+ data (nested list/tuple/dictionary of `torch.Tensor`): The data from which to find the batch size.
+
+ Returns:
+ `int`: The batch size.
+ """
+ if isinstance(data, (tuple, list, Mapping)) and (len(data) == 0):
+ raise ValueError(f"Cannot find the batch size from empty {type(data)}.")
+
+ if isinstance(data, (tuple, list)):
+ return find_batch_size(data[0])
+ elif isinstance(data, Mapping):
+ for k in data.keys():
+ return find_batch_size(data[k])
+ elif not isinstance(data, torch.Tensor):
+ raise TypeError(f"Can only find the batch size of tensors but got {type(data)}.")
+ return data.shape[0]
+
+
+def ignorant_find_batch_size(data):
+ """
+ Same as [`utils.operations.find_batch_size`] except will ignore if `ValueError` and `TypeErrors` are raised
+
+ Args:
+ data (nested list/tuple/dictionary of `torch.Tensor`): The data from which to find the batch size.
+
+ Returns:
+ `int`: The batch size.
+ """
+ try:
+ return find_batch_size(data)
+ except (ValueError, TypeError):
+ pass
+ return None
+
+
+def listify(data):
+ """
+ Recursively finds tensors in a nested list/tuple/dictionary and converts them to a list of numbers.
+
+ Args:
+ data (nested list/tuple/dictionary of `torch.Tensor`): The data from which to convert to regular numbers.
+
+ Returns:
+ The same data structure as `data` with lists of numbers instead of `torch.Tensor`.
+ """
+
+ def _convert_to_list(tensor):
+ tensor = tensor.detach().cpu()
+ if tensor.dtype == torch.bfloat16:
+ # As of Numpy 1.21.4, NumPy does not support bfloat16 (see
+ # https://github.com/numpy/numpy/blob/a47ecdea856986cd60eabbd53265c2ca5916ad5d/doc/source/user/basics.types.rst ).
+ # Until Numpy adds bfloat16, we must convert float32.
+ tensor = tensor.to(torch.float32)
+ return tensor.tolist()
+
+ return recursively_apply(_convert_to_list, data)
+
+
+def _tpu_gather(tensor):
+ def _tpu_gather_one(tensor):
+ if tensor.ndim == 0:
+ tensor = tensor.clone()[None]
+
+ # Can only gather contiguous tensors
+ if not tensor.is_contiguous():
+ tensor = tensor.contiguous()
+ return xm.all_gather(tensor)
+
+ res = recursively_apply(_tpu_gather_one, tensor, error_on_other_type=True)
+ xm.mark_step()
+ return res
+
+
+def _gpu_gather(tensor):
+ state = PartialState()
+ gather_op = torch.distributed.all_gather_into_tensor
+
+ # NOTE: need manually synchronize to workaourd a INT64 collectives bug in oneCCL before torch 2.9.0
+ if state.device.type == "xpu" and is_torch_version("<=", "2.8"):
+ torch.xpu.synchronize()
+
+ def _gpu_gather_one(tensor):
+ if tensor.ndim == 0:
+ tensor = tensor.clone()[None]
+
+ # Can only gather contiguous tensors
+ if not tensor.is_contiguous():
+ tensor = tensor.contiguous()
+
+ if state.backend is not None and state.backend != "gloo":
+ # We use `empty` as `all_gather_into_tensor` slightly
+ # differs from `all_gather` for better efficiency,
+ # and we rely on the number of items in the tensor
+ # rather than its direct shape
+ output_tensors = torch.empty(
+ state.num_processes * tensor.numel(),
+ dtype=tensor.dtype,
+ device=state.device,
+ )
+ gather_op(output_tensors, tensor)
+ return output_tensors.view(-1, *tensor.size()[1:])
+ else:
+ # a backend of `None` is always CPU
+ # also gloo does not support `all_gather_into_tensor`,
+ # which will result in a larger memory overhead for the op
+ output_tensors = [torch.empty_like(tensor) for _ in range(state.num_processes)]
+ torch.distributed.all_gather(output_tensors, tensor)
+ return torch.cat(output_tensors, dim=0)
+
+ return recursively_apply(_gpu_gather_one, tensor, error_on_other_type=True)
+
+
+class DistributedOperationException(Exception):
+ """
+ An exception class for distributed operations. Raised if the operation cannot be performed due to the shape of the
+ tensors.
+ """
+
+ pass
+
+
+def verify_operation(function):
+ """
+ Verifies that `tensor` is the same shape across all processes. Only ran if `PartialState().debug` is `True`.
+ """
+
+ @wraps(function)
+ def wrapper(*args, **kwargs):
+ if PartialState().distributed_type == DistributedType.NO or not PartialState().debug:
+ return function(*args, **kwargs)
+ operation = f"{function.__module__}.{function.__name__}"
+ if "tensor" in kwargs:
+ tensor = kwargs["tensor"]
+ else:
+ tensor = args[0]
+ if PartialState().device.type != find_device(tensor).type:
+ raise DistributedOperationException(
+ f"One or more of the tensors passed to {operation} were not on the {tensor.device.type} while the `Accelerator` is configured for {PartialState().device.type}. "
+ f"Please move it to the {PartialState().device.type} before calling {operation}."
+ )
+ shapes = get_shape(tensor)
+ output = gather_object([shapes])
+ if output[0] is not None:
+ are_same = output.count(output[0]) == len(output)
+ if not are_same:
+ process_shape_str = "\n - ".join([f"Process {i}: {shape}" for i, shape in enumerate(output)])
+ raise DistributedOperationException(
+ f"Cannot apply desired operation due to shape mismatches. "
+ "All shapes across devices must be valid."
+ f"\n\nOperation: `{operation}`\nInput shapes:\n - {process_shape_str}"
+ )
+ return function(*args, **kwargs)
+
+ return wrapper
+
+
+def chained_operation(function):
+ """
+ Checks that `verify_operation` failed and if so reports a more helpful error chaining the existing
+ `DistributedOperationException`.
+ """
+
+ @wraps(function)
+ def wrapper(*args, **kwargs):
+ try:
+ return function(*args, **kwargs)
+ except DistributedOperationException as e:
+ operation = f"{function.__module__}.{function.__name__}"
+ raise DistributedOperationException(
+ f"Error found while calling `{operation}`. Please see the earlier error for more details."
+ ) from e
+
+ return wrapper
+
+
+@verify_operation
+def gather(tensor):
+ """
+ Recursively gather tensor in a nested list/tuple/dictionary of tensors from all devices.
+
+ Args:
+ tensor (nested list/tuple/dictionary of `torch.Tensor`):
+ The data to gather.
+
+ Returns:
+ The same data structure as `tensor` with all tensors sent to the proper device.
+ """
+ if PartialState().distributed_type == DistributedType.XLA:
+ return _tpu_gather(tensor)
+ elif PartialState().distributed_type in TORCH_DISTRIBUTED_OPERATION_TYPES:
+ return _gpu_gather(tensor)
+ else:
+ return tensor
+
+
+def _gpu_gather_object(object: Any):
+ output_objects = [None for _ in range(PartialState().num_processes)]
+ torch.distributed.all_gather_object(output_objects, object)
+ # all_gather_object returns a list of lists, so we need to flatten it
+ return [x for y in output_objects for x in y]
+
+
+def gather_object(object: Any):
+ """
+ Recursively gather object in a nested list/tuple/dictionary of objects from all devices.
+
+ Args:
+ object (nested list/tuple/dictionary of picklable object):
+ The data to gather.
+
+ Returns:
+ The same data structure as `object` with all the objects sent to every device.
+ """
+ if PartialState().distributed_type == DistributedType.XLA:
+ raise NotImplementedError("gather objects in TPU is not supported")
+ elif PartialState().distributed_type in TORCH_DISTRIBUTED_OPERATION_TYPES:
+ return _gpu_gather_object(object)
+ else:
+ return object
+
+
+def _gpu_broadcast(data, src=0):
+ def _gpu_broadcast_one(tensor, src=0):
+ torch.distributed.broadcast(tensor, src=src)
+ return tensor
+
+ return recursively_apply(_gpu_broadcast_one, data, error_on_other_type=True, src=src)
+
+
+def _tpu_broadcast(tensor, src=0, name="broadcast tensor"):
+ if isinstance(tensor, (list, tuple)):
+ return honor_type(tensor, (_tpu_broadcast(t, name=f"{name}_{i}") for i, t in enumerate(tensor)))
+ elif isinstance(tensor, Mapping):
+ return type(tensor)({k: _tpu_broadcast(v, name=f"{name}_{k}") for k, v in tensor.items()})
+ return xm.mesh_reduce(name, tensor, lambda x: x[src])
+
+
+TENSOR_TYPE_TO_INT = {
+ torch.float: 1,
+ torch.double: 2,
+ torch.half: 3,
+ torch.bfloat16: 4,
+ torch.uint8: 5,
+ torch.int8: 6,
+ torch.int16: 7,
+ torch.int32: 8,
+ torch.int64: 9,
+ torch.bool: 10,
+}
+
+TENSOR_INT_TO_DTYPE = {v: k for k, v in TENSOR_TYPE_TO_INT.items()}
+
+
+def gather_tensor_shape(tensor):
+ """
+ Grabs the shape of `tensor` only available on one process and returns a tensor of its shape
+ """
+ # Allocate 80 bytes to store the shape
+ max_tensor_dimension = 2**20
+ state = PartialState()
+ base_tensor = torch.empty(max_tensor_dimension, dtype=torch.int, device=state.device)
+
+ # Since PyTorch can't just send a tensor to another GPU without
+ # knowing its size, we store the size of the tensor with data
+ # in an allocation
+ if tensor is not None:
+ shape = tensor.shape
+ tensor_dtype = TENSOR_TYPE_TO_INT[tensor.dtype]
+ base_tensor[: len(shape) + 1] = torch.tensor(list(shape) + [tensor_dtype], dtype=int)
+ # Perform a reduction to copy the size data onto all GPUs
+ base_tensor = reduce(base_tensor, reduction="sum")
+ base_tensor = base_tensor[base_tensor.nonzero()]
+ # The last non-zero data contains the coded dtype the source tensor is
+ dtype = int(base_tensor[-1:][0])
+ base_tensor = base_tensor[:-1]
+ return base_tensor, dtype
+
+
+def copy_tensor_to_devices(tensor=None) -> torch.Tensor:
+ """
+ Copies a tensor that only exists on a single device and broadcasts it to other devices. Differs from `broadcast` as
+ each worker doesn't need to know its shape when used (and tensor can be `None`)
+
+ Args:
+ tensor (`torch.tensor`):
+ The tensor that should be sent to all devices. Must only have it be defined on a single device, the rest
+ should be `None`.
+ """
+ state = PartialState()
+ shape, dtype = gather_tensor_shape(tensor)
+ if tensor is None:
+ tensor = torch.zeros(shape, dtype=TENSOR_INT_TO_DTYPE[dtype]).to(state.device)
+ return reduce(tensor, reduction="sum")
+
+
+@verify_operation
+def broadcast(tensor, from_process: int = 0):
+ """
+ Recursively broadcast tensor in a nested list/tuple/dictionary of tensors to all devices.
+
+ Args:
+ tensor (nested list/tuple/dictionary of `torch.Tensor`):
+ The data to gather.
+ from_process (`int`, *optional*, defaults to 0):
+ The process from which to send the data
+
+ Returns:
+ The same data structure as `tensor` with all tensors broadcasted to the proper device.
+ """
+ if PartialState().distributed_type == DistributedType.XLA:
+ return _tpu_broadcast(tensor, src=from_process, name="accelerate.utils.broadcast")
+ elif PartialState().distributed_type in TORCH_DISTRIBUTED_OPERATION_TYPES:
+ return _gpu_broadcast(tensor, src=from_process)
+ else:
+ return tensor
+
+
+def broadcast_object_list(object_list, from_process: int = 0):
+ """
+ Broadcast a list of picklable objects from one process to the others.
+
+ Args:
+ object_list (list of picklable objects):
+ The list of objects to broadcast. This list will be modified inplace.
+ from_process (`int`, *optional*, defaults to 0):
+ The process from which to send the data.
+
+ Returns:
+ The same list containing the objects from process 0.
+ """
+ if PartialState().distributed_type == DistributedType.XLA:
+ for i, obj in enumerate(object_list):
+ object_list[i] = xm.mesh_reduce("accelerate.utils.broadcast_object_list", obj, lambda x: x[from_process])
+ elif PartialState().distributed_type in TORCH_DISTRIBUTED_OPERATION_TYPES:
+ torch.distributed.broadcast_object_list(object_list, src=from_process)
+ return object_list
+
+
+def slice_tensors(data, tensor_slice, process_index=None, num_processes=None):
+ """
+ Recursively takes a slice in a nested list/tuple/dictionary of tensors.
+
+ Args:
+ data (nested list/tuple/dictionary of `torch.Tensor`):
+ The data to slice.
+ tensor_slice (`slice`):
+ The slice to take.
+
+ Returns:
+ The same data structure as `data` with all the tensors slices.
+ """
+
+ def _slice_tensor(tensor, tensor_slice):
+ return tensor[tensor_slice]
+
+ return recursively_apply(_slice_tensor, data, tensor_slice)
+
+
+def concatenate(data, dim=0):
+ """
+ Recursively concatenate the tensors in a nested list/tuple/dictionary of lists of tensors with the same shape.
+
+ Args:
+ data (nested list/tuple/dictionary of lists of tensors `torch.Tensor`):
+ The data to concatenate.
+ dim (`int`, *optional*, defaults to 0):
+ The dimension on which to concatenate.
+
+ Returns:
+ The same data structure as `data` with all the tensors concatenated.
+ """
+ if isinstance(data[0], (tuple, list)):
+ return honor_type(data[0], (concatenate([d[i] for d in data], dim=dim) for i in range(len(data[0]))))
+ elif isinstance(data[0], Mapping):
+ return type(data[0])({k: concatenate([d[k] for d in data], dim=dim) for k in data[0].keys()})
+ elif not isinstance(data[0], torch.Tensor):
+ raise TypeError(f"Can only concatenate tensors but got {type(data[0])}")
+ return torch.cat(data, dim=dim)
+
+
+class CannotPadNestedTensorWarning(UserWarning):
+ pass
+
+
+@chained_operation
+def pad_across_processes(tensor, dim=0, pad_index=0, pad_first=False):
+ """
+ Recursively pad the tensors in a nested list/tuple/dictionary of tensors from all devices to the same size so they
+ can safely be gathered.
+
+ Args:
+ tensor (nested list/tuple/dictionary of `torch.Tensor`):
+ The data to gather.
+ dim (`int`, *optional*, defaults to 0):
+ The dimension on which to pad.
+ pad_index (`int`, *optional*, defaults to 0):
+ The value with which to pad.
+ pad_first (`bool`, *optional*, defaults to `False`):
+ Whether to pad at the beginning or the end.
+ """
+
+ def _pad_across_processes(tensor, dim=0, pad_index=0, pad_first=False):
+ if getattr(tensor, "is_nested", False):
+ warnings.warn(
+ "Cannot pad nested tensors without more information. Leaving unprocessed.",
+ CannotPadNestedTensorWarning,
+ )
+ return tensor
+ if dim >= len(tensor.shape) or dim < -len(tensor.shape):
+ return tensor
+ # Convert negative dimensions to non-negative
+ if dim < 0:
+ dim += len(tensor.shape)
+
+ # Gather all sizes
+ size = torch.tensor(tensor.shape, device=tensor.device)[None]
+ sizes = gather(size).cpu()
+ # Then pad to the maximum size
+ max_size = max(s[dim] for s in sizes)
+ if max_size == tensor.shape[dim]:
+ return tensor
+
+ old_size = tensor.shape
+ new_size = list(old_size)
+ new_size[dim] = max_size
+ new_tensor = tensor.new_zeros(tuple(new_size)) + pad_index
+ if pad_first:
+ indices = tuple(
+ slice(max_size - old_size[dim], max_size) if i == dim else slice(None) for i in range(len(new_size))
+ )
+ else:
+ indices = tuple(slice(0, old_size[dim]) if i == dim else slice(None) for i in range(len(new_size)))
+ new_tensor[indices] = tensor
+ return new_tensor
+
+ return recursively_apply(
+ _pad_across_processes, tensor, error_on_other_type=True, dim=dim, pad_index=pad_index, pad_first=pad_first
+ )
+
+
+def pad_input_tensors(tensor, batch_size, num_processes, dim=0):
+ """
+ Takes a `tensor` of arbitrary size and pads it so that it can work given `num_processes` needed dimensions.
+
+ New tensors are just the last input repeated.
+
+ E.g.:
+ Tensor: ([3,4,4]) Num processes: 4 Expected result shape: ([4,4,4])
+
+ """
+
+ def _pad_input_tensors(tensor, batch_size, num_processes, dim=0):
+ remainder = batch_size // num_processes
+ last_inputs = batch_size - (remainder * num_processes)
+ if batch_size // num_processes == 0:
+ to_pad = num_processes - batch_size
+ else:
+ to_pad = num_processes - (batch_size // num_processes)
+ # In the rare case that `to_pad` is negative,
+ # we need to pad the last inputs - the found `to_pad`
+ if last_inputs > to_pad & to_pad < 1:
+ to_pad = last_inputs - to_pad
+ old_size = tensor.shape
+ new_size = list(old_size)
+ new_size[0] = batch_size + to_pad
+ new_tensor = tensor.new_zeros(tuple(new_size))
+ indices = tuple(slice(0, old_size[dim]) if i == dim else slice(None) for i in range(len(new_size)))
+ new_tensor[indices] = tensor
+ return new_tensor
+
+ return recursively_apply(
+ _pad_input_tensors,
+ tensor,
+ error_on_other_type=True,
+ batch_size=batch_size,
+ num_processes=num_processes,
+ dim=dim,
+ )
+
+
+@verify_operation
+def reduce(tensor, reduction="mean", scale=1.0):
+ """
+ Recursively reduce the tensors in a nested list/tuple/dictionary of lists of tensors across all processes by the
+ mean of a given operation.
+
+ Args:
+ tensor (nested list/tuple/dictionary of `torch.Tensor`):
+ The data to reduce.
+ reduction (`str`, *optional*, defaults to `"mean"`):
+ A reduction method. Can be of "mean", "sum", or "none"
+ scale (`float`, *optional*):
+ A default scaling value to be applied after the reduce, only valid on XLA.
+
+ Returns:
+ The same data structure as `data` with all the tensors reduced.
+ """
+
+ def _reduce_across_processes(tensor, reduction="mean", scale=1.0):
+ state = PartialState()
+ cloned_tensor = tensor.clone()
+ if state.distributed_type == DistributedType.NO:
+ return cloned_tensor
+ if state.distributed_type == DistributedType.XLA:
+ # Some processes may have different HLO graphs than other
+ # processes, for example in the breakpoint API
+ # accelerator.set_trigger(). Use mark_step to make HLOs
+ # the same on all processes.
+ xm.mark_step()
+ xm.all_reduce(xm.REDUCE_SUM, [cloned_tensor], scale)
+ xm.mark_step()
+ elif state.distributed_type.value in TORCH_DISTRIBUTED_OPERATION_TYPES:
+ torch.distributed.all_reduce(cloned_tensor, ReduceOp.SUM)
+ if reduction == "mean":
+ cloned_tensor /= state.num_processes
+ return cloned_tensor
+
+ return recursively_apply(
+ _reduce_across_processes, tensor, error_on_other_type=True, reduction=reduction, scale=scale
+ )
+
+
+def convert_to_fp32(tensor):
+ """
+ Recursively converts the elements nested list/tuple/dictionary of tensors in FP16/BF16 precision to FP32.
+
+ Args:
+ tensor (nested list/tuple/dictionary of `torch.Tensor`):
+ The data to convert from FP16/BF16 to FP32.
+
+ Returns:
+ The same data structure as `tensor` with all tensors that were in FP16/BF16 precision converted to FP32.
+ """
+
+ def _convert_to_fp32(tensor):
+ return tensor.float()
+
+ def _is_fp16_bf16_tensor(tensor):
+ return (is_torch_tensor(tensor) or hasattr(tensor, "dtype")) and tensor.dtype in (
+ torch.float16,
+ torch.bfloat16,
+ )
+
+ return recursively_apply(_convert_to_fp32, tensor, test_type=_is_fp16_bf16_tensor)
+
+
+class ConvertOutputsToFp32:
+ """
+ Decorator to apply to a function outputting tensors (like a model forward pass) that ensures the outputs in FP16
+ precision will be convert back to FP32.
+
+ Args:
+ model_forward (`Callable`):
+ The function which outputs we want to treat.
+
+ Returns:
+ The same function as `model_forward` but with converted outputs.
+ """
+
+ def __init__(self, model_forward):
+ self.model_forward = model_forward
+ update_wrapper(self, model_forward)
+
+ def __call__(self, *args, **kwargs):
+ return convert_to_fp32(self.model_forward(*args, **kwargs))
+
+ def __getstate__(self):
+ raise pickle.PicklingError(
+ "Cannot pickle a prepared model with automatic mixed precision, please unwrap the model with `Accelerator.unwrap_model(model)` before pickling it."
+ )
+
+
+def convert_outputs_to_fp32(model_forward):
+ model_forward = ConvertOutputsToFp32(model_forward)
+
+ def forward(*args, **kwargs):
+ return model_forward(*args, **kwargs)
+
+ # To act like a decorator so that it can be popped when doing `extract_model_from_parallel`
+ forward.__wrapped__ = model_forward
+
+ return forward
+
+
+def find_device(data):
+ """
+ Finds the device on which a nested dict/list/tuple of tensors lies (assuming they are all on the same device).
+
+ Args:
+ (nested list/tuple/dictionary of `torch.Tensor`): The data we want to know the device of.
+ """
+ if isinstance(data, Mapping):
+ for obj in data.values():
+ device = find_device(obj)
+ if device is not None:
+ return device
+ elif isinstance(data, (tuple, list)):
+ for obj in data:
+ device = find_device(obj)
+ if device is not None:
+ return device
+ elif isinstance(data, torch.Tensor):
+ return data.device
+
+
+@contextmanager
+def GatheredParameters(params, modifier_rank=None, fwd_module=None, enabled=True):
+ """
+ Wrapper around `deepspeed.runtime.zero.GatheredParameters`, but if Zero-3 is not enabled, will be a no-op context
+ manager.
+ """
+ # We need to use the `AcceleratorState` here since it has access to the deepspeed plugin
+ if AcceleratorState().distributed_type != DistributedType.DEEPSPEED or (
+ AcceleratorState().deepspeed_plugin is not None
+ and not AcceleratorState().deepspeed_plugin.is_zero3_init_enabled()
+ ):
+ gather_param_context = nullcontext()
+ else:
+ import deepspeed
+
+ gather_param_context = deepspeed.zero.GatheredParameters(
+ params, modifier_rank=modifier_rank, fwd_module=fwd_module, enabled=enabled
+ )
+ with gather_param_context:
+ yield
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/other.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/other.py
new file mode 100644
index 0000000000000000000000000000000000000000..69bed25cb66b31e32cbc984e8779af875b0cfde1
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/other.py
@@ -0,0 +1,561 @@
+# Copyright 2022 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import collections
+import platform
+import re
+import socket
+from codecs import encode
+from collections import OrderedDict
+from functools import partial, reduce
+from types import MethodType
+from typing import Optional
+
+import numpy as np
+import torch
+from packaging.version import Version
+from safetensors.torch import save_file as safe_save_file
+
+from ..commands.config.default import write_basic_config # noqa: F401
+from ..logging import get_logger
+from ..state import PartialState
+from .constants import FSDP_PYTORCH_VERSION
+from .dataclasses import DistributedType
+from .imports import (
+ is_deepspeed_available,
+ is_numpy_available,
+ is_torch_distributed_available,
+ is_torch_xla_available,
+ is_weights_only_available,
+)
+from .modeling import id_tensor_storage
+from .transformer_engine import convert_model
+from .versions import is_torch_version
+
+
+logger = get_logger(__name__)
+
+
+if is_torch_xla_available():
+ import torch_xla.core.xla_model as xm
+
+
+def is_compiled_module(module: torch.nn.Module) -> bool:
+ """
+ Check whether the module was compiled with torch.compile()
+ """
+ if not hasattr(torch, "_dynamo"):
+ return False
+
+ return isinstance(module, torch._dynamo.eval_frame.OptimizedModule)
+
+
+def has_compiled_regions(module: torch.nn.Module) -> bool:
+ """
+ Check whether the module has submodules that were compiled with `torch.compile()`.
+ """
+ if not hasattr(torch, "_dynamo"):
+ return False
+
+ if module._modules:
+ for submodule in module.modules():
+ if isinstance(submodule, torch._dynamo.eval_frame.OptimizedModule):
+ return True
+
+ return False
+
+
+def is_repeated_blocks(module: torch.nn.Module) -> bool:
+ """
+ Check whether the module is a repeated block, i.e. `torch.nn.ModuleList` with all children of the same class. This
+ is useful to determine whether we should apply regional compilation to the module.
+ """
+
+ return isinstance(module, torch.nn.ModuleList) and all(isinstance(m, module[0].__class__) for m in module)
+
+
+def has_repeated_blocks(module: torch.nn.Module) -> bool:
+ """
+ Check whether the module has repeated blocks, i.e. `torch.nn.ModuleList` with all children of the same class, at
+ any level of the module hierarchy. This is useful to determine whether we should apply regional compilation to the
+ module.
+ """
+ if module._modules:
+ for submodule in module.modules():
+ if is_repeated_blocks(submodule):
+ return True
+
+ return False
+
+
+def compile_regions(module: torch.nn.Module, **compile_kwargs) -> torch.nn.Module:
+ """
+ Performs regional compilation where we target repeated blocks of the same class and compile them sequentially to
+ hit the compiler's cache. For example, in `GPT2LMHeadModel`, the repeated block/class is `GPT2Block`, and can be
+ accessed as `model.transformer.h[0]`. The rest of the model (e.g. model.lm_head) is compiled separately.
+
+ This allows us to speed up the compilation overhead / cold start of models like LLMs and Transformers in general.
+ See https://pytorch.org/tutorials/recipes/regional_compilation.html for more details.
+
+ Args:
+ module (`torch.nn.Module`):
+ The model to compile.
+ **compile_kwargs:
+ Additional keyword arguments to pass to `torch.compile()`.
+
+ Returns:
+ `torch.nn.Module`: A new instance of the model with some compiled regions.
+
+ Example:
+ ```python
+ >>> from accelerate.utils import compile_regions
+ >>> from transformers import AutoModelForCausalLM
+
+ >>> model = AutoModelForCausalLM.from_pretrained("gpt2")
+ >>> compiled_model = compile_regions(model, mode="reduce-overhead")
+ >>> compiled_model.transformer.h[0]
+ OptimizedModule(
+ (_orig_mod): GPT2Block(
+ (ln_1): LayerNorm((768,), eps=1e-05, elementwise_affine=True)
+ (attn): GPT2Attention(
+ (c_attn): Conv1D(nf=2304, nx=768)
+ (c_proj): Conv1D(nf=768, nx=768)
+ (attn_dropout): Dropout(p=0.1, inplace=False)
+ (resid_dropout): Dropout(p=0.1, inplace=False)
+ )
+ (ln_2): LayerNorm((768,), eps=1e-05, elementwise_affine=True)
+ (mlp): GPT2MLP(
+ (c_fc): Conv1D(nf=3072, nx=768)
+ (c_proj): Conv1D(nf=768, nx=3072)
+ (act): NewGELUActivation()
+ (dropout): Dropout(p=0.1, inplace=False)
+ )
+ )
+ )
+ ```
+ """
+
+ def _compile_regions(module: torch.nn.Module, **compile_kwargs) -> torch.nn.Module:
+ if is_repeated_blocks(module):
+ new_module = torch.nn.ModuleList()
+ for submodule in module:
+ new_module.append(torch.compile(submodule, **compile_kwargs))
+ elif has_repeated_blocks(module):
+ new_module = module.__class__.__new__(module.__class__)
+ new_module.__dict__.update(module.__dict__)
+ new_module._modules = {}
+ for name, submodule in module.named_children():
+ new_module.add_module(name, _compile_regions(submodule, **compile_kwargs))
+ else:
+ new_module = torch.compile(module, **compile_kwargs)
+
+ return new_module
+
+ new_module = _compile_regions(module, **compile_kwargs)
+
+ if "_orig_mod" not in new_module.__dict__:
+ # Keeps a reference to the original module to decompile/unwrap it later
+ new_module.__dict__["_orig_mod"] = module
+
+ return new_module
+
+
+def compile_regions_deepspeed(module: torch.nn.Module, **compile_kwargs):
+ """
+ Performs regional compilation the same way as `compile_regions`, but specifically for `DeepSpeedEngine.module`.
+ Since the model is wrapped in a `DeepSpeedEngine` and has many added hooks, offloaded parameters, etc that
+ `torch.compile(...)` interferes with, version of trgional compilation uses the inplace `module.compile()` method
+ instead.
+
+ Args:
+ module (`torch.nn.Module`):
+ The model to compile.
+ **compile_kwargs:
+ Additional keyword arguments to pass to `module.compile()`.
+ """
+
+ if is_repeated_blocks(module):
+ for submodule in module:
+ submodule.compile(**compile_kwargs)
+ elif has_repeated_blocks(module):
+ for child in module.children():
+ compile_regions_deepspeed(child, **compile_kwargs)
+ else: # leaf node
+ module.compile(**compile_kwargs)
+
+
+def model_has_dtensor(model: torch.nn.Module) -> bool:
+ """
+ Check if the model has DTensor parameters.
+
+ Args:
+ model (`torch.nn.Module`):
+ The model to check.
+
+ Returns:
+ `bool`: Whether the model has DTensor parameters.
+ """
+ if is_torch_version(">=", "2.5.0"):
+ from torch.distributed.tensor import DTensor
+ else:
+ # from torch 2.0.0 (oldest supported accelerate torch version), DTensor is in torch.distributed._tensor
+ from torch.distributed._tensor import DTensor
+
+ return any(isinstance(p, DTensor) for p in model.parameters())
+
+
+def extract_model_from_parallel(
+ model, keep_fp32_wrapper: bool = True, keep_torch_compile: bool = True, recursive: bool = False
+):
+ """
+ Extract a model from its distributed containers.
+
+ Args:
+ model (`torch.nn.Module`):
+ The model to extract.
+ keep_fp32_wrapper (`bool`, *optional*):
+ Whether to remove mixed precision hooks from the model.
+ keep_torch_compile (`bool`, *optional*):
+ Whether to unwrap compiled model.
+ recursive (`bool`, *optional*, defaults to `False`):
+ Whether to recursively extract all cases of `module.module` from `model` as well as unwrap child sublayers
+ recursively, not just the top-level distributed containers.
+
+ Returns:
+ `torch.nn.Module`: The extracted model.
+ """
+ options = (torch.nn.parallel.DistributedDataParallel, torch.nn.DataParallel)
+
+ is_compiled = is_compiled_module(model)
+ has_compiled = has_compiled_regions(model)
+
+ if is_compiled:
+ compiled_model = model
+ model = model._orig_mod
+ elif has_compiled:
+ compiled_model = model
+ model = model.__dict__["_orig_mod"]
+
+ if is_deepspeed_available():
+ from deepspeed import DeepSpeedEngine
+
+ options += (DeepSpeedEngine,)
+
+ if is_torch_version(">=", FSDP_PYTORCH_VERSION) and is_torch_distributed_available():
+ from torch.distributed.fsdp.fully_sharded_data_parallel import FullyShardedDataParallel as FSDP
+
+ options += (FSDP,)
+
+ while isinstance(model, options):
+ model = model.module
+
+ if recursive:
+ # This is needed in cases such as using FSDPv2 on XLA
+ def _recursive_unwrap(module):
+ # Wrapped modules are standardly wrapped as `module`, similar to the cases earlier
+ # with DDP, DataParallel, DeepSpeed, and FSDP
+ if hasattr(module, "module"):
+ unwrapped_module = _recursive_unwrap(module.module)
+ else:
+ unwrapped_module = module
+ # Next unwrap child sublayers recursively
+ for name, child in unwrapped_module.named_children():
+ setattr(unwrapped_module, name, _recursive_unwrap(child))
+ return unwrapped_module
+
+ # Start with top-level
+ model = _recursive_unwrap(model)
+
+ if not keep_fp32_wrapper:
+ forward = model.forward
+ original_forward = model.__dict__.pop("_original_forward", None)
+ if original_forward is not None:
+ while hasattr(forward, "__wrapped__"):
+ forward = forward.__wrapped__
+ if forward == original_forward:
+ break
+ model.forward = MethodType(forward, model)
+ if getattr(model, "_converted_to_transformer_engine", False):
+ convert_model(model, to_transformer_engine=False)
+
+ if keep_torch_compile:
+ if is_compiled:
+ compiled_model._orig_mod = model
+ model = compiled_model
+ elif has_compiled:
+ compiled_model.__dict__["_orig_mod"] = model
+ model = compiled_model
+
+ return model
+
+
+def wait_for_everyone():
+ """
+ Introduces a blocking point in the script, making sure all processes have reached this point before continuing.
+
+
+
+ Make sure all processes will reach this instruction otherwise one of your processes will hang forever.
+
+
+ """
+ PartialState().wait_for_everyone()
+
+
+def clean_state_dict_for_safetensors(state_dict: dict):
+ """
+ Cleans the state dictionary from a model and removes tensor aliasing if present.
+
+ Args:
+ state_dict (`dict`):
+ The state dictionary from a model
+ """
+ ptrs = collections.defaultdict(list)
+ # When bnb serialization is used, weights in state dict can be strings
+ for name, tensor in state_dict.items():
+ if not isinstance(tensor, str):
+ ptrs[id_tensor_storage(tensor)].append(name)
+
+ # These are all pointers of tensors with shared memory
+ shared_ptrs = {ptr: names for ptr, names in ptrs.items() if len(names) > 1}
+ warn_names = set()
+ for names in shared_ptrs.values():
+ # When not all duplicates have been cleaned, we still remove those keys but put a clear warning.
+ # If the link between tensors was done at runtime then `from_pretrained` will not get
+ # the key back leading to random tensor. A proper warning will be shown
+ # during reload (if applicable), but since the file is not necessarily compatible with
+ # the config, better show a proper warning.
+ found_names = [name for name in names if name in state_dict]
+ warn_names.update(found_names[1:])
+ for name in found_names[1:]:
+ del state_dict[name]
+ if len(warn_names) > 0:
+ logger.warning(
+ f"Removed shared tensor {warn_names} while saving. This should be OK, but check by verifying that you don't receive any warning while reloading",
+ )
+ state_dict = {k: v.contiguous() if isinstance(v, torch.Tensor) else v for k, v in state_dict.items()}
+ return state_dict
+
+
+def save(obj, f, save_on_each_node: bool = False, safe_serialization: bool = False):
+ """
+ Save the data to disk. Use in place of `torch.save()`.
+
+ Args:
+ obj:
+ The data to save
+ f:
+ The file (or file-like object) to use to save the data
+ save_on_each_node (`bool`, *optional*, defaults to `False`):
+ Whether to only save on the global main process
+ safe_serialization (`bool`, *optional*, defaults to `False`):
+ Whether to save `obj` using `safetensors` or the traditional PyTorch way (that uses `pickle`).
+ """
+ # When TorchXLA is enabled, it's necessary to transfer all data to the CPU before saving.
+ # Another issue arises with `id_tensor_storage`, which treats all XLA tensors as identical.
+ # If tensors remain on XLA, calling `clean_state_dict_for_safetensors` will result in only
+ # one XLA tensor remaining.
+ if PartialState().distributed_type == DistributedType.XLA:
+ obj = xm._maybe_convert_to_cpu(obj)
+ # Check if it's a model and remove duplicates
+ if safe_serialization:
+ save_func = partial(safe_save_file, metadata={"format": "pt"})
+ if isinstance(obj, OrderedDict):
+ obj = clean_state_dict_for_safetensors(obj)
+ else:
+ save_func = torch.save
+
+ if PartialState().is_main_process and not save_on_each_node:
+ save_func(obj, f)
+ elif PartialState().is_local_main_process and save_on_each_node:
+ save_func(obj, f)
+
+
+# The following are considered "safe" globals to reconstruct various types of objects when using `weights_only=True`
+# These should be added and then removed after loading in the file
+np_core = np._core if is_numpy_available("2.0.0") else np.core
+TORCH_SAFE_GLOBALS = [
+ # numpy arrays are just numbers, not objects, so we can reconstruct them safely
+ np_core.multiarray._reconstruct,
+ np.ndarray,
+ # The following are needed for the RNG states
+ encode,
+ np.dtype,
+]
+
+if is_numpy_available("1.25.0"):
+ TORCH_SAFE_GLOBALS.append(np.dtypes.UInt32DType)
+
+
+def load(f, map_location=None, **kwargs):
+ """
+ Compatible drop-in replacement of `torch.load()` which allows for `weights_only` to be used if `torch` version is
+ 2.4.0 or higher. Otherwise will ignore the kwarg.
+
+ Will also add (and then remove) an exception for numpy arrays
+
+ Args:
+ f:
+ The file (or file-like object) to use to load the data
+ map_location:
+ a function, `torch.device`, string or a dict specifying how to remap storage locations
+ **kwargs:
+ Additional keyword arguments to pass to `torch.load()`.
+ """
+ try:
+ if is_weights_only_available():
+ old_safe_globals = torch.serialization.get_safe_globals()
+ if "weights_only" not in kwargs:
+ kwargs["weights_only"] = True
+ torch.serialization.add_safe_globals(TORCH_SAFE_GLOBALS)
+ else:
+ kwargs.pop("weights_only", None)
+ loaded_obj = torch.load(f, map_location=map_location, **kwargs)
+ finally:
+ if is_weights_only_available():
+ torch.serialization.clear_safe_globals()
+ if old_safe_globals:
+ torch.serialization.add_safe_globals(old_safe_globals)
+ return loaded_obj
+
+
+def get_pretty_name(obj):
+ """
+ Gets a pretty name from `obj`.
+ """
+ if not hasattr(obj, "__qualname__") and not hasattr(obj, "__name__"):
+ obj = getattr(obj, "__class__", obj)
+ if hasattr(obj, "__qualname__"):
+ return obj.__qualname__
+ if hasattr(obj, "__name__"):
+ return obj.__name__
+ return str(obj)
+
+
+def merge_dicts(source, destination):
+ """
+ Recursively merges two dictionaries.
+
+ Args:
+ source (`dict`): The dictionary to merge into `destination`.
+ destination (`dict`): The dictionary to merge `source` into.
+ """
+ for key, value in source.items():
+ if isinstance(value, dict):
+ node = destination.setdefault(key, {})
+ merge_dicts(value, node)
+ else:
+ destination[key] = value
+
+ return destination
+
+
+def is_port_in_use(port: Optional[int] = None) -> bool:
+ """
+ Checks if a port is in use on `localhost`. Useful for checking if multiple `accelerate launch` commands have been
+ run and need to see if the port is already in use.
+ """
+ if port is None:
+ port = 29500
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
+ return s.connect_ex(("localhost", port)) == 0
+
+
+def get_free_port() -> int:
+ """
+ Gets a free port on `localhost`. Useful for automatic port selection when port 0 is specified in distributed
+ training scenarios.
+
+ Returns:
+ int: An available port number
+ """
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
+ s.bind(("", 0)) # bind to port 0 for OS to assign a free port
+ return s.getsockname()[1]
+
+
+def convert_bytes(size):
+ "Converts `size` from bytes to the largest possible unit"
+ for x in ["bytes", "KB", "MB", "GB", "TB"]:
+ if size < 1024.0:
+ return f"{round(size, 2)} {x}"
+ size /= 1024.0
+
+ return f"{round(size, 2)} PB"
+
+
+def check_os_kernel():
+ """Warns if the kernel version is below the recommended minimum on Linux."""
+ # see issue #1929
+ info = platform.uname()
+ system = info.system
+ if system != "Linux":
+ return
+
+ _, version, *_ = re.split(r"(\d+\.\d+\.\d+)", info.release)
+ min_version = "5.5.0"
+ if Version(version) < Version(min_version):
+ msg = (
+ f"Detected kernel version {version}, which is below the recommended minimum of {min_version}; this can "
+ "cause the process to hang. It is recommended to upgrade the kernel to the minimum version or higher."
+ )
+ logger.warning(msg, main_process_only=True)
+
+
+def recursive_getattr(obj, attr: str):
+ """
+ Recursive `getattr`.
+
+ Args:
+ obj:
+ A class instance holding the attribute.
+ attr (`str`):
+ The attribute that is to be retrieved, e.g. 'attribute1.attribute2'.
+ """
+
+ def _getattr(obj, attr):
+ return getattr(obj, attr)
+
+ return reduce(_getattr, [obj] + attr.split("."))
+
+
+def get_module_children_bottom_up(model: torch.nn.Module, return_fqns: bool = False) -> list[torch.nn.Module]:
+ """Traverse the model in bottom-up order and return the children modules in that order.
+
+ Args:
+ model (`torch.nn.Module`): the model to get the children of
+
+ Returns:
+ `list[torch.nn.Module]`: a list of children modules of `model` in bottom-up order. The last element is the
+ `model` itself.
+ """
+ top = model if not return_fqns else ("", model)
+ stack = [top]
+ ordered_modules = []
+ while stack:
+ current_module = stack.pop()
+ if return_fqns:
+ current_module_name, current_module = current_module
+ for name, attr in current_module.named_children():
+ if isinstance(attr, torch.nn.Module):
+ if return_fqns:
+ child_name = current_module_name + "." + name if current_module_name else name
+ stack.append((child_name, attr))
+ else:
+ stack.append(attr)
+ if return_fqns:
+ ordered_modules.append((current_module_name, current_module))
+ else:
+ ordered_modules.append(current_module)
+ return ordered_modules[::-1]
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/random.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/random.py
new file mode 100644
index 0000000000000000000000000000000000000000..9dceb598cacc1c1d17b198e0a7c19789ab3b9f39
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/random.py
@@ -0,0 +1,156 @@
+# Copyright 2022 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import random
+from typing import Optional, Union
+
+import numpy as np
+import torch
+
+from ..state import AcceleratorState
+from .constants import CUDA_DISTRIBUTED_TYPES
+from .dataclasses import DistributedType, RNGType
+from .imports import (
+ is_hpu_available,
+ is_mlu_available,
+ is_musa_available,
+ is_npu_available,
+ is_sdaa_available,
+ is_torch_xla_available,
+ is_xpu_available,
+)
+
+
+if is_torch_xla_available():
+ import torch_xla.core.xla_model as xm
+
+
+def set_seed(seed: int, device_specific: bool = False, deterministic: bool = False):
+ """
+ Helper function for reproducible behavior to set the seed in `random`, `numpy`, `torch`.
+
+ Args:
+ seed (`int`):
+ The seed to set.
+ device_specific (`bool`, *optional*, defaults to `False`):
+ Whether to differ the seed on each device slightly with `self.process_index`.
+ deterministic (`bool`, *optional*, defaults to `False`):
+ Whether to use deterministic algorithms where available. Can slow down training.
+ """
+ if device_specific:
+ seed += AcceleratorState().process_index
+ random.seed(seed)
+ np.random.seed(seed)
+ torch.manual_seed(seed)
+ if is_xpu_available():
+ torch.xpu.manual_seed_all(seed)
+ elif is_npu_available():
+ torch.npu.manual_seed_all(seed)
+ elif is_mlu_available():
+ torch.mlu.manual_seed_all(seed)
+ elif is_sdaa_available():
+ torch.sdaa.manual_seed_all(seed)
+ elif is_musa_available():
+ torch.musa.manual_seed_all(seed)
+ elif is_hpu_available():
+ torch.hpu.manual_seed_all(seed)
+ else:
+ torch.cuda.manual_seed_all(seed)
+ # ^^ safe to call this function even if cuda is not available
+ if is_torch_xla_available():
+ xm.set_rng_state(seed)
+
+ if deterministic:
+ torch.use_deterministic_algorithms(True)
+
+
+def synchronize_rng_state(rng_type: Optional[RNGType] = None, generator: Optional[torch.Generator] = None):
+ # Get the proper rng state
+ if rng_type == RNGType.TORCH:
+ rng_state = torch.get_rng_state()
+ elif rng_type == RNGType.CUDA:
+ rng_state = torch.cuda.get_rng_state()
+ elif rng_type == RNGType.XLA:
+ assert is_torch_xla_available(), "Can't synchronize XLA seeds as torch_xla is unavailable."
+ rng_state = torch.tensor(xm.get_rng_state())
+ elif rng_type == RNGType.NPU:
+ assert is_npu_available(), "Can't synchronize NPU seeds on an environment without NPUs."
+ rng_state = torch.npu.get_rng_state()
+ elif rng_type == RNGType.MLU:
+ assert is_mlu_available(), "Can't synchronize MLU seeds on an environment without MLUs."
+ rng_state = torch.mlu.get_rng_state()
+ elif rng_type == RNGType.SDAA:
+ assert is_sdaa_available(), "Can't synchronize SDAA seeds on an environment without SDAAs."
+ rng_state = torch.sdaa.get_rng_state()
+ elif rng_type == RNGType.MUSA:
+ assert is_musa_available(), "Can't synchronize MUSA seeds on an environment without MUSAs."
+ rng_state = torch.musa.get_rng_state()
+ elif rng_type == RNGType.XPU:
+ assert is_xpu_available(), "Can't synchronize XPU seeds on an environment without XPUs."
+ rng_state = torch.xpu.get_rng_state()
+ elif rng_type == RNGType.HPU:
+ assert is_hpu_available(), "Can't synchronize HPU seeds on an environment without HPUs."
+ rng_state = torch.hpu.get_rng_state()
+ elif rng_type == RNGType.GENERATOR:
+ assert generator is not None, "Need a generator to synchronize its seed."
+ rng_state = generator.get_state()
+
+ # Broadcast the rng state from device 0 to other devices
+ state = AcceleratorState()
+ if state.distributed_type == DistributedType.XLA:
+ rng_state = rng_state.to(xm.xla_device())
+ xm.collective_broadcast([rng_state])
+ xm.mark_step()
+ rng_state = rng_state.cpu()
+ elif (
+ state.distributed_type in CUDA_DISTRIBUTED_TYPES
+ or state.distributed_type == DistributedType.MULTI_MLU
+ or state.distributed_type == DistributedType.MULTI_SDAA
+ or state.distributed_type == DistributedType.MULTI_MUSA
+ or state.distributed_type == DistributedType.MULTI_NPU
+ or state.distributed_type == DistributedType.MULTI_XPU
+ or state.distributed_type == DistributedType.MULTI_HPU
+ ):
+ rng_state = rng_state.to(state.device)
+ torch.distributed.broadcast(rng_state, 0)
+ rng_state = rng_state.cpu()
+ elif state.distributed_type == DistributedType.MULTI_CPU:
+ torch.distributed.broadcast(rng_state, 0)
+
+ # Set the broadcast rng state
+ if rng_type == RNGType.TORCH:
+ torch.set_rng_state(rng_state)
+ elif rng_type == RNGType.CUDA:
+ torch.cuda.set_rng_state(rng_state)
+ elif rng_type == RNGType.NPU:
+ torch.npu.set_rng_state(rng_state)
+ elif rng_type == RNGType.MLU:
+ torch.mlu.set_rng_state(rng_state)
+ elif rng_type == RNGType.SDAA:
+ torch.sdaa.set_rng_state(rng_state)
+ elif rng_type == RNGType.MUSA:
+ torch.musa.set_rng_state(rng_state)
+ elif rng_type == RNGType.XPU:
+ torch.xpu.set_rng_state(rng_state)
+ elif rng_state == RNGType.HPU:
+ torch.hpu.set_rng_state(rng_state)
+ elif rng_type == RNGType.XLA:
+ xm.set_rng_state(rng_state.item())
+ elif rng_type == RNGType.GENERATOR:
+ generator.set_state(rng_state)
+
+
+def synchronize_rng_states(rng_types: list[Union[str, RNGType]], generator: Optional[torch.Generator] = None):
+ for rng_type in rng_types:
+ synchronize_rng_state(RNGType(rng_type), generator=generator)
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/rich.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/rich.py
new file mode 100644
index 0000000000000000000000000000000000000000..2d48661b7fcef92ef1168b74cc275c6d3ccc67a1
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/rich.py
@@ -0,0 +1,24 @@
+# Copyright 2022 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from .imports import is_rich_available
+
+
+if is_rich_available():
+ from rich.traceback import install
+
+ install(show_locals=False)
+
+else:
+ raise ModuleNotFoundError("To use the rich extension, install rich with `pip install rich`")
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/torch_xla.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/torch_xla.py
new file mode 100644
index 0000000000000000000000000000000000000000..140133926c2f88d39c70f5a9f46a08f88bed36da
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/torch_xla.py
@@ -0,0 +1,51 @@
+# Copyright 2022 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import importlib.metadata
+import subprocess
+import sys
+
+
+def install_xla(upgrade: bool = False):
+ """
+ Helper function to install appropriate xla wheels based on the `torch` version in Google Colaboratory.
+
+ Args:
+ upgrade (`bool`, *optional*, defaults to `False`):
+ Whether to upgrade `torch` and install the latest `torch_xla` wheels.
+
+ Example:
+
+ ```python
+ >>> from accelerate.utils import install_xla
+
+ >>> install_xla(upgrade=True)
+ ```
+ """
+ in_colab = False
+ if "IPython" in sys.modules:
+ in_colab = "google.colab" in str(sys.modules["IPython"].get_ipython())
+
+ if in_colab:
+ if upgrade:
+ torch_install_cmd = ["pip", "install", "-U", "torch"]
+ subprocess.run(torch_install_cmd, check=True)
+ # get the current version of torch
+ torch_version = importlib.metadata.version("torch")
+ torch_version_trunc = torch_version[: torch_version.rindex(".")]
+ xla_wheel = f"https://storage.googleapis.com/tpu-pytorch/wheels/colab/torch_xla-{torch_version_trunc}-cp37-cp37m-linux_x86_64.whl"
+ xla_install_cmd = ["pip", "install", xla_wheel]
+ subprocess.run(xla_install_cmd, check=True)
+ else:
+ raise RuntimeError("`install_xla` utility works only on google colab.")
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/tqdm.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/tqdm.py
new file mode 100644
index 0000000000000000000000000000000000000000..2d4873c1573eb2ee7392162f440a76d4f07cd8ce
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/tqdm.py
@@ -0,0 +1,43 @@
+# Copyright 2022 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+from .imports import is_tqdm_available
+
+
+if is_tqdm_available():
+ from tqdm.auto import tqdm as _tqdm
+
+from ..state import PartialState
+
+
+def tqdm(*args, main_process_only: bool = True, **kwargs):
+ """
+ Wrapper around `tqdm.tqdm` that optionally displays only on the main process.
+
+ Args:
+ main_process_only (`bool`, *optional*):
+ Whether to display the progress bar only on the main process
+ """
+ if not is_tqdm_available():
+ raise ImportError("Accelerate's `tqdm` module requires `tqdm` to be installed. Please run `pip install tqdm`.")
+ if len(args) > 0 and isinstance(args[0], bool):
+ raise ValueError(
+ "Passing `True` or `False` as the first argument to Accelerate's `tqdm` wrapper is unsupported. "
+ "Please use the `main_process_only` keyword argument instead."
+ )
+ disable = kwargs.pop("disable", False)
+ if main_process_only and not disable:
+ disable = PartialState().local_process_index != 0
+ return _tqdm(*args, **kwargs, disable=disable)
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/transformer_engine.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/transformer_engine.py
new file mode 100644
index 0000000000000000000000000000000000000000..6a950d131ddcb1575a2cccd7937ed25bf762663e
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/transformer_engine.py
@@ -0,0 +1,186 @@
+# Copyright 2022 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from types import MethodType
+
+import torch.nn as nn
+
+from .imports import is_hpu_available, is_transformer_engine_available
+from .operations import GatheredParameters
+
+
+# Do not import `transformer_engine` at package level to avoid potential issues
+
+
+def convert_model(model, to_transformer_engine=True, _convert_linear=True, _convert_ln=True):
+ """
+ Recursively converts the linear and layernorm layers of a model to their `transformers_engine` counterpart.
+ """
+ if not is_transformer_engine_available():
+ raise ImportError("Using `convert_model` requires transformer_engine to be installed.")
+
+ if is_hpu_available():
+ import intel_transformer_engine as te
+
+ if not hasattr(te, "LayerNorm"):
+ # HPU does not have a LayerNorm implementation in TE
+ te.LayerNorm = nn.LayerNorm
+ else:
+ import transformer_engine.pytorch as te
+
+ for name, module in model.named_children():
+ if isinstance(module, nn.Linear) and to_transformer_engine and _convert_linear:
+ has_bias = module.bias is not None
+ params_to_gather = [module.weight]
+ if has_bias:
+ params_to_gather.append(module.bias)
+
+ with GatheredParameters(params_to_gather, modifier_rank=0):
+ if any(p % 16 != 0 for p in module.weight.shape):
+ return
+ te_module = te.Linear(
+ module.in_features, module.out_features, bias=has_bias, params_dtype=module.weight.dtype
+ )
+ te_module.weight.copy_(module.weight)
+ if has_bias:
+ te_module.bias.copy_(module.bias)
+
+ setattr(model, name, te_module)
+ # Note: @xrsrke (Phuc) found that te.LayerNorm doesn't have any real memory savings or speedups over nn.LayerNorm
+ elif isinstance(module, nn.LayerNorm) and to_transformer_engine and _convert_ln:
+ with GatheredParameters([module.weight, module.bias], modifier_rank=0):
+ has_bias = module.bias is not None
+ te_module = te.LayerNorm(module.normalized_shape[0], eps=module.eps, params_dtype=module.weight.dtype)
+ te_module.weight.copy_(module.weight)
+ if has_bias:
+ te_module.bias.copy_(module.bias)
+
+ setattr(model, name, te_module)
+ elif isinstance(module, te.Linear) and not to_transformer_engine and _convert_linear:
+ has_bias = module.bias is not None
+ new_module = nn.Linear(
+ module.in_features, module.out_features, bias=has_bias, params_dtype=module.weight.dtype
+ )
+ new_module.weight.copy_(module.weight)
+ if has_bias:
+ new_module.bias.copy_(module.bias)
+
+ setattr(model, name, new_module)
+ elif isinstance(module, te.LayerNorm) and not to_transformer_engine and _convert_ln:
+ new_module = nn.LayerNorm(module.normalized_shape[0], eps=module.eps, params_dtype=module.weight.dtype)
+ new_module.weight.copy_(module.weight)
+ new_module.bias.copy_(module.bias)
+
+ setattr(model, name, new_module)
+ else:
+ convert_model(
+ module,
+ to_transformer_engine=to_transformer_engine,
+ _convert_linear=_convert_linear,
+ _convert_ln=_convert_ln,
+ )
+
+
+def has_transformer_engine_layers(model):
+ """
+ Returns whether a given model has some `transformer_engine` layer or not.
+ """
+ if not is_transformer_engine_available():
+ raise ImportError("Using `has_transformer_engine_layers` requires transformer_engine to be installed.")
+
+ if is_hpu_available():
+ import intel_transformer_engine as te
+
+ module_cls_to_check = te.Linear
+ else:
+ import transformer_engine.pytorch as te
+
+ module_cls_to_check = (te.LayerNorm, te.Linear, te.TransformerLayer)
+
+ for m in model.modules():
+ if isinstance(m, module_cls_to_check):
+ return True
+
+ return False
+
+
+def contextual_fp8_autocast(model_forward, fp8_recipe, use_during_eval=False):
+ """
+ Wrapper for a model's forward method to apply FP8 autocast. Is context aware, meaning that by default it will
+ disable FP8 autocast during eval mode, which is generally better for more accurate metrics.
+ """
+ if not is_transformer_engine_available():
+ raise ImportError("Using `contextual_fp8_autocast` requires transformer_engine to be installed.")
+
+ if is_hpu_available():
+ from intel_transformer_engine import fp8_autocast
+ else:
+ from transformer_engine.pytorch import fp8_autocast
+
+ def forward(self, *args, **kwargs):
+ enabled = use_during_eval or self.training
+ with fp8_autocast(enabled=enabled, fp8_recipe=fp8_recipe):
+ return model_forward(*args, **kwargs)
+
+ # To act like a decorator so that it can be popped when doing `extract_model_from_parallel`
+ forward.__wrapped__ = model_forward
+
+ return forward
+
+
+def apply_fp8_autowrap(model, fp8_recipe_handler):
+ """
+ Applies FP8 context manager to the model's forward method
+ """
+ if not is_transformer_engine_available():
+ raise ImportError("Using `apply_fp8_autowrap` requires transformer_engine to be installed.")
+
+ if is_hpu_available():
+ import intel_transformer_engine.recipe as te_recipe
+
+ is_fp8_block_scaling_available = False
+ message = "MXFP8 block scaling is not available on HPU."
+
+ else:
+ import transformer_engine.common.recipe as te_recipe
+ import transformer_engine.pytorch as te
+
+ is_fp8_block_scaling_available, message = te.fp8.check_mxfp8_support()
+
+ kwargs = fp8_recipe_handler.to_kwargs() if fp8_recipe_handler is not None else {}
+ if "fp8_format" in kwargs:
+ kwargs["fp8_format"] = getattr(te_recipe.Format, kwargs["fp8_format"])
+ use_during_eval = kwargs.pop("use_autocast_during_eval", False)
+ use_mxfp8_block_scaling = kwargs.pop("use_mxfp8_block_scaling", False)
+
+ if use_mxfp8_block_scaling and not is_fp8_block_scaling_available:
+ raise ValueError(f"MXFP8 block scaling is not available: {message}")
+
+ if use_mxfp8_block_scaling:
+ if "amax_compute_algo" in kwargs:
+ raise ValueError("`amax_compute_algo` is not supported for MXFP8 block scaling.")
+ if "amax_history_len" in kwargs:
+ raise ValueError("`amax_history_len` is not supported for MXFP8 block scaling.")
+ fp8_recipe = te_recipe.MXFP8BlockScaling(**kwargs)
+ else:
+ fp8_recipe = te_recipe.DelayedScaling(**kwargs)
+
+ new_forward = contextual_fp8_autocast(model.forward, fp8_recipe, use_during_eval)
+
+ if hasattr(model.forward, "__func__"):
+ model.forward = MethodType(new_forward, model)
+ else:
+ model.forward = new_forward
+
+ return model
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/versions.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/versions.py
new file mode 100644
index 0000000000000000000000000000000000000000..985c918f0e057bacc70c372f6906071bb73db577
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate/utils/versions.py
@@ -0,0 +1,56 @@
+# Copyright 2022 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import importlib.metadata
+from typing import Union
+
+from packaging.version import Version, parse
+
+from .constants import STR_OPERATION_TO_FUNC
+
+
+torch_version = parse(importlib.metadata.version("torch"))
+
+
+def compare_versions(library_or_version: Union[str, Version], operation: str, requirement_version: str):
+ """
+ Compares a library version to some requirement using a given operation.
+
+ Args:
+ library_or_version (`str` or `packaging.version.Version`):
+ A library name or a version to check.
+ operation (`str`):
+ A string representation of an operator, such as `">"` or `"<="`.
+ requirement_version (`str`):
+ The version to compare the library version against
+ """
+ if operation not in STR_OPERATION_TO_FUNC.keys():
+ raise ValueError(f"`operation` must be one of {list(STR_OPERATION_TO_FUNC.keys())}, received {operation}")
+ operation = STR_OPERATION_TO_FUNC[operation]
+ if isinstance(library_or_version, str):
+ library_or_version = parse(importlib.metadata.version(library_or_version))
+ return operation(library_or_version, parse(requirement_version))
+
+
+def is_torch_version(operation: str, version: str):
+ """
+ Compares the current PyTorch version to a given reference with an operation.
+
+ Args:
+ operation (`str`):
+ A string representation of an operator, such as `">"` or `"<="`
+ version (`str`):
+ A string version of PyTorch
+ """
+ return compare_versions(torch_version, operation, version)
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/annotated_doc/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/annotated_doc/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..98c2564c8966644aa958350a4afc2a19f19f86ba
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/annotated_doc/__pycache__/__init__.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/annotated_doc/__pycache__/main.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/annotated_doc/__pycache__/main.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f3a27e7b870169958255e3f0641a6d8801e98555
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/annotated_doc/__pycache__/main.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/cuda_pathfinder-1.4.0.dist-info/licenses/LICENSE b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/cuda_pathfinder-1.4.0.dist-info/licenses/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..f433b1a53f5b830a205fd2df78e2b34974656c7b
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/cuda_pathfinder-1.4.0.dist-info/licenses/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a154b6c3f66b9747ea4b20827b879c599a9699ea
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/__init__.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/__version__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/__version__.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d96937a1ab7e1de0569e0c45cc5bf71d0e3dce69
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/__version__.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_align.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_align.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a85f9de40d76319b2272a028ab1a911b40da6965
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_align.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_align_getter.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_align_getter.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..013b432dc99f031790e596676bf6037d4163dc06
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_align_getter.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_base.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_base.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..06b3b57ea1a8e40bc3c3e2090530e464e957e061
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_base.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_column.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_column.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0ecec2689e08698adcc07f90a2060c5727ef3fd7
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_column.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_common.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_common.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..711210fa2a636e917be5bb7668818b7cf406f35c
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_common.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_container.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_container.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b23ab100108d7e629094a668e21bab3abfa1f506
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_container.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_converter.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_converter.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3230c8f52e3fb9426d5748a43caf1ff7d71f2363
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_converter.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_dataproperty.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_dataproperty.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..42244310abeba55262d7346b74be7d1acde53478
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_dataproperty.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_extractor.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_extractor.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e91d2ed17fb58600ff68f6b33dcbe237af3b3411
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_extractor.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_formatter.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_formatter.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..bb28999c1e4edd828dc75c6b94bba42bedfeffe6
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_formatter.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_function.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_function.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..8cb79ad7fe3685cfb2b21795a3a5d132d6acb66c
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_function.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_interface.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_interface.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f200b38789938bfb52db2bee7e8771c1e915444e
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_interface.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_line_break.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_line_break.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..81224d415abe824b4ba780575fa3478efe35c1e1
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_line_break.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_preprocessor.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_preprocessor.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c7de264a800ef8b6edd9531b239323ff93d7bb66
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/_preprocessor.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/typing.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/typing.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f06d96a8f1d354412a78ee849947dc4d61587224
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__pycache__/typing.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..af2ff6d54dfd57bdea24e51fc39722ae07b14491
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__init__.py
@@ -0,0 +1,7 @@
+from ._logger import logger, set_logger # type: ignore
+
+
+__all__ = (
+ "logger",
+ "set_logger",
+)
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1d52afc2e77d2426ea921edc3547761bd7fc6ca3
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__pycache__/__init__.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__pycache__/_logger.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__pycache__/_logger.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..eb0d9572fec69988484026c89e89f561a079560e
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__pycache__/_logger.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__pycache__/_null_logger.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__pycache__/_null_logger.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..94cfc04edde1d715bf18f2dc4bdf8a1502e00e43
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/__pycache__/_null_logger.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/_logger.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/_logger.py
new file mode 100644
index 0000000000000000000000000000000000000000..4a828f2bcf3d9ecbcfd6c0aaeaf9227e4edd4f17
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/_logger.py
@@ -0,0 +1,22 @@
+"""
+.. codeauthor:: Tsuyoshi Hombashi
+"""
+
+from ._null_logger import NullLogger
+
+
+MODULE_NAME = "dataproperty"
+
+try:
+ from loguru import logger # type: ignore
+
+ logger.disable(MODULE_NAME)
+except ImportError:
+ logger = NullLogger()
+
+
+def set_logger(is_enable: bool, propagation_depth: int = 1) -> None:
+ if is_enable:
+ logger.enable(MODULE_NAME)
+ else:
+ logger.disable(MODULE_NAME)
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/_null_logger.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/_null_logger.py
new file mode 100644
index 0000000000000000000000000000000000000000..ad0f293ce2a288057ea07297e21504c7669edfd0
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/logger/_null_logger.py
@@ -0,0 +1,41 @@
+class NullLogger:
+ level_name = None
+
+ def remove(self, handler_id=None): # pragma: no cover
+ pass
+
+ def add(self, sink, **kwargs): # pragma: no cover
+ pass
+
+ def disable(self, name): # pragma: no cover
+ pass
+
+ def enable(self, name): # pragma: no cover
+ pass
+
+ def critical(self, __message, *args, **kwargs): # pragma: no cover
+ pass
+
+ def debug(self, __message, *args, **kwargs): # pragma: no cover
+ pass
+
+ def error(self, __message, *args, **kwargs): # pragma: no cover
+ pass
+
+ def exception(self, __message, *args, **kwargs): # pragma: no cover
+ pass
+
+ def info(self, __message, *args, **kwargs): # pragma: no cover
+ pass
+
+ def log(self, __level, __message, *args, **kwargs): # pragma: no cover
+ pass
+
+ def success(self, __message, *args, **kwargs): # pragma: no cover
+ pass
+
+ def trace(self, __message, *args, **kwargs): # pragma: no cover
+ pass
+
+ def warning(self, __message, *args, **kwargs): # pragma: no cover
+ pass
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/__init__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..90ff33cd3da492341e937479b9a0e3e123ad28ec
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/__init__.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/__main__.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/__main__.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..bbd8753299bd6b25c9855f044f91fbd988ba5509
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/__main__.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_check.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_check.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e06075dbd1a4ae6c343b18a37c86b173ee8ba0f3
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_check.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_classdef.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_classdef.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..678ed43d82fe16a3551d06f9464eba0dcbbe73d6
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_classdef.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_dataclasses.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_dataclasses.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3e871e04d69e52728a90ee81e105bf896047c2c2
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_dataclasses.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_diff.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_diff.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a4907221962617d54634d8da90dc6f4c12ea35ca
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_diff.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_extendpickle.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_extendpickle.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..8a698de7ab74d5b7829a3583c69c7c5184a4733b
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_extendpickle.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_file.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_file.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..23cc0a4d1a6e671559bfe282232564ae836c0183
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_file.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_functions.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_functions.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..2f0181607e3f40b988aecfa42e688f880d39a01a
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_functions.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_functors.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_functors.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..dca06df76f489f36485b5c037f4a1e6cf17986f9
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_functors.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_module.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_module.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..786730dca9789517498274f365f3813c435e2bbc
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_module.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_nested.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_nested.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..13f60f69eacfefc50a753fd08bb71c53a8a04302
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_nested.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_objects.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_objects.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b99ea2861438a2787ef5f8a42a16cbce85b202c8
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_objects.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_properties.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_properties.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..bc826d81e2d1ae2e80fcc10264676d52d4e318be
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_properties.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_pycapsule.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_pycapsule.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c16322692715b62fff4acaf89013f85dcab8db3a
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_pycapsule.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_recursive.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_recursive.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..879b9a31c81f44d4ebe091e56ae83f34a55eed25
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_recursive.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_registered.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_registered.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a14f7741a3525217954a6ec4d2650931253fd683
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_registered.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_restricted.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_restricted.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ae461b4e4e51d4374104c2ab17f7f5fcbdc4150d
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_restricted.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_selected.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_selected.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..265041dc77c06a6691efba262228e2175f4ad8c6
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_selected.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_temp.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_temp.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c287433aa1776d15c9ad1f420c7562fcfb85c039
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_temp.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_weakref.cpython-312.pyc b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_weakref.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..cf0766e92f1af89015c9f96317d502e3cf5eaccd
Binary files /dev/null and b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/tests/__pycache__/test_weakref.cpython-312.pyc differ
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluation_suite/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluation_suite/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..a306d8068a6d66b60fbcc5420bf0cbb334c36305
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluation_suite/__init__.py
@@ -0,0 +1,128 @@
+import importlib
+import inspect
+from dataclasses import dataclass
+from pathlib import Path
+from typing import Callable, Dict, Optional, Union
+
+from datasets import Dataset, DownloadConfig, DownloadMode, load_dataset
+from datasets.utils.version import Version
+
+from ..evaluator import evaluator
+from ..loading import evaluation_module_factory
+from ..utils.logging import get_logger
+
+
+logger = get_logger(__name__)
+
+
+@dataclass
+class SubTask:
+ task_type: str
+ data: Optional[Union[str, Dataset]] = None
+ subset: Optional[str] = None
+ split: Optional[str] = None
+ data_preprocessor: Optional[Callable] = None
+ args_for_task: Optional[dict] = None
+
+ def __post_init__(self):
+ if type(self.task_type) is not str:
+ raise ValueError(f"'task_type' must be type 'str', got {type(self.task_type)}")
+ if type(self.data) not in [Dataset, str]:
+ raise ValueError(
+ f"'data' must be an already-instantiated Dataset object or type 'str', got {type(self.data)}"
+ )
+ if self.subset and type(self.subset) is not str:
+ raise ValueError(f"'subset' must be type 'str', got {type(self.subset)}")
+ if self.split and type(self.split) is not str:
+ raise ValueError(f"'split' must be type 'str', got {type(self.split)}")
+ if self.data_preprocessor and not callable(self.data_preprocessor):
+ raise ValueError(f"'data_preprocessor' must be a Callable', got {self.data_preprocessor}")
+ if self.args_for_task and type(self.args_for_task) is not dict:
+ raise ValueError(f"'args_for_task' must be type 'dict', got {type(self.args_for_task)}")
+
+
+def import_main_class(module_path):
+ """Import a module at module_path and return the EvaluationSuite class"""
+ module = importlib.import_module(module_path)
+
+ module_main_cls = None
+ for name, obj in module.__dict__.items():
+ if isinstance(obj, type) and obj.__name__ == "Suite":
+ if inspect.isabstract(obj):
+ continue
+ module_main_cls = obj
+ break
+
+ return module_main_cls
+
+
+class EvaluationSuite:
+ """
+ This class instantiates an evaluation suite made up of multiple tasks, where each task consists of a dataset and
+ an associated metric, and runs evaluation on a model or pipeline. Evaluation suites can be a Python script found
+ either locally or uploaded as a Space on the Hugging Face Hub.
+ Usage:
+ ```python
+ from evaluate import EvaluationSuite
+ suite = EvaluationSuite.load("evaluate/evaluation-suite-ci")
+ results = suite.run("lvwerra/distilbert-imdb")
+ ```
+ """
+
+ def __init__(self, name):
+ self.name = name
+
+ @staticmethod
+ def load(
+ path: str,
+ download_mode: Optional[DownloadMode] = None,
+ revision: Optional[Union[str, Version]] = None,
+ download_config: Optional[DownloadConfig] = None,
+ ):
+ download_mode = DownloadMode(download_mode or DownloadMode.REUSE_DATASET_IF_EXISTS)
+ evaluation_module = evaluation_module_factory(
+ path, module_type=None, revision=revision, download_config=download_config, download_mode=download_mode
+ )
+ name = Path(path).stem
+ evaluation_cls = import_main_class(evaluation_module.module_path)
+ evaluation_instance = evaluation_cls(name)
+
+ return evaluation_instance
+
+ def __repr__(self):
+ self.tasks = [str(task) for task in self.suite]
+ return f'EvaluationSuite name: "{self.name}", ' f"Tasks: {self.tasks})"
+
+ def assert_suite_nonempty(self):
+ if not self.suite:
+ raise ValueError(
+ "No evaluation tasks found. The EvaluationSuite must include at least one SubTask definition."
+ )
+
+ def run(
+ self, model_or_pipeline: Union[str, "Pipeline", Callable, "PreTrainedModel", "TFPreTrainedModel"] # noqa: F821
+ ) -> Dict[str, float]:
+
+ self.assert_suite_nonempty()
+
+ results_all = []
+ for task in self.suite:
+
+ task_name = task.data
+
+ if task.data_preprocessor: # task requires extra preprocessing
+ ds = load_dataset(task.data, name=task.subset, split=task.split)
+ task.data = ds.map(task.data_preprocessor)
+
+ task_evaluator = evaluator(task.task_type)
+ args_for_task = task.args_for_task
+ args_for_task["model_or_pipeline"] = model_or_pipeline
+ args_for_task["data"] = task.data
+ args_for_task["subset"] = task.subset
+ args_for_task["split"] = task.split
+ results = task_evaluator.compute(**args_for_task)
+
+ results["task_name"] = task_name + "/" + task.subset if task.subset else task_name
+ results["data_preprocessor"] = str(task.data_preprocessor) if task.data_preprocessor is not None else None
+ results_all.append(results)
+ return results_all
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/__init__.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..fac692eeb80def645bce9901324902ac9e1899f5
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/__init__.py
@@ -0,0 +1,39 @@
+# Copyright 2020 The HuggingFace Datasets Authors and the TensorFlow Datasets Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# flake8: noqa
+# Lint as: python3
+"""Util import."""
+
+__all__ = [
+ "disable_progress_bar",
+ "enable_progress_bar",
+ "is_progress_bar_enabled",
+ "infer_gradio_input_types",
+ "json_to_string_type",
+ "parse_readme",
+ "parse_gradio_data",
+ "parse_test_cases",
+ "launch_gradio_widget",
+]
+
+from .gradio import (
+ infer_gradio_input_types,
+ json_to_string_type,
+ launch_gradio_widget,
+ parse_gradio_data,
+ parse_readme,
+ parse_test_cases,
+)
+from .logging import disable_progress_bar, enable_progress_bar, is_progress_bar_enabled
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/file_utils.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/file_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..4c278905f9bf9a61810b6ba256dae331ce6d8a8c
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/file_utils.py
@@ -0,0 +1,605 @@
+"""
+Utilities for working with the local dataset cache.
+This file is adapted from the AllenNLP library at https://github.com/allenai/allennlp
+Copyright by the AllenNLP authors.
+"""
+
+import copy
+import io
+import json
+import os
+import posixpath
+import re
+import shutil
+import sys
+import tempfile
+import time
+import urllib
+from contextlib import closing, contextmanager
+from functools import partial
+from hashlib import sha256
+from pathlib import Path
+from typing import List, Optional, Type, TypeVar, Union
+from urllib.parse import urlparse
+
+import requests
+from datasets import DownloadConfig
+from datasets.utils.extract import ExtractManager
+from datasets.utils.filelock import FileLock
+
+from .. import __version__, config
+from . import logging
+
+
+logger = logging.get_logger(__name__) # pylint: disable=invalid-name
+
+INCOMPLETE_SUFFIX = ".incomplete"
+
+T = TypeVar("T", str, Path)
+
+
+def init_hf_modules(hf_modules_cache: Optional[Union[Path, str]] = None) -> str:
+ """
+ Add hf_modules_cache to the python path.
+ By default hf_modules_cache='~/.cache/huggingface/modules'.
+ It can also be set with the environment variable HF_MODULES_CACHE.
+ This is used to add modules such as `datasets_modules`
+ """
+ hf_modules_cache = hf_modules_cache if hf_modules_cache is not None else config.HF_MODULES_CACHE
+ hf_modules_cache = str(hf_modules_cache)
+ if hf_modules_cache not in sys.path:
+ sys.path.append(hf_modules_cache)
+
+ os.makedirs(hf_modules_cache, exist_ok=True)
+ if not os.path.exists(os.path.join(hf_modules_cache, "__init__.py")):
+ with open(os.path.join(hf_modules_cache, "__init__.py"), "w"):
+ pass
+ return hf_modules_cache
+
+
+def is_remote_url(url_or_filename: str) -> bool:
+ parsed = urlparse(url_or_filename)
+ return parsed.scheme in ("http", "https", "s3", "gs", "hdfs", "ftp")
+
+
+def is_local_path(url_or_filename: str) -> bool:
+ # On unix the scheme of a local path is empty (for both absolute and relative),
+ # while on windows the scheme is the drive name (ex: "c") for absolute paths.
+ # for details on the windows behavior, see https://bugs.python.org/issue42215
+ return urlparse(url_or_filename).scheme == "" or os.path.ismount(urlparse(url_or_filename).scheme + ":/")
+
+
+def is_relative_path(url_or_filename: str) -> bool:
+ return urlparse(url_or_filename).scheme == "" and not os.path.isabs(url_or_filename)
+
+
+def relative_to_absolute_path(path: T) -> T:
+ """Convert relative path to absolute path."""
+ abs_path_str = os.path.abspath(os.path.expanduser(os.path.expandvars(str(path))))
+ return Path(abs_path_str) if isinstance(path, Path) else abs_path_str
+
+
+def hf_bucket_url(identifier: str, filename: str, use_cdn=False, dataset=True) -> str:
+ if dataset:
+ endpoint = config.CLOUDFRONT_DATASETS_DISTRIB_PREFIX if use_cdn else config.S3_DATASETS_BUCKET_PREFIX
+ else:
+ endpoint = config.CLOUDFRONT_METRICS_DISTRIB_PREFIX if use_cdn else config.S3_METRICS_BUCKET_PREFIX
+ return "/".join((endpoint, identifier, filename))
+
+
+def head_hf_s3(
+ identifier: str, filename: str, use_cdn=False, dataset=True, max_retries=0
+) -> Union[requests.Response, Exception]:
+ return http_head(
+ hf_bucket_url(identifier=identifier, filename=filename, use_cdn=use_cdn, dataset=dataset),
+ max_retries=max_retries,
+ )
+
+
+def hf_hub_url(path: str, name: str, revision: Optional[str] = None) -> str:
+ revision = revision or config.HUB_DEFAULT_VERSION
+ return config.HUB_EVALUATE_URL.format(path=path, name=name, revision=revision)
+
+
+def url_or_path_join(base_name: str, *pathnames: str) -> str:
+ if is_remote_url(base_name):
+ return posixpath.join(base_name, *(str(pathname).replace(os.sep, "/").lstrip("/") for pathname in pathnames))
+ else:
+ return Path(base_name, *pathnames).as_posix()
+
+
+def url_or_path_parent(url_or_path: str) -> str:
+ if is_remote_url(url_or_path):
+ return url_or_path[: url_or_path.rindex("/")]
+ else:
+ return os.path.dirname(url_or_path)
+
+
+def hash_url_to_filename(url, etag=None):
+ """
+ Convert `url` into a hashed filename in a repeatable way.
+ If `etag` is specified, append its hash to the url's, delimited
+ by a period.
+ If the url ends with .h5 (Keras HDF5 weights) adds '.h5' to the name
+ so that TF 2.0 can identify it as a HDF5 file
+ (see https://github.com/tensorflow/tensorflow/blob/00fad90125b18b80fe054de1055770cfb8fe4ba3/tensorflow/python/keras/engine/network.py#L1380)
+ """
+ url_bytes = url.encode("utf-8")
+ url_hash = sha256(url_bytes)
+ filename = url_hash.hexdigest()
+
+ if etag:
+ etag_bytes = etag.encode("utf-8")
+ etag_hash = sha256(etag_bytes)
+ filename += "." + etag_hash.hexdigest()
+
+ if url.endswith(".py"):
+ filename += ".py"
+
+ return filename
+
+
+def cached_path(
+ url_or_filename,
+ download_config=None,
+ **download_kwargs,
+) -> str:
+ """
+ Given something that might be a URL (or might be a local path),
+ determine which. If it's a URL, download the file and cache it, and
+ return the path to the cached file. If it's already a local path,
+ make sure the file exists and then return the path.
+
+ Return:
+ Local path (string)
+
+ Raises:
+ FileNotFoundError: in case of non-recoverable file
+ (non-existent or no cache on disk)
+ ConnectionError: in case of unreachable url
+ and no cache on disk
+ ValueError: if it couldn't parse the url or filename correctly
+ requests.exceptions.ConnectionError: in case of internet connection issue
+ """
+ if download_config is None:
+ download_config = DownloadConfig(**download_kwargs)
+
+ cache_dir = download_config.cache_dir or config.DOWNLOADED_EVALUATE_PATH
+ if isinstance(cache_dir, Path):
+ cache_dir = str(cache_dir)
+ if isinstance(url_or_filename, Path):
+ url_or_filename = str(url_or_filename)
+
+ if is_remote_url(url_or_filename):
+ # URL, so get it from the cache (downloading if necessary)
+ output_path = get_from_cache(
+ url_or_filename,
+ cache_dir=cache_dir,
+ force_download=download_config.force_download,
+ proxies=download_config.proxies,
+ resume_download=download_config.resume_download,
+ user_agent=download_config.user_agent,
+ local_files_only=download_config.local_files_only,
+ use_etag=download_config.use_etag,
+ max_retries=download_config.max_retries,
+ token=download_config.token,
+ download_desc=download_config.download_desc,
+ )
+ elif os.path.exists(url_or_filename):
+ # File, and it exists.
+ output_path = url_or_filename
+ elif is_local_path(url_or_filename):
+ # File, but it doesn't exist.
+ raise FileNotFoundError(f"Local file {url_or_filename} doesn't exist")
+ else:
+ # Something unknown
+ raise ValueError(f"unable to parse {url_or_filename} as a URL or as a local path")
+
+ if output_path is None:
+ return output_path
+
+ if download_config.extract_compressed_file:
+ output_path = ExtractManager(cache_dir=download_config.cache_dir).extract(
+ output_path, force_extract=download_config.force_extract
+ )
+
+ return output_path
+
+
+def get_datasets_user_agent(user_agent: Optional[Union[str, dict]] = None) -> str:
+ ua = f"datasets/{__version__}; python/{config.PY_VERSION}"
+ ua += f"; pyarrow/{config.PYARROW_VERSION}"
+ if config.TORCH_AVAILABLE:
+ ua += f"; torch/{config.TORCH_VERSION}"
+ if config.TF_AVAILABLE:
+ ua += f"; tensorflow/{config.TF_VERSION}"
+ if config.JAX_AVAILABLE:
+ ua += f"; jax/{config.JAX_VERSION}"
+ if isinstance(user_agent, dict):
+ ua += f"; {'; '.join(f'{k}/{v}' for k, v in user_agent.items())}"
+ elif isinstance(user_agent, str):
+ ua += "; " + user_agent
+ return ua
+
+
+def get_authentication_headers_for_url(url: str, token: Optional[Union[str, bool]] = None) -> dict:
+ """Handle the HF authentication"""
+ headers = {}
+ if url.startswith(config.HF_ENDPOINT):
+ from huggingface_hub.utils import build_hf_headers
+
+ headers = build_hf_headers(token=token, library_name="evaluate", library_version=__version__)
+
+ return headers
+
+
+class OfflineModeIsEnabled(ConnectionError):
+ pass
+
+
+def _raise_if_offline_mode_is_enabled(msg: Optional[str] = None):
+ """Raise an OfflineModeIsEnabled error (subclass of ConnectionError) if HF_EVALUATE_OFFLINE is True."""
+ if config.HF_EVALUATE_OFFLINE:
+ raise OfflineModeIsEnabled(
+ "Offline mode is enabled." if msg is None else "Offline mode is enabled. " + str(msg)
+ )
+
+
+def _retry(
+ func,
+ func_args: Optional[tuple] = None,
+ func_kwargs: Optional[dict] = None,
+ exceptions: Type[requests.exceptions.RequestException] = requests.exceptions.RequestException,
+ status_codes: Optional[List[int]] = None,
+ max_retries: int = 0,
+ base_wait_time: float = 0.5,
+ max_wait_time: float = 2,
+):
+ func_args = func_args or ()
+ func_kwargs = func_kwargs or {}
+ retry = 0
+ while True:
+ try:
+ return func(*func_args, **func_kwargs)
+ except exceptions as err:
+ if retry >= max_retries or (status_codes and err.response.status_code not in status_codes):
+ raise err
+ else:
+ sleep_time = min(max_wait_time, base_wait_time * 2**retry) # Exponential backoff
+ logger.info(f"{func} timed out, retrying in {sleep_time}s... [{retry/max_retries}]")
+ time.sleep(sleep_time)
+ retry += 1
+
+
+def _request_with_retry(
+ method: str,
+ url: str,
+ max_retries: int = 0,
+ base_wait_time: float = 0.5,
+ max_wait_time: float = 2,
+ timeout: float = 10.0,
+ **params,
+) -> requests.Response:
+ """Wrapper around requests to retry in case it fails with a ConnectTimeout, with exponential backoff.
+
+ Note that if the environment variable HF_EVALUATE_OFFLINE is set to 1, then a OfflineModeIsEnabled error is raised.
+
+ Args:
+ method (str): HTTP method, such as 'GET' or 'HEAD'.
+ url (str): The URL of the resource to fetch.
+ max_retries (int): Maximum number of retries, defaults to 0 (no retries).
+ base_wait_time (float): Duration (in seconds) to wait before retrying the first time. Wait time between
+ retries then grows exponentially, capped by max_wait_time.
+ max_wait_time (float): Maximum amount of time between two retries, in seconds.
+ **params: Params to pass to :obj:`requests.request`.
+ """
+ _raise_if_offline_mode_is_enabled(f"Tried to reach {url}")
+ tries, success = 0, False
+ while not success:
+ tries += 1
+ try:
+ response = requests.request(method=method.upper(), url=url, timeout=timeout, **params)
+ success = True
+ except (requests.exceptions.ConnectTimeout, requests.exceptions.ConnectionError) as err:
+ if tries > max_retries:
+ raise err
+ else:
+ logger.info(f"{method} request to {url} timed out, retrying... [{tries/max_retries}]")
+ sleep_time = min(max_wait_time, base_wait_time * 2 ** (tries - 1)) # Exponential backoff
+ time.sleep(sleep_time)
+ return response
+
+
+def ftp_head(url, timeout=10.0):
+ _raise_if_offline_mode_is_enabled(f"Tried to reach {url}")
+ try:
+ with closing(urllib.request.urlopen(url, timeout=timeout)) as r:
+ r.read(1)
+ except Exception:
+ return False
+ return True
+
+
+def ftp_get(url, temp_file, timeout=10.0):
+ _raise_if_offline_mode_is_enabled(f"Tried to reach {url}")
+ try:
+ logger.info(f"Getting through FTP {url} into {temp_file.name}")
+ with closing(urllib.request.urlopen(url, timeout=timeout)) as r:
+ shutil.copyfileobj(r, temp_file)
+ except urllib.error.URLError as e:
+ raise ConnectionError(e) from None
+
+
+def http_get(
+ url, temp_file, proxies=None, resume_size=0, headers=None, cookies=None, timeout=100.0, max_retries=0, desc=None
+):
+ headers = copy.deepcopy(headers) or {}
+ headers["user-agent"] = get_datasets_user_agent(user_agent=headers.get("user-agent"))
+ if resume_size > 0:
+ headers["Range"] = f"bytes={resume_size:d}-"
+ response = _request_with_retry(
+ method="GET",
+ url=url,
+ stream=True,
+ proxies=proxies,
+ headers=headers,
+ cookies=cookies,
+ max_retries=max_retries,
+ timeout=timeout,
+ )
+ if response.status_code == 416: # Range not satisfiable
+ return
+ content_length = response.headers.get("Content-Length")
+ total = resume_size + int(content_length) if content_length is not None else None
+ with logging.tqdm(
+ unit="B",
+ unit_scale=True,
+ total=total,
+ initial=resume_size,
+ desc=desc or "Downloading",
+ disable=not logging.is_progress_bar_enabled(),
+ ) as progress:
+ for chunk in response.iter_content(chunk_size=1024):
+ progress.update(len(chunk))
+ temp_file.write(chunk)
+
+
+def http_head(
+ url, proxies=None, headers=None, cookies=None, allow_redirects=True, timeout=10.0, max_retries=0
+) -> requests.Response:
+ headers = copy.deepcopy(headers) or {}
+ headers["user-agent"] = get_datasets_user_agent(user_agent=headers.get("user-agent"))
+ response = _request_with_retry(
+ method="HEAD",
+ url=url,
+ proxies=proxies,
+ headers=headers,
+ cookies=cookies,
+ allow_redirects=allow_redirects,
+ timeout=timeout,
+ max_retries=max_retries,
+ )
+ return response
+
+
+def request_etag(url: str, token: Optional[Union[str, bool]] = None) -> Optional[str]:
+ headers = get_authentication_headers_for_url(url, token=token)
+ response = http_head(url, headers=headers, max_retries=3)
+ response.raise_for_status()
+ etag = response.headers.get("ETag") if response.ok else None
+ return etag
+
+
+def get_from_cache(
+ url,
+ cache_dir=None,
+ force_download=False,
+ proxies=None,
+ etag_timeout=100,
+ resume_download=False,
+ user_agent=None,
+ local_files_only=False,
+ use_etag=True,
+ max_retries=0,
+ token=None,
+ download_desc=None,
+) -> str:
+ """
+ Given a URL, look for the corresponding file in the local cache.
+ If it's not there, download it. Then return the path to the cached file.
+
+ Return:
+ Local path (string)
+
+ Raises:
+ FileNotFoundError: in case of non-recoverable file
+ (non-existent or no cache on disk)
+ ConnectionError: in case of unreachable url
+ and no cache on disk
+ """
+ if cache_dir is None:
+ cache_dir = config.HF_EVALUATE_CACHE
+ if isinstance(cache_dir, Path):
+ cache_dir = str(cache_dir)
+
+ os.makedirs(cache_dir, exist_ok=True)
+
+ connected = False
+ response = None
+ cookies = None
+ etag = None
+ head_error = None
+
+ # Try a first time to file the file on the local file system without eTag (None)
+ # if we don't ask for 'force_download' then we spare a request
+ filename = hash_url_to_filename(url, etag=None)
+ cache_path = os.path.join(cache_dir, filename)
+
+ if os.path.exists(cache_path) and not force_download and not use_etag:
+ return cache_path
+
+ # Prepare headers for authentication
+ headers = get_authentication_headers_for_url(url, token=token)
+ if user_agent is not None:
+ headers["user-agent"] = user_agent
+
+ # We don't have the file locally or we need an eTag
+ if not local_files_only:
+ if url.startswith("ftp://"):
+ connected = ftp_head(url)
+ try:
+ response = http_head(
+ url,
+ allow_redirects=True,
+ proxies=proxies,
+ timeout=etag_timeout,
+ max_retries=max_retries,
+ headers=headers,
+ )
+ if response.status_code == 200: # ok
+ etag = response.headers.get("ETag") if use_etag else None
+ for k, v in response.cookies.items():
+ # In some edge cases, we need to get a confirmation token
+ if k.startswith("download_warning") and "drive.google.com" in url:
+ url += "&confirm=" + v
+ cookies = response.cookies
+ connected = True
+ # Fix Google Drive URL to avoid Virus scan warning
+ if "drive.google.com" in url and "confirm=" not in url:
+ url += "&confirm=t"
+ # In some edge cases, head request returns 400 but the connection is actually ok
+ elif (
+ (response.status_code == 400 and "firebasestorage.googleapis.com" in url)
+ or (response.status_code == 405 and "drive.google.com" in url)
+ or (
+ response.status_code == 403
+ and (
+ re.match(r"^https?://github.com/.*?/.*?/releases/download/.*?/.*?$", url)
+ or re.match(r"^https://.*?s3.*?amazonaws.com/.*?$", response.url)
+ )
+ )
+ or (response.status_code == 403 and "ndownloader.figstatic.com" in url)
+ ):
+ connected = True
+ logger.info(f"Couldn't get ETag version for url {url}")
+ elif response.status_code == 401 and config.HF_ENDPOINT in url and token is None:
+ raise ConnectionError(
+ f"Unauthorized for URL {url}. Please use the parameter ``token=True`` after logging in with ``huggingface-cli login``"
+ )
+ except (OSError, requests.exceptions.Timeout) as e:
+ # not connected
+ head_error = e
+ pass
+
+ # connected == False = we don't have a connection, or url doesn't exist, or is otherwise inaccessible.
+ # try to get the last downloaded one
+ if not connected:
+ if os.path.exists(cache_path) and not force_download:
+ return cache_path
+ if local_files_only:
+ raise FileNotFoundError(
+ f"Cannot find the requested files in the cached path at {cache_path} and outgoing traffic has been"
+ " disabled. To enable file online look-ups, set 'local_files_only' to False."
+ )
+ elif response is not None and response.status_code == 404:
+ raise FileNotFoundError(f"Couldn't find file at {url}")
+ _raise_if_offline_mode_is_enabled(f"Tried to reach {url}")
+ if head_error is not None:
+ raise ConnectionError(f"Couldn't reach {url} ({repr(head_error)})")
+ elif response is not None:
+ raise ConnectionError(f"Couldn't reach {url} (error {response.status_code})")
+ else:
+ raise ConnectionError(f"Couldn't reach {url}")
+
+ # Try a second time
+ filename = hash_url_to_filename(url, etag)
+ cache_path = os.path.join(cache_dir, filename)
+
+ if os.path.exists(cache_path) and not force_download:
+ return cache_path
+
+ # From now on, connected is True.
+ # Prevent parallel downloads of the same file with a lock.
+ lock_path = cache_path + ".lock"
+ with FileLock(lock_path):
+
+ if resume_download:
+ incomplete_path = cache_path + ".incomplete"
+
+ @contextmanager
+ def _resumable_file_manager():
+ with open(incomplete_path, "a+b") as f:
+ yield f
+
+ temp_file_manager = _resumable_file_manager
+ if os.path.exists(incomplete_path):
+ resume_size = os.stat(incomplete_path).st_size
+ else:
+ resume_size = 0
+ else:
+ temp_file_manager = partial(tempfile.NamedTemporaryFile, dir=cache_dir, delete=False)
+ resume_size = 0
+
+ # Download to temporary file, then copy to cache dir once finished.
+ # Otherwise you get corrupt cache entries if the download gets interrupted.
+ with temp_file_manager() as temp_file:
+ logger.info(f"{url} not found in cache or force_download set to True, downloading to {temp_file.name}")
+
+ # GET file object
+ if url.startswith("ftp://"):
+ ftp_get(url, temp_file)
+ else:
+ http_get(
+ url,
+ temp_file,
+ proxies=proxies,
+ resume_size=resume_size,
+ headers=headers,
+ cookies=cookies,
+ max_retries=max_retries,
+ desc=download_desc,
+ )
+
+ logger.info(f"storing {url} in cache at {cache_path}")
+ shutil.move(temp_file.name, cache_path)
+
+ logger.info(f"creating metadata file for {cache_path}")
+ meta = {"url": url, "etag": etag}
+ meta_path = cache_path + ".json"
+ with open(meta_path, "w", encoding="utf-8") as meta_file:
+ json.dump(meta, meta_file)
+
+ return cache_path
+
+
+def add_start_docstrings(*docstr):
+ def docstring_decorator(fn):
+ fn.__doc__ = "".join(docstr) + "\n\n" + (fn.__doc__ if fn.__doc__ is not None else "")
+ return fn
+
+ return docstring_decorator
+
+
+def add_end_docstrings(*docstr):
+ def docstring_decorator(fn):
+ fn.__doc__ = (fn.__doc__ if fn.__doc__ is not None else "") + "\n\n" + "".join(docstr)
+ return fn
+
+ return docstring_decorator
+
+
+def estimate_dataset_size(paths):
+ return sum(path.stat().st_size for path in paths)
+
+
+def readline(f: io.RawIOBase):
+ # From: https://github.com/python/cpython/blob/d27e2f4d118e7a9909b6a3e5da06c5ff95806a85/Lib/_pyio.py#L525
+ res = bytearray()
+ while True:
+ b = f.read(1)
+ if not b:
+ break
+ res += b
+ if res.endswith(b"\n"):
+ break
+ return bytes(res)
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/gradio.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/gradio.py
new file mode 100644
index 0000000000000000000000000000000000000000..3b73d9c67e711caad66edaf0f66808fff296aabd
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/gradio.py
@@ -0,0 +1,131 @@
+import json
+import os
+import re
+import sys
+from pathlib import Path
+
+import numpy as np
+from datasets import Value
+
+from .logging import get_logger
+
+
+logger = get_logger(__name__)
+
+REGEX_YAML_BLOCK = re.compile(r"---[\n\r]+([\S\s]*?)[\n\r]+---[\n\r]")
+
+
+def infer_gradio_input_types(feature_types):
+ """
+ Maps metric feature types to input types for gradio Dataframes:
+ - float/int -> numbers
+ - string -> strings
+ - any other -> json
+ Note that json is not a native gradio type but will be treated as string that
+ is then parsed as a json.
+ """
+ input_types = []
+ for feature_type in feature_types:
+ input_type = "json"
+ if isinstance(feature_type, Value):
+ if feature_type.dtype.startswith("int") or feature_type.dtype.startswith("float"):
+ input_type = "number"
+ elif feature_type.dtype == "string":
+ input_type = "str"
+ input_types.append(input_type)
+ return input_types
+
+
+def json_to_string_type(input_types):
+ """Maps json input type to str."""
+ return ["str" if i == "json" else i for i in input_types]
+
+
+def parse_readme(filepath):
+ """Parses a repositories README and removes"""
+ if not os.path.exists(filepath):
+ return "No README.md found."
+ with open(filepath, "r") as f:
+ text = f.read()
+ match = REGEX_YAML_BLOCK.search(text)
+ if match:
+ text = text[match.end() :]
+ return text
+
+
+def parse_gradio_data(data, input_types):
+ """Parses data from gradio Dataframe for use in metric."""
+ metric_inputs = {}
+ data.replace("", np.nan, inplace=True)
+ data.dropna(inplace=True)
+ for feature_name, input_type in zip(data, input_types):
+ if input_type == "json":
+ metric_inputs[feature_name] = [json.loads(d) for d in data[feature_name].to_list()]
+ elif input_type == "str":
+ metric_inputs[feature_name] = [d.strip('"') for d in data[feature_name].to_list()]
+ else:
+ metric_inputs[feature_name] = data[feature_name]
+ return metric_inputs
+
+
+def parse_test_cases(test_cases, feature_names, input_types):
+ """
+ Parses test cases to be used in gradio Dataframe. Note that an apostrophe is added
+ to strings to follow the format in json.
+ """
+ if len(test_cases) == 0:
+ return None
+ examples = []
+ for test_case in test_cases:
+ parsed_cases = []
+ for feat, input_type in zip(feature_names, input_types):
+ if input_type == "json":
+ parsed_cases.append([str(element) for element in test_case[feat]])
+ elif input_type == "str":
+ parsed_cases.append(['"' + element + '"' for element in test_case[feat]])
+ else:
+ parsed_cases.append(test_case[feat])
+ examples.append([list(i) for i in zip(*parsed_cases)])
+ return examples
+
+
+def launch_gradio_widget(metric):
+ """Launches `metric` widget with Gradio."""
+
+ try:
+ import gradio as gr
+ except ImportError as error:
+ logger.error("To create a metric widget with Gradio make sure gradio is installed.")
+ raise error
+
+ local_path = Path(sys.path[0])
+ # if there are several input types, use first as default.
+ if isinstance(metric.features, list):
+ (feature_names, feature_types) = zip(*metric.features[0].items())
+ else:
+ (feature_names, feature_types) = zip(*metric.features.items())
+ gradio_input_types = infer_gradio_input_types(feature_types)
+
+ def compute(data):
+ return metric.compute(**parse_gradio_data(data, gradio_input_types))
+
+ iface = gr.Interface(
+ fn=compute,
+ inputs=gr.inputs.Dataframe(
+ headers=feature_names,
+ col_count=len(feature_names),
+ row_count=1,
+ datatype=json_to_string_type(gradio_input_types),
+ ),
+ outputs=gr.outputs.Textbox(label=metric.name),
+ description=(
+ metric.info.description + "\nIf this is a text-based metric, make sure to wrap you input in double quotes."
+ " Alternatively you can use a JSON-formatted list as input."
+ ),
+ title=f"Metric: {metric.name}",
+ article=parse_readme(local_path / "README.md"),
+ # TODO: load test cases and use them to populate examples
+ # examples=[parse_test_cases(test_cases, feature_names, gradio_input_types)]
+ )
+
+ iface.launch()
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/logging.py b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/logging.py
new file mode 100644
index 0000000000000000000000000000000000000000..d29b7f4845f292f13dc40a4b3df123c704b8d807
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/utils/logging.py
@@ -0,0 +1,233 @@
+# Copyright 2020 Optuna, Hugging Face
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+""" Logging utilities. """
+
+import logging
+import os
+from logging import CRITICAL # NOQA
+from logging import DEBUG # NOQA
+from logging import ERROR # NOQA
+from logging import FATAL # NOQA
+from logging import INFO # NOQA
+from logging import NOTSET # NOQA
+from logging import WARN # NOQA
+from logging import WARNING # NOQA
+from typing import Optional
+
+from tqdm import auto as tqdm_lib
+
+
+log_levels = {
+ "debug": logging.DEBUG,
+ "info": logging.INFO,
+ "warning": logging.WARNING,
+ "error": logging.ERROR,
+ "critical": logging.CRITICAL,
+}
+
+_default_log_level = logging.WARNING
+
+
+def _get_default_logging_level():
+ """
+ If EVALUATE_VERBOSITY env var is set to one of the valid choices return that as the new default level.
+ If it is not - fall back to ``_default_log_level``
+ """
+ env_level_str = os.getenv("EVALUATE_VERBOSITY", None)
+ if env_level_str:
+ if env_level_str in log_levels:
+ return log_levels[env_level_str]
+ else:
+ logging.getLogger().warning(
+ f"Unknown option EVALUATE_VERBOSITY={env_level_str}, "
+ f"has to be one of: { ', '.join(log_levels.keys()) }"
+ )
+ return _default_log_level
+
+
+def _get_library_name() -> str:
+ return __name__.split(".")[0]
+
+
+def _get_library_root_logger() -> logging.Logger:
+ return logging.getLogger(_get_library_name())
+
+
+def _configure_library_root_logger() -> None:
+ # Apply our default configuration to the library root logger.
+ library_root_logger = _get_library_root_logger()
+ library_root_logger.setLevel(_get_default_logging_level())
+
+
+def _reset_library_root_logger() -> None:
+ library_root_logger = _get_library_root_logger()
+ library_root_logger.setLevel(logging.NOTSET)
+
+
+def get_logger(name: Optional[str] = None) -> logging.Logger:
+ """Return a logger with the specified name."""
+ if name is None:
+ name = _get_library_name()
+ return logging.getLogger(name)
+
+
+def get_verbosity() -> int:
+ """Return the current level for the Hugging Face Evaluate library's root logger.
+ Returns:
+ Logging level, e.g., `evaluate.logging.DEBUG` and `evaluate.logging.INFO`.
+
+
+
+ Hugging Face Evaluate library has following logging levels:
+ - `evaluate.logging.CRITICAL`, `evaluate.logging.FATAL`
+ - `evaluate.logging.ERROR`
+ - `evaluate.logging.WARNING`, `evaluate.logging.WARN`
+ - `evaluate.logging.INFO`
+ - `evaluate.logging.DEBUG`
+
+
+ """
+ return _get_library_root_logger().getEffectiveLevel()
+
+
+def set_verbosity(verbosity: int) -> None:
+ """Set the level for the Hugging Face Evaluate library's root logger.
+ Args:
+ verbosity:
+ Logging level, e.g., `evaluate.logging.DEBUG` and `evaluate.logging.INFO`.
+ """
+ _get_library_root_logger().setLevel(verbosity)
+
+
+def set_verbosity_info():
+ """Set the level for the Hugging Face Evaluate library's root logger to `INFO`.
+
+ This will display most of the logging information and tqdm bars.
+
+ Shortcut to `evaluate.logging.set_verbosity(evaluate.logging.INFO)`.
+ """
+ return set_verbosity(INFO)
+
+
+def set_verbosity_warning():
+ """Set the level for the Hugging Face Evaluate library's root logger to `WARNING`.
+
+ This will display only the warning and errors logging information and tqdm bars.
+
+ Shortcut to `evaluate.logging.set_verbosity(evaluate.logging.WARNING)`.
+ """
+ return set_verbosity(WARNING)
+
+
+def set_verbosity_debug():
+ """Set the level for the Hugging Face Evaluate library's root logger to `DEBUG`.
+
+ This will display all the logging information and tqdm bars.
+
+ Shortcut to `evaluate.logging.set_verbosity(evaluate.logging.DEBUG)`.
+ """
+ return set_verbosity(DEBUG)
+
+
+def set_verbosity_error():
+ """Set the level for the Hugging Face Evaluate library's root logger to `ERROR`.
+
+ This will display only the errors logging information and tqdm bars.
+
+ Shortcut to `evaluate.logging.set_verbosity(evaluate.logging.ERROR)`.
+ """
+ return set_verbosity(ERROR)
+
+
+def disable_propagation() -> None:
+ """Disable propagation of the library log outputs.
+ Note that log propagation is disabled by default.
+ """
+ _get_library_root_logger().propagate = False
+
+
+def enable_propagation() -> None:
+ """Enable propagation of the library log outputs.
+ Please disable the Hugging Face Evaluate library's default handler to prevent double logging if the root logger has
+ been configured.
+ """
+ _get_library_root_logger().propagate = True
+
+
+# Configure the library root logger at the module level (singleton-like)
+_configure_library_root_logger()
+
+
+class EmptyTqdm:
+ """Dummy tqdm which doesn't do anything."""
+
+ def __init__(self, *args, **kwargs): # pylint: disable=unused-argument
+ self._iterator = args[0] if args else None
+
+ def __iter__(self):
+ return iter(self._iterator)
+
+ def __getattr__(self, _):
+ """Return empty function."""
+
+ def empty_fn(*args, **kwargs): # pylint: disable=unused-argument
+ return
+
+ return empty_fn
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type_, value, traceback):
+ return
+
+
+_tqdm_active = True
+
+
+class _tqdm_cls:
+ def __call__(self, *args, **kwargs):
+ if _tqdm_active:
+ return tqdm_lib.tqdm(*args, **kwargs)
+ else:
+ return EmptyTqdm(*args, **kwargs)
+
+ def set_lock(self, *args, **kwargs):
+ self._lock = None
+ if _tqdm_active:
+ return tqdm_lib.tqdm.set_lock(*args, **kwargs)
+
+ def get_lock(self):
+ if _tqdm_active:
+ return tqdm_lib.tqdm.get_lock()
+
+
+tqdm = _tqdm_cls()
+
+
+def is_progress_bar_enabled() -> bool:
+ """Return a boolean indicating whether tqdm progress bars are enabled."""
+ return bool(_tqdm_active)
+
+
+def enable_progress_bar():
+ """Enable tqdm progress bar."""
+ global _tqdm_active
+ _tqdm_active = True
+
+
+def disable_progress_bar():
+ """Enable tqdm progress bar."""
+ global _tqdm_active
+ _tqdm_active = False
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/hf_xet-1.3.2.dist-info/licenses/LICENSE b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/hf_xet-1.3.2.dist-info/licenses/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/hf_xet-1.3.2.dist-info/licenses/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/hf_xet-1.3.2.dist-info/sboms/hf_xet.cyclonedx.json b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/hf_xet-1.3.2.dist-info/sboms/hf_xet.cyclonedx.json
new file mode 100644
index 0000000000000000000000000000000000000000..0d428a16fade54a583c7ee17489a129e7828e423
--- /dev/null
+++ b/Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/hf_xet-1.3.2.dist-info/sboms/hf_xet.cyclonedx.json
@@ -0,0 +1,12019 @@
+{
+ "bomFormat": "CycloneDX",
+ "specVersion": "1.5",
+ "version": 1,
+ "serialNumber": "urn:uuid:8142c7e6-0d78-4fdc-8071-fe9a0e46fe4a",
+ "metadata": {
+ "timestamp": "2026-02-27T17:17:38.240074353Z",
+ "tools": [
+ {
+ "vendor": "CycloneDX",
+ "name": "cargo-cyclonedx",
+ "version": "0.5.7"
+ }
+ ],
+ "component": {
+ "type": "library",
+ "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/hf_xet#1.3.2",
+ "name": "hf_xet",
+ "version": "1.3.2",
+ "scope": "required",
+ "licenses": [
+ {
+ "expression": "Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/hf_xet@1.3.2?download_url=file://.",
+ "components": [
+ {
+ "type": "library",
+ "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/hf_xet#1.3.2 bin-target-0",
+ "name": "hf_xet",
+ "version": "1.3.2",
+ "purl": "pkg:cargo/hf_xet@1.3.2?download_url=file://.#src/lib.rs"
+ }
+ ]
+ },
+ "properties": [
+ {
+ "name": "cdx:rustc:sbom:target:all_targets",
+ "value": "true"
+ }
+ ]
+ },
+ "components": [
+ {
+ "type": "library",
+ "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/cas_client#0.14.5",
+ "name": "cas_client",
+ "version": "0.14.5",
+ "scope": "required",
+ "purl": "pkg:cargo/cas_client@0.14.5?download_url=file:///home/runner/work/xet-core/xet-core/cas_client"
+ },
+ {
+ "type": "library",
+ "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/cas_object#0.1.0",
+ "name": "cas_object",
+ "version": "0.1.0",
+ "scope": "required",
+ "purl": "pkg:cargo/cas_object@0.1.0?download_url=file:///home/runner/work/xet-core/xet-core/cas_object"
+ },
+ {
+ "type": "library",
+ "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/cas_types#0.1.0",
+ "name": "cas_types",
+ "version": "0.1.0",
+ "scope": "required",
+ "purl": "pkg:cargo/cas_types@0.1.0?download_url=file:///home/runner/work/xet-core/xet-core/cas_types"
+ },
+ {
+ "type": "library",
+ "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/data#0.14.5",
+ "name": "data",
+ "version": "0.14.5",
+ "scope": "required",
+ "purl": "pkg:cargo/data@0.14.5?download_url=file:///home/runner/work/xet-core/xet-core/data"
+ },
+ {
+ "type": "library",
+ "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/deduplication#0.14.5",
+ "name": "deduplication",
+ "version": "0.14.5",
+ "scope": "required",
+ "purl": "pkg:cargo/deduplication@0.14.5?download_url=file:///home/runner/work/xet-core/xet-core/deduplication"
+ },
+ {
+ "type": "library",
+ "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/error_printer#0.14.5",
+ "name": "error_printer",
+ "version": "0.14.5",
+ "scope": "required",
+ "purl": "pkg:cargo/error_printer@0.14.5?download_url=file:///home/runner/work/xet-core/xet-core/error_printer"
+ },
+ {
+ "type": "library",
+ "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/file_reconstruction#0.14.5",
+ "name": "file_reconstruction",
+ "version": "0.14.5",
+ "scope": "required",
+ "purl": "pkg:cargo/file_reconstruction@0.14.5?download_url=file:///home/runner/work/xet-core/xet-core/file_reconstruction"
+ },
+ {
+ "type": "library",
+ "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/file_utils#0.14.2",
+ "name": "file_utils",
+ "version": "0.14.2",
+ "scope": "required",
+ "purl": "pkg:cargo/file_utils@0.14.2?download_url=file:///home/runner/work/xet-core/xet-core/file_utils"
+ },
+ {
+ "type": "library",
+ "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/hub_client#0.1.0",
+ "name": "hub_client",
+ "version": "0.1.0",
+ "scope": "required",
+ "purl": "pkg:cargo/hub_client@0.1.0?download_url=file:///home/runner/work/xet-core/xet-core/hub_client"
+ },
+ {
+ "type": "library",
+ "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/mdb_shard#0.14.5",
+ "name": "mdb_shard",
+ "version": "0.14.5",
+ "scope": "required",
+ "purl": "pkg:cargo/mdb_shard@0.14.5?download_url=file:///home/runner/work/xet-core/xet-core/mdb_shard"
+ },
+ {
+ "type": "library",
+ "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/merklehash#0.14.5",
+ "name": "merklehash",
+ "version": "0.14.5",
+ "scope": "required",
+ "purl": "pkg:cargo/merklehash@0.14.5?download_url=file:///home/runner/work/xet-core/xet-core/merklehash"
+ },
+ {
+ "type": "library",
+ "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/progress_tracking#0.1.0",
+ "name": "progress_tracking",
+ "version": "0.1.0",
+ "scope": "required",
+ "purl": "pkg:cargo/progress_tracking@0.1.0?download_url=file:///home/runner/work/xet-core/xet-core/progress_tracking"
+ },
+ {
+ "type": "library",
+ "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/utils#0.14.5",
+ "name": "utils",
+ "version": "0.14.5",
+ "scope": "required",
+ "purl": "pkg:cargo/utils@0.14.5?download_url=file:///home/runner/work/xet-core/xet-core/utils"
+ },
+ {
+ "type": "library",
+ "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/xet_config#0.14.5",
+ "name": "xet_config",
+ "version": "0.14.5",
+ "scope": "required",
+ "purl": "pkg:cargo/xet_config@0.14.5?download_url=file:///home/runner/work/xet-core/xet-core/xet_config"
+ },
+ {
+ "type": "library",
+ "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/xet_logging#0.14.5",
+ "name": "xet_logging",
+ "version": "0.14.5",
+ "scope": "required",
+ "purl": "pkg:cargo/xet_logging@0.14.5?download_url=file:///home/runner/work/xet-core/xet-core/xet_logging"
+ },
+ {
+ "type": "library",
+ "bom-ref": "path+file:///home/runner/work/xet-core/xet-core/xet_runtime#0.1.0",
+ "name": "xet_runtime",
+ "version": "0.1.0",
+ "scope": "required",
+ "purl": "pkg:cargo/xet_runtime@0.1.0?download_url=file:///home/runner/work/xet-core/xet-core/xet_runtime"
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#aho-corasick@1.1.4",
+ "author": "Andrew Gallant ",
+ "name": "aho-corasick",
+ "version": "1.1.4",
+ "description": "Fast multiple substring searching.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Unlicense OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/aho-corasick@1.1.4",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://github.com/BurntSushi/aho-corasick"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/BurntSushi/aho-corasick"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#anstream@0.6.21",
+ "name": "anstream",
+ "version": "0.6.21",
+ "description": "IO stream adapters for writing colored text that will gracefully degrade according to your terminal's capabilities.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/anstream@0.6.21",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-cli/anstyle.git"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#anstyle-parse@0.2.7",
+ "name": "anstyle-parse",
+ "version": "0.2.7",
+ "description": "Parse ANSI Style Escapes",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/anstyle-parse@0.2.7",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-cli/anstyle.git"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#anstyle-query@1.1.5",
+ "name": "anstyle-query",
+ "version": "1.1.5",
+ "description": "Look up colored console capabilities",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/anstyle-query@1.1.5",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-cli/anstyle.git"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#anstyle@1.0.13",
+ "name": "anstyle",
+ "version": "1.0.13",
+ "description": "ANSI text styling",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/anstyle@1.0.13",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-cli/anstyle.git"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.101",
+ "author": "David Tolnay ",
+ "name": "anyhow",
+ "version": "1.0.101",
+ "description": "Flexible concrete Error type built on std::error::Error",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/anyhow@1.0.101",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/anyhow"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/dtolnay/anyhow"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#approx@0.5.1",
+ "author": "Brendan Zabarauskas ",
+ "name": "approx",
+ "version": "0.5.1",
+ "description": "Approximate floating point equality comparisons and assertions.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/approx@0.5.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/approx"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/brendanzab/approx"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/brendanzab/approx"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#arrayref@0.3.9",
+ "author": "David Roundy ",
+ "name": "arrayref",
+ "version": "0.3.9",
+ "description": "Macros to take array references of slices",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "BSD-2-Clause"
+ }
+ ],
+ "purl": "pkg:cargo/arrayref@0.3.9",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/arrayref"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/droundy/arrayref"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#arrayvec@0.7.6",
+ "author": "bluss",
+ "name": "arrayvec",
+ "version": "0.7.6",
+ "description": "A vector with fixed capacity, backed by an array (it can be stored on the stack too). Implements fixed capacity ArrayVec and ArrayString.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/arrayvec@0.7.6",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/arrayvec/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/bluss/arrayvec"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89",
+ "author": "David Tolnay ",
+ "name": "async-trait",
+ "version": "0.1.89",
+ "description": "Type erasure for async trait methods",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/async-trait@0.1.89",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/async-trait"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/dtolnay/async-trait"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#atomic-waker@1.1.2",
+ "author": "Stjepan Glavina , Contributors to futures-rs",
+ "name": "atomic-waker",
+ "version": "1.1.2",
+ "description": "A synchronization primitive for task wakeup",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/atomic-waker@1.1.2",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/smol-rs/atomic-waker"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#autocfg@1.5.0",
+ "author": "Josh Stone ",
+ "name": "autocfg",
+ "version": "1.5.0",
+ "description": "Automatic cfg for Rust compiler features",
+ "scope": "excluded",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/autocfg@1.5.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/autocfg/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/cuviper/autocfg"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#aws-lc-rs@1.15.4",
+ "author": "AWS-LibCrypto",
+ "name": "aws-lc-rs",
+ "version": "1.15.4",
+ "description": "aws-lc-rs is a cryptographic library using AWS-LC for its cryptographic operations. This library strives to be API-compatible with the popular Rust library named ring.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "7b7b6141e96a8c160799cc2d5adecd5cbbe5054cb8c7c4af53da0f83bb7ad256"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "ISC AND (Apache-2.0 OR ISC)"
+ }
+ ],
+ "purl": "pkg:cargo/aws-lc-rs@1.15.4",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/crate/aws-lc-rs"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/aws/aws-lc-rs"
+ },
+ {
+ "type": "other",
+ "url": "aws_lc_rs_1_15_4_sys"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/aws/aws-lc-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#aws-lc-sys@0.37.0",
+ "author": "AWS-LC",
+ "name": "aws-lc-sys",
+ "version": "0.37.0",
+ "description": "AWS-LC is a general-purpose cryptographic library maintained by the AWS Cryptography team for AWS and their customers. It іs based on code from the Google BoringSSL project and the OpenSSL project.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "5c34dda4df7017c8db52132f0f8a2e0f8161649d15723ed63fc00c82d0f2081a"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "ISC AND (Apache-2.0 OR ISC) AND OpenSSL"
+ }
+ ],
+ "purl": "pkg:cargo/aws-lc-sys@0.37.0",
+ "externalReferences": [
+ {
+ "type": "other",
+ "url": "aws_lc_0_37_0"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/aws/aws-lc-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#axum-core@0.5.6",
+ "name": "axum-core",
+ "version": "0.5.6",
+ "description": "Core types and traits for axum",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/axum-core@0.5.6",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://github.com/tokio-rs/axum"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/tokio-rs/axum"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#axum@0.8.8",
+ "name": "axum",
+ "version": "0.8.8",
+ "description": "Web framework that focuses on ergonomics and modularity",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/axum@0.8.8",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://github.com/tokio-rs/axum"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/tokio-rs/axum"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#base64@0.22.1",
+ "author": "Marshall Pierce ",
+ "name": "base64",
+ "version": "0.22.1",
+ "description": "encodes and decodes base64 as bytes or utf8",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/base64@0.22.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/base64"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/marshallpierce/rust-base64"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#bincode@1.3.3",
+ "author": "Ty Overby , Francesco Mazzoli , David Tolnay , Zoey Riordan ",
+ "name": "bincode",
+ "version": "1.3.3",
+ "description": "A binary serialization / deserialization strategy that uses Serde for transforming structs into bytes and vice versa!",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/bincode@1.3.3",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/bincode"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/servo/bincode"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#bitflags@2.10.0",
+ "author": "The Rust Project Developers",
+ "name": "bitflags",
+ "version": "2.10.0",
+ "description": "A macro to generate structures which behave like bitflags. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/bitflags@2.10.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/bitflags"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/bitflags/bitflags"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/bitflags/bitflags"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#blake3@1.8.3",
+ "author": "Jack O'Connor , Samuel Neves",
+ "name": "blake3",
+ "version": "1.8.3",
+ "description": "the BLAKE3 hash function",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "2468ef7d57b3fb7e16b576e8377cdbde2320c60e1491e961d11da40fc4f02a2d"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "CC0-1.0 OR Apache-2.0 OR Apache-2.0 WITH LLVM-exception"
+ }
+ ],
+ "purl": "pkg:cargo/blake3@1.8.3",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/blake3"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/BLAKE3-team/BLAKE3"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#block-buffer@0.10.4",
+ "author": "RustCrypto Developers",
+ "name": "block-buffer",
+ "version": "0.10.4",
+ "description": "Buffer type for block processing of data",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/block-buffer@0.10.4",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/block-buffer"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/RustCrypto/utils"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#bstr@1.12.1",
+ "author": "Andrew Gallant ",
+ "name": "bstr",
+ "version": "1.12.1",
+ "description": "A string type that is not required to be valid UTF-8.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/bstr@1.12.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/bstr"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/BurntSushi/bstr"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/BurntSushi/bstr"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#bytemuck@1.25.0",
+ "author": "Lokathor ",
+ "name": "bytemuck",
+ "version": "1.25.0",
+ "description": "A crate for mucking around with piles of bytes.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Zlib OR Apache-2.0 OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/bytemuck@1.25.0",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/Lokathor/bytemuck"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#byteorder@1.5.0",
+ "author": "Andrew Gallant ",
+ "name": "byteorder",
+ "version": "1.5.0",
+ "description": "Library for reading/writing numbers in big-endian and little-endian.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Unlicense OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/byteorder@1.5.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/byteorder"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/BurntSushi/byteorder"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/BurntSushi/byteorder"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.1",
+ "author": "Carl Lerche , Sean McArthur ",
+ "name": "bytes",
+ "version": "1.11.1",
+ "description": "Types and traits for working with bytes",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/bytes@1.11.1",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/tokio-rs/bytes"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#cc@1.2.55",
+ "author": "Alex Crichton ",
+ "name": "cc",
+ "version": "1.2.55",
+ "description": "A build-time dependency for Cargo build scripts to assist in invoking the native C compiler to compile native C code into a static archive to be linked into Rust code. ",
+ "scope": "excluded",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/cc@1.2.55",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/cc"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/rust-lang/cc-rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/cc-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#cfg-if@0.1.10",
+ "author": "Alex Crichton ",
+ "name": "cfg-if",
+ "version": "0.1.10",
+ "description": "A macro to ergonomically define an item depending on a large number of #[cfg] parameters. Structured like an if-else chain, the first matching branch is the item that gets emitted. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/cfg-if@0.1.10",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/cfg-if"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/alexcrichton/cfg-if"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/alexcrichton/cfg-if"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4",
+ "author": "Alex Crichton ",
+ "name": "cfg-if",
+ "version": "1.0.4",
+ "description": "A macro to ergonomically define an item depending on a large number of #[cfg] parameters. Structured like an if-else chain, the first matching branch is the item that gets emitted. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/cfg-if@1.0.4",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/cfg-if"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#cfg_aliases@0.2.1",
+ "author": "Zicklag ",
+ "name": "cfg_aliases",
+ "version": "0.2.1",
+ "description": "A tiny utility to help save you a lot of effort with long winded `#[cfg()]` checks.",
+ "scope": "excluded",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/cfg_aliases@0.2.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/cfg_aliases"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/katharostech/cfg_aliases"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/katharostech/cfg_aliases"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#chrono@0.4.43",
+ "name": "chrono",
+ "version": "0.4.43",
+ "description": "Date and time library for Rust",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/chrono@0.4.43",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/chrono/"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/chronotope/chrono"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/chronotope/chrono"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#clap@4.5.57",
+ "name": "clap",
+ "version": "4.5.57",
+ "description": "A simple to use, efficient, and full-featured Command Line Argument Parser",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "6899ea499e3fb9305a65d5ebf6e3d2248c5fab291f300ad0a704fbe142eae31a"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/clap@4.5.57",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/clap-rs/clap"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#clap_builder@4.5.57",
+ "name": "clap_builder",
+ "version": "4.5.57",
+ "description": "A simple to use, efficient, and full-featured Command Line Argument Parser",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "7b12c8b680195a62a8364d16b8447b01b6c2c8f9aaf68bee653be34d4245e238"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/clap_builder@4.5.57",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/clap-rs/clap"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#clap_derive@4.5.55",
+ "name": "clap_derive",
+ "version": "4.5.55",
+ "description": "Parse command line argument by defining a struct, derive crate.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/clap_derive@4.5.55",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/clap-rs/clap"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#clap_lex@0.7.7",
+ "name": "clap_lex",
+ "version": "0.7.7",
+ "description": "Minimal, flexible command line parser",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/clap_lex@0.7.7",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/clap-rs/clap"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#cmake@0.1.57",
+ "author": "Alex Crichton ",
+ "name": "cmake",
+ "version": "0.1.57",
+ "description": "A build dependency for running `cmake` to build a native library ",
+ "scope": "excluded",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/cmake@0.1.57",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/cmake"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/rust-lang/cmake-rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/cmake-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#colorchoice@1.0.4",
+ "name": "colorchoice",
+ "version": "1.0.4",
+ "description": "Global override of color control",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/colorchoice@1.0.4",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-cli/anstyle.git"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#colored@3.1.1",
+ "author": "Thomas Wickham ",
+ "name": "colored",
+ "version": "3.1.1",
+ "description": "The most simple way to add colors in your terminal",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MPL-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/colored@3.1.1",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://github.com/mackwic/colored"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/mackwic/colored"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#const-str@1.1.0",
+ "author": "Nugine ",
+ "name": "const-str",
+ "version": "1.1.0",
+ "description": "compile-time string operations",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "18f12cc9948ed9604230cdddc7c86e270f9401ccbe3c2e98a4378c5e7632212f"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/const-str@1.1.0",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/Nugine/const-str"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#const_panic@0.2.15",
+ "author": "rodrimati1992 ",
+ "name": "const_panic",
+ "version": "0.2.15",
+ "description": "const panic with formatting",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "e262cdaac42494e3ae34c43969f9cdeb7da178bdb4b66fa6a1ea2edb4c8ae652"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Zlib"
+ }
+ ],
+ "purl": "pkg:cargo/const_panic@0.2.15",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/rodrimati1992/const_panic/"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#constant_time_eq@0.4.2",
+ "author": "Cesar Eduardo Barros ",
+ "name": "constant_time_eq",
+ "version": "0.4.2",
+ "description": "Compares two equal-sized byte strings in constant time.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "CC0-1.0 OR MIT-0 OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/constant_time_eq@0.4.2",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/constant_time_eq"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/cesarb/constant_time_eq"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#countio@0.3.0",
+ "author": "Oleh Martsokha ",
+ "name": "countio",
+ "version": "0.3.0",
+ "description": "Byte counting for std::io::{Read, Write, Seek} and its async variants from futures and tokio. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "b9702aee5d1d744c01d82f6915644f950f898e014903385464c773b96fefdecb"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/countio@0.3.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/countio"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/spire-rs/countio"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/spire-rs/countio"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#cpufeatures@0.2.17",
+ "author": "RustCrypto Developers",
+ "name": "cpufeatures",
+ "version": "0.2.17",
+ "description": "Lightweight runtime CPU feature detection for aarch64, loongarch64, and x86/x86_64 targets, with no_std support and support for mobile targets including Android and iOS ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/cpufeatures@0.2.17",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/cpufeatures"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/RustCrypto/utils"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#crossbeam-channel@0.5.15",
+ "name": "crossbeam-channel",
+ "version": "0.5.15",
+ "description": "Multi-producer multi-consumer channels for message passing",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/crossbeam-channel@0.5.15",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-channel"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/crossbeam-rs/crossbeam"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#crossbeam-queue@0.3.12",
+ "name": "crossbeam-queue",
+ "version": "0.3.12",
+ "description": "Concurrent queues",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/crossbeam-queue@0.3.12",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-queue"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/crossbeam-rs/crossbeam"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#crossbeam-utils@0.8.21",
+ "name": "crossbeam-utils",
+ "version": "0.8.21",
+ "description": "Utilities for concurrent programming",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/crossbeam-utils@0.8.21",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-utils"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/crossbeam-rs/crossbeam"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#crypto-common@0.1.7",
+ "author": "RustCrypto Developers",
+ "name": "crypto-common",
+ "version": "0.1.7",
+ "description": "Common cryptographic traits",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/crypto-common@0.1.7",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/crypto-common"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/RustCrypto/traits"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#csv-core@0.1.13",
+ "author": "Andrew Gallant ",
+ "name": "csv-core",
+ "version": "0.1.13",
+ "description": "Bare bones CSV parsing with no_std support.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Unlicense OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/csv-core@0.1.13",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/csv-core"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/BurntSushi/rust-csv"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/BurntSushi/rust-csv"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#csv@1.4.0",
+ "author": "Andrew Gallant ",
+ "name": "csv",
+ "version": "1.4.0",
+ "description": "Fast CSV parsing with support for serde.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "52cd9d68cf7efc6ddfaaee42e7288d3a99d613d4b50f76ce9827ae0c6e14f938"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Unlicense OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/csv@1.4.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/csv"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/BurntSushi/rust-csv"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/BurntSushi/rust-csv"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#ctor-proc-macro@0.0.7",
+ "author": "Matt Mastracci ",
+ "name": "ctor-proc-macro",
+ "version": "0.0.7",
+ "description": "proc-macro support for the ctor crate",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "52560adf09603e58c9a7ee1fe1dcb95a16927b17c127f0ac02d6e768a0e25bc1"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/ctor-proc-macro@0.0.7",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/mmastrac/rust-ctor"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#ctor@0.6.3",
+ "author": "Matt Mastracci ",
+ "name": "ctor",
+ "version": "0.6.3",
+ "description": "__attribute__((constructor)) for Rust",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "424e0138278faeb2b401f174ad17e715c829512d74f3d1e81eb43365c2e0590e"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/ctor@0.6.3",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/mmastrac/rust-ctor"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#deranged@0.5.5",
+ "author": "Jacob Pratt ",
+ "name": "deranged",
+ "version": "0.5.5",
+ "description": "Ranged integers",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/deranged@0.5.5",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/jhpratt/deranged"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#derivative@2.2.0",
+ "author": "mcarton ",
+ "name": "derivative",
+ "version": "2.2.0",
+ "description": "A set of alternative `derive` attributes for Rust",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/derivative@2.2.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://mcarton.github.io/rust-derivative/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/mcarton/rust-derivative"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#digest@0.10.7",
+ "author": "RustCrypto Developers",
+ "name": "digest",
+ "version": "0.10.7",
+ "description": "Traits for cryptographic hash functions and message authentication codes",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/digest@0.10.7",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/digest"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/RustCrypto/traits"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#dirs-sys@0.5.0",
+ "author": "Simon Ochsenreither ",
+ "name": "dirs-sys",
+ "version": "0.5.0",
+ "description": "System-level helper functions for the dirs and directories crates.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/dirs-sys@0.5.0",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/dirs-dev/dirs-sys-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#dirs@6.0.0",
+ "author": "Simon Ochsenreither ",
+ "name": "dirs",
+ "version": "6.0.0",
+ "description": "A tiny low-level library that provides platform-specific standard locations of directories for config, cache and other data on Linux, Windows, macOS and Redox by leveraging the mechanisms defined by the XDG base/user directory specifications on Linux, the Known Folder API on Windows, and the Standard Directory guidelines on macOS.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/dirs@6.0.0",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/soc/dirs-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#displaydoc@0.2.5",
+ "author": "Jane Lusby ",
+ "name": "displaydoc",
+ "version": "0.2.5",
+ "description": "A derive macro for implementing the display Trait via a doc comment and string interpolation ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/displaydoc@0.2.5",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/displaydoc"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/yaahc/displaydoc"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/yaahc/displaydoc"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#doxygen-rs@0.4.2",
+ "name": "doxygen-rs",
+ "version": "0.4.2",
+ "description": "Transform Doxygen to Rustdoc",
+ "scope": "excluded",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "415b6ec780d34dcf624666747194393603d0373b7141eef01d12ee58881507d9"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "BSD-3-Clause"
+ }
+ ],
+ "purl": "pkg:cargo/doxygen-rs@0.4.2",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://github.com/Techie-Pi/doxygen-rs/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/Techie-Pi/doxygen-rs/"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#dtor-proc-macro@0.0.6",
+ "author": "Matt Mastracci ",
+ "name": "dtor-proc-macro",
+ "version": "0.0.6",
+ "description": "proc-macro support for the dtor crate",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/dtor-proc-macro@0.0.6",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/mmastrac/rust-ctor"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#dtor@0.1.1",
+ "author": "Matt Mastracci ",
+ "name": "dtor",
+ "version": "0.1.1",
+ "description": "__attribute__((destructor)) for Rust",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "404d02eeb088a82cfd873006cb713fe411306c7d182c344905e101fb1167d301"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/dtor@0.1.1",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/mmastrac/rust-ctor"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#dunce@1.0.5",
+ "author": "Kornel ",
+ "name": "dunce",
+ "version": "1.0.5",
+ "description": "Normalize Windows paths to the most compatible format, avoiding UNC where possible",
+ "scope": "excluded",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "CC0-1.0 OR MIT-0 OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/dunce@1.0.5",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/dunce"
+ },
+ {
+ "type": "website",
+ "url": "https://lib.rs/crates/dunce"
+ },
+ {
+ "type": "vcs",
+ "url": "https://gitlab.com/kornelski/dunce"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#duration-str@0.19.0",
+ "author": "baoyachi ",
+ "name": "duration-str",
+ "version": "0.19.0",
+ "description": "duration string parser",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "12494809f9915b6132014cc259c4e204ab53ab6c6dd2225672703b5359267d82"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/duration-str@0.19.0",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/baoyachi/duration-str"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#either@1.15.0",
+ "author": "bluss",
+ "name": "either",
+ "version": "1.15.0",
+ "description": "The enum `Either` with variants `Left` and `Right` is a general purpose sum type with two cases. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/either@1.15.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/either/1/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rayon-rs/either"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#equivalent@1.0.2",
+ "name": "equivalent",
+ "version": "1.0.2",
+ "description": "Traits for key comparison in maps.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/equivalent@1.0.2",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/indexmap-rs/equivalent"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#errno@0.3.14",
+ "author": "Chris Wong , Dan Gohman ",
+ "name": "errno",
+ "version": "0.3.14",
+ "description": "Cross-platform interface to the `errno` variable.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/errno@0.3.14",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/errno"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/lambda-fairy/rust-errno"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#fastrand@2.3.0",
+ "author": "Stjepan Glavina ",
+ "name": "fastrand",
+ "version": "2.3.0",
+ "description": "A simple and fast random number generator",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/fastrand@2.3.0",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/smol-rs/fastrand"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#find-msvc-tools@0.1.9",
+ "name": "find-msvc-tools",
+ "version": "0.1.9",
+ "description": "Find windows-specific tools, read MSVC versions from the registry and from COM interfaces",
+ "scope": "excluded",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/find-msvc-tools@0.1.9",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/find-msvc-tools"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/cc-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#fnv@1.0.7",
+ "author": "Alex Crichton ",
+ "name": "fnv",
+ "version": "1.0.7",
+ "description": "Fowler–Noll–Vo hash function",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/fnv@1.0.7",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://doc.servo.org/fnv/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/servo/rust-fnv"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#form_urlencoded@1.2.2",
+ "author": "The rust-url developers",
+ "name": "form_urlencoded",
+ "version": "1.2.2",
+ "description": "Parser and serializer for the application/x-www-form-urlencoded syntax, as used by HTML forms.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/form_urlencoded@1.2.2",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/servo/rust-url"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#fs_extra@1.3.0",
+ "author": "Denis Kurilenko ",
+ "name": "fs_extra",
+ "version": "1.3.0",
+ "description": "Expanding std::fs and std::io. Recursively copy folders with information about process and much more.",
+ "scope": "excluded",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/fs_extra@1.3.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/fs_extra"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/webdesus/fs_extra"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/webdesus/fs_extra"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-channel@0.3.31",
+ "name": "futures-channel",
+ "version": "0.3.31",
+ "description": "Channels for asynchronous communication using futures-rs. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/futures-channel@0.3.31",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://rust-lang.github.io/futures-rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/futures-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-core@0.3.31",
+ "name": "futures-core",
+ "version": "0.3.31",
+ "description": "The core traits and types in for the `futures` library. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/futures-core@0.3.31",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://rust-lang.github.io/futures-rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/futures-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-executor@0.3.31",
+ "name": "futures-executor",
+ "version": "0.3.31",
+ "description": "Executors for asynchronous tasks based on the futures-rs library. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/futures-executor@0.3.31",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://rust-lang.github.io/futures-rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/futures-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-io@0.3.31",
+ "name": "futures-io",
+ "version": "0.3.31",
+ "description": "The `AsyncRead`, `AsyncWrite`, `AsyncSeek`, and `AsyncBufRead` traits for the futures-rs library. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/futures-io@0.3.31",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://rust-lang.github.io/futures-rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/futures-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-macro@0.3.31",
+ "name": "futures-macro",
+ "version": "0.3.31",
+ "description": "The futures-rs procedural macro implementations. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/futures-macro@0.3.31",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://rust-lang.github.io/futures-rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/futures-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-sink@0.3.31",
+ "name": "futures-sink",
+ "version": "0.3.31",
+ "description": "The asynchronous `Sink` trait for the futures-rs library. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/futures-sink@0.3.31",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://rust-lang.github.io/futures-rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/futures-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-task@0.3.31",
+ "name": "futures-task",
+ "version": "0.3.31",
+ "description": "Tools for working with tasks. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/futures-task@0.3.31",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://rust-lang.github.io/futures-rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/futures-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures-util@0.3.31",
+ "name": "futures-util",
+ "version": "0.3.31",
+ "description": "Common utilities and extension traits for the futures-rs library. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/futures-util@0.3.31",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://rust-lang.github.io/futures-rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/futures-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#futures@0.3.31",
+ "name": "futures",
+ "version": "0.3.31",
+ "description": "An implementation of futures and streams featuring zero allocations, composability, and iterator-like interfaces. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/futures@0.3.31",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://rust-lang.github.io/futures-rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/futures-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#gearhash@0.1.3",
+ "author": "Sam Rijs ",
+ "name": "gearhash",
+ "version": "0.1.3",
+ "description": "Fast, SIMD-accelerated hash function for content-defined chunking",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "c8cf82cf76cd16485e56295a1377c775ce708c9f1a0be6b029076d60a245d213"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/gearhash@0.1.3",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/srijs/rust-gearhash"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#generic-array@0.14.7",
+ "author": "Bartłomiej Kamiński , Aaron Trent ",
+ "name": "generic-array",
+ "version": "0.14.7",
+ "description": "Generic types implementing functionality of arrays",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/generic-array@0.14.7",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "http://fizyk20.github.io/generic-array/generic_array/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/fizyk20/generic-array.git"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.2.17",
+ "author": "The Rand Project Developers",
+ "name": "getrandom",
+ "version": "0.2.17",
+ "description": "A small cross-platform library for retrieving random data from system source",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/getrandom@0.2.17",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/getrandom"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-random/getrandom"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.3.4",
+ "author": "The Rand Project Developers",
+ "name": "getrandom",
+ "version": "0.3.4",
+ "description": "A small cross-platform library for retrieving random data from system source",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/getrandom@0.3.4",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/getrandom"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-random/getrandom"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#getrandom@0.4.1",
+ "author": "The Rand Project Developers",
+ "name": "getrandom",
+ "version": "0.4.1",
+ "description": "A small cross-platform library for retrieving random data from system source",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/getrandom@0.4.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/getrandom"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-random/getrandom"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#git-version-macro@0.3.9",
+ "author": "David Roundy , Maarten de Vries , Mara Bos ",
+ "name": "git-version-macro",
+ "version": "0.3.9",
+ "description": "Internal macro crate for git-version.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "BSD-2-Clause"
+ }
+ ],
+ "purl": "pkg:cargo/git-version-macro@0.3.9",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/fusion-engineering/rust-git-version"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#git-version@0.3.9",
+ "author": "Mara Bos , Maarten de Vries , David Roundy ",
+ "name": "git-version",
+ "version": "0.3.9",
+ "description": "Compile the git version (tag name, or hash otherwise) and dirty state into your program.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "1ad568aa3db0fcbc81f2f116137f263d7304f512a1209b35b85150d3ef88ad19"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "BSD-2-Clause"
+ }
+ ],
+ "purl": "pkg:cargo/git-version@0.3.9",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/git-version/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/fusion-engineering/rust-git-version"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#h2@0.4.13",
+ "author": "Carl Lerche , Sean McArthur ",
+ "name": "h2",
+ "version": "0.4.13",
+ "description": "An HTTP/2 client and server",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/h2@0.4.13",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/h2"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/hyperium/h2"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#half@2.7.1",
+ "author": "Kathryn Long ",
+ "name": "half",
+ "version": "2.7.1",
+ "description": "Half-precision floating point f16 and bf16 types for Rust implementing the IEEE 754-2008 standard binary16 and bfloat16 types.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/half@2.7.1",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/VoidStarKat/half-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#hashbrown@0.16.1",
+ "author": "Amanieu d'Antras ",
+ "name": "hashbrown",
+ "version": "0.16.1",
+ "description": "A Rust port of Google's SwissTable hash map",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/hashbrown@0.16.1",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/hashbrown"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#headers-core@0.3.0",
+ "author": "Sean McArthur ",
+ "name": "headers-core",
+ "version": "0.3.0",
+ "description": "typed HTTP headers core trait",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/headers-core@0.3.0",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://hyper.rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/hyperium/headers"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#headers@0.4.1",
+ "author": "Sean McArthur ",
+ "name": "headers",
+ "version": "0.4.1",
+ "description": "typed HTTP headers",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/headers@0.4.1",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://hyper.rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/hyperium/headers"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#heapify@0.2.0",
+ "name": "heapify",
+ "version": "0.2.0",
+ "description": "Convenience functions to turn slices into max-heaps.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "0049b265b7f201ca9ab25475b22b47fe444060126a51abe00f77d986fc5cc52e"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/heapify@0.2.0",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/ethereal-sheep/heapify"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#heck@0.5.0",
+ "name": "heck",
+ "version": "0.5.0",
+ "description": "heck is a case conversion library.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/heck@0.5.0",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/withoutboats/heck"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#heed-traits@0.20.0",
+ "author": "Kerollmops ",
+ "name": "heed-traits",
+ "version": "0.20.0",
+ "description": "The traits used inside of the fully typed LMDB wrapper, heed",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "eb3130048d404c57ce5a1ac61a903696e8fcde7e8c2991e9fcfc1f27c3ef74ff"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/heed-traits@0.20.0",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/Kerollmops/heed"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#heed-types@0.21.0",
+ "author": "Kerollmops ",
+ "name": "heed-types",
+ "version": "0.21.0",
+ "description": "The types used with the fully typed LMDB wrapper, heed",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "13c255bdf46e07fb840d120a36dcc81f385140d7191c76a7391672675c01a55d"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/heed-types@0.21.0",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/Kerollmops/heed"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#heed@0.22.0",
+ "author": "Kerollmops ",
+ "name": "heed",
+ "version": "0.22.0",
+ "description": "A fully typed LMDB (mdb.master) wrapper with minimum overhead",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "6a56c94661ddfb51aa9cdfbf102cfcc340aa69267f95ebccc4af08d7c530d393"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/heed@0.22.0",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/Kerollmops/heed"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#http-body-util@0.1.3",
+ "author": "Carl Lerche , Lucio Franco , Sean McArthur ",
+ "name": "http-body-util",
+ "version": "0.1.3",
+ "description": "Combinators and adapters for HTTP request or response bodies. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/http-body-util@0.1.3",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/http-body-util"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/hyperium/http-body"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#http-body@1.0.1",
+ "author": "Carl Lerche , Lucio Franco , Sean McArthur ",
+ "name": "http-body",
+ "version": "1.0.1",
+ "description": "Trait representing an asynchronous, streaming, HTTP request or response body. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/http-body@1.0.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/http-body"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/hyperium/http-body"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#http@1.4.0",
+ "author": "Alex Crichton , Carl Lerche , Sean McArthur ",
+ "name": "http",
+ "version": "1.4.0",
+ "description": "A set of types for representing HTTP requests and responses. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/http@1.4.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/http"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/hyperium/http"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#httparse@1.10.1",
+ "author": "Sean McArthur ",
+ "name": "httparse",
+ "version": "1.10.1",
+ "description": "A tiny, safe, speedy, zero-copy HTTP/1.x parser.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/httparse@1.10.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/httparse"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/seanmonstar/httparse"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#httpdate@1.0.3",
+ "author": "Pyfisch ",
+ "name": "httpdate",
+ "version": "1.0.3",
+ "description": "HTTP date parsing and formatting",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/httpdate@1.0.3",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/pyfisch/httpdate"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#hyper-rustls@0.27.7",
+ "name": "hyper-rustls",
+ "version": "0.27.7",
+ "description": "Rustls+hyper integration for pure rust HTTPS",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR ISC OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/hyper-rustls@0.27.7",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/hyper-rustls/"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/rustls/hyper-rustls"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rustls/hyper-rustls"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#hyper-util@0.1.20",
+ "author": "Sean McArthur ",
+ "name": "hyper-util",
+ "version": "0.1.20",
+ "description": "hyper utilities",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/hyper-util@0.1.20",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/hyper-util"
+ },
+ {
+ "type": "website",
+ "url": "https://hyper.rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/hyperium/hyper-util"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#hyper@1.8.1",
+ "author": "Sean McArthur ",
+ "name": "hyper",
+ "version": "1.8.1",
+ "description": "A protective and efficient HTTP library for all.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/hyper@1.8.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/hyper"
+ },
+ {
+ "type": "website",
+ "url": "https://hyper.rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/hyperium/hyper"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#iana-time-zone@0.1.65",
+ "author": "Andrew Straw , René Kijewski , Ryan Lopopolo ",
+ "name": "iana-time-zone",
+ "version": "0.1.65",
+ "description": "get the IANA time zone for the current system",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/iana-time-zone@0.1.65",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/strawlab/iana-time-zone"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#icu_collections@2.1.1",
+ "author": "The ICU4X Project Developers",
+ "name": "icu_collections",
+ "version": "2.1.1",
+ "description": "Collection of API for use in ICU libraries.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Unicode-3.0"
+ }
+ ],
+ "purl": "pkg:cargo/icu_collections@2.1.1",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://icu4x.unicode.org"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/unicode-org/icu4x"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#icu_locale_core@2.1.1",
+ "author": "The ICU4X Project Developers",
+ "name": "icu_locale_core",
+ "version": "2.1.1",
+ "description": "API for managing Unicode Language and Locale Identifiers",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Unicode-3.0"
+ }
+ ],
+ "purl": "pkg:cargo/icu_locale_core@2.1.1",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://icu4x.unicode.org"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/unicode-org/icu4x"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#icu_normalizer@2.1.1",
+ "author": "The ICU4X Project Developers",
+ "name": "icu_normalizer",
+ "version": "2.1.1",
+ "description": "API for normalizing text into Unicode Normalization Forms",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Unicode-3.0"
+ }
+ ],
+ "purl": "pkg:cargo/icu_normalizer@2.1.1",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://icu4x.unicode.org"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/unicode-org/icu4x"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#icu_normalizer_data@2.1.1",
+ "author": "The ICU4X Project Developers",
+ "name": "icu_normalizer_data",
+ "version": "2.1.1",
+ "description": "Data for the icu_normalizer crate",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Unicode-3.0"
+ }
+ ],
+ "purl": "pkg:cargo/icu_normalizer_data@2.1.1",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://icu4x.unicode.org"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/unicode-org/icu4x"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#icu_properties@2.1.2",
+ "author": "The ICU4X Project Developers",
+ "name": "icu_properties",
+ "version": "2.1.2",
+ "description": "Definitions for Unicode properties",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Unicode-3.0"
+ }
+ ],
+ "purl": "pkg:cargo/icu_properties@2.1.2",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://icu4x.unicode.org"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/unicode-org/icu4x"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#icu_properties_data@2.1.2",
+ "author": "The ICU4X Project Developers",
+ "name": "icu_properties_data",
+ "version": "2.1.2",
+ "description": "Data for the icu_properties crate",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Unicode-3.0"
+ }
+ ],
+ "purl": "pkg:cargo/icu_properties_data@2.1.2",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://icu4x.unicode.org"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/unicode-org/icu4x"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#icu_provider@2.1.1",
+ "author": "The ICU4X Project Developers",
+ "name": "icu_provider",
+ "version": "2.1.1",
+ "description": "Trait and struct definitions for the ICU data provider",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Unicode-3.0"
+ }
+ ],
+ "purl": "pkg:cargo/icu_provider@2.1.1",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://icu4x.unicode.org"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/unicode-org/icu4x"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#idna@1.1.0",
+ "author": "The rust-url developers",
+ "name": "idna",
+ "version": "1.1.0",
+ "description": "IDNA (Internationalizing Domain Names in Applications) and Punycode.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/idna@1.1.0",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/servo/rust-url/"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#idna_adapter@1.2.1",
+ "author": "The rust-url developers",
+ "name": "idna_adapter",
+ "version": "1.2.1",
+ "description": "Back end adapter for idna",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/idna_adapter@1.2.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/idna_adapter/latest/idna_adapter/"
+ },
+ {
+ "type": "website",
+ "url": "https://docs.rs/crate/idna_adapter/latest"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/hsivonen/idna_adapter"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#indexmap@2.13.0",
+ "name": "indexmap",
+ "version": "2.13.0",
+ "description": "A hash table with consistent order and fast iteration.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/indexmap@2.13.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/indexmap/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/indexmap-rs/indexmap"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#indoc@2.0.7",
+ "author": "David Tolnay ",
+ "name": "indoc",
+ "version": "2.0.7",
+ "description": "Indented document literals",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/indoc@2.0.7",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/indoc"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/dtolnay/indoc"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#ipnet@2.11.0",
+ "author": "Kris Price ",
+ "name": "ipnet",
+ "version": "2.11.0",
+ "description": "Provides types and useful methods for working with IPv4 and IPv6 network addresses, commonly called IP prefixes. The new `IpNet`, `Ipv4Net`, and `Ipv6Net` types build on the existing `IpAddr`, `Ipv4Addr`, and `Ipv6Addr` types already provided in Rust's standard library and align to their design to stay consistent. The module also provides useful traits that extend `Ipv4Addr` and `Ipv6Addr` with methods for `Add`, `Sub`, `BitAnd`, and `BitOr` operations. The module only uses stable feature so it is guaranteed to compile using the stable toolchain.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/ipnet@2.11.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/ipnet"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/krisprice/ipnet"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#iri-string@0.7.10",
+ "author": "YOSHIOKA Takuma ",
+ "name": "iri-string",
+ "version": "0.7.10",
+ "description": "IRI as string types",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/iri-string@0.7.10",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/lo48576/iri-string"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#is_terminal_polyfill@1.70.2",
+ "name": "is_terminal_polyfill",
+ "version": "1.70.2",
+ "description": "Polyfill for `is_terminal` stdlib feature for use with older MSRVs",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/is_terminal_polyfill@1.70.2",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/polyfill-rs/is_terminal_polyfill"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#itertools@0.14.0",
+ "author": "bluss",
+ "name": "itertools",
+ "version": "0.14.0",
+ "description": "Extra iterator adaptors, iterator methods, free functions, and macros.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/itertools@0.14.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/itertools/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-itertools/itertools"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.17",
+ "author": "David Tolnay ",
+ "name": "itoa",
+ "version": "1.0.17",
+ "description": "Fast integer primitive to string conversion",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/itoa@1.0.17",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/itoa"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/dtolnay/itoa"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#jobserver@0.1.34",
+ "author": "Alex Crichton ",
+ "name": "jobserver",
+ "version": "0.1.34",
+ "description": "An implementation of the GNU Make jobserver for Rust. ",
+ "scope": "excluded",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/jobserver@0.1.34",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/jobserver"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/rust-lang/jobserver-rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/jobserver-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#konst@0.4.3",
+ "author": "rodrimati1992 ",
+ "name": "konst",
+ "version": "0.4.3",
+ "description": "Const equivalents of std features: comparison, destructuring, iteration, and parsing",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "f660d5f887e3562f9ab6f4a14988795b694099d66b4f5dedc02d197ba9becb1d"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Zlib"
+ }
+ ],
+ "purl": "pkg:cargo/konst@0.4.3",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/konst/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rodrimati1992/konst/"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#konst_proc_macros@0.4.1",
+ "author": "rodrimati1992 ",
+ "name": "konst_proc_macros",
+ "version": "0.4.1",
+ "description": "Implementation detail of the `konst` crate",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "e037a2e1d8d5fdbd49b16a4ea09d5d6401c1f29eca5ff29d03d3824dba16256a"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Zlib"
+ }
+ ],
+ "purl": "pkg:cargo/konst_proc_macros@0.4.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/konst/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rodrimati1992/konst/"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#lazy_static@1.5.0",
+ "author": "Marvin Löbel ",
+ "name": "lazy_static",
+ "version": "1.5.0",
+ "description": "A macro for declaring lazily evaluated statics in Rust.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/lazy_static@1.5.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/lazy_static"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang-nursery/lazy-static.rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.181",
+ "author": "The Rust Project Developers",
+ "name": "libc",
+ "version": "0.2.181",
+ "description": "Raw FFI bindings to platform libraries like libc.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "459427e2af2b9c839b132acb702a1c654d95e10f8c326bfc2ad11310e458b1c5"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/libc@0.2.181",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/libc"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#libm@0.2.16",
+ "author": "Alex Crichton , Amanieu d'Antras , Jorge Aparicio , Trevor Gross ",
+ "name": "libm",
+ "version": "0.2.16",
+ "description": "libm in pure Rust",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/libm@0.2.16",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/compiler-builtins"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#linux-raw-sys@0.11.0",
+ "author": "Dan Gohman ",
+ "name": "linux-raw-sys",
+ "version": "0.11.0",
+ "description": "Generated bindings for Linux's userspace API",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/linux-raw-sys@0.11.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/linux-raw-sys"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/sunfishcode/linux-raw-sys"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#litemap@0.8.1",
+ "author": "The ICU4X Project Developers",
+ "name": "litemap",
+ "version": "0.8.1",
+ "description": "A key-value Map implementation based on a flat, sorted Vec.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Unicode-3.0"
+ }
+ ],
+ "purl": "pkg:cargo/litemap@0.8.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/litemap"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/unicode-org/icu4x"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#lmdb-master-sys@0.2.5",
+ "author": "Kerollmops , Dan Burkert , Victor Porof ",
+ "name": "lmdb-master-sys",
+ "version": "0.2.5",
+ "description": "Rust bindings for liblmdb on the mdb.master branch.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "864808e0b19fb6dd3b70ba94ee671b82fce17554cf80aeb0a155c65bb08027df"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/lmdb-master-sys@0.2.5",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/lmdb-master-sys"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/meilisearch/heed/tree/main/lmdb-master-sys"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#lock_api@0.4.14",
+ "author": "Amanieu d'Antras ",
+ "name": "lock_api",
+ "version": "0.4.14",
+ "description": "Wrappers to create fully-featured Mutex and RwLock types. Compatible with no_std.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/lock_api@0.4.14",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/Amanieu/parking_lot"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#log@0.4.29",
+ "author": "The Rust Project Developers",
+ "name": "log",
+ "version": "0.4.29",
+ "description": "A lightweight logging facade for Rust ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/log@0.4.29",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/log"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/log"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#lru-slab@0.1.2",
+ "author": "Benjamin Saunders ",
+ "name": "lru-slab",
+ "version": "0.1.2",
+ "description": "Pre-allocated storage with constant-time LRU tracking",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0 OR Zlib"
+ }
+ ],
+ "purl": "pkg:cargo/lru-slab@0.1.2",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/Ralith/lru-slab"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#lz4_flex@0.12.0",
+ "author": "Pascal Seitz , Arthur Silva , ticki ",
+ "name": "lz4_flex",
+ "version": "0.12.0",
+ "description": "Fastest LZ4 implementation in Rust, no unsafe by default.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "ab6473172471198271ff72e9379150e9dfd70d8e533e0752a27e515b48dd375e"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/lz4_flex@0.12.0",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://github.com/pseitz/lz4_flex"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/pseitz/lz4_flex"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#matchers@0.2.0",
+ "author": "Eliza Weisman ",
+ "name": "matchers",
+ "version": "0.2.0",
+ "description": "Regex matching on character and byte streams. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/matchers@0.2.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/matchers/"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/hawkw/matchers"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/hawkw/matchers"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#matchit@0.8.4",
+ "author": "Ibraheem Ahmed ",
+ "name": "matchit",
+ "version": "0.8.4",
+ "description": "A high performance, zero-copy URL router.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT AND BSD-3-Clause"
+ }
+ ],
+ "purl": "pkg:cargo/matchit@0.8.4",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/ibraheemdev/matchit"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#matrixmultiply@0.3.10",
+ "author": "bluss, R. Janis Goldschmidt",
+ "name": "matrixmultiply",
+ "version": "0.3.10",
+ "description": "General matrix multiplication for f32 and f64 matrices. Operates on matrices with general layout (they can use arbitrary row and column stride). Detects and uses AVX or SSE2 on x86 platforms transparently for higher performance. Uses a microkernel strategy, so that the implementation is easy to parallelize and optimize. Supports multithreading.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/matrixmultiply@0.3.10",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/matrixmultiply/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/bluss/matrixmultiply/"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#memchr@2.8.0",
+ "author": "Andrew Gallant , bluss",
+ "name": "memchr",
+ "version": "2.8.0",
+ "description": "Provides extremely fast (uses SIMD on x86_64, aarch64 and wasm32) routines for 1, 2 or 3 byte search and single substring search. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Unlicense OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/memchr@2.8.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/memchr/"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/BurntSushi/memchr"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/BurntSushi/memchr"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#memoffset@0.9.1",
+ "author": "Gilad Naaman ",
+ "name": "memoffset",
+ "version": "0.9.1",
+ "description": "offset_of functionality for Rust structs.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/memoffset@0.9.1",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/Gilnaa/memoffset"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#mime@0.3.17",
+ "author": "Sean McArthur ",
+ "name": "mime",
+ "version": "0.3.17",
+ "description": "Strongly Typed Mimes",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/mime@0.3.17",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/mime"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/hyperium/mime"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#mime_guess@2.0.5",
+ "author": "Austin Bonander ",
+ "name": "mime_guess",
+ "version": "2.0.5",
+ "description": "A simple crate for detection of a file's MIME type by its extension.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/mime_guess@2.0.5",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/mime_guess/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/abonander/mime_guess"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#mio@1.1.1",
+ "author": "Carl Lerche , Thomas de Zeeuw , Tokio Contributors ",
+ "name": "mio",
+ "version": "1.1.1",
+ "description": "Lightweight non-blocking I/O.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/mio@1.1.1",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://github.com/tokio-rs/mio"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/tokio-rs/mio"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#more-asserts@0.3.1",
+ "author": "Thom Chiovoloni ",
+ "name": "more-asserts",
+ "version": "0.3.1",
+ "description": "Small library providing additional assert_* and debug_assert_* macros.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "1fafa6961cabd9c63bcd77a45d7e3b7f3b552b70417831fb0f56db717e72407e"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Unlicense OR MIT OR Apache-2.0 OR CC0-1.0"
+ }
+ ],
+ "purl": "pkg:cargo/more-asserts@0.3.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/more-asserts"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/thomcc/rust-more-asserts"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/thomcc/rust-more-asserts"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#nalgebra@0.33.2",
+ "author": "Sébastien Crozet ",
+ "name": "nalgebra",
+ "version": "0.33.2",
+ "description": "General-purpose linear algebra library with transformations and statically-sized or dynamically-sized matrices.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/nalgebra@0.33.2",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://www.nalgebra.org/docs"
+ },
+ {
+ "type": "website",
+ "url": "https://nalgebra.org"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/dimforge/nalgebra"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#nu-ansi-term@0.50.3",
+ "author": "ogham@bsago.me, Ryan Scheel (Havvy) , Josh Triplett , The Nushell Project Developers",
+ "name": "nu-ansi-term",
+ "version": "0.50.3",
+ "description": "Library for ANSI terminal colors and styles (bold, underline)",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/nu-ansi-term@0.50.3",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/nushell/nu-ansi-term"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#num-bigint@0.4.6",
+ "author": "The Rust Project Developers",
+ "name": "num-bigint",
+ "version": "0.4.6",
+ "description": "Big integer implementation for Rust",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/num-bigint@0.4.6",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/num-bigint"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/rust-num/num-bigint"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-num/num-bigint"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#num-complex@0.4.6",
+ "author": "The Rust Project Developers",
+ "name": "num-complex",
+ "version": "0.4.6",
+ "description": "Complex numbers implementation for Rust",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/num-complex@0.4.6",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/num-complex"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/rust-num/num-complex"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-num/num-complex"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#num-conv@0.2.0",
+ "author": "Jacob Pratt ",
+ "name": "num-conv",
+ "version": "0.2.0",
+ "description": "`num_conv` is a crate to convert between integer types without using `as` casts. This provides better certainty when refactoring, makes the exact behavior of code more explicit, and allows using turbofish syntax. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/num-conv@0.2.0",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/jhpratt/num-conv"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#num-integer@0.1.46",
+ "author": "The Rust Project Developers",
+ "name": "num-integer",
+ "version": "0.1.46",
+ "description": "Integer traits and functions",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/num-integer@0.1.46",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/num-integer"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/rust-num/num-integer"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-num/num-integer"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#num-rational@0.4.2",
+ "author": "The Rust Project Developers",
+ "name": "num-rational",
+ "version": "0.4.2",
+ "description": "Rational numbers implementation for Rust",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/num-rational@0.4.2",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/num-rational"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/rust-num/num-rational"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-num/num-rational"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19",
+ "author": "The Rust Project Developers",
+ "name": "num-traits",
+ "version": "0.2.19",
+ "description": "Numeric traits for generic mathematics",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/num-traits@0.2.19",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/num-traits"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/rust-num/num-traits"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-num/num-traits"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#once_cell@1.21.3",
+ "author": "Aleksey Kladov ",
+ "name": "once_cell",
+ "version": "1.21.3",
+ "description": "Single assignment cells and lazy values.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/once_cell@1.21.3",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/once_cell"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/matklad/once_cell"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#oneshot@0.1.13",
+ "author": "Linus Färnstrand ",
+ "name": "oneshot",
+ "version": "0.1.13",
+ "description": "Oneshot spsc channel with (potentially) lock-free non-blocking send, and a receiver supporting both thread blocking receive operations as well as Future based async polling. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "269bca4c2591a28585d6bf10d9ed0332b7d76900a1b02bec41bdc3a2cdcda107"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/oneshot@0.1.13",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/faern/oneshot"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#openssl-probe@0.2.1",
+ "author": "Alex Crichton ",
+ "name": "openssl-probe",
+ "version": "0.2.1",
+ "description": "A library for helping to find system-wide trust anchor (\"root\") certificate locations based on paths typically used by `openssl`. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/openssl-probe@0.2.1",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://github.com/rustls/openssl-probe"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rustls/openssl-probe"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#option-ext@0.2.0",
+ "author": "Simon Ochsenreither ",
+ "name": "option-ext",
+ "version": "0.2.0",
+ "description": "Extends `Option` with additional operations",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MPL-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/option-ext@0.2.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/option-ext/"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/soc/option-ext"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/soc/option-ext.git"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#os_str_bytes@6.6.1",
+ "author": "dylni",
+ "name": "os_str_bytes",
+ "version": "6.6.1",
+ "description": "Convert between byte sequences and platform-native strings ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/os_str_bytes@6.6.1",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/dylni/os_str_bytes"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#page_size@0.6.0",
+ "author": "Philip Woods ",
+ "name": "page_size",
+ "version": "0.6.0",
+ "description": "Provides an easy, fast, cross-platform way to retrieve the memory page size",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/page_size@0.6.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/page_size/"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/Elzair/page_size_rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/Elzair/page_size_rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#parking_lot@0.12.5",
+ "author": "Amanieu d'Antras ",
+ "name": "parking_lot",
+ "version": "0.12.5",
+ "description": "More compact and efficient implementations of the standard synchronization primitives.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/parking_lot@0.12.5",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/Amanieu/parking_lot"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#parking_lot_core@0.9.12",
+ "author": "Amanieu d'Antras ",
+ "name": "parking_lot_core",
+ "version": "0.9.12",
+ "description": "An advanced API for creating custom synchronization primitives.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/parking_lot_core@0.9.12",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/Amanieu/parking_lot"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#paste@1.0.15",
+ "author": "David Tolnay ",
+ "name": "paste",
+ "version": "1.0.15",
+ "description": "Macros for all your token pasting needs",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/paste@1.0.15",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/paste"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/dtolnay/paste"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#percent-encoding@2.3.2",
+ "author": "The rust-url developers",
+ "name": "percent-encoding",
+ "version": "2.3.2",
+ "description": "Percent encoding and decoding",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/percent-encoding@2.3.2",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/servo/rust-url/"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#phf@0.11.3",
+ "author": "Steven Fackler ",
+ "name": "phf",
+ "version": "0.11.3",
+ "description": "Runtime support for perfect hash function data structures",
+ "scope": "excluded",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/phf@0.11.3",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-phf/rust-phf"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#phf_generator@0.11.3",
+ "author": "Steven Fackler ",
+ "name": "phf_generator",
+ "version": "0.11.3",
+ "description": "PHF generation logic",
+ "scope": "excluded",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/phf_generator@0.11.3",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-phf/rust-phf"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#phf_macros@0.11.3",
+ "author": "Steven Fackler ",
+ "name": "phf_macros",
+ "version": "0.11.3",
+ "description": "Macros to generate types in the phf crate",
+ "scope": "excluded",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/phf_macros@0.11.3",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-phf/rust-phf"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#phf_shared@0.11.3",
+ "author": "Steven Fackler ",
+ "name": "phf_shared",
+ "version": "0.11.3",
+ "description": "Support code shared by PHF libraries",
+ "scope": "excluded",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/phf_shared@0.11.3",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-phf/rust-phf"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pin-project-internal@1.1.10",
+ "name": "pin-project-internal",
+ "version": "1.1.10",
+ "description": "Implementation detail of the `pin-project` crate. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/pin-project-internal@1.1.10",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/taiki-e/pin-project"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.16",
+ "name": "pin-project-lite",
+ "version": "0.2.16",
+ "description": "A lightweight version of pin-project written with declarative macros. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/pin-project-lite@0.2.16",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/taiki-e/pin-project-lite"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pin-project@1.1.10",
+ "name": "pin-project",
+ "version": "1.1.10",
+ "description": "A crate for safe and ergonomic pin-projection. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/pin-project@1.1.10",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/taiki-e/pin-project"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pin-utils@0.1.0",
+ "author": "Josef Brandl ",
+ "name": "pin-utils",
+ "version": "0.1.0",
+ "description": "Utilities for pinning ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/pin-utils@0.1.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/pin-utils"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang-nursery/pin-utils"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#potential_utf@0.1.4",
+ "author": "The ICU4X Project Developers",
+ "name": "potential_utf",
+ "version": "0.1.4",
+ "description": "Unvalidated string and character types",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Unicode-3.0"
+ }
+ ],
+ "purl": "pkg:cargo/potential_utf@0.1.4",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://icu4x.unicode.org"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/unicode-org/icu4x"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#powerfmt@0.2.0",
+ "author": "Jacob Pratt ",
+ "name": "powerfmt",
+ "version": "0.2.0",
+ "description": " `powerfmt` is a library that provides utilities for formatting values. This crate makes it significantly easier to support filling to a minimum width with alignment, avoid heap allocation, and avoid repetitive calculations. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/powerfmt@0.2.0",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/jhpratt/powerfmt"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#ppv-lite86@0.2.21",
+ "author": "The CryptoCorrosion Contributors",
+ "name": "ppv-lite86",
+ "version": "0.2.21",
+ "description": "Cross-platform cryptography-oriented low-level SIMD library.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/ppv-lite86@0.2.21",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/cryptocorrosion/cryptocorrosion"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.106",
+ "author": "David Tolnay , Alex Crichton ",
+ "name": "proc-macro2",
+ "version": "1.0.106",
+ "description": "A substitute implementation of the compiler's `proc_macro` API to decouple token-based libraries from the procedural macro use case.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/proc-macro2@1.0.106",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/proc-macro2"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/dtolnay/proc-macro2"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#prometheus@0.14.0",
+ "author": "overvenus@gmail.com, siddontang@gmail.com, vistaswx@gmail.com",
+ "name": "prometheus",
+ "version": "0.14.0",
+ "description": "Prometheus instrumentation library for Rust applications.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "3ca5326d8d0b950a9acd87e6a3f94745394f62e4dae1b1ee22b2bc0c394af43a"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/prometheus@0.14.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/prometheus"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/tikv/rust-prometheus"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/tikv/rust-prometheus"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#protobuf-support@3.7.2",
+ "author": "Stepan Koltsov ",
+ "name": "protobuf-support",
+ "version": "3.7.2",
+ "description": "Code supporting protobuf implementation. None of code in this crate is public API. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "3e36c2f31e0a47f9280fb347ef5e461ffcd2c52dd520d8e216b52f93b0b0d7d6"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/protobuf-support@3.7.2",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://github.com/stepancheg/rust-protobuf/blob/master/README.md"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/stepancheg/rust-protobuf/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/stepancheg/rust-protobuf/"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#protobuf@3.7.2",
+ "author": "Stepan Koltsov ",
+ "name": "protobuf",
+ "version": "3.7.2",
+ "description": "Rust implementation of Google protocol buffers ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "d65a1d4ddae7d8b5de68153b48f6aa3bba8cb002b243dbdbc55a5afbc98f99f4"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/protobuf@3.7.2",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://github.com/stepancheg/rust-protobuf/blob/master/README.md"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/stepancheg/rust-protobuf/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/stepancheg/rust-protobuf/"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3-build-config@0.26.0",
+ "author": "PyO3 Project and Contributors ",
+ "name": "pyo3-build-config",
+ "version": "0.26.0",
+ "description": "Build configuration for the PyO3 ecosystem",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "4fc6ddaf24947d12a9aa31ac65431fb1b851b8f4365426e182901eabfb87df5f"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/pyo3-build-config@0.26.0",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://github.com/pyo3/pyo3"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/pyo3/pyo3"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3-ffi@0.26.0",
+ "author": "PyO3 Project and Contributors ",
+ "name": "pyo3-ffi",
+ "version": "0.26.0",
+ "description": "Python-API bindings for the PyO3 ecosystem",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "025474d3928738efb38ac36d4744a74a400c901c7596199e20e45d98eb194105"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/pyo3-ffi@0.26.0",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://github.com/pyo3/pyo3"
+ },
+ {
+ "type": "other",
+ "url": "python"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/pyo3/pyo3"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3-macros-backend@0.26.0",
+ "author": "PyO3 Project and Contributors ",
+ "name": "pyo3-macros-backend",
+ "version": "0.26.0",
+ "description": "Code generation for PyO3 package",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "100246c0ecf400b475341b8455a9213344569af29a3c841d29270e53102e0fcf"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/pyo3-macros-backend@0.26.0",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://github.com/pyo3/pyo3"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/pyo3/pyo3"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3-macros@0.26.0",
+ "author": "PyO3 Project and Contributors ",
+ "name": "pyo3-macros",
+ "version": "0.26.0",
+ "description": "Proc macros for PyO3 package",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "2e64eb489f22fe1c95911b77c44cc41e7c19f3082fc81cce90f657cdc42ffded"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/pyo3-macros@0.26.0",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://github.com/pyo3/pyo3"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/pyo3/pyo3"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#pyo3@0.26.0",
+ "author": "PyO3 Project and Contributors ",
+ "name": "pyo3",
+ "version": "0.26.0",
+ "description": "Bindings to Python interpreter",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "7ba0117f4212101ee6544044dae45abe1083d30ce7b29c4b5cbdfa2354e07383"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/pyo3@0.26.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/crate/pyo3/"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/pyo3/pyo3"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/pyo3/pyo3"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#quinn-proto@0.11.13",
+ "name": "quinn-proto",
+ "version": "0.11.13",
+ "description": "State machine for the QUIC transport protocol",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/quinn-proto@0.11.13",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/quinn-rs/quinn"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#quinn-udp@0.5.14",
+ "name": "quinn-udp",
+ "version": "0.5.14",
+ "description": "UDP sockets with ECN information for the QUIC transport protocol",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/quinn-udp@0.5.14",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/quinn-rs/quinn"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#quinn@0.11.9",
+ "name": "quinn",
+ "version": "0.11.9",
+ "description": "Versatile QUIC transport protocol implementation",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/quinn@0.11.9",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/quinn-rs/quinn"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#quote@1.0.44",
+ "author": "David Tolnay ",
+ "name": "quote",
+ "version": "1.0.44",
+ "description": "Quasi-quoting macro quote!(...)",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/quote@1.0.44",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/quote/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/dtolnay/quote"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rand@0.8.5",
+ "author": "The Rand Project Developers, The Rust Project Developers",
+ "name": "rand",
+ "version": "0.8.5",
+ "description": "Random number generators and other randomness functionality. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/rand@0.8.5",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/rand"
+ },
+ {
+ "type": "website",
+ "url": "https://rust-random.github.io/book"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-random/rand"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rand@0.9.2",
+ "author": "The Rand Project Developers, The Rust Project Developers",
+ "name": "rand",
+ "version": "0.9.2",
+ "description": "Random number generators and other randomness functionality. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/rand@0.9.2",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/rand"
+ },
+ {
+ "type": "website",
+ "url": "https://rust-random.github.io/book"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-random/rand"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rand_chacha@0.3.1",
+ "author": "The Rand Project Developers, The Rust Project Developers, The CryptoCorrosion Contributors",
+ "name": "rand_chacha",
+ "version": "0.3.1",
+ "description": "ChaCha random number generator ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/rand_chacha@0.3.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/rand_chacha"
+ },
+ {
+ "type": "website",
+ "url": "https://rust-random.github.io/book"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-random/rand"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rand_chacha@0.9.0",
+ "author": "The Rand Project Developers, The Rust Project Developers, The CryptoCorrosion Contributors",
+ "name": "rand_chacha",
+ "version": "0.9.0",
+ "description": "ChaCha random number generator ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/rand_chacha@0.9.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/rand_chacha"
+ },
+ {
+ "type": "website",
+ "url": "https://rust-random.github.io/book"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-random/rand"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rand_core@0.6.4",
+ "author": "The Rand Project Developers, The Rust Project Developers",
+ "name": "rand_core",
+ "version": "0.6.4",
+ "description": "Core random number generator traits and tools for implementation. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/rand_core@0.6.4",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/rand_core"
+ },
+ {
+ "type": "website",
+ "url": "https://rust-random.github.io/book"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-random/rand"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rand_core@0.9.5",
+ "author": "The Rand Project Developers, The Rust Project Developers",
+ "name": "rand_core",
+ "version": "0.9.5",
+ "description": "Core random number generator traits and tools for implementation. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/rand_core@0.9.5",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/rand_core"
+ },
+ {
+ "type": "website",
+ "url": "https://rust-random.github.io/book"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-random/rand"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rand_distr@0.4.3",
+ "author": "The Rand Project Developers",
+ "name": "rand_distr",
+ "version": "0.4.3",
+ "description": "Sampling from random number distributions ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/rand_distr@0.4.3",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/rand_distr"
+ },
+ {
+ "type": "website",
+ "url": "https://rust-random.github.io/book"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-random/rand"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rawpointer@0.2.1",
+ "author": "bluss",
+ "name": "rawpointer",
+ "version": "0.2.1",
+ "description": "Extra methods for raw pointers and `NonNull`. For example `.post_inc()` and `.pre_dec()` (c.f. `ptr++` and `--ptr`), `offset` and `add` for `NonNull`, and the function `ptrdistance`. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/rawpointer@0.2.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/rawpointer/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/bluss/rawpointer/"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#regex-automata@0.4.14",
+ "author": "The Rust Project Developers, Andrew Gallant ",
+ "name": "regex-automata",
+ "version": "0.4.14",
+ "description": "Automata construction and matching using regular expressions.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/regex-automata@0.4.14",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/regex-automata"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/rust-lang/regex/tree/master/regex-automata"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/regex"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#regex-syntax@0.8.9",
+ "author": "The Rust Project Developers, Andrew Gallant ",
+ "name": "regex-syntax",
+ "version": "0.8.9",
+ "description": "A regular expression parser.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/regex-syntax@0.8.9",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/regex-syntax"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/rust-lang/regex/tree/master/regex-syntax"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/regex"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#regex@1.12.3",
+ "author": "The Rust Project Developers, Andrew Gallant ",
+ "name": "regex",
+ "version": "1.12.3",
+ "description": "An implementation of regular expressions for Rust. This implementation uses finite automata and guarantees linear time matching on all inputs. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/regex@1.12.3",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/regex"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/rust-lang/regex"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/regex"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#reqwest-middleware@0.5.1",
+ "author": "Rodrigo Gryzinski ",
+ "name": "reqwest-middleware",
+ "version": "0.5.1",
+ "description": "Wrapper around reqwest to allow for client middleware chains.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "199dda04a536b532d0cc04d7979e39b1c763ea749bf91507017069c00b96056f"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/reqwest-middleware@0.5.1",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/TrueLayer/reqwest-middleware"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#reqwest-retry@0.9.1",
+ "author": "Rodrigo Gryzinski ",
+ "name": "reqwest-retry",
+ "version": "0.9.1",
+ "description": "Retry middleware for reqwest.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "fe2412db2af7d2268e7a5406be0431f37d9eb67ff390f35b395716f5f06c2eaa"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/reqwest-retry@0.9.1",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/TrueLayer/reqwest-middleware"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#reqwest@0.13.2",
+ "author": "Sean McArthur ",
+ "name": "reqwest",
+ "version": "0.13.2",
+ "description": "higher level HTTP client library",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/reqwest@0.13.2",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/reqwest"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/seanmonstar/reqwest"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#retry-policies@0.5.1",
+ "author": "Luca Palmieri ",
+ "name": "retry-policies",
+ "version": "0.5.1",
+ "description": "A collection of plug-and-play retry policies for Rust projects.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "46a4bd6027df676bcb752d3724db0ea3c0c5fc1dd0376fec51ac7dcaf9cc69be"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/retry-policies@0.5.1",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/TrueLayer/retry-policies"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#ring@0.17.14",
+ "name": "ring",
+ "version": "0.17.14",
+ "description": "An experiment.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 AND ISC"
+ }
+ ],
+ "purl": "pkg:cargo/ring@0.17.14",
+ "externalReferences": [
+ {
+ "type": "other",
+ "url": "ring_core_0_17_14_"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/briansmith/ring"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rust_decimal@1.40.0",
+ "author": "Paul Mason ",
+ "name": "rust_decimal",
+ "version": "1.40.0",
+ "description": "Decimal number implementation written in pure Rust suitable for financial and fixed-precision calculations.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "61f703d19852dbf87cbc513643fa81428361eb6940f1ac14fd58155d295a3eb0"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/rust_decimal@1.40.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/rust_decimal/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/paupino/rust-decimal"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustc-hash@2.1.1",
+ "author": "The Rust Project Developers",
+ "name": "rustc-hash",
+ "version": "2.1.1",
+ "description": "A speedy, non-cryptographic hashing algorithm used by rustc",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/rustc-hash@2.1.1",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/rustc-hash"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustix@1.1.3",
+ "author": "Dan Gohman , Jakub Konka ",
+ "name": "rustix",
+ "version": "1.1.3",
+ "description": "Safe Rust bindings to POSIX/Unix/Linux/Winsock-like syscalls",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/rustix@1.1.3",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/rustix"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/bytecodealliance/rustix"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustls-native-certs@0.8.3",
+ "name": "rustls-native-certs",
+ "version": "0.8.3",
+ "description": "rustls-native-certs allows rustls to use the platform native certificate store",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR ISC OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/rustls-native-certs@0.8.3",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://github.com/rustls/rustls-native-certs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rustls/rustls-native-certs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustls-pki-types@1.14.0",
+ "name": "rustls-pki-types",
+ "version": "1.14.0",
+ "description": "Shared types for the rustls PKI ecosystem",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/rustls-pki-types@1.14.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/rustls-pki-types"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/rustls/pki-types"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rustls/pki-types"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustls-platform-verifier@0.6.2",
+ "name": "rustls-platform-verifier",
+ "version": "0.6.2",
+ "description": "rustls-platform-verifier supports verifying TLS certificates in rustls with the operating system verifier",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/rustls-platform-verifier@0.6.2",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/rustls/rustls-platform-verifier"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustls-webpki@0.103.9",
+ "name": "rustls-webpki",
+ "version": "0.103.9",
+ "description": "Web PKI X.509 Certificate Verification.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "ISC"
+ }
+ ],
+ "purl": "pkg:cargo/rustls-webpki@0.103.9",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/rustls/webpki"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustls@0.23.36",
+ "name": "rustls",
+ "version": "0.23.36",
+ "description": "Rustls is a modern TLS library written in Rust.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR ISC OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/rustls@0.23.36",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://github.com/rustls/rustls"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rustls/rustls"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#rustversion@1.0.22",
+ "author": "David Tolnay ",
+ "name": "rustversion",
+ "version": "1.0.22",
+ "description": "Conditional compilation according to rustc compiler version",
+ "scope": "excluded",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/rustversion@1.0.22",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/rustversion"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/dtolnay/rustversion"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#ryu@1.0.23",
+ "author": "David Tolnay ",
+ "name": "ryu",
+ "version": "1.0.23",
+ "description": "Fast floating point to string conversion",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR BSL-1.0"
+ }
+ ],
+ "purl": "pkg:cargo/ryu@1.0.23",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/ryu"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/dtolnay/ryu"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#safe-transmute@0.11.3",
+ "author": "наб , Eduardo Pinho , Lukas Kalbertodt , Philipp Tessenow , Marijn Suijten ",
+ "name": "safe-transmute",
+ "version": "0.11.3",
+ "description": "A safeguarded transmute() for Rust",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "3944826ff8fa8093089aba3acb4ef44b9446a99a16f3bf4e74af3f77d340ab7d"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/safe-transmute@0.11.3",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://rawcdn.githack.com/nabijaczleweli/safe-transmute-rs/doc/safe_transmute/index.html"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/nabijaczleweli/safe-transmute-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#safe_arch@0.7.4",
+ "author": "Lokathor ",
+ "name": "safe_arch",
+ "version": "0.7.4",
+ "description": "Crate that exposes `core::arch` safely via `#[cfg()]`.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Zlib OR Apache-2.0 OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/safe_arch@0.7.4",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/Lokathor/safe_arch"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#same-file@1.0.6",
+ "author": "Andrew Gallant ",
+ "name": "same-file",
+ "version": "1.0.6",
+ "description": "A simple crate for determining whether two file paths point to the same file. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Unlicense OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/same-file@1.0.6",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/same-file"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/BurntSushi/same-file"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/BurntSushi/same-file"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#scoped-tls@1.0.1",
+ "author": "Alex Crichton ",
+ "name": "scoped-tls",
+ "version": "1.0.1",
+ "description": "Library implementation of the standard library's old `scoped_thread_local!` macro for providing scoped access to thread local storage (TLS) so any type can be stored into TLS. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/scoped-tls@1.0.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/scoped-tls"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/alexcrichton/scoped-tls"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/alexcrichton/scoped-tls"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#scopeguard@1.2.0",
+ "author": "bluss",
+ "name": "scopeguard",
+ "version": "1.2.0",
+ "description": "A RAII scope guard that will run a given closure when it goes out of scope, even if the code between panics (assuming unwinding panic). Defines the macros `defer!`, `defer_on_unwind!`, `defer_on_success!` as shorthands for guards with one of the implemented strategies. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/scopeguard@1.2.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/scopeguard/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/bluss/scopeguard"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228",
+ "author": "Erick Tryzelaar , David Tolnay ",
+ "name": "serde",
+ "version": "1.0.228",
+ "description": "A generic serialization/deserialization framework",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/serde@1.0.228",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/serde"
+ },
+ {
+ "type": "website",
+ "url": "https://serde.rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/serde-rs/serde"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228",
+ "author": "Erick Tryzelaar , David Tolnay ",
+ "name": "serde_core",
+ "version": "1.0.228",
+ "description": "Serde traits only, with no support for derive -- use the `serde` crate instead",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/serde_core@1.0.228",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/serde_core"
+ },
+ {
+ "type": "website",
+ "url": "https://serde.rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/serde-rs/serde"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.228",
+ "author": "Erick Tryzelaar , David Tolnay ",
+ "name": "serde_derive",
+ "version": "1.0.228",
+ "description": "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/serde_derive@1.0.228",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://serde.rs/derive.html"
+ },
+ {
+ "type": "website",
+ "url": "https://serde.rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/serde-rs/serde"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.149",
+ "author": "Erick Tryzelaar , David Tolnay ",
+ "name": "serde_json",
+ "version": "1.0.149",
+ "description": "A JSON serialization file format",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/serde_json@1.0.149",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/serde_json"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/serde-rs/json"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#serde_path_to_error@0.1.20",
+ "author": "David Tolnay ",
+ "name": "serde_path_to_error",
+ "version": "0.1.20",
+ "description": "Path to the element that failed to deserialize",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/serde_path_to_error@0.1.20",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/serde_path_to_error"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/dtolnay/path-to-error"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#serde_repr@0.1.20",
+ "author": "David Tolnay ",
+ "name": "serde_repr",
+ "version": "0.1.20",
+ "description": "Derive Serialize and Deserialize that delegates to the underlying repr of a C-like enum.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/serde_repr@0.1.20",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/serde_repr"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/dtolnay/serde-repr"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#serde_urlencoded@0.7.1",
+ "author": "Anthony Ramine ",
+ "name": "serde_urlencoded",
+ "version": "0.7.1",
+ "description": "`x-www-form-urlencoded` meets Serde",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/serde_urlencoded@0.7.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/serde_urlencoded/0.7.1/serde_urlencoded/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/nox/serde_urlencoded"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#sha1@0.10.6",
+ "author": "RustCrypto Developers",
+ "name": "sha1",
+ "version": "0.10.6",
+ "description": "SHA-1 hash function",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/sha1@0.10.6",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/sha1"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/RustCrypto/hashes"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#sha2-asm@0.6.4",
+ "author": "RustCrypto Developers",
+ "name": "sha2-asm",
+ "version": "0.6.4",
+ "description": "Assembly implementation of SHA-2 compression functions",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "b845214d6175804686b2bd482bcffe96651bb2d1200742b712003504a2dac1ab"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/sha2-asm@0.6.4",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/sha2-asm"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/RustCrypto/asm-hashes"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#sha2@0.10.9",
+ "author": "RustCrypto Developers",
+ "name": "sha2",
+ "version": "0.10.9",
+ "description": "Pure Rust implementation of the SHA-2 hash function family including SHA-224, SHA-256, SHA-384, and SHA-512. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/sha2@0.10.9",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/sha2"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/RustCrypto/hashes"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#sharded-slab@0.1.7",
+ "author": "Eliza Weisman ",
+ "name": "sharded-slab",
+ "version": "0.1.7",
+ "description": "A lock-free concurrent slab. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/sharded-slab@0.1.7",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/sharded-slab/"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/hawkw/sharded-slab"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/hawkw/sharded-slab"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#shellexpand@3.1.1",
+ "author": "Vladimir Matveev , Ian Jackson ",
+ "name": "shellexpand",
+ "version": "3.1.1",
+ "description": "Shell-like expansions in strings",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "8b1fdf65dd6331831494dd616b30351c38e96e45921a27745cf98490458b90bb"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/shellexpand@3.1.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "http://docs.rs/shellexpand/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://gitlab.com/ijackson/rust-shellexpand"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#shlex@1.3.0",
+ "author": "comex , Fenhl , Adrian Taylor , Alex Touchet , Daniel Parks , Garrett Berg ",
+ "name": "shlex",
+ "version": "1.3.0",
+ "description": "Split a string into shell words, like Python's shlex.",
+ "scope": "excluded",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/shlex@1.3.0",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/comex/rust-shlex"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#signal-hook-registry@1.4.8",
+ "author": "Michal 'vorner' Vaner , Masaki Hara ",
+ "name": "signal-hook-registry",
+ "version": "1.4.8",
+ "description": "Backend crate for signal-hook",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/signal-hook-registry@1.4.8",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/signal-hook-registry"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/vorner/signal-hook"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#signal-hook@0.3.18",
+ "author": "Michal 'vorner' Vaner , Thomas Himmelstoss ",
+ "name": "signal-hook",
+ "version": "0.3.18",
+ "description": "Unix signal handling",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/signal-hook@0.3.18",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/signal-hook"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/vorner/signal-hook"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#simba@0.9.1",
+ "author": "sebcrozet ",
+ "name": "simba",
+ "version": "0.9.1",
+ "description": "SIMD algebra for Rust",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "c99284beb21666094ba2b75bbceda012e610f5479dfcc2d6e2426f53197ffd95"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/simba@0.9.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/simba"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/dimforge/simba"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#siphasher@1.0.2",
+ "author": "Frank Denis ",
+ "name": "siphasher",
+ "version": "1.0.2",
+ "description": "SipHash-2-4, SipHash-1-3 and 128-bit variants in pure Rust",
+ "scope": "excluded",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/siphasher@1.0.2",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/siphasher"
+ },
+ {
+ "type": "website",
+ "url": "https://docs.rs/siphasher"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/jedisct1/rust-siphash"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#slab@0.4.12",
+ "author": "Carl Lerche ",
+ "name": "slab",
+ "version": "0.4.12",
+ "description": "Pre-allocated storage for a uniform data type",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/slab@0.4.12",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/tokio-rs/slab"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#smallvec@1.15.1",
+ "author": "The Servo Project Developers",
+ "name": "smallvec",
+ "version": "1.15.1",
+ "description": "'Small vector' optimization: store up to a small number of items on the stack",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/smallvec@1.15.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/smallvec/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/servo/rust-smallvec"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#socket2@0.6.2",
+ "author": "Alex Crichton , Thomas de Zeeuw ",
+ "name": "socket2",
+ "version": "0.6.2",
+ "description": "Utilities for handling networking sockets with a maximal amount of configuration possible intended. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/socket2@0.6.2",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/socket2"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/rust-lang/socket2"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rust-lang/socket2"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#stable_deref_trait@1.2.1",
+ "author": "Robert Grosse ",
+ "name": "stable_deref_trait",
+ "version": "1.2.1",
+ "description": "An unsafe marker trait for types like Box and Rc that dereference to a stable address even when moved, and hence can be used with libraries such as owning_ref and rental. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/stable_deref_trait@1.2.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/stable_deref_trait/1.2.1/stable_deref_trait"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/storyyeller/stable_deref_trait"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#static_assertions@1.1.0",
+ "author": "Nikolai Vazquez",
+ "name": "static_assertions",
+ "version": "1.1.0",
+ "description": "Compile-time assertions to ensure that invariants are met.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/static_assertions@1.1.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/static_assertions/"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/nvzqz/static-assertions-rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/nvzqz/static-assertions-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#statrs@0.18.0",
+ "author": "Michael Ma",
+ "name": "statrs",
+ "version": "0.18.0",
+ "description": "Statistical computing library for Rust",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "2a3fe7c28c6512e766b0874335db33c94ad7b8f9054228ae1c2abd47ce7d335e"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/statrs@0.18.0",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://github.com/statrs-dev/statrs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/statrs-dev/statrs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#strsim@0.11.1",
+ "author": "Danny Guo , maxbachmann ",
+ "name": "strsim",
+ "version": "0.11.1",
+ "description": "Implementations of string similarity metrics. Includes Hamming, Levenshtein, OSA, Damerau-Levenshtein, Jaro, Jaro-Winkler, and Sørensen-Dice. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/strsim@0.11.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/strsim/"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/rapidfuzz/strsim-rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rapidfuzz/strsim-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#subtle@2.6.1",
+ "author": "Isis Lovecruft , Henry de Valence ",
+ "name": "subtle",
+ "version": "2.6.1",
+ "description": "Pure-Rust traits and utilities for constant-time cryptographic implementations.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "BSD-3-Clause"
+ }
+ ],
+ "purl": "pkg:cargo/subtle@2.6.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/subtle"
+ },
+ {
+ "type": "website",
+ "url": "https://dalek.rs/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/dalek-cryptography/subtle"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#syn@1.0.109",
+ "author": "David Tolnay ",
+ "name": "syn",
+ "version": "1.0.109",
+ "description": "Parser for Rust source code",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/syn@1.0.109",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/syn"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/dtolnay/syn"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#syn@2.0.114",
+ "author": "David Tolnay ",
+ "name": "syn",
+ "version": "2.0.114",
+ "description": "Parser for Rust source code",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/syn@2.0.114",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/syn"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/dtolnay/syn"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#sync_wrapper@1.0.2",
+ "author": "Actyx AG ",
+ "name": "sync_wrapper",
+ "version": "1.0.2",
+ "description": "A tool for enlisting the compiler's help in proving the absence of concurrency",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/sync_wrapper@1.0.2",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/sync_wrapper"
+ },
+ {
+ "type": "website",
+ "url": "https://docs.rs/sync_wrapper"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/Actyx/sync_wrapper"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#synchronoise@1.0.1",
+ "author": "QuietMisdreavus ",
+ "name": "synchronoise",
+ "version": "1.0.1",
+ "description": "Synchronization primitives that build upon the standard library",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "3dbc01390fc626ce8d1cffe3376ded2b72a11bb70e1c75f404a210e4daa4def2"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/synchronoise@1.0.1",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/synchronoise/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/QuietMisdreavus/synchronoise"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#synstructure@0.13.2",
+ "author": "Nika Layzell ",
+ "name": "synstructure",
+ "version": "0.13.2",
+ "description": "Helper methods and macros for custom derives",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/synstructure@0.13.2",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/synstructure"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/mystor/synstructure"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#sysinfo@0.38.1",
+ "author": "Guillaume Gomez ",
+ "name": "sysinfo",
+ "version": "0.38.1",
+ "description": "Library to get system information such as processes, CPUs, disks, components and networks",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "5792d209c2eac902426c0c4a166c9f72147db453af548cf9bf3242644c4d4fe3"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/sysinfo@0.38.1",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/GuillaumeGomez/sysinfo"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#target-lexicon@0.13.4",
+ "author": "Dan Gohman ",
+ "name": "target-lexicon",
+ "version": "0.13.4",
+ "description": "LLVM target triple types",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "b1dd07eb858a2067e2f3c7155d54e929265c264e6f37efe3ee7a8d1b5a1dd0ba"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 WITH LLVM-exception"
+ }
+ ],
+ "purl": "pkg:cargo/target-lexicon@0.13.4",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/target-lexicon/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/bytecodealliance/target-lexicon"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tempfile@3.25.0",
+ "author": "Steven Allen , The Rust Project Developers, Ashley Mannix , Jason White ",
+ "name": "tempfile",
+ "version": "3.25.0",
+ "description": "A library for managing temporary files and directories.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "0136791f7c95b1f6dd99f9cc786b91bb81c3800b639b3478e561ddb7be95e5f1"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/tempfile@3.25.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/tempfile"
+ },
+ {
+ "type": "website",
+ "url": "https://stebalien.com/projects/tempfile-rs/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/Stebalien/tempfile"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#thiserror-impl@1.0.69",
+ "author": "David Tolnay ",
+ "name": "thiserror-impl",
+ "version": "1.0.69",
+ "description": "Implementation detail of the `thiserror` crate",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/thiserror-impl@1.0.69",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/dtolnay/thiserror"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#thiserror-impl@2.0.18",
+ "author": "David Tolnay ",
+ "name": "thiserror-impl",
+ "version": "2.0.18",
+ "description": "Implementation detail of the `thiserror` crate",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/thiserror-impl@2.0.18",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/dtolnay/thiserror"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#thiserror@1.0.69",
+ "author": "David Tolnay ",
+ "name": "thiserror",
+ "version": "1.0.69",
+ "description": "derive(Error)",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/thiserror@1.0.69",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/thiserror"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/dtolnay/thiserror"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.18",
+ "author": "David Tolnay ",
+ "name": "thiserror",
+ "version": "2.0.18",
+ "description": "derive(Error)",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/thiserror@2.0.18",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/thiserror"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/dtolnay/thiserror"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#thread_local@1.1.9",
+ "author": "Amanieu d'Antras ",
+ "name": "thread_local",
+ "version": "1.1.9",
+ "description": "Per-object thread-local storage",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/thread_local@1.1.9",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/thread_local/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/Amanieu/thread_local-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#time-core@0.1.8",
+ "author": "Jacob Pratt , Time contributors",
+ "name": "time-core",
+ "version": "0.1.8",
+ "description": "This crate is an implementation detail and should not be relied upon directly.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/time-core@0.1.8",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/time-rs/time"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#time-macros@0.2.27",
+ "author": "Jacob Pratt , Time contributors",
+ "name": "time-macros",
+ "version": "0.2.27",
+ "description": " Procedural macros for the time crate. This crate is an implementation detail and should not be relied upon directly. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/time-macros@0.2.27",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/time-rs/time"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#time@0.3.47",
+ "author": "Jacob Pratt , Time contributors",
+ "name": "time",
+ "version": "0.3.47",
+ "description": "Date and time library. Fully interoperable with the standard library. Mostly compatible with #![no_std].",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/time@0.3.47",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://time-rs.github.io"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/time-rs/time"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tinystr@0.8.2",
+ "author": "The ICU4X Project Developers",
+ "name": "tinystr",
+ "version": "0.8.2",
+ "description": "A small ASCII-only bounded length string representation.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Unicode-3.0"
+ }
+ ],
+ "purl": "pkg:cargo/tinystr@0.8.2",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/unicode-org/icu4x"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tinyvec@1.10.0",
+ "author": "Lokathor ",
+ "name": "tinyvec",
+ "version": "1.10.0",
+ "description": "`tinyvec` provides 100% safe vec-like data structures.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Zlib OR Apache-2.0 OR MIT"
+ }
+ ],
+ "purl": "pkg:cargo/tinyvec@1.10.0",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/Lokathor/tinyvec"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tinyvec_macros@0.1.1",
+ "author": "Soveu ",
+ "name": "tinyvec_macros",
+ "version": "0.1.1",
+ "description": "Some macros for tiny containers",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0 OR Zlib"
+ }
+ ],
+ "purl": "pkg:cargo/tinyvec_macros@0.1.1",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/Soveu/tinyvec_macros"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tokio-macros@2.6.0",
+ "author": "Tokio Contributors ",
+ "name": "tokio-macros",
+ "version": "2.6.0",
+ "description": "Tokio's proc macros. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/tokio-macros@2.6.0",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://tokio.rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/tokio-rs/tokio"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tokio-retry@0.3.0",
+ "author": "Sam Rijs ",
+ "name": "tokio-retry",
+ "version": "0.3.0",
+ "description": "Extensible, asynchronous retry behaviours for futures/tokio",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "7f57eb36ecbe0fc510036adff84824dd3c24bb781e21bfa67b69d556aa85214f"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/tokio-retry@0.3.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/tokio-retry"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/srijs/rust-tokio-retry"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tokio-rustls@0.26.4",
+ "name": "tokio-rustls",
+ "version": "0.26.4",
+ "description": "Asynchronous TLS/SSL streams for Tokio using Rustls.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/tokio-rustls@0.26.4",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/tokio-rustls"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/rustls/tokio-rustls"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rustls/tokio-rustls"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tokio-util@0.7.18",
+ "author": "Tokio Contributors ",
+ "name": "tokio-util",
+ "version": "0.7.18",
+ "description": "Additional utilities for working with Tokio. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/tokio-util@0.7.18",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://tokio.rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/tokio-rs/tokio"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tokio@1.49.0",
+ "author": "Tokio Contributors ",
+ "name": "tokio",
+ "version": "1.49.0",
+ "description": "An event-driven, non-blocking I/O platform for writing asynchronous I/O backed applications. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/tokio@1.49.0",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://tokio.rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/tokio-rs/tokio"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tower-http@0.6.8",
+ "author": "Tower Maintainers ",
+ "name": "tower-http",
+ "version": "0.6.8",
+ "description": "Tower middleware and utilities for HTTP clients and servers",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/tower-http@0.6.8",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://github.com/tower-rs/tower-http"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/tower-rs/tower-http"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tower-layer@0.3.3",
+ "author": "Tower Maintainers ",
+ "name": "tower-layer",
+ "version": "0.3.3",
+ "description": "Decorates a `Service` to allow easy composition between `Service`s. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/tower-layer@0.3.3",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/tower-layer/0.3.3"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/tower-rs/tower"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/tower-rs/tower"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tower-service@0.3.3",
+ "author": "Tower Maintainers ",
+ "name": "tower-service",
+ "version": "0.3.3",
+ "description": "Trait representing an asynchronous, request / response based, client or server. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/tower-service@0.3.3",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/tower-service/0.3.3"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/tower-rs/tower"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/tower-rs/tower"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tower@0.5.3",
+ "author": "Tower Maintainers ",
+ "name": "tower",
+ "version": "0.5.3",
+ "description": "Tower is a library of modular and reusable components for building robust clients and servers. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/tower@0.5.3",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://github.com/tower-rs/tower"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/tower-rs/tower"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-appender@0.2.4",
+ "author": "Zeki Sherif , Tokio Contributors ",
+ "name": "tracing-appender",
+ "version": "0.2.4",
+ "description": "Provides utilities for file appenders and making non-blocking writers. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/tracing-appender@0.2.4",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://tokio.rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/tokio-rs/tracing"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-attributes@0.1.31",
+ "author": "Tokio Contributors , Eliza Weisman , David Barsky ",
+ "name": "tracing-attributes",
+ "version": "0.1.31",
+ "description": "Procedural macro attributes for automatically instrumenting functions. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/tracing-attributes@0.1.31",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://tokio.rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/tokio-rs/tracing"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-core@0.1.36",
+ "author": "Tokio Contributors ",
+ "name": "tracing-core",
+ "version": "0.1.36",
+ "description": "Core primitives for application-level tracing. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/tracing-core@0.1.36",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://tokio.rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/tokio-rs/tracing"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-log@0.2.0",
+ "author": "Tokio Contributors ",
+ "name": "tracing-log",
+ "version": "0.2.0",
+ "description": "Provides compatibility between `tracing` and the `log` crate. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/tracing-log@0.2.0",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://tokio.rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/tokio-rs/tracing"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-serde@0.2.0",
+ "author": "Tokio Contributors ",
+ "name": "tracing-serde",
+ "version": "0.2.0",
+ "description": "A compatibility layer for serializing trace data with `serde` ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/tracing-serde@0.2.0",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://tokio.rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/tokio-rs/tracing"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tracing-subscriber@0.3.22",
+ "author": "Eliza Weisman , David Barsky , Tokio Contributors ",
+ "name": "tracing-subscriber",
+ "version": "0.3.22",
+ "description": "Utilities for implementing and composing `tracing` subscribers. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/tracing-subscriber@0.3.22",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://tokio.rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/tokio-rs/tracing"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44",
+ "author": "Eliza Weisman , Tokio Contributors ",
+ "name": "tracing",
+ "version": "0.1.44",
+ "description": "Application-level tracing for Rust. ",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/tracing@0.1.44",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://tokio.rs"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/tokio-rs/tracing"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#try-lock@0.2.5",
+ "author": "Sean McArthur ",
+ "name": "try-lock",
+ "version": "0.2.5",
+ "description": "A lightweight atomic lock.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/try-lock@0.2.5",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/try-lock"
+ },
+ {
+ "type": "website",
+ "url": "https://github.com/seanmonstar/try-lock"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/seanmonstar/try-lock"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#twox-hash@2.1.2",
+ "author": "Jake Goulding ",
+ "name": "twox-hash",
+ "version": "2.1.2",
+ "description": "A Rust implementation of the XXHash and XXH3 algorithms",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/twox-hash@2.1.2",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/twox-hash/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/shepmaster/twox-hash"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#typenum@1.19.0",
+ "author": "Paho Lurie-Gregg , Andre Bogus ",
+ "name": "typenum",
+ "version": "1.19.0",
+ "description": "Typenum is a Rust library for type-level numbers evaluated at compile time. It currently supports bits, unsigned integers, and signed integers. It also provides a type-level array of type-level numbers, but its implementation is incomplete.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/typenum@1.19.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/typenum"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/paholg/typenum"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#typewit@1.14.2",
+ "author": "rodrimati1992 ",
+ "name": "typewit",
+ "version": "1.14.2",
+ "description": "type-witness-based abstractions, mostly for emulating polymorphism in const fns",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "f8c1ae7cc0fdb8b842d65d127cb981574b0d2b249b74d1c7a2986863dc134f71"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Zlib"
+ }
+ ],
+ "purl": "pkg:cargo/typewit@1.14.2",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/typewit/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/rodrimati1992/typewit/"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#ulid@1.2.1",
+ "author": "dylanhart ",
+ "name": "ulid",
+ "version": "1.2.1",
+ "description": "a Universally Unique Lexicographically Sortable Identifier implementation",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "470dbf6591da1b39d43c14523b2b469c86879a53e8b758c8e090a470fe7b1fbe"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/ulid@1.2.1",
+ "externalReferences": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/dylanhart/ulid-rs"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#unicase@2.9.0",
+ "author": "Sean McArthur ",
+ "name": "unicase",
+ "version": "2.9.0",
+ "description": "A case-insensitive wrapper around strings.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/unicase@2.9.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/unicase"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/seanmonstar/unicase"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#unicode-ident@1.0.23",
+ "author": "David Tolnay ",
+ "name": "unicode-ident",
+ "version": "1.0.23",
+ "description": "Determine whether characters have the XID_Start or XID_Continue properties according to Unicode Standard Annex #31",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "(MIT OR Apache-2.0) AND Unicode-3.0"
+ }
+ ],
+ "purl": "pkg:cargo/unicode-ident@1.0.23",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/unicode-ident"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/dtolnay/unicode-ident"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#unindent@0.2.4",
+ "author": "David Tolnay ",
+ "name": "unindent",
+ "version": "0.2.4",
+ "description": "Remove a column of leading whitespace from a string",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/unindent@0.2.4",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/unindent"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/dtolnay/indoc"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#untrusted@0.9.0",
+ "author": "Brian Smith ",
+ "name": "untrusted",
+ "version": "0.9.0",
+ "description": "Safe, fast, zero-panic, zero-crashing, zero-allocation parsing of untrusted inputs in Rust.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "ISC"
+ }
+ ],
+ "purl": "pkg:cargo/untrusted@0.9.0",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://briansmith.org/rustdoc/untrusted/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/briansmith/untrusted"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#url@2.5.8",
+ "author": "The rust-url developers",
+ "name": "url",
+ "version": "2.5.8",
+ "description": "URL library for Rust, based on the WHATWG URL Standard",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT OR Apache-2.0"
+ }
+ ],
+ "purl": "pkg:cargo/url@2.5.8",
+ "externalReferences": [
+ {
+ "type": "documentation",
+ "url": "https://docs.rs/url"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/servo/rust-url"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#urlencoding@2.1.3",
+ "author": "Kornel , Bertram Truong ",
+ "name": "urlencoding",
+ "version": "2.1.3",
+ "description": "A Rust library for doing URL percentage encoding.",
+ "scope": "required",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "MIT"
+ }
+ ],
+ "purl": "pkg:cargo/urlencoding@2.1.3",
+ "externalReferences": [
+ {
+ "type": "website",
+ "url": "https://lib.rs/urlencoding"
+ },
+ {
+ "type": "vcs",
+ "url": "https://github.com/kornelski/rust_urlencoding"
+ }
+ ]
+ },
+ {
+ "type": "library",
+ "bom-ref": "registry+https://github.com/rust-lang/crates.io-index#utf8_iter@1.0.4",
+ "author": "Henri Sivonen