• Home
  • About Us
  • Contact Us
  • Disclaimer
  • Privacy Policy
Tuesday, August 11, 2026
newsaiworld
  • Home
  • Artificial Intelligence
  • ChatGPT
  • Data Science
  • Machine Learning
  • Crypto Coins
  • Contact Us
No Result
View All Result
  • Home
  • Artificial Intelligence
  • ChatGPT
  • Data Science
  • Machine Learning
  • Crypto Coins
  • Contact Us
No Result
View All Result
Morning News
No Result
View All Result
Home Artificial Intelligence

Measuring Efficiency of Transformer Inference

Admin by Admin
August 11, 2026
in Artificial Intelligence
0
Tomas anton escobar PHyF2mCMei0 unsplash scaled.jpg
0
SHARES
0
VIEWS
Share on FacebookShare on Twitter


Whenever you optimize the inference efficiency of an LLM, that you must know find out how to measure it. With out measurement, it’s simple to make a mannequin extra difficult with out making it quicker, or to enhance throughput whereas making user-visible latency worse.

An LLM service has a number of sorts of efficiency. A person cares about how lengthy it takes to see the primary token and the way shortly the remainder of the reply streams. An operator cares about what number of requests the {hardware} can serve, how a lot reminiscence is used, and the way a lot every generated token prices. A researcher could care about whether or not an optimization modifications the mannequin’s output high quality.

On this chapter, you’ll study:

  • Latency and throughput metrics
  • Time to first token and time per output token
  • Measuring CPU and GPU inference
  • Utilizing CUDA occasions
  • Benchmarking a number of requests
  • Serious about a number of GPUs and a number of machines

Let’s get began.

 

Measuring Efficiency of Transformer Inference
Picture by Tomas Anton Escobar. Some rights reserved.

Overview

This chapter is split into eight components; they’re:

  • Metrics for LLM Inference
  • Measuring a Single Request
  • Warmup and Synchronization
  • Measuring GPU Work with CUDA Occasions
  • Measuring Reminiscence Utilization
  • Measuring Concurrent Requests
  • A number of GPUs and A number of Machines
  • Price per Token

Metrics for LLM Inference

The most typical inference metrics are:

  • Latency: How lengthy a request takes from begin to end.
  • Time to first token (TTFT): How lengthy the person waits earlier than the primary output token seems.
  • Time per output token (TPOT): The common time between generated tokens after the primary token.
  • Throughput: What number of tokens or requests are processed per second.
  • Reminiscence utilization: How a lot CPU reminiscence or GPU reminiscence is used.
  • Utilization: How busy the accelerator is throughout the benchmark.
  • Price per token: The {hardware} or service value divided by the variety of tokens processed.

For LLMs, a single latency quantity is often not sufficient. Contemplate two requests:

  • Request A: 2,000 immediate tokens and 20 output tokens
  • Request B: 20 immediate tokens and a pair of,000 output tokens

Request A stresses prefill. Request B stresses decode. They might have the identical complete variety of tokens, however they’ve totally different efficiency profiles. Because of this it is best to file immediate tokens and output tokens individually.

Tail latency additionally issues. If most requests full in a single second however a number of take ten seconds, customers will discover. Report high-percentile latencies resembling p90, p95, and p99 along with the imply or median. The excessive percentiles describe the worst circumstances higher. You may simply discover these percentiles from an inventory of values utilizing NumPy:

import numpy as np

 

def summarize(values):

    values = np.asarray(values, dtype=np.float64)

    return {

        “imply”: values.imply(),

        “median”: np.percentile(values, 50),

        “p90”: np.percentile(values, 90),

        “p95”: np.percentile(values, 95),

        “p99”: np.percentile(values, 99),

    }

These numbers are easy, however they forestall a typical mistake: optimizing the typical whereas making the worst circumstances slower.

Measuring a Single Request

The best measurement makes use of time.perf_counter(). It’s a built-in high-resolution wall-clock timer appropriate for measuring elapsed time in Python. It’s extra correct than time.time().

The next instance measures prefill and decode individually for a Hugging Face causal language mannequin:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

import time

import torch

from transformers import AutoModelForCausalLM, AutoTokenizer

 

 

def load_model(model_name=“sshleifer/tiny-gpt2”, gadget=“cpu”):

    tokenizer = AutoTokenizer.from_pretrained(model_name)

    mannequin = AutoModelForCausalLM.from_pretrained(model_name).to(gadget)

    mannequin.eval()

    return tokenizer, mannequin

 

 

@torch.no_grad()

