---
title: benchmark_weight_loading
---

<div class="python-reference">
<a id="fastvideo.models.loader.benchmarks.benchmark_weight_loading-functions"></a>
<a id="fastvideo.models.loader.benchmarks.benchmark_weight_loading"></a>
<p>Benchmark for model weight loading speed.</p>
<p>Measures the time to load model weights from safetensors files using
different strategies (CPU vs GPU, broadcast vs independent).</p>
<p>Usage (single GPU):
    python fastvideo/models/loader/benchmarks/benchmark_weight_loading.py         --model-path /path/to/model</p>
<p>Usage (multi-GPU, e.g. 4 GPUs):
    torchrun --nproc_per_node=4         fastvideo/models/loader/benchmarks/benchmark_weight_loading.py         --model-path /path/to/model</p>
<h2 id="fastvideo.models.loader.benchmarks.benchmark_weight_loading.cleanup_dist_env_and_memory"><code>fastvideo.models.loader.benchmarks.benchmark_weight_loading.cleanup_dist_env_and_memory</code></h2>
<pre class="doc-signature"><code>cleanup_dist_env_and_memory(shutdown_ray: bool = False)</code></pre>

<h2 id="fastvideo.models.loader.benchmarks.benchmark_weight_loading.get_node_group"><code>fastvideo.models.loader.benchmarks.benchmark_weight_loading.get_node_group</code></h2>
<pre class="doc-signature"><code>get_node_group() -&gt; GroupCoordinator</code></pre>

