Skip to content

Commit 59a7ca2

Browse files
Merge pull request #1148 from qualcomm/fix/bench-prefill-padding
fix(sdk): report qairt prefill rate over padded prompt length
2 parents 95abcb6 + 7ad2063 commit 59a7ca2

2 files changed

Lines changed: 28 additions & 0 deletions

File tree

sdk/benchmark/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ Run `geniex-bench --help` for the full flag list.
144144
yields meaningless text.
145145
- llama_cpp gets a `[warmup=i]` / `[run=i]` suffix appended to the prompt
146146
so the KV cache is busted between runs
147+
- for `--plugin qairt`, `prompt_tokens` and `prefill_tps` are reported over the
148+
padded prompt length `ceil(prompt_tokens / 128) * 128`: the QAIRT engine pads
149+
input_ids to a 128-token prefill chunk, so the padded count reflects the work
150+
actually done (#1194). llama_cpp does no such padding and is reported as-is
147151

148152
## Per-cell JSON shape
149153

sdk/benchmark/benchmark.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ static const char* const VLM_DEFAULT_PROMPT = "Describe the image.";
6060

6161
#define MAX_PATHS 16
6262

63+
/* QAIRT prefill chunk size: the engine pads input_ids up to the next multiple
64+
* of this before running prefill, so the real prefill work (and thus the honest
65+
* tokens/sec) is over the padded length, not the raw prompt length. llama_cpp
66+
* has no such padding and is left untouched. See qcom-ai-hub/geniex#1194. */
67+
#define QAIRT_PREFILL_CHUNK 128
68+
6369
typedef struct {
6470
const char* plugin;
6571
const char* device;
@@ -136,6 +142,19 @@ typedef struct {
136142
char err[256];
137143
} run_result_t;
138144

145+
/* Adjust the reported prefill metrics for the engine's real prefill work.
146+
* QAIRT pads the prompt to a QAIRT_PREFILL_CHUNK multiple before prefill, so
147+
* prompt_tokens/prefill_tps should reflect that padded length (#1194); QAIRT's
148+
* prompt_time equals ttft, so recomputing the rate over the padded count keeps
149+
* rate == prompt_tokens / prompt_time consistent. llama_cpp does no such
150+
* padding, so its metrics are left as the SDK reported them. */
151+
static void normalize_prefill_metrics(run_result_t* r, const char* plugin) {
152+
if (!plugin || strcmp(plugin, "qairt") != 0 || r->prompt_tokens <= 0) return;
153+
int64_t padded = ((r->prompt_tokens + QAIRT_PREFILL_CHUNK - 1) / QAIRT_PREFILL_CHUNK) * QAIRT_PREFILL_CHUNK;
154+
r->prompt_tokens = padded;
155+
r->prefill_tps = r->prompt_time_us > 0 ? (double)padded / ((double)r->prompt_time_us / 1e6) : 0.0;
156+
}
157+
139158
static void die(int32_t code, const char* what) {
140159
const char* msg = geniex_get_error_message((geniex_ErrorCode)code);
141160
fprintf(stderr, "ERROR: %s: %s (code=%d)\n", what, msg ? msg : "?", code);
@@ -206,6 +225,9 @@ static void usage(const char* argv0) {
206225
" only way to bench plugins that don't support\n"
207226
" input_ids (today: qairt). With this flag, reported\n"
208227
" `pp` is the tokenizer's count, NOT --n-prompt.\n"
228+
" For qairt, `pp` and prefill tok/s are reported over\n"
229+
" the padded length ceil(pp/128)*128, matching the\n"
230+
" engine's 128-token prefill chunking (#1194).\n"
209231
" --no-reset-between-runs\n"
210232
" keep KV cache across measured runs (default is\n"
211233
" to call geniex_llm_reset() before every run so\n"
@@ -1054,6 +1076,7 @@ static void run_llm(const options_t* o, const char* device_id, int32_t ngl, run_
10541076
r->decode_tps = gout.profile_data.decoding_speed;
10551077
r->stop_reason = gout.profile_data.stop_reason;
10561078
r->status = 0;
1079+
normalize_prefill_metrics(r, o->plugin);
10571080
}
10581081

10591082
if (!is_warmup && o->accuracy && gout.full_text) {
@@ -1138,6 +1161,7 @@ static void run_vlm(const options_t* o, const char* device_id, int32_t ngl, run_
11381161
r->decode_tps = gout.profile_data.decoding_speed;
11391162
r->stop_reason = gout.profile_data.stop_reason;
11401163
r->status = 0;
1164+
normalize_prefill_metrics(r, o->plugin);
11411165
}
11421166

11431167
if (!is_warmup && o->accuracy && gout.full_text) {

0 commit comments

Comments
 (0)