def measure_one_request(mannequin, tokenizer, immediate, max_new_tokens=50, gadget=“cpu”):

    input_ids = tokenizer(immediate, return_tensors=“pt”).input_ids.to(gadget)

 

    begin = time.perf_counter()

    outputs = mannequin(input_ids, use_cache=True)

    prefill_end = time.perf_counter()

 

    past_key_values = outputs.past_key_values

    next_token = outputs.logits[:, –1, :].argmax(dim=–1, keepdim=True)

    generated = [next_token]

 

    decode_times = []

 

    for _ in vary(max_new_tokens – 1):

        step_start = time.perf_counter()

        outputs = mannequin(

            next_token,

            past_key_values=past_key_values,

            use_cache=True,

        )

        # Be aware: Chances are you’ll want torch.cuda.synchronize() right here

        step_end = time.perf_counter()

 

        decode_times.append(step_end – step_start)

        past_key_values = outputs.past_key_values

        next_token = outputs.logits[:, –1, :].argmax(dim=–1, keepdim=True)

        generated.append(next_token)

 

        if tokenizer.eos_token_id is not None:

            if next_token.merchandise() == tokenizer.eos_token_id:

                break

 

    finish = time.perf_counter()

    output_ids = torch.cat([input_ids] + generated, dim=1)

 

    return {

        “textual content”: tokenizer.decode(output_ids[0], skip_special_tokens=True),

        “prompt_tokens”: input_ids.measurement(1),

        “output_tokens”: len(generated),

        “prefill_seconds”: prefill_end – begin,

        “decode_seconds”: sum(decode_times),

        “total_seconds”: finish – begin,

        “ttft_seconds”: prefill_end – begin,

        “seconds_per_output_token”: (

            sum(decode_times) / max(1, len(decode_times))

        ),

    }

This operate doesn’t use the mannequin’s generate() technique. That’s intentional. The objective is to show prefill and decode to allow them to be measured individually. The variety of output_tokens contains the tokens generated by each prefill and decode. The seconds_per_output_token is the typical time per output token within the decode section.

There are two particulars to note:

  • use_cache=True asks the mannequin to return the KV cache.
  • Throughout decode, the mannequin receives solely next_token, not the entire sequence.

This is identical thought as Chapter 1, however utilizing a library mannequin.

Warmup and Synchronization

Whenever you measure efficiency, notice that some one-time prices mustn’t dominate the end result. In Python, import of a module could be sluggish however subsequent import of the identical module is immediate. Equally, the primary execution of some code could also be slower than subsequent executions because of initialization of knowledge buildings or warmup of caches. You need to measure steady-state work, not that setup overhead.

Due to this fact, benchmarks ought to embody warmup. The primary few iterations could also be slower for varied causes. As an alternative of measuring the whole time and dividing by the variety of iterations, it is best to measure the time for every iteration and analyze the steady-state ones. For instance, should you use the mannequin to generate a number of tokens, you’ll probably put the era in a loop. Measure every iteration as follows, then ignore the primary few outcomes:

def iterations(mannequin, tokenizer, immediate, gadget, steps=100, warmup=10):

    outcomes = []

    for _ in vary(steps):

        end result = measure_one_request(

            mannequin,

            tokenizer,

            immediate,

            max_new_tokens=8,

            gadget=gadget,

        )

        outcomes.append(end result)

    regular = outcomes[warmup:]

    return summarize([item[“total_seconds”] for merchandise in regular])

If you happen to use GPU to run your LLM inference, you additionally must initialize the kernels if you first run them. Sadly, many GPU operations are asynchronous. That’s, when you launched an operation on GPU, Python could proceed along with your code instantly whereas the GPU continues to be working. Due to this fact, a naive strategy to measure the time could be incorrect. As an alternative, it is best to use torch.cuda.synchronize() to attend for the GPU to complete the operation earlier than you cease the timer:

def sync_if_needed(gadget):

    if gadget.startswith(“cuda”):

        torch.cuda.synchronize()

 

begin = time.perf_counter()

outputs = mannequin(input_ids, use_cache=True)

sync_if_needed(gadget)

elapsed = time.perf_counter() – begin

This provides a wall-clock measurement that features the precise GPU work. For correct prefill and per-token decode timings on GPU, name sync_if_needed(gadget) after every timed mannequin(...) name in measure_one_request(), not solely as soon as on the finish of the request.

Measuring GPU Work with CUDA Occasions

CUDA occasions measure elapsed time the GPU spent executing kernels, not the end-to-end person latency. This time doesn’t embody any Python overhead. Beneath is an instance of find out how to use CUDA occasions to measure the time:

def cuda_event_time(fn):

    begin = torch.cuda.Occasion(enable_timing=True)

    finish = torch.cuda.Occasion(enable_timing=True)

 

    begin.file()

    end result = fn()

    finish.file()

 

    torch.cuda.synchronize()

    milliseconds = begin.elapsed_time(finish)

    return end result, milliseconds / 1000.0

You should use it to measure one ahead go:

with torch.no_grad():

    outputs, seconds = cuda_event_time(

        lambda: mannequin(input_ids, use_cache=True)

    )

 

print(f“GPU ahead time: {seconds:.6f} seconds”)

CUDA occasion timing and wall-clock timing reply totally different questions:

  • Wall-clock timing measures what the applying experiences.
  • CUDA occasion timing measures how lengthy the GPU work took.

For an inference service, wall-clock timing is often the first metric as a result of customers expertise queues, tokenization, scheduling, community overhead, and streaming. CUDA occasions are helpful if you end up optimizing kernels or evaluating mannequin execution paths.

For deeper GPU profiling, use instruments resembling PyTorch Profiler, Nsight Techniques, Nsight Compute, or CUPTI-based monitoring. These instruments can report kernel timelines, reminiscence copies, GPU utilization, and operator-level breakdowns. They’re extra advanced than a timer, however they’re vital when a easy benchmark says the mannequin is sluggish and that you must know why.