<h2 id="fastvideo.models.loader.benchmarks.benchmark_weight_loading.maybe_init_distributed_environment_and_model_parallel"><code>fastvideo.models.loader.benchmarks.benchmark_weight_loading.maybe_init_distributed_environment_and_model_parallel</code></h2>
<pre class="doc-signature"><code>maybe_init_distributed_environment_and_model_parallel(tp_size: int, sp_size: int, distributed_init_method: str = &#x27;env://&#x27;, timeout: timedelta | None = None, sp_group_ranks: list&#91;list&#91;int&#93;&#93; | None = None, dp_group_ranks: list&#91;list&#91;int&#93;&#93; | None = None)</code></pre>

<h2 id="fastvideo.models.loader.benchmarks.benchmark_weight_loading.init_logger"><code>fastvideo.models.loader.benchmarks.benchmark_weight_loading.init_logger</code></h2>
<pre class="doc-signature"><code>init_logger(name: str) -&gt; _FastvideoLogger</code></pre>
<p>The main purpose of this function is to ensure that loggers are
retrieved in such a way that we can be sure the root fastvideo logger has
already been configured.</p>
<h2 id="fastvideo.models.loader.benchmarks.benchmark_weight_loading.resolve_safetensors_files"><code>fastvideo.models.loader.benchmarks.benchmark_weight_loading.resolve_safetensors_files</code></h2>
<pre class="doc-signature"><code>resolve_safetensors_files(model_path: str) -&gt; list&#91;str&#93;</code></pre>
<p>Discover safetensors files in a model directory.</p>
<h2 id="fastvideo.models.loader.benchmarks.benchmark_weight_loading.safetensors_weights_iterator"><code>fastvideo.models.loader.benchmarks.benchmark_weight_loading.safetensors_weights_iterator</code></h2>
<pre class="doc-signature"><code>safetensors_weights_iterator(hf_weights_files: list&#91;str&#93;, to_cpu: bool = False, broadcast: bool = True, async_broadcast: bool = False) -&gt; Generator&#91;tuple&#91;str, torch.Tensor&#93;, None, None&#93;</code></pre>
<p>Iterate over the weights in the model safetensor files.
Args:
    hf_weights_files: List of safetensor files to load.
    to_cpu: Whether to load the weights to CPU. If False, will load to the GPU device bound to the current
        process.
    broadcast: Whether node-group rank 0 should read GPU weights and broadcast them to the other ranks of the node.
    async_broadcast: Whether to overlap loading from disk and broadcasting to other ranks. If True,
        must iterate over all the weights before use. Only used when broadcast is True and to_cpu is False.</p>
<h2 id="fastvideo.models.loader.benchmarks.benchmark_weight_loading.benchmark_loading"><code>fastvideo.models.loader.benchmarks.benchmark_weight_loading.benchmark_loading</code></h2>
<pre class="doc-signature"><code>benchmark_loading(files: list&#91;str&#93;, to_cpu: bool, broadcast: bool, warmup: int, repeats: int, label: str) -&gt; None</code></pre>
<p>Run the weight loading benchmark and print results.</p>
<details><summary>Source</summary><pre><code>def benchmark_loading(
    files: list&#91;str&#93;,
    to_cpu: bool,
    broadcast: bool,
    warmup: int,
    repeats: int,
    label: str,
) -&gt; None:
    &quot;&quot;&quot;Run the weight loading benchmark and print results.&quot;&quot;&quot;
    rank = dist.get_rank() if dist.is_initialized() else 0
    node_group = get_node_group()

    # Count total params and bytes on first pass
    total_params = 0
    total_bytes = 0
    for name, tensor in safetensors_weights_iterator(files, to_cpu=to_cpu, broadcast=broadcast):
        total_params += 1
        total_bytes += tensor.nelement() * tensor.element_size()

    if rank == 0:
        logger.info(&quot;&#91;%s&#93; %d tensors, %.2f GB total&quot;, label, total_params, total_bytes / 1e9)

    # Warmup
    for _ in range(warmup):
        for _ in safetensors_weights_iterator(files, to_cpu=to_cpu, broadcast=broadcast):
            pass
        if dist.is_initialized():
            dist.barrier()

    # Timed runs
    times = &#91;&#93;
    for i in range(repeats):
        if dist.is_initialized():
            dist.barrier()
        torch.cuda.synchronize() if torch.cuda.is_available() else None

        t0 = time.perf_counter()
        for _ in safetensors_weights_iterator(files, to_cpu=to_cpu, broadcast=broadcast):
            pass
        torch.cuda.synchronize() if torch.cuda.is_available() else None

        if dist.is_initialized():
            dist.barrier()
        elapsed = time.perf_counter() - t0
        times.append(elapsed)

    if rank == 0:
        avg = sum(times) / len(times)
        best = min(times)
        throughput = total_bytes / avg / 1e9
        logger.info(
            &quot;&#91;%s&#93; avg %.3fs | best %.3fs | throughput %.2f GB/s &quot;
            &quot;(over %d runs, %d warmup, %d GPU(s), node_size=%d)&quot;,
            label,
            avg,
            best,
            throughput,
            repeats,
            warmup,
            node_group.world_size,
            node_group.world_size,
        )</code></pre></details>
<h2 id="fastvideo.models.loader.benchmarks.benchmark_weight_loading.main"><code>fastvideo.models.loader.benchmarks.benchmark_weight_loading.main</code></h2>
<pre class="doc-signature"><code>main() -&gt; None</code></pre>

<details><summary>Source</summary><pre><code>def main() -&gt; None:
    parser = argparse.ArgumentParser(description=&quot;Benchmark model weight loading speed&quot;)
    parser.add_argument(&quot;--model-path&quot;,
                        type=str,
                        required=True,
                        help=&quot;Path to a local model directory containing .safetensors files&quot;)
    parser.add_argument(&quot;--subfolder&quot;,
                        type=str,
                        default=None,
                        help=&quot;Subfolder within model-path to load (e.g. &#x27;transformer&#x27;, &quot;
                        &quot;&#x27;text_encoder&#x27;). If not set, loads from model-path directly.&quot;)
    parser.add_argument(&quot;--warmup&quot;, type=int, default=1, help=&quot;Number of warmup iterations (default: 1)&quot;)
    parser.add_argument(&quot;--repeats&quot;, type=int, default=3, help=&quot;Number of timed iterations (default: 3)&quot;)
    args = parser.parse_args()

    load_path = args.model_path
    if args.subfolder:
        load_path = os.path.join(load_path, args.subfolder)

    files = resolve_safetensors_files(load_path)

    # Set default env vars for single-GPU standalone mode (no torchrun)
    envs.setdefault_external(&quot;MASTER_ADDR&quot;, &quot;localhost&quot;)
    envs.setdefault_external(&quot;MASTER_PORT&quot;, &quot;29500&quot;)
    envs.setdefault_external(&quot;RANK&quot;, &quot;0&quot;)
    envs.setdefault_external(&quot;WORLD_SIZE&quot;, &quot;1&quot;)

    maybe_init_distributed_environment_and_model_parallel(1, 1)
    rank = dist.get_rank() if dist.is_initialized() else 0
    world_size = dist.get_world_size() if dist.is_initialized() else 1

    if rank == 0:
        logger.info(&quot;Model path: %s&quot;, load_path)
        logger.info(&quot;Safetensors files: %d&quot;, len(files))
        logger.info(&quot;World size: %d&quot;, world_size)

    # Benchmark: load to CPU (no broadcast, each rank reads independently)
    benchmark_loading(files,
                      to_cpu=True,
                      broadcast=False,
                      warmup=args.warmup,
                      repeats=args.repeats,
                      label=&quot;to_cpu=True&quot;)

    # Benchmark: load to GPU (rank 0 reads, broadcasts to others)
    if torch.cuda.is_available():
        benchmark_loading(files,
                          to_cpu=False,
                          broadcast=True,
                          warmup=args.warmup,
                          repeats=args.repeats,
                          label=&quot;to_cpu=False (broadcast)&quot;)

    cleanup_dist_env_and_memory()</code></pre></details>
</div>
