[QNN] 16a8w: gathered tensor read wrong by a consumer that only feeds a graph output
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 48/100
- issue の種類
- バグ
- 明瞭さ
- おおむね明確
- 活発さ
- 活発
調査の方向性
Start with the provided reproducer and run rope_gather.pte with the three raw inputs, comparing output 2 with expected_out2.npy; the report says the QDQ host output is accurate while the deployed QNN output is wrong. Trace how gathered tensors reach their last consumer when that consumer feeds only a graph output, and compare with output 0, which also feeds a bmm. Done when the graph output matches the expected result and the unaffected cases remain correct.
索引モデルが issue の本文から書いたものです。
説明
🐛 Describe the bug
In a 16a8w HTP graph, a tensor gathered in-graph (table[pos]) is read wrong by its last consumer when that consumer's result only feeds a graph output. Below, cos/sin are gathered once and used by two RoPEs: output 0 (which also feeds a bmm) is correct, output 2 is not (rel err 0.77 vs 0.0017 for the QDQ module on host). Position p gets row p % 40 for most rows.
Not affected: the same graph in fp16, passing cos/sin as inputs instead of gathering them, or a single RoPE. We hit it in a TTS model where the last layer's keys are a method output; returning one more tensor computed from them works around it.
import numpy as np
import torch
from executorch.backends.qualcomm.export_utils import make_quantizer
from executorch.backends.qualcomm.quantizer.quantizer import QuantDtype
from executorch.backends.qualcomm.serialization.qc_schema import QcomChipset
from executorch.backends.qualcomm.utils.utils import (
generate_htp_compiler_spec, generate_qnn_executorch_compiler_spec, to_edge_transform_and_lower_to_qnn)
from torchao.quantization.pt2e.quantize_pt2e import convert_pt2e, prepare_pt2e
H, N, D = 6, 320, 128
def rope(x, cos, sin):
return x * cos + torch.cat([-x[..., D // 2:], x[..., :D // 2]], -1) * sin
class M(torch.nn.Module):
def __init__(self):
super().__init__()
ang = torch.arange(2048).float()[:, None] / 1e6 ** (torch.arange(0, D, 2).float() / D)
self.register_buffer("cos_t", torch.cat([ang.cos(), ang.cos()], -1))
self.register_buffer("sin_t", torch.cat([ang.sin(), ang.sin()], -1))
def forward(self, x0, x1, pos):
cos, sin = self.cos_t[pos.long()], self.sin_t[pos.long()]
k0 = rope(x0, cos, sin)
# k0 also feeds a bmm; k1 feeds only the graph output and comes out wrong
return k0, torch.bmm(k0, x0.transpose(1, 2)), rope(x1, cos, sin)
torch.manual_seed(0)
sample = lambda: (torch.randn(H, N, D) * 3, torch.randn(H, N, D) * 3, torch.arange(N, dtype=torch.int32)) # noqa: E731
m, ex = M().eval(), sample()
q = prepare_pt2e(torch.export.export(m, ex).module(), make_quantizer(quant_dtype=QuantDtype.use_16a8w, soc_model="SM8850"))
for _ in range(8):
q(*sample())
q = convert_pt2e(q)
specs = generate_qnn_executorch_compiler_spec(soc_model=QcomChipset.SM8850,
backend_options=generate_htp_compiler_spec(use_fp16=False))
with open("rope_gather.pte", "wb") as f:
f.write(to_edge_transform_and_lower_to_qnn(q, ex, specs).to_executorch().buffer)
for i, t in enumerate(ex):
t.numpy().tofile(f"input_{i}.raw")
np.save("expected_out2.npy", m(*ex)[2].numpy())
print("QDQ rel err of output 2:", float((q(*ex)[2] - m(*ex)[2]).norm() / m(*ex)[2].norm()))
Run rope_gather.pte with the three inputs and compare output 2 with expected_out2.npy.
Versions
ExecuTorch 1.4.1 (our fork of v1.4.1, not yet checked on main), QAIRT 2.47.0.260601, SM8850 (Galaxy S26 Ultra, HTP v81).
- 主要言語
- Python
- スター
- 5.1k
- フォーク
- 1.2k
- 平均マージ
- 1日 16時間
- マージ済み PR(30日)
- 621
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
pytorch/executorch のほかの issue
-
Windows: _get_flatc_path() looks for data/bin/flatc but the wheel ships flatc.exe (WinError 2)対応中かも @JacobSzwejbka が 4 日前に担当しました。 オープンbug module: exir triaged
難易度 2/5 1〜3時間 初心者へのやさしさ 83/100
pytorch/executorch#23989 · リアクション 1 件 · 担当者 3 名 ·
メンテナーはふだん 1 日以内に返信
-
Portable remainder kernel: wrong sign for integers and float64 rounded to float対応中かも @JakeStevens が 13 日前に担当しました。 オープンbug module: kernels triaged
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
pytorch/executorch#23682 · 担当者 2 名 ·
メンテナーはふだん 1 日以内に返信
-
enhancement triaged
難易度 2/5 半日 初心者へのやさしさ 68/100
pytorch/executorch#21640 ·
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 20/100
pytorch/executorch#24106 ·
メンテナーはふだん 1 日以内に返信
-
Arm/TOSA: allow int64 through when the spec declares the int64 extension対応中かも @abm-77 が 2 日前に担当しました。 オープンbug module: arm partner: arm
難易度 4/5 3〜5日 初心者へのやさしさ 54/100
pytorch/executorch#24095 · コメント 4 件 ·
メンテナーはふだん 1 日以内に返信
pytorch/executorch の issue をすべて見る
似ている issue
-
link-rot
難易度 1/5 1時間未満 初心者へのやさしさ 67/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
developmentseed/titiler-cmr#265 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
Insecure Brotli version <1.2.1対応中かも @jamescw19 が今日担当しました。 オープン
難易度 1/5 1時間未満 初心者へのやさしさ 85/100
stac-utils/stac-fastapi-pgstac#438 · リアクション 1 件 ·
-
bug triage
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
メンテナーはふだん 1 日以内に返信