Measuring Reminiscence Utilization

Reminiscence is a unique dimension to measure as a result of it limits not velocity for one person a lot as what number of customers your system can serve. Normally the GPU reminiscence is the bottleneck. In PyTorch, you may report allotted and reserved reminiscence like the next:

def gpu_memory_summary(gadget=“cuda”):

    torch.cuda.synchronize()

    return {

        “allocated_gb”: torch.cuda.memory_allocated(gadget) / 1e9,

        “reserved_gb”: torch.cuda.memory_reserved(gadget) / 1e9,

        “max_allocated_gb”: torch.cuda.max_memory_allocated(gadget) / 1e9,

    }

The allotted worth is reminiscence utilized by tensors. The reserved worth is reminiscence held by PyTorch’s caching allocator. The utmost allotted worth is commonly probably the most helpful quantity for capability planning.

The allotted and reserved reminiscence are real-time snapshots however the max allotted worth is a peak over time. For correct measurement, it is best to reset the height statistic earlier than a benchmark:

torch.cuda.reset_peak_memory_stats()

end result = measure_one_request(mannequin, tokenizer, immediate, gadget=“cuda”)

reminiscence = gpu_memory_summary(“cuda”)

print(reminiscence)

Reminiscence ought to be measured along with tokens. A run with an extended immediate or extra generated tokens will naturally use extra KV cache reminiscence.

Measuring Concurrent Requests

To create a server that runs a language mannequin, consider the system by what number of requests you may serve per second. Throughput is dependent upon each how briskly you fulfill one request and what number of requests you may run concurrently, although concurrency doesn’t scale linearly underneath rivalry.

Manufacturing methods ought to deal with a number of customers, and the scheduler could batch their work collectively. The next easy benchmark runs a number of requests concurrently utilizing Python threads. This doesn’t implement steady batching. It solely measures how a mannequin wrapper behaves when a number of callers use it on the identical time.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

from concurrent.futures import ThreadPoolExecutor, as_completed

 

def run_prompt(mannequin, tokenizer, immediate, gadget):

    begin = time.perf_counter()

    end result = measure_one_request(

        mannequin,

        tokenizer,

        immediate,

        max_new_tokens=32,

        gadget=gadget,

    )

    finish = time.perf_counter()

    end result[“wall_seconds”] = finish – begin

    return end result

 

 

def benchmark_concurrent(mannequin, tokenizer, prompts, gadget=“cpu”, employees=4):

    outcomes = []

    begin = time.perf_counter()

 

    with ThreadPoolExecutor(max_workers=employees) as pool:

        futures = [

            pool.submit(run_prompt, model, tokenizer, prompt, device)

            for prompt in prompts

        ]

        for future in as_completed(futures):

            outcomes.append(future.end result())

 

    finish = time.perf_counter()

    total_output_tokens = sum(merchandise[“output_tokens”] for merchandise in outcomes)

 

    return {

        “requests”: len(outcomes),

        “total_seconds”: finish – begin,

        “output_tokens”: total_output_tokens,

        “output_tokens_per_second”: total_output_tokens / (finish – begin),

        “latency_summary”: summarize([item[“wall_seconds”] for merchandise in outcomes]),

    }

This benchmark is for illustration solely. It’s not a alternative for an actual serving benchmark. It doesn’t mannequin HTTP overhead, streaming, request queues, batching, cancellation, or cache eviction. However it’s a helpful subsequent step after a single-request benchmark the place you may run the mannequin in parallel and observe the per-request latency. The Python GIL (World Interpreter Lock) is often not the primary concern right here as a result of heavyweight mannequin execution is commonly offloaded to compiled code. Concurrent use of the identical mannequin or tensors from a number of threads is unsafe with out synchronization, so share one mannequin on CUDA solely with a lock or a single employee thread.

When benchmarking an actual server, file no less than:

  • Variety of concurrent customers
  • Immediate token distribution
  • Output token distribution
  • Request fee
  • TTFT (Time to first token) percentiles
  • Inter-token latency percentiles
  • Complete tokens per second
  • Error fee and timeout fee

The distributions matter. A benchmark with all prompts at precisely 128 tokens and all outputs at precisely 128 tokens is straightforward to check, however it might not signify your software.

A number of GPUs and A number of Machines

A number of GPUs can be utilized for inference in a number of alternative ways. Completely different approaches can drastically change the efficiency of your system.

The best strategy is replication. You load one copy of the mannequin on every GPU and route totally different requests to totally different replicas. This will increase throughput and is straightforward to motive about, however every GPU should have sufficient reminiscence for the total mannequin and its KV cache.

One other strategy is to separate one mannequin throughout a number of GPUs. Tensor parallelism splits weight matrices throughout units. Pipeline parallelism locations totally different layers on totally different units. Context parallelism partitions sequence work. Knowledgeable parallelism is used for mixture-of-experts fashions. These methods permit bigger fashions to run, however they introduce communication overhead and might improve latency.

A number of machines add one other layer. A system could use many replicas throughout machines for prime request quantity. It might additionally cut up a single massive mannequin throughout machines, however that is tougher as a result of community communication is slower than communication inside one machine. For low-latency serving, crossing machine boundaries inside one ahead go ought to be handled as costly.

