fastsafetensors

repository·main·Indexed 41 days ago

https://github.com/foundation-model-stack/fastsafetensors

A high-performance safetensors model loader designed to accelerate the initialization of large foundation models. It provides high-throughput loading across NVIDIA (CUDA/GDS) and AMD (ROCm) platforms, offering significant speedups over the default safetensors deserializer. The library integrates with vLLM via the `--load-format fastsafetensors` flag and supports advanced memory management, pipeline modes for overlapping copies and broadcasts, and specialized loaders like 3FS.

Tokens
16.8K
Snippets
57
Records
78
Agent score
49%

What's inside fastsafetensors

  1. Overview of fastsafetensors performance and compatibility

    main

    Performance

    fastsafetensors is designed for high-throughput model loading. Key performance characteristics include:

    • Standalone loading: Up to 4.8x-7.5x faster than the default safetensors deserializer.
    • NVMe Throughput: Can reach up to 26.4 GB/s with GDS (GPUDirect Storage).
    • vLLM Integration: Significant reductions in startup time (e.g., from ~12s to ~4.7s for Llama-2-13B on 4x L40S).
    • AMD ROCm: Provides a nogds path that outperforms standard mmap by 2.6x to 4.7x.

    Platform Support

    The library supports various environments including:

    • Linux/CUDA
    • ROCm (AMD)
    • Windows
    • 3FS
    • Unified-memory systems (e.g., DGX Spark)

    Compatibility

    • Python: 3.10 - 3.14
    • PyTorch: 2.11.0
  2. Manage device memory with max_batch_bytes and device_memory_budget

    main

    To prevent Out-of-Memory (OOM) errors, use these two parameters:

    • max_batch_bytes: Caps the size of each sub-file chunk. It must be at least as large as the largest selected tensor, as tensors cannot be split across chunks.
    • device_memory_budget: Bounds the total memory used by resident tensors and transient chunk buffers. In distributed broadcast, every rank must use the same value.

    Error Handling: If the requested queue depth cannot fit within the budget, the loader automatically reduces the depth down to queue_size=-1. If even serial loading is impossible, it raises fastsafetensors.BudgetInfeasibleError (a subclass of ValueError).

    Best Practices: When calculating a budget from free device memory, leave a reserve for allocator rounding and copier fixed pools. A recommended starting point is max(5% of free memory, 1 GiB).

  3. Configure queue_size and pipeline modes

    main

    The queue_size parameter controls how the loader manages buffers and concurrency:

    queue_sizeModeLive chunk buffers per rankBehavior
    -1Fully serial1copy_files → broadcast → copy_files → ...
    0Unbuffered pipelineUp to 21 batch copying + 1 batch broadcasting concurrently
    >0Buffered pipelineUp to queue_size+2Queued batches + producer + consumer

    Important Notes:

    • Setting use_pipeline: false forces queue_size=-1 (serial mode with minimal GPU memory usage).
    • Buffer counts exclude resident tensors, broadcast receive tensors, yield clones, and copier staging memory (which are handled by the memory planner).
  4. Benchmark DeepSeek-R1 weight loading speed on AMD GPUs

    main

    To compare the performance of safetensors versus fastsafetensors when loading model weights on AMD ROCm platforms (e.g., MI300X), follow these steps:

    1. Clear system cache to ensure a consistent cold-start baseline:

      sudo sh -c 'sync && echo 3 > /proc/sys/vm/drop_caches'
    2. Launch vLLM using the --load-format fastsafetensors flag. Ensure you set the necessary environment variables for ROCm and vLLM V1 support.

    Note: The benchmark uses --tensor-parallel-size 8 for multi-GPU setups and specific compilation configs for optimal performance.

    MODEL=EmbeddedLLM/deepseek-r1-FP8-Dynamic
    
    VLLM_USE_V1=1 \
    VLLM_ROCM_USE_AITER=1 \
    vllm serve $MODEL \
    --tensor-parallel-size 8 \
    --disable-log-requests \
    --compilation-config '{"cudagraph_mode": "FULL_AND_PIECEWISE"}' \
    --trust-remote-code \
    --load-format fastsafetensors \
    --block-size 1
  5. Set up pre-commit hooks for development

    main

    To ensure code formatting and linting comply with the CI workflow (which uses Python 3.13), set up pre-commit hooks. This automates checks for black, isort, flake8, mypy, and several file-format validators.

    1. Install development dependencies:
    pip install -e ".[dev]"
    1. Install the hooks:
    pre-commit install

    To manually run all checks on all files:

    pre-commit run --all-files
    pip install -e ".[dev]"
    pre-commit install
  6. Discover and load configuration for AutoLoader

    main

    AutoLoader resolves configuration using the following priority (highest first):

    1. Environment variable: Set FASTSAFETENSORS_CONFIG to the path of your .json config file.
    2. Default path: A file named ./fastsafetensors.json in your current working directory.
    3. Built-in defaults: The values defined in the LoaderConfig() dataclass.

    All fields are optional. If a field is omitted from your configuration file, the loader falls back to the built-in default.

    # Set via environment variable
    export FASTSAFETENSORS_CONFIG=/path/to/config.json
    
    # Or place a file at ./fastsafetensors.json
  7. Enable DirectStorage on Windows

    main

    On Windows, fastsafetensors uses Microsoft DirectStorage to achieve high-throughput loading by bridging D3D12 resources with CUDA via external memory interop.

    Setup

    If the DirectStorage DLLs are not in the standard search path, you must provide the directory containing dstoragecore.dll and dstorage.dll using the following environment variable:

    FASTSAFETENSORS_DSTORAGE_DLL_DIR (must be an absolute directory).

    Fallback and CUDA Runtime

    • If DirectStorage DLLs are missing, the loader falls back to the bounce-buffer (nogds) path.
    • The loader automatically discovers the CUDA runtime (checking PyTorch's torch\lib first, then system locations).
    • You can explicitly specify the CUDA runtime DLL path using: FASTSAFETENSORS_CUDART_LIB (absolute path, takes precedence).