Amazon S3 Connector for PyTorch

repository·main·Indexed 42 days ago

https://github.com/awslabs/s3-connector-for-pytorch

Optimizes high-throughput data loading and checkpointing for PyTorch training jobs using Amazon S3. It provides specialized dataset primitives like S3IterableDataset and S3MapDataset, distributed checkpointing tools including S3LightningCheckpoint for PyTorch Lightning, and an S3Client for direct object streaming. The connector supports multiple reader types via S3ReaderConstructor, including sequential, range-based, and DCP-optimized readers for PyTorch Distributed Checkpoint (DCP) loading.

Tokens
25.9K
Snippets
86
Records
103
Agent score
53%

What's inside S3 Connector for PyTorch

  1. Overview of Amazon S3 Connector for PyTorch

    main

    The Amazon S3 Connector for PyTorch is designed to provide high throughput for PyTorch training jobs that interact with Amazon S3. It optimizes performance for downloading training data and writing checkpoints, removing the manual overhead of listing S3 buckets and managing concurrent requests.

    Key capabilities include:

    • Dataset Primitives: Provides implementations of PyTorch dataset primitives to load data directly from S3.
    • Map-style Datasets: Supports random data access patterns.
    • Iterable-style Datasets: Supports streaming sequential data access patterns.
    • Checkpointing Interface: Allows saving and loading checkpoints directly to Amazon S3, bypassing the need for intermediate local storage.
  2. Run PyTorch Distributed Checkpoint (DCP) benchmarks with FSDP

    main

    The dcp package provides benchmarks to evaluate the performance of PyTorch's Distributed Checkpointing (DCP) feature when compared to the s3torchconnector library. These benchmarks use Fully Sharded Data Parallel (FSDP) to measure how efficiently model parameters, sharded across multiple GPUs/processes, are saved and loaded.

    Benchmark Metrics

    Save Benchmarks measure:

    • Checkpoint saving throughput (MiB/s)
    • Checkpoint "corrected" save durations (seconds), excluding model load duration on the device.

    Load Benchmarks measure:

    • Checkpoint loading throughput (MiB/s)
    • Checkpoint "corrected" load durations (seconds), excluding process setup and model loading to device.
    # Run save benchmarks (default behavior)
    ./utils/run_dcp_fsdp_benchmarks.sh
    
    # Explicitly run save benchmarks
    ./utils/run_dcp_fsdp_benchmarks.sh --save
    
    # Run load benchmarks
    ./utils/run_dcp_fsdp_benchmarks.sh --load
  3. Configure S3Reader types via S3ReaderConstructor

    main

    The connector supports three reader types via S3ReaderConstructor. Choose the one that best fits your access pattern:

    1. Sequential Reader (S3ReaderConstructor.sequential()):

      • Use case: Processing entire objects or when repeated access is required.
      • Behavior: Downloads and buffers the entire S3 object in memory. Prioritizes performance.
    2. Range-based Reader (S3ReaderConstructor.range_based()):

      • Use case: Large objects (100MB+) requiring sparse partial reads or in memory-constrained environments.
      • Behavior: Uses byte-range requests. Features adaptive buffering: small reads (< buffer_size) use an internal buffer, while large reads (≥ buffer_size) bypass it for direct transfer.
    3. DCP-Optimized Reader (S3ReaderConstructor.dcp_optimized()):

      • Use case: PyTorch Distributed Checkpoint (DCP) loading for highest performance and memory efficiency.
      • Behavior: Default for S3StorageReader. Provides per-item buffers, zero-copy management, and range coalescing for selective data fetching. Requires sequential access patterns.

    Note: S3Reader instances are not thread-safe. For DataLoader multiprocessing, each worker creates its own instance automatically.

  4. Understand benchmark result organization

    main

    Benchmark results are stored in a ./multirun directory. The structure is organized by scenario, then by timestamped run directories, and finally by individual job subdirectories.

    Directory Structure

    ./multirun
    └── <scenario_name>
        └── <timestamp>
            ├── <job_id>
            │   ├── benchmark.log
            │   └── job_results.json
            ├── multirun.yaml
            └── run_results.json

    Result Files

    • benchmark.log: Individual job logs (collected by Hydra) located in job subdirectories.
    • job_results.json: Individual job results located in job subdirectories.
    • multirun.yaml: The global Hydra configuration used for the entire run.
    • run_results.json: Comprehensive run results including metadata, located in the timestamped run directory.

    If a DynamoDB table is configured in conf/aws/dynamodb.yaml, results are also written to that table.

  5. Configure S3 prefix strategies for distributed checkpointing

    main

    To prevent S3 throttling (503 Slow Down errors) during high-throughput distributed training, S3StorageWriter supports different prefix strategies to distribute keys across S3 partitions.

    Available Strategies:

    1. RoundRobinPrefixStrategy: Distributes checkpoints across a list of user-provided prefixes in a round-robin fashion.
    2. BinaryPrefixStrategy: Generates binary (base-2) prefixes for optimal partitioning.
    3. HexPrefixStrategy: Uses hexadecimal (base-16) prefixes for a balance of efficiency and readability.

    Custom Strategies

    You can implement a custom strategy by extending S3PrefixStrategyBase and overriding the generate_prefix(self, rank: int) -> str method.

    from s3torchconnector.dcp import RoundRobinPrefixStrategy, S3StorageWriter
    
    # Example: RoundRobin
    strategy = RoundRobinPrefixStrategy(
        user_prefixes=["shard1", "shard2", "shard3"],
        epoch_num=5
    )
    
    writer = S3StorageWriter(
        region=REGION,
        path="s3://my-bucket/checkpoints/",
        prefix_strategy=strategy
    )
    
    # Example: Custom Strategy
    from s3torchconnector.dcp import S3PrefixStrategyBase
    
    class CustomPrefixStrategy(S3PrefixStrategyBase):
        def __init__(self, custom_param):
            super().__init__()
            self.custom_param = custom_param
    
        def generate_prefix(self, rank: int) -> str:
            return f"custom_{self.custom_param}/{rank}/"
  6. Run PyTorch Distributed Checkpoint (DCP) benchmarks

    main

    The dcp package provides benchmarks to evaluate PyTorch's Distributed Checkpointing (DCP) performance against the s3torchconnector library using DistributedDataParallel (DDP). These benchmarks measure throughput (MiB/s) and corrected durations (seconds) for both saving and loading checkpoints.

    To run the benchmarks, use the run_dcp_ddp_benchmarks.sh script with the appropriate flag.

    # Run save benchmarks (default)
    ./utils/run_dcp_ddp_benchmarks.sh
    ./utils/run_dcp_ddp_benchmarks.sh --save
    
    # Run load benchmarks
    ./utils/run_dcp_ddp_benchmarks.sh --load
  7. Enable parallel and distributed training with S3MapDataset

    main

    To use S3MapDataset for parallel or distributed training, you must wrap the dataset in a PyTorch DistributedSampler before passing it to the DataLoader. The DistributedSampler ensures that each worker or node receives a unique subset of the dataset.

    dataset = S3MapDataset.from_prefix(DATASET_URI, region=REGION)
    sampler = DistributedSampler(dataset)
    dataloader = DataLoader(dataset, sampler=sampler, num_workers=4)
  8. Run s3torchbenchmarking scenarios

    main

    Benchmarks are executed by editing Hydra configuration files in the conf/ directory (ensuring all ??? placeholders are replaced) and then running the corresponding shell script.

    Important: Ensure your S3 bucket is in the same region as your EC2 instance to avoid network latency affecting measurements. You can override Hydra parameters via the command line using the + prefix.

    Available Scenarios

    ScenarioConfig File(s)Execution Script
    Dataset./conf/dataset.yaml./utils/run_dataset_benchmarks.sh
    PyTorch Checkpointing./conf/pytorch_checkpointing.yaml./utils/run_checkpoint_benchmarks.sh
    PyTorch Lightning./conf/lightning_checkpointing.yaml./utils/run_lightning_benchmarks.sh
    DCP (DDP) Save./conf/dcp_ddp_save.yaml./utils/run_dcp_ddp_benchmarks.sh
    DCP (FSDP) Save./conf/dcp_fsdp_save.yaml./utils/run_dcp_fsdp_benchmarks.sh
    DCP (DDP) Load./conf/dcp_ddp_load.yaml./utils/run_ddp_benchmarks.sh --load
    DCP (FSDP) Load./conf/dcp_fsdp_load.yaml./utils/run_dcp_fsdp_benchmarks.sh --load
    # Example: Running dataset benchmarks with a parameter override
    ./utils/run_dataset_benchmarks.sh +disambiguator=some_key
  9. Set up an environment for s3torchbenchmarking

    main

    To run benchmarks, it is recommended to use an EC2 instance with GPUs (e.g., G5 instance type) using an AWS Deep Learning AMI (DLAMI). For best results, use a dedicated instance without other resource-intensive processes. To avoid token expiration during long-running benchmarks, attach an IAM role to the EC2 instance with:

    • Full access to S3
    • (Optional) Full access to DynamoDB (required if writing run results to DynamoDB)

    Follow these steps to create a clean Conda environment and install the package:

    1. Create a new Conda environment with Python 3.12.
    2. Initialize Conda and activate the environment.
    3. Install the s3torchbenchmarking module in editable mode using pip install -e ..

    Note: Some scenarios may require the Mountpoint for Amazon S3 file client.

    # Create environment
    conda create -n pytorch-benchmarks python=3.12
    conda init
    
    # Activate (you may need to log out/in after conda init)
    source activate pytorch-benchmarks
    
    # Install the module
    pip install -e .
  10. Enable debug logging for Rust components

    main

    While Python logging handles the Python-side implementation, the Rust components use tracing_subscriber. You can control Rust-side logs using the S3_TORCH_CONNECTOR_DEBUG_LOGS environment variable.

    Note on AWS CRT logs: AWS CRT logs are very noisy. To avoid noise, append awscrt=off to your log configuration.

    To save logs to a file instead of STDOUT, set the S3_TORCH_CONNECTOR_LOGS_DIR_PATH environment variable to a writable directory. Logs will be written to ${S3_TORCH_CONNECTOR_LOGS_DIR_PATH}/s3torchconnectorclient.log.yyyy-MM-dd-HH and rolled hourly.

    # Configure INFO level logs to be written to STDOUT
    export S3_TORCH_CONNECTOR_DEBUG_LOGS=info
    
    # Enable TRACE level logs (most verbose) written to a directory
    export S3_TORCH_CONNECTOR_DEBUG_LOGS=trace
    export S3_TORCH_CONNECTOR_LOGS_DIR_PATH="/tmp/s3torchconnector-logs"
    
    # Enable TRACE level logs with AWS CRT logs filtered out
    export S3_TORCH_CONNECTOR_DEBUG_LOGS=trace,awscrt=off
    export S3_TORCH_CONNECTOR_LOGS_DIR_PATH="/tmp/s3torchconnector-logs"
    
    # Set up different levels for inner components
    export S3_TORCH_CONNECTOR_DEBUG_LOGS=trace,mountpoint_s3_client=debug,awscrt=error
  11. Integrate with PyTorch Lightning using S3LightningCheckpoint

    main

    The connector provides S3LightningCheckpoint, an implementation of Lightning's CheckpointIO, to enable S3 checkpointing within PyTorch Lightning.

    First, install the lightning extra:

    pip install s3torchconnector[lightning]

    Then, add S3LightningCheckpoint to the plugins list in your Lightning Trainer and specify the default_root_dir as an S3 URI.

    from lightning import Trainer
    from s3torchconnector.lightning import S3LightningCheckpoint
    
    # ... model definition ...
    
    s3_checkpoint_io = S3LightningCheckpoint("us-east-1")
    trainer = Trainer(
        plugins=[s3_checkpoint_io],
        default_root_dir="s3://bucket_name/key_prefix/"
    )
    trainer.fit(model)
  12. Configure AWS credentials for s3torchconnector

    main

    The library requires AWS credentials to access S3. You can provide them using any of the following standard methods:

    • EC2 Instance Role: Assign an IAM role to your EC2 instance.
    • AWS CLI: Run aws configure to set up local credentials.
    • AWS Credential Files: Place credentials in ~/.aws/credentials (Unix/macOS).
    • Environment Variables: Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.

    To use a specific AWS profile from your config files, you can:

    1. Set the AWS_PROFILE environment variable.
    2. Pass the profile name to the S3ClientConfig object.