Measuring efficiency of a system with a number of GPUs or a number of machines provides a brand new dimension of communication and synchronization overhead. Earlier than selecting a multi-GPU or multi-machine design, reply these questions:

  • Are you serving one massive mannequin or many smaller fashions?
  • Are you restricted by mannequin weight reminiscence or KV cache reminiscence?
  • Do you want decrease latency, increased throughput, or each?
  • Are requests impartial, or do they share lengthy immediate prefixes?
  • Can one GPU maintain the mannequin, or should the mannequin be partitioned?

These questions matter as a result of the very best design is dependent upon the bottleneck. Including GPUs doesn’t robotically make a single request quicker. It might assist throughput by means of replication, or it might make a bigger mannequin doable by means of partitioning. The benchmark ought to present which impact you’re getting.

Price per Token

Price is a efficiency metric. A quicker system that makes use of way more costly {hardware} might not be higher for an software.

A easy value estimate is:

cost_per_output_token = hardware_cost_per_second / output_tokens_per_second

If a GPU occasion prices 3 {dollars} per hour and the service generates 1,000 output tokens per second:

hardware_cost_per_second = 3.00 / 3600 = 0.000833

cost_per_output_token = 0.000833 / 1000

                      = 0.000000833

That is lower than one millionth of a greenback per output token for {hardware} alone. An actual calculation may additionally embody idle capability, storage, networking, engineering time, orchestration overhead, and failed requests.

Price ought to be in contrast with high quality. Quantization, smaller fashions, and routing can scale back value, however they might change mannequin conduct. An environment friendly inference system just isn’t merely the quickest one. It’s the one which meets high quality and reliability necessities on the lowest sensible value.

Additional Studying

Beneath are some sources chances are you’ll discover helpful:

  • Little’s legislation, on Wikipedia.
    It is a helpful queueing-theory end result for relating common concurrency, arrival fee, and response time. It’s a useful psychological mannequin when reasoning about request fee, latency, and the variety of in-flight inference requests.
  • Metrics, in NVIDIA NIM LLMs Benchmarking.
    This web page defines frequent LLM inference metrics resembling time to first token, end-to-end latency, inter-token latency, tokens per second, and requests per second.
  • MLPerf Inference, by MLCommons.
    It is a extensively used benchmark suite for measuring inference efficiency throughout deployment eventualities. It’s not restricted to LLMs, however it offers helpful self-discipline round repeatable benchmarking and reporting.
  • torch.profiler, within the PyTorch documentation.
    That is the primary PyTorch profiling interface for gathering CPU and accelerator exercise, operator timings, reminiscence data, tensor shapes, and traces that may be inspected later.
  • NVIDIA Nsight Techniques Person Information, by NVIDIA.
    Nsight Techniques is helpful when wall-clock timers usually are not sufficient and also you want a timeline of CUDA API calls, GPU kernels, reminiscence copies, CPU work, and synchronization.
  • Taming the Titans: A Survey of Environment friendly LLM Inference Serving, by Zhen et al.
    This survey provides a broader view of LLM inference serving, together with request scheduling, mannequin placement, storage administration, disaggregation, load balancing, and cluster-level serving points.

Abstract

On this chapter, you discovered find out how to measure LLM inference efficiency. You noticed why prefill and decode ought to be measured individually, find out how to use wall-clock timers and CUDA occasions, find out how to file reminiscence utilization, and find out how to report latency percentiles. You additionally discovered that a number of GPUs can imply replication for extra throughput or partitioning for bigger fashions, and that the benchmark ought to make this distinction clear.

Within the subsequent a part of the ebook, you’ll start finding out methods for making one mannequin quicker, beginning with floating-point precision.

 

READ ALSO

Find out how to Successfully Deploy Code With Claude Code

Designing AI Brokers That Can Self-Right


Whenever you optimize the inference efficiency of an LLM, that you must know find out how to measure it. With out measurement, it’s simple to make a mannequin extra difficult with out making it quicker, or to enhance throughput whereas making user-visible latency worse.

An LLM service has a number of sorts of efficiency. A person cares about how lengthy it takes to see the primary token and the way shortly the remainder of the reply streams. An operator cares about what number of requests the {hardware} can serve, how a lot reminiscence is used, and the way a lot every generated token prices. A researcher could care about whether or not an optimization modifications the mannequin’s output high quality.

On this chapter, you’ll study:

  • Latency and throughput metrics
  • Time to first token and time per output token
  • Measuring CPU and GPU inference
  • Utilizing CUDA occasions
  • Benchmarking a number of requests
  • Serious about a number of GPUs and a number of machines

Let’s get began.

 

Measuring Efficiency of Transformer Inference
Picture by Tomas Anton Escobar. Some rights reserved.

Overview

This chapter is split into eight components; they’re:

  • Metrics for LLM Inference
  • Measuring a Single Request
  • Warmup and Synchronization
  • Measuring GPU Work with CUDA Occasions
  • Measuring Reminiscence Utilization
  • Measuring Concurrent Requests
  • A number of GPUs and A number of Machines
  • Price per Token

Metrics for LLM Inference

