Vulkan: how much of each LeRobot policy the Vulkan backend takes, and what blocks the rest
Les mainteneurs répondent en général sous 1 jour
@SS-JIA y travaille déjà.
Depuis le 5/11/2026.
Évaluation
Cette issue n'a pas encore été évaluée.
Description
This issue tracks LeRobot policies exported to ExecuTorch with its Vulkan GPU backend (VulkanPartitioner): how much of each policy Vulkan takes, whether the program exports, and what each project still needs to look at. Other backends have their own issues: TensorRT in #24353, OpenVINO in #24325, XNNPACK in #24667, Qualcomm in #24668, Core ML and MLX in #24669, the CUDA backend in #24684, and Arm in #24697.
Why this matters for LeRobot: Vulkan is a GPU path for boards with no CUDA and no NPU that ExecuTorch supports, for example the Arm Mali GPU on RK3588 boards. ExecuTorch's Vulkan backend is built mainly for Android GPUs, so a board running Linux is on the less tested path. It can also use the Adreno GPU in Qualcomm chips, which also have a Hexagon NPU (see #24668). On NVIDIA GPUs, TensorRT or the CUDA backend is the main path, so the H100 column here only checks correctness. No Mali or Adreno device has been tested yet.
Coverage
| Policy | Ops on Vulkan | Heavy math on Vulkan | Vulkan programs | Exports to .pte | H100 (correctness) |
|---|---|---|---|---|---|
| act | 1556 / 1561 (100%) | 100% | 3 | $\color{#2da44e}{\checkmark}$ | $\color{#2da44e}{\checkmark}$ 88.7 (1.0x) |
| diffusion | 534 / 619 (86%) | 94% | 50 | $\color{#2da44e}{\checkmark}$ | ❌ |
| dm05 | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ |
| eo1 | 20136 / 56586 (36%) | 1% | at least 1987 | $\color{#d4a017}{\textsf{slow}}$ | ⏳ |
| evo1 | 13904 / 16601 (84%) | 26% | 61 | $\color{#d4a017}{\textsf{slow}}$ | ⏳ |
| fastwam | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ |
| fineart_vla | 21670 / 21704 (100%) | 100% | 6 | $\color{#d4a017}{\textsf{slow}}$ | ❌ |
| flux3 | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ |
| gaussian_actor | 114 / 127 (90%) | 100% | 5 | $\color{#2da44e}{\checkmark}$ | $\color{#2da44e}{\checkmark}$ 1.14 (1.9x) |
| groot | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ |
| lawam | 15409 / 18124 (85%) | 44% | at least 198 | $\color{#d4a017}{\textsf{slow}}$ | ⏳ |
| lingbot_va | 3998 / 10375 (39%) | 10% | at least 688 | $\color{#d4a017}{\textsf{slow}}$ | ⏳ |
| lingbot_vla_v2 | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ |
| molmoact2 | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ |
| multi_task_dit | 1460 / 1463 (100%) | 100% | 5 | $\color{#2da44e}{\checkmark}$ | $\color{#2da44e}{\checkmark}$ 774 (3.9x) |
| pi0 | 5624 / 5654 (99%) | 100% | 17 | $\color{#2da44e}{\checkmark}$ | ❌ |
| pi05 | ❌ | ❌ | ❌ | ❌ | - |
| pi0_fast | 9059 / 9082 (100%) | 100% | 11 | $\color{#2da44e}{\checkmark}$ | ❌ |
| smolvla | 2933 / 7163 (41%) | 16% | 209 | $\color{#2da44e}{\checkmark}$ | ❌ |
| tdmpc | 5477 / 5895 (93%) | 100% | 140 | $\color{#2da44e}{\checkmark}$ | $\color{#2da44e}{\checkmark}$ 494 (0.9x) |
| vla_jepa | 7049 / 10817 (65%) | 6% | 191 | $\color{#d4a017}{\textsf{slow}}$ | ⏳ |
| vqbet | 567 / 594 (95%) | 23% | 22 | $\color{#2da44e}{\checkmark}$ | $\color{#2da44e}{\checkmark}$ 1241 (0.02x) |
| wall_oss_05 | 36455 / 87088 (42%) | 4% | at least 2752 | $\color{#d4a017}{\textsf{slow}}$ | ⏳ |
| wall_x | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ |
| xvla | 16565 / 16643 (100%) | 99% | 61 | $\color{#d4a017}{\textsf{slow}}$ | $\color{#2da44e}{\checkmark}$ 6568 (0.5x) |
Legend:
- "Ops on Vulkan": the graph ops that
VulkanPartitioner()takes, out of all ops, over all programs of the policy. Ops are counted afterto_edge, so a linear layer counts as a matmul and a transpose. - "Heavy math on Vulkan": the share of multiply-adds in matmuls, linear layers, convolutions and attention that Vulkan takes. A program counts as many times as one action chunk runs it (for example, once per denoising step).
- "Vulkan programs": how many Vulkan partitions the policy is split into. Between 2 partitions, the data goes back to the CPU. "At least N" means partitioning itself did not finish within 15 minutes; N is the number of connected groups of ops that Vulkan takes, a lower bound.
- "Exports to .pte": $\color{#2da44e}{\checkmark}$ means
to_edge_transform_and_lower(...).to_executorch()finished with the default options. $\color{#d4a017}{\textsf{slow}}$ means the export did not finish within 15 minutes; a longer run is queued. ❌ means it fails; the cause is in the tables below. - "H100 (correctness)": the bundle run with
lerobot-rollout --bundle.pathon an H100 through its Vulkan driver, with PyTorch never loaded. $\color{#2da44e}{\checkmark}$ means it passed the export's own accuracy check and, for policies without a frame history, a 16-frame comparison against eager PyTorch. The number is milliseconds per action chunk (batch size 1, median). In brackets: how many times faster than eager PyTorch (lerobot-rollout --policy.path --device=cpu) on 16 CPU cores of the same machine, because a Vulkan bundle takes its inputs and returns its outputs on the CPU. Ops that Vulkan does not take run on ExecuTorch's portable CPU kernels, which are slow, so a bundle with heavy ops left on the CPU can be much slower than eager (vqbet). -: not measured, because an earlier step fails.- ⏳: this cell is being measured (running or queued).
Notes:
- The ExecuTorch 1.6.0 wheel has the Vulkan partitioner but not the Vulkan runtime. For the H100 column, ExecuTorch 1.6.0 was built from source with the Vulkan backend on (
EXECUTORCH_BUILD_VULKAN=1, shaders compiled withglslcfrom conda-forge's shaderc, as ExecuTorch's CI does) and with the event tracer off (ExecuTorch table). - LeRobot has no Vulkan backend for
lerobot-exportyet (LeRobot table). So each policy is traced with the trace step oflerobot-export(same checkpoint, task and export flags as the XNNPACK rows of #24667 and the OpenVINO rows of #24325), and each traced program is lowered the waylerobot-exportlowers for its ExecuTorch backends, withVulkanPartitioner()and its default options. - diffusion, dm05, eo1, fineart_vla, gaussian_actor, lingbot_vla_v2, molmoact2, multi_task_dit, tdmpc, vla_jepa, vqbet and wall_x use random weights, made by the same script and seed as in #24353. The other policies use their real weights.
- With
force_fp16(run inside the backend in fp16), act, diffusion, gaussian_actor, multi_task_dit, pi0_fast, smolvla and vqbet also export. It does not change what the partitioner takes. - evo1 keeps its bf16 weights, so its vision-language part stays on the CPU (first ExecuTorch row).
- pi0 and pi05 checkpoints use the SigLIP weight names of transformers before 5.22, which the branch cannot load yet (LeRobot table). The pi0 row uses the same pi0 weights re-saved under the new names, which does not change the graph. pi05 is not measured yet.
Built on
- ExecuTorch: the official 1.6.0 CPU wheel (the final release). Its
backends/vulkanPython code is what was measured. No source build and no patches. - torch 2.15.0, transformers 5.22.1.
- LeRobot: the
lerobot-export-stackbranch of shoumikhin/lerobot, as it was on Nov 3 at 10:53 AM Pacific (see #24353). - GPU (for the correctness column): H100, NVIDIA driver 580, Vulkan 1.4.
Known issues
"Fix" is an open pull request unless it says merged. "Needs a decision" is a design question for the maintainers. "Needs an owner" means nobody is fixing it yet.
ExecuTorch
- Pick up the rows marked "needs an owner". bf16 (first row) and batched convolutions (second row) cost the most heavy math.
- Every row has a short repro below the table. Repros 1 to 4 need only the ExecuTorch 1.6.0 wheel and no GPU. Repros 5 and 6 need ExecuTorch built with Vulkan, and a GPU.
| Problem | Policies | Fix | Status |
|---|---|---|---|
No bf16. torch.bfloat16 is not in the backend's dtype table (_VULKAN_DTYPES in backends/vulkan/utils.py), so every bf16 op stays on the CPU with "dtype not supported". |
evo1 (74% of its heavy math stays on the CPU), smolvla (84%), vla_jepa (94%), eo1 (99%), wall_oss_05 (96%) | needs a decision: support bf16, or run bf16 programs in fp16 or fp32 inside the backend | Repro ready (repro 1) |
A 4D convolution is taken only with batch size 1 (check_conv_node in backends/vulkan/op_registry.py). Policies that encode 2 or more frames or cameras as one batch keep their image encoder on the CPU. |
vqbet (77% of its heavy math stays on the CPU), diffusion, xvla, multi_task_dit | needs an owner | Repro ready (repro 2) |
No Vulkan kernel for elu, log1p (used by Mish through softplus), var, index_put, or transposed 1D convolution. Each one cuts the graph into more Vulkan programs. |
tdmpc (elu 181 times, log1p 150, var 36), diffusion (log1p 38, transposed conv1d 2), xvla (index_put 21) | needs an owner | Repro ready (repro 3) |
Partitioning big graphs is very slow. VulkanPartitioner uses torch.fx's CapabilityBasedPartitioner, and its merge step grows much faster than the graph. tdmpc (5,895 ops) takes 603 s to partition and ends with 140 Vulkan programs, while its supported ops form only 41 connected groups. |
tdmpc, evo1, xvla, and the larger policies | needs an owner | Repro ready (repro 4): 200 blocks take 13 s, 400 blocks take 95 s |
With the event tracer on, which the Python wheel's build preset turns on (tools/cmake/preset/pybind.cmake), the Vulkan runtime writes 2 GPU timestamps per dispatch into a query pool of 4,096 (VULKAN_QUERY_POOL_SIZE). A program with more than about 2,000 dispatches stops with "Vulkan QueryPool: Exceeded the maximum number of queries". |
act (from Python) | needs an owner: use the query pool only when profiling is asked for, or let it grow | Repro ready (repro 5): 1,000 steps run, 1,500 steps stop; with -DEXECUTORCH_ENABLE_EVENT_TRACER=OFF, 4,000 steps run |
| GroupNorm on a 3D input (batch, channels, length) gives wrong values with no error: the largest difference from eager PyTorch is 7.9 to 10.5 for the 5 shapes tried. The same GroupNorm on a 4D input is right. diffusion's 1D U-Net uses it in every denoising step. | diffusion (on the H100 its export check gives 1.79, limit 2e-05; with GroupNorm kept on the CPU, its step program matches eager PyTorch to 3e-06) | needs an owner: fix the kernel, or have the partitioner refuse 3D inputs until then | Repro ready (repro 6) |
x[idx] (aten.index.Tensor) on an int64 or int32 tensor is taken by the partitioner, but the runtime has no shader for it, so the program fails to load with Could not find ShaderInfo with name index_tensor_buffer_buffer_int32. The op is registered for float and int dtypes (register_index_tensor in backends/vulkan/op_registry.py), while index_tensor_buffer.yaml and index_tensor_texture.yaml build only half and float. |
pi0_fast (its prefill program does not load on the H100), fineart_vla (same, for its model program) | needs an owner: add int variants of the shader, or register the op for float dtypes only | Repro ready (repro 7) |
A Vulkan program whose output is a copy of a constant returns zeros, or the data of another tensor, with no error. The backend's RemoveRedundantOpsTransform (backends/vulkan/_passes/remove_redundant_ops.py) removes the clone, so the constant itself becomes the program output, and it looks like the runtime never copies it into the output. This happens for bool, float32 and int32. |
pi0 (its first program returns an all-False attention mask, so the export check gives 1.07, limit 2e-05; every other pi0 program matches eager PyTorch to 4e-05) | needs an owner: keep the copy when its input is a constant, or have the partitioner leave such a clone on the CPU | Repro ready (repro 8) |
The RMSNorm fusion (backends/vulkan/patterns/rms_norm.py) accepts any tensor as the scale, but the fused op needs a constant weight when the program loads. When the norm weight is bf16 and the input is fp32, the weight reaches the Vulkan program through a cast that stays on the CPU (bf16 is not supported), so it arrives as a plain input, and the program fails to load with (graph.val_is_tref(tensor_data)) is false in prepack_standard. |
smolvla (its language model program does not load on the H100) | needs an owner: fuse only when the scale is a constant | Repro ready (repro 9) |
Repros (export only, ExecuTorch 1.6.0, torch 2.15.0)
import time
import torch
from executorch.backends.vulkan.partitioner.vulkan_partitioner import VulkanPartitioner
from executorch.exir import to_edge, to_edge_transform_and_lower
def lowered(model, *inputs):
"""How many Vulkan programs the model lowers to, and which ops stay on the CPU."""
edge = to_edge_transform_and_lower(torch.export.export(model.eval(), inputs), partitioner=[VulkanPartitioner()])
nodes = [n for n in edge.exported_program().graph.nodes if n.op == "call_function"]
names = [getattr(n.target, "__name__", str(n.target)) for n in nodes]
vulkan = names.count("executorch_call_delegate")
cpu = sorted({name for name in names if name not in ("executorch_call_delegate", "getitem")})
return vulkan, cpu
class Fn(torch.nn.Module):
def __init__(self, fn):
super().__init__()
self.fn = fn
def forward(self, x):
return self.fn(x)
def case(label, model, *inputs):
print(f"{label:44s} -> Vulkan programs, CPU ops: {lowered(model, *inputs)}")
# 1. bf16: no op is delegated.
case("Linear float32", torch.nn.Linear(64, 64), torch.randn(4, 64))
case("Linear bfloat16", torch.nn.Linear(64, 64).to(torch.bfloat16), torch.randn(4, 64, dtype=torch.bfloat16))
# 2. A 4D convolution is taken only with batch size 1.
case("Conv2d batch 1", torch.nn.Conv2d(3, 8, 3), torch.randn(1, 3, 32, 32))
case("Conv2d batch 2", torch.nn.Conv2d(3, 8, 3), torch.randn(2, 3, 32, 32))
# 3. Ops with no Vulkan kernel.
x = torch.randn(1, 16, 32)
case("ELU", torch.nn.ELU(), x)
case("Mish (softplus -> log1p)", torch.nn.Mish(), x)
case("var", Fn(lambda t: t.var(dim=-1, keepdim=True)), x)
case("ConvTranspose1d", torch.nn.ConvTranspose1d(16, 8, 4, stride=2, padding=1), x)
class Put(torch.nn.Module):
def forward(self, t, idx):
y = t.clone()
y[idx] = 0.0
return y
case("index_put (y[idx] = 0)", Put(), torch.randn(8, 32), torch.tensor([1, 3]))
# 4. Partitioning time grows fast with graph size when CPU ops sit on side branches.
class Blocks(torch.nn.Module):
def __init__(self, n):
super().__init__()
self.layers = torch.nn.ModuleList(torch.nn.Linear(32, 32) for _ in range(n))
def forward(self, x):
for layer in self.layers:
a = layer(x)
x = a * torch.sigmoid(a) + torch.nn.functional.elu(a) # elu stays on the CPU
return x
for n in (50, 100, 200, 400):
ep = to_edge(torch.export.export(Blocks(n).eval(), (torch.randn(1, 32),))).exported_program()
start = time.time()
tags = VulkanPartitioner().partition(ep).partition_tags
print(f"{n:4d} blocks: {len(tags):4d} Vulkan partitions, partition() took {time.time() - start:6.1f} s")
Output:
Linear float32 -> Vulkan programs, CPU ops: (1, [])
Linear bfloat16 -> Vulkan programs, CPU ops: (0, ['aten.addmm.default', 'aten.permute_copy.default'])
Conv2d batch 1 -> Vulkan programs, CPU ops: (1, [])
Conv2d batch 2 -> Vulkan programs, CPU ops: (0, ['aten.convolution.default'])
ELU -> Vulkan programs, CPU ops: (0, ['aten.elu.default'])
Mish (softplus -> log1p) -> Vulkan programs, CPU ops: (2, ['aten.log1p.default'])
var -> Vulkan programs, CPU ops: (0, ['aten.var.correction'])
ConvTranspose1d -> Vulkan programs, CPU ops: (0, ['aten.convolution.default'])
index_put (y[idx] = 0) -> Vulkan programs, CPU ops: (1, ['aten.index_put.default'])
50 blocks: 51 Vulkan partitions, partition() took 2.6 s
100 blocks: 101 Vulkan partitions, partition() took 3.8 s
200 blocks: 201 Vulkan partitions, partition() took 13.1 s
400 blocks: 401 Vulkan partitions, partition() took 94.7 s
Repro 5 (needs ExecuTorch 1.6.0 built with Vulkan, and a GPU)
import sys
import torch
from executorch.backends.vulkan.partitioner.vulkan_partitioner import VulkanPartitioner
from executorch.exir import to_edge_transform_and_lower
from executorch.runtime import Runtime
class Many(torch.nn.Module):
def __init__(self, n):
super().__init__()
self.n = n
def forward(self, x):
for i in range(self.n):
x = x * 1.0001 + 0.001 # 2 dispatches per step
return x
for n in [int(a) for a in sys.argv[1:]] or [500, 1000, 2000]:
x = torch.randn(1, 64)
et = to_edge_transform_and_lower(torch.export.export(Many(n), (x,)), partitioner=[VulkanPartitioner()]).to_executorch()
method = Runtime.get().load_program(et.buffer).load_method("forward")
try:
out = method.execute([x])[0]
print(n, "steps: ok, max abs diff", (out - Many(n)(x)).abs().max().item())
except RuntimeError as error:
print(n, "steps: RuntimeError:", str(error).split("\n")[0][:200])
Output on an H100:
# built with the event tracer on (the default of the Python wheel's build preset)
500 steps: ok, max abs diff 0.0
1000 steps: ok, max abs diff 0.0
1500 steps: RuntimeError: Exception raised from write_timestamp at .../backends/vulkan/runtime/vk_api/QueryPool.cpp:79: (num_queries_ < config_.max_query_count) is false! ...
2000 steps: RuntimeError: (same)
# built with -DEXECUTORCH_ENABLE_EVENT_TRACER=OFF
1500 steps: ok, max abs diff 0.0
4000 steps: ok, max abs diff 0.0
Repro 6 (needs ExecuTorch 1.6.0 built with Vulkan, and a GPU)
import torch
from executorch.backends.vulkan.partitioner.vulkan_partitioner import VulkanPartitioner
from executorch.exir import to_edge_transform_and_lower
from executorch.runtime import Runtime
torch.manual_seed(0)
for groups, channels, shape in [(8, 64, (1, 64, 16)), (8, 512, (1, 512, 16)), (8, 1024, (1, 1024, 8)), (8, 2048, (1, 2048, 4)),
(8, 512, (1, 512, 4, 4)), (32, 512, (1, 512, 16))]:
m = torch.nn.GroupNorm(groups, channels).eval()
with torch.no_grad():
m.weight.normal_()
m.bias.normal_()
x = torch.randn(*shape)
et = to_edge_transform_and_lower(torch.export.export(m, (x,)), partitioner=[VulkanPartitioner()]).to_executorch()
out = Runtime.get().load_program(et.buffer).load_method("forward").execute([x])[0]
ref = m(x)
print(f"GroupNorm({groups}, {channels}) on {tuple(shape)}: max abs diff {(out - ref).abs().max().item():.2e}")
Output on an H100:
GroupNorm(8, 64) on (1, 64, 16): max abs diff 9.20e+00
GroupNorm(8, 512) on (1, 512, 16): max abs diff 1.05e+01
GroupNorm(8, 1024) on (1, 1024, 8): max abs diff 7.85e+00
GroupNorm(8, 2048) on (1, 2048, 4): max abs diff 8.08e+00
GroupNorm(8, 512) on (1, 512, 4, 4): max abs diff 9.54e-07
GroupNorm(32, 512) on (1, 512, 16): max abs diff 9.56e+00
Repro 7 (needs ExecuTorch 1.6.0 built with Vulkan, and a GPU)
import torch
from executorch.backends.vulkan.partitioner.vulkan_partitioner import VulkanPartitioner
from executorch.exir import to_edge_transform_and_lower
from executorch.runtime import Runtime
class Index(torch.nn.Module):
def forward(self, x, idx):
return x[idx]
for dtype in (torch.float32, torch.int64, torch.int32, torch.bool):
x = (torch.randn(8, 16) * 10).to(dtype)
idx = torch.tensor([1, 3, 5])
try:
edge = to_edge_transform_and_lower(torch.export.export(Index(), (x, idx)), partitioner=[VulkanPartitioner()])
names = [getattr(n.target, "__name__", "") for n in edge.exported_program().graph.nodes if n.op == "call_function"]
method = Runtime.get().load_program(edge.to_executorch().buffer).load_method("forward")
out = method.execute([x, idx])[0]
print(f"{str(dtype):14s} delegated={names.count('executorch_call_delegate')} ok={torch.equal(out, x[idx])}")
except Exception as error:
print(f"{str(dtype):14s} {type(error).__name__}: {str(error).splitlines()[0].split('!')[-1].strip()[:120]}")
Output on an H100:
torch.float32 delegated=1 ok=True
torch.int64 RuntimeError: Could not find ShaderInfo with name index_tensor_buffer_buffer_int32
torch.int32 RuntimeError: Could not find ShaderInfo with name index_tensor_buffer_buffer_int32
torch.bool delegated=0 ok=True
Repro 8 (needs ExecuTorch 1.6.0 built with Vulkan, and a GPU)
import torch
from executorch.backends.vulkan.partitioner.vulkan_partitioner import VulkanPartitioner
from executorch.exir import to_edge_transform_and_lower
from executorch.runtime import Runtime
class Mask(torch.nn.Module):
def __init__(self, dtype):
super().__init__()
self.register_buffer("mask", (torch.arange(12) % 3 != 0).reshape(1, 12).to(dtype))
def forward(self, x):
return self.mask.clone(), x + 1
for dtype in (torch.bool, torch.float32, torch.int32):
m = Mask(dtype)
x = torch.randn(1, 12)
edge = to_edge_transform_and_lower(torch.export.export(m, (x,)), partitioner=[VulkanPartitioner()])
names = [getattr(n.target, "__name__", "") for n in edge.exported_program().graph.nodes if n.op == "call_function"]
out = Runtime.get().load_program(edge.to_executorch().buffer).load_method("forward").execute([x])[0]
print(f"{str(dtype):14s} delegated={names.count('executorch_call_delegate')} got={out.int().tolist()[0]} want={m.mask.int().tolist()[0]}")
Output on an H100:
torch.bool delegated=1 got=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] want=[0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1]
torch.float32 delegated=1 got=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] want=[0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1]
torch.int32 delegated=1 got=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] want=[0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1]
Repro 9 (needs ExecuTorch 1.6.0 built with Vulkan, and a GPU)
import torch
from executorch.backends.vulkan.partitioner.vulkan_partitioner import VulkanPartitioner
from executorch.exir import to_edge_transform_and_lower
from executorch.runtime import Runtime
class Rms(torch.nn.Module):
def __init__(self, scale):
super().__init__()
self.scale = scale
self.weight = torch.nn.Parameter(torch.randn(64).to(torch.bfloat16 if scale == "bf16 weight" else torch.float32))
def forward(self, x, s):
norm = x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + 1e-6)
return norm * (s if self.scale == "input" else self.weight)
x, s = torch.randn(1, 8, 64), torch.randn(1, 8, 64)
for scale in ("fp32 weight", "bf16 weight", "input"):
m = Rms(scale).eval()
try:
et = to_edge_transform_and_lower(torch.export.export(m, (x, s)), partitioner=[VulkanPartitioner()]).to_executorch()
out = Runtime.get().load_program(et.buffer).load_method("forward").execute([x, s])[0]
print(f"scale is {scale}: loads, max abs diff {(out - m(x, s)).abs().max().item():.2e}")
except Exception as error:
print(f"scale is {scale}: fails to load, {str(error).split('!')[0].split('Staging.cpp:')[-1][4:]}")
Output on an H100:
scale is fp32 weight: loads, max abs diff 2.38e-07
scale is bf16 weight: fails to load, (graph.val_is_tref(tensor_data)) is false
scale is input: fails to load, (graph.val_is_tref(tensor_data)) is false
LeRobot
- Decide the rows marked "needs a decision".
| Problem | Policies | Fix | Status |
|---|---|---|---|
lerobot-export has no Vulkan backend, so there is no Vulkan bundle for lerobot-rollout --bundle.path to run. |
all | needs a decision: an executorch_vulkan backend in LeRobot, next to executorch_xnnpack and executorch_openvino |
Open |
lerobot-export and the torch-free lerobot-rollout --bundle.path exist only on the lerobot-export-stack branch. |
all | needs a decision: how to bring them upstream in reviewable pieces (same row as #24684) | Open |
With transformers 5.22, a pi0 or pi05 checkpoint saved with older SigLIP weight names does not load: model.safetensors does not hold model.paligemma_with_expert.paligemma.model.vision_tower.embeddings.patch_embedding.weight and 436 more. |
pi0, pi05 | huggingface/lerobot#4775 | Open |
cc @SS-JIA @manuelcandales @digantdesai @cbilgin
- Langage dominant
- Python
- Étoiles
- 5.2k
- Forks
- 1.2k
- Merge moyen
- 1 j 23 h
- PR mergées (30 j)
- 696
Préparer son environnement
- Aucun Dockerfile ni fichier Docker Compose
- Propose un modèle de pull request
- Lire le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de pytorch/executorch
-
Difficulté 2/5 1-3 heures Accessibilité débutants 74/100
pytorch/executorch#24434 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 82/100
pytorch/executorch#24410 ·
Les mainteneurs répondent en général sous 1 jour
-
enhancement triaged
Difficulté 2/5 Une demi-journée Accessibilité débutants 68/100
pytorch/executorch#21640 ·
Les mainteneurs répondent en général sous 1 jour
-
Qualcomm AI Engine Direct: HTP float16 Concat reads a static bool input of all True as FalseOuvertemodule: qnn partner: qualcomm
Difficulté 4/5 3-5 jours Accessibilité débutants 45/100
pytorch/executorch#24750 ·
Les mainteneurs répondent en général sous 1 jour
-
module: qnn partner: qualcomm
Difficulté 4/5 3-5 jours Accessibilité débutants 48/100
pytorch/executorch#24749 ·
Les mainteneurs répondent en général sous 1 jour
Toutes les issues de pytorch/executorch
Issues similaires
-
[BUG]: Compliance rules never see Unity Catalog views as viewsPeut-être pris @wagnercsantos l’a pris aujourd’hui. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
databrickslabs/ontos#1348 ·
Les mainteneurs répondent en général sous 3 jours
-
Difficulté 2/5 1-3 heures Accessibilité débutants 76/100
ibm-granite/granite.build#649 ·
Les mainteneurs répondent en général sous 1 jour
-
`forum_pr_poster` action will always return `none` when checking for pre-existing feedback threads, even if a feedback thread already exists.Peut-être pris @pgmzeta l’a pris aujourd’hui. OuverteE-Verified P-Major
Difficulté 2/5 1-3 heures Accessibilité débutants 79/100
goonstation/goonstation#28259 ·
Les mainteneurs répondent en général sous 2 jours
-
enhancement
Difficulté 2/5 1-3 heures Accessibilité débutants 65/100
woonstadrotterdam/monumenten#70 ·
Les mainteneurs répondent en général sous 15 jours
-
binding:python bug
Difficulté 2/5 1-3 heures Accessibilité débutants 82/100
Les mainteneurs répondent en général sous 1 jour