The most typical inference metrics are:

  • Latency: How lengthy a request takes from begin to end.
  • Time to first token (TTFT): How lengthy the person waits earlier than the primary output token seems.
  • Time per output token (TPOT): The common time between generated tokens after the primary token.
  • Throughput: What number of tokens or requests are processed per second.
  • Reminiscence utilization: How a lot CPU reminiscence or GPU reminiscence is used.
  • Utilization: How busy the accelerator is throughout the benchmark.
  • Price per token: The {hardware} or service value divided by the variety of tokens processed.

For LLMs, a single latency quantity is often not sufficient. Contemplate two requests:

  • Request A: 2,000 immediate tokens and 20 output tokens
  • Request B: 20 immediate tokens and a pair of,000 output tokens

Request A stresses prefill. Request B stresses decode. They might have the identical complete variety of tokens, however they’ve totally different efficiency profiles. Because of this it is best to file immediate tokens and output tokens individually.

Tail latency additionally issues. If most requests full in a single second however a number of take ten seconds, customers will discover. Report high-percentile latencies resembling p90, p95, and p99 along with the imply or median. The excessive percentiles describe the worst circumstances higher. You may simply discover these percentiles from an inventory of values utilizing NumPy:

import numpy as np

 

def summarize(values):

    values = np.asarray(values, dtype=np.float64)

    return {

        “imply”: values.imply(),

        “median”: np.percentile(values, 50),

        “p90”: np.percentile(values, 90),

        “p95”: np.percentile(values, 95),

        “p99”: np.percentile(values, 99),

    }

These numbers are easy, however they forestall a typical mistake: optimizing the typical whereas making the worst circumstances slower.

Measuring a Single Request

The best measurement makes use of time.perf_counter(). It’s a built-in high-resolution wall-clock timer appropriate for measuring elapsed time in Python. It’s extra correct than time.time().

The next instance measures prefill and decode individually for a Hugging Face causal language mannequin:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

import time

import torch

from transformers import AutoModelForCausalLM, AutoTokenizer

 

 

def load_model(model_name=“sshleifer/tiny-gpt2”, gadget=“cpu”):

    tokenizer = AutoTokenizer.from_pretrained(model_name)

    mannequin = AutoModelForCausalLM.from_pretrained(model_name).to(gadget)

    mannequin.eval()

    return tokenizer, mannequin

 

 

@torch.no_grad()

def measure_one_request(mannequin, tokenizer, immediate, max_new_tokens=50, gadget=“cpu”):

    input_ids = tokenizer(immediate, return_tensors=“pt”).input_ids.to(gadget)

 

    begin = time.perf_counter()

    outputs = mannequin(input_ids, use_cache=True)

    prefill_end = time.perf_counter()

 

    past_key_values = outputs.past_key_values

    next_token = outputs.logits[:, –1, :].argmax(dim=–1, keepdim=True)

    generated = [next_token]

 

    decode_times = []

 

    for _ in vary(max_new_tokens – 1):

        step_start = time.perf_counter()

        outputs = mannequin(

            next_token,

            past_key_values=past_key_values,

            use_cache=True,

        )

        # Be aware: Chances are you’ll want torch.cuda.synchronize() right here

        step_end = time.perf_counter()

 

        decode_times.append(step_end – step_start)

        past_key_values = outputs.past_key_values

        next_token = outputs.logits[:, –1, :].argmax(dim=–1, keepdim=True)

        generated.append(next_token)

 

        if tokenizer.eos_token_id is not None:

            if next_token.merchandise() == tokenizer.eos_token_id:

                break

 

    finish = time.perf_counter()

    output_ids = torch.cat([input_ids] + generated, dim=1)

 

    return {

        “textual content”: tokenizer.decode(output_ids[0], skip_special_tokens=True),

        “prompt_tokens”: input_ids.measurement(1),

        “output_tokens”: len(generated),

        “prefill_seconds”: prefill_end – begin,

        “decode_seconds”: sum(decode_times),

        “total_seconds”: finish – begin,

        “ttft_seconds”: prefill_end – begin,

        “seconds_per_output_token”: (

            sum(decode_times) / max(1, len(decode_times))

        ),

    }

This operate doesn’t use the mannequin’s generate() technique. That’s intentional. The objective is to show prefill and decode to allow them to be measured individually. The variety of output_tokens contains the tokens generated by each prefill and decode. The seconds_per_output_token is the typical time per output token within the decode section.

There are two particulars to note:

  • use_cache=True asks the mannequin to return the KV cache.
  • Throughout decode, the mannequin receives solely next_token, not the entire sequence.

This is identical thought as Chapter 1, however utilizing a library mannequin.

Warmup and Synchronization

Whenever you measure efficiency, notice that some one-time prices mustn’t dominate the end result. In Python, import of a module could be sluggish however subsequent import of the identical module is immediate. Equally, the primary execution of some code could also be slower than subsequent executions because of initialization of knowledge buildings or warmup of caches. You need to measure steady-state work, not that setup overhead.

Due to this fact, benchmarks ought to embody warmup. The primary few iterations could also be slower for varied causes. As an alternative of measuring the whole time and dividing by the variety of iterations, it is best to measure the time for every iteration and analyze the steady-state ones. For instance, should you use the mannequin to generate a number of tokens, you’ll probably put the era in a loop. Measure every iteration as follows, then ignore the primary few outcomes:

def iterations(mannequin, tokenizer, immediate, gadget, steps=100, warmup=10):

    outcomes = []

    for _ in vary(steps):

        end result = measure_one_request(

            mannequin,

            tokenizer,

            immediate,

            max_new_tokens=8,

            gadget=gadget,

        )

        outcomes.append(end result)

    regular = outcomes[warmup:]

    return summarize([item[“total_seconds”] for merchandise in regular])

If you happen to use GPU to run your LLM inference, you additionally must initialize the kernels if you first run them. Sadly, many GPU operations are asynchronous. That’s, when you launched an operation on GPU, Python could proceed along with your code instantly whereas the GPU continues to be working. Due to this fact, a naive strategy to measure the time could be incorrect. As an alternative, it is best to use torch.cuda.synchronize() to attend for the GPU to complete the operation earlier than you cease the timer:

def sync_if_needed(gadget):

    if gadget.startswith(“cuda”):

        torch.cuda.synchronize()

 

begin = time.perf_counter()

outputs = mannequin(input_ids, use_cache=True)

sync_if_needed(gadget)

elapsed = time.perf_counter() – begin

This provides a wall-clock measurement that features the precise GPU work. For correct prefill and per-token decode timings on GPU, name sync_if_needed(gadget) after every timed mannequin(...) name in measure_one_request(), not solely as soon as on the finish of the request.

Measuring GPU Work with CUDA Occasions

CUDA occasions measure elapsed time the GPU spent executing kernels, not the end-to-end person latency. This time doesn’t embody any Python overhead. Beneath is an instance of find out how to use CUDA occasions to measure the time:

def cuda_event_time(fn):

    begin = torch.cuda.Occasion(enable_timing=True)

    finish = torch.cuda.Occasion(enable_timing=True)

 

    begin.file()

    end result = fn()

    finish.file()

 

    torch.cuda.synchronize()

    milliseconds = begin.elapsed_time(finish)

    return end result, milliseconds / 1000.0

You should use it to measure one ahead go:

with torch.no_grad():

    outputs, seconds = cuda_event_time(

        lambda: mannequin(input_ids, use_cache=True)

    )

 

print(f“GPU ahead time: {seconds:.6f} seconds”)

CUDA occasion timing and wall-clock timing reply totally different questions:

  • Wall-clock timing measures what the applying experiences.
  • CUDA occasion timing measures how lengthy the GPU work took.

For an inference service, wall-clock timing is often the first metric as a result of customers expertise queues, tokenization, scheduling, community overhead, and streaming. CUDA occasions are helpful if you end up optimizing kernels or evaluating mannequin execution paths.

For deeper GPU profiling, use instruments resembling PyTorch Profiler, Nsight Techniques, Nsight Compute, or CUPTI-based monitoring. These instruments can report kernel timelines, reminiscence copies, GPU utilization, and operator-level breakdowns. They’re extra advanced than a timer, however they’re vital when a easy benchmark says the mannequin is sluggish and that you must know why.

Measuring Reminiscence Utilization

Reminiscence is a unique dimension to measure as a result of it limits not velocity for one person a lot as what number of customers your system can serve. Normally the GPU reminiscence is the bottleneck. In PyTorch, you may report allotted and reserved reminiscence like the next:

def gpu_memory_summary(gadget=“cuda”):

    torch.cuda.synchronize()

    return {

        “allocated_gb”: torch.cuda.memory_allocated(gadget) / 1e9,

        “reserved_gb”: torch.cuda.memory_reserved(gadget) / 1e9,

        “max_allocated_gb”: torch.cuda.max_memory_allocated(gadget) / 1e9,

    }

The allotted worth is reminiscence utilized by tensors. The reserved worth is reminiscence held by PyTorch’s caching allocator. The utmost allotted worth is commonly probably the most helpful quantity for capability planning.

The allotted and reserved reminiscence are real-time snapshots however the max allotted worth is a peak over time. For correct measurement, it is best to reset the height statistic earlier than a benchmark:

torch.cuda.reset_peak_memory_stats()

end result = measure_one_request(mannequin, tokenizer, immediate, gadget=“cuda”)

reminiscence = gpu_memory_summary(“cuda”)

print(reminiscence)

Reminiscence ought to be measured along with tokens. A run with an extended immediate or extra generated tokens will naturally use extra KV cache reminiscence.

Measuring Concurrent Requests

To create a server that runs a language mannequin, consider the system by what number of requests you may serve per second. Throughput is dependent upon each how briskly you fulfill one request and what number of requests you may run concurrently, although concurrency doesn’t scale linearly underneath rivalry.

Manufacturing methods ought to deal with a number of customers, and the scheduler could batch their work collectively. The next easy benchmark runs a number of requests concurrently utilizing Python threads. This doesn’t implement steady batching. It solely measures how a mannequin wrapper behaves when a number of callers use it on the identical time.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

from concurrent.futures import ThreadPoolExecutor, as_completed

 

def run_prompt(mannequin, tokenizer, immediate, gadget):

    begin = time.perf_counter()

    end result = measure_one_request(

        mannequin,

        tokenizer,

        immediate,

        max_new_tokens=32,

        gadget=gadget,

    )

    finish = time.perf_counter()

    end result[“wall_seconds”] = finish – begin

    return end result

 

 

def benchmark_concurrent(mannequin, tokenizer, prompts, gadget=“cpu”, employees=4):

    outcomes = []

    begin = time.perf_counter()

 

    with ThreadPoolExecutor(max_workers=employees) as pool:

        futures = [

            pool.submit(run_prompt, model, tokenizer, prompt, device)

            for prompt in prompts

        ]

        for future in as_completed(futures):

            outcomes.append(future.end result())

 

    finish = time.perf_counter()

    total_output_tokens = sum(merchandise[“output_tokens”] for merchandise in outcomes)

 

    return {

        “requests”: len(outcomes),

        “total_seconds”: finish – begin,

        “output_tokens”: total_output_tokens,

        “output_tokens_per_second”: total_output_tokens / (finish – begin),

        “latency_summary”: summarize([item[“wall_seconds”] for merchandise in outcomes]),

    }

This benchmark is for illustration solely. It’s not a alternative for an actual serving benchmark. It doesn’t mannequin HTTP overhead, streaming, request queues, batching, cancellation, or cache eviction. However it’s a helpful subsequent step after a single-request benchmark the place you may run the mannequin in parallel and observe the per-request latency. The Python GIL (World Interpreter Lock) is often not the primary concern right here as a result of heavyweight mannequin execution is commonly offloaded to compiled code. Concurrent use of the identical mannequin or tensors from a number of threads is unsafe with out synchronization, so share one mannequin on CUDA solely with a lock or a single employee thread.

When benchmarking an actual server, file no less than:

  • Variety of concurrent customers
  • Immediate token distribution
  • Output token distribution
  • Request fee
  • TTFT (Time to first token) percentiles
  • Inter-token latency percentiles
  • Complete tokens per second
  • Error fee and timeout fee

The distributions matter. A benchmark with all prompts at precisely 128 tokens and all outputs at precisely 128 tokens is straightforward to check, however it might not signify your software.

A number of GPUs and A number of Machines

A number of GPUs can be utilized for inference in a number of alternative ways. Completely different approaches can drastically change the efficiency of your system.

The best strategy is replication. You load one copy of the mannequin on every GPU and route totally different requests to totally different replicas. This will increase throughput and is straightforward to motive about, however every GPU should have sufficient reminiscence for the total mannequin and its KV cache.

One other strategy is to separate one mannequin throughout a number of GPUs. Tensor parallelism splits weight matrices throughout units. Pipeline parallelism locations totally different layers on totally different units. Context parallelism partitions sequence work. Knowledgeable parallelism is used for mixture-of-experts fashions. These methods permit bigger fashions to run, however they introduce communication overhead and might improve latency.

A number of machines add one other layer. A system could use many replicas throughout machines for prime request quantity. It might additionally cut up a single massive mannequin throughout machines, however that is tougher as a result of community communication is slower than communication inside one machine. For low-latency serving, crossing machine boundaries inside one ahead go ought to be handled as costly.

Measuring efficiency of a system with a number of GPUs or a number of machines provides a brand new dimension of communication and synchronization overhead. Earlier than selecting a multi-GPU or multi-machine design, reply these questions:

  • Are you serving one massive mannequin or many smaller fashions?
  • Are you restricted by mannequin weight reminiscence or KV cache reminiscence?
  • Do you want decrease latency, increased throughput, or each?
  • Are requests impartial, or do they share lengthy immediate prefixes?
  • Can one GPU maintain the mannequin, or should the mannequin be partitioned?

These questions matter as a result of the very best design is dependent upon the bottleneck. Including GPUs doesn’t robotically make a single request quicker. It might assist throughput by means of replication, or it might make a bigger mannequin doable by means of partitioning. The benchmark ought to present which impact you’re getting.

Price per Token

Price is a efficiency metric. A quicker system that makes use of way more costly {hardware} might not be higher for an software.

A easy value estimate is:

cost_per_output_token = hardware_cost_per_second / output_tokens_per_second

If a GPU occasion prices 3 {dollars} per hour and the service generates 1,000 output tokens per second:

hardware_cost_per_second = 3.00 / 3600 = 0.000833

cost_per_output_token = 0.000833 / 1000

                      = 0.000000833

That is lower than one millionth of a greenback per output token for {hardware} alone. An actual calculation may additionally embody idle capability, storage, networking, engineering time, orchestration overhead, and failed requests.

Price ought to be in contrast with high quality. Quantization, smaller fashions, and routing can scale back value, however they might change mannequin conduct. An environment friendly inference system just isn’t merely the quickest one. It’s the one which meets high quality and reliability necessities on the lowest sensible value.

Additional Studying

Beneath are some sources chances are you’ll discover helpful:

  • Little’s legislation, on Wikipedia.
    It is a helpful queueing-theory end result for relating common concurrency, arrival fee, and response time. It’s a useful psychological mannequin when reasoning about request fee, latency, and the variety of in-flight inference requests.
  • Metrics, in NVIDIA NIM LLMs Benchmarking.
    This web page defines frequent LLM inference metrics resembling time to first token, end-to-end latency, inter-token latency, tokens per second, and requests per second.
  • MLPerf Inference, by MLCommons.
    It is a extensively used benchmark suite for measuring inference efficiency throughout deployment eventualities. It’s not restricted to LLMs, however it offers helpful self-discipline round repeatable benchmarking and reporting.
  • torch.profiler, within the PyTorch documentation.
    That is the primary PyTorch profiling interface for gathering CPU and accelerator exercise, operator timings, reminiscence data, tensor shapes, and traces that may be inspected later.
  • NVIDIA Nsight Techniques Person Information, by NVIDIA.
    Nsight Techniques is helpful when wall-clock timers usually are not sufficient and also you want a timeline of CUDA API calls, GPU kernels, reminiscence copies, CPU work, and synchronization.
  • Taming the Titans: A Survey of Environment friendly LLM Inference Serving, by Zhen et al.
    This survey provides a broader view of LLM inference serving, together with request scheduling, mannequin placement, storage administration, disaggregation, load balancing, and cluster-level serving points.

Abstract

On this chapter, you discovered find out how to measure LLM inference efficiency. You noticed why prefill and decode ought to be measured individually, find out how to use wall-clock timers and CUDA occasions, find out how to file reminiscence utilization, and find out how to report latency percentiles. You additionally discovered that a number of GPUs can imply replication for extra throughput or partitioning for bigger fashions, and that the benchmark ought to make this distinction clear.

Within the subsequent a part of the ebook, you’ll start finding out methods for making one mannequin quicker, beginning with floating-point precision.

 

Tags: InferenceMeasuringperformanceTransformer

Related Posts

Optimize cicd coding agents cover.jpg
Artificial Intelligence

Find out how to Successfully Deploy Code With Claude Code

August 11, 2026
Mlm designing ai agents that can self correct feature.png
Artificial Intelligence

Designing AI Brokers That Can Self-Right

August 10, 2026
Pexels photo 36496927 scaled 1.jpg
Artificial Intelligence

Constructing an Agent-Prepared Knowledge Warehouse: What Conventional Architectures Do Fallacious

August 10, 2026
RSS transform article dbt.jpg
Artificial Intelligence

I Thought Loading Information Was the End Line. It Was the Beginning Level.

August 9, 2026
Towards data science cognitive overhead.jpg
Artificial Intelligence

The Drawback with pandas Isn’t Efficiency. It’s Cognitive Overhead.

August 9, 2026
Towfiqu barbhuiya 9gPKrsbGmc unsplash scaled 1.jpg
Artificial Intelligence

Constructing a Streamlit UI for My LangGraph AI Agent

August 8, 2026

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

POPULAR NEWS

Gemini 2.0 Fash Vs Gpt 4o.webp.webp

Gemini 2.0 Flash vs GPT 4o: Which is Higher?

January 19, 2025
Chainlink Link And Cardano Ada Dominate The Crypto Coin Development Chart.jpg

Chainlink’s Run to $20 Beneficial properties Steam Amid LINK Taking the Helm because the High Creating DeFi Challenge ⋆ ZyCrypto

May 17, 2025
Image 100 1024x683.png

Easy methods to Use LLMs for Highly effective Computerized Evaluations

August 13, 2025
Blog.png

XMN is accessible for buying and selling!

October 10, 2025
0 3.png

College endowments be a part of crypto rush, boosting meme cash like Meme Index

February 10, 2025

EDITOR'S PICK

Not all recsys problems are created equal featured image 1.png

Not All RecSys Issues Are Created Equal

February 12, 2026
Goldman sachs bitcoinetf.jpg

Goldman Sachs discloses practically $420 million in Bitcoin ETF holdings

August 14, 2024
01988c26 526f 7665 8fee 1136ab5cd884.jpeg

Ether Quick Wipeout Amid $4K Reclaim Led To Eric Trump Smiling

August 9, 2025
1 Fesfrrh6hoh1mxvxkyjkma.webp.webp

LLaDA: The Diffusion Mannequin That May Redefine Language Era

February 27, 2025

About Us

Welcome to News AI World, your go-to source for the latest in artificial intelligence news and developments. Our mission is to deliver comprehensive and insightful coverage of the rapidly evolving AI landscape, keeping you informed about breakthroughs, trends, and the transformative impact of AI technologies across industries.

Categories

  • Artificial Intelligence
  • ChatGPT
  • Crypto Coins
  • Data Science
  • Machine Learning

Recent Posts

  • Measuring Efficiency of Transformer Inference
  • Bitcoin futures carry tops Treasury yield in matched CME verify
  • Find out how to Successfully Deploy Code With Claude Code
  • Home
  • About Us
  • Contact Us
  • Disclaimer
  • Privacy Policy

© 2024 Newsaiworld.com. All rights reserved.

No Result
View All Result
  • Home
  • Artificial Intelligence
  • ChatGPT
  • Data Science
  • Machine Learning
  • Crypto Coins
  • Contact Us

© 2024 Newsaiworld.com. All rights reserved.

Are you sure want to unlock this post?
Unlock left : 0
Are you sure want to cancel subscription?