Skip to content

Commit ffda3ae

Browse files
JakeStevensmeta-codesync[bot]
authored andcommitted
Move examples/hf_llm to examples/hf and share HF export reporting (pytorch#23898)
Summary: Pull Request resolved: pytorch#23898 Rename `backends/native/examples/hf_llm` to `examples/hf` in preparation for non-LLM Hugging Face exporters, and factor delegated-versus-residual op reporting into `hf_utils.py` for reuse. `export_hf_llm` and `convert_meta_llama` retain their flags and exported artifacts. Diagnostic report headers now include the method label, and an empty residual-op section prints `(none)`. Updated with AI assistance from Codex. Differential Revision: D125295022
1 parent e21a7d6 commit ffda3ae

18 files changed

Lines changed: 95 additions & 65 deletions
Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,24 @@ load("@fbsource//xplat/executorch/build:runtime_wrapper.bzl", "runtime")
33

44
oncall("executorch")
55

6+
fbcode_target(
7+
_kind = runtime.python_library,
8+
name = "hf_utils",
9+
srcs = ["hf_utils.py"],
10+
deps = [
11+
"//caffe2:torch",
12+
"//executorch/backends/native:lib",
13+
"//executorch/exir:lib",
14+
],
15+
)
16+
617
fbcode_target(
718
_kind = runtime.python_library,
819
name = "export_hf_llm_lib",
920
srcs = ["export_hf_llm.py"],
1021
deps = [
1122
":gguf_hf",
23+
":hf_utils",
1224
"//caffe2:torch",
1325
"//executorch/backends/native:lib",
1426
"//executorch/exir:lib",
@@ -23,7 +35,7 @@ fbcode_target(
2335
fbcode_target(
2436
_kind = runtime.python_binary,
2537
name = "export_hf_llm",
26-
main_function = "executorch.backends.native.examples.hf_llm.export_hf_llm.main",
38+
main_function = "executorch.backends.native.examples.hf.export_hf_llm.main",
2739
deps = [":export_hf_llm_lib"],
2840
)
2941

@@ -43,7 +55,7 @@ fbcode_target(
4355
_kind = runtime.python_binary,
4456
name = "convert_meta_llama",
4557
srcs = ["convert_meta_llama.py"],
46-
main_function = "executorch.backends.native.examples.hf_llm.convert_meta_llama.main",
58+
main_function = "executorch.backends.native.examples.hf.convert_meta_llama.main",
4759
deps = [
4860
"//caffe2:torch",
4961
"fbsource//third-party/pypi/safetensors:safetensors",
File renamed without changes.

backends/native/examples/hf_llm/export_hf_llm.py renamed to backends/native/examples/hf/export_hf_llm.py

Lines changed: 3 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,12 @@
1616
"""
1717

1818
import argparse
19-
import collections
2019
import logging
21-
import operator
2220

2321
import torch
2422
import torch.nn as nn
25-
from executorch.backends.native import get_default_compile_config
26-
from executorch.backends.native.examples.hf_llm.gguf_hf import (
27-
gguf_architecture,
28-
gguf_to_hf,
29-
)
30-
from executorch.backends.native.partitioner import NativePartitioner
31-
from executorch.backends.native.passes import get_default_passes
32-
from executorch.exir import to_edge_transform_and_lower
33-
from executorch.exir.lowered_backend_module import (
34-
executorch_call_delegate,
35-
get_lowered_submodules,
36-
)
23+
from executorch.backends.native.examples.hf.gguf_hf import gguf_architecture, gguf_to_hf
24+
from executorch.backends.native.examples.hf.hf_utils import report_lowering
3725
from executorch.exir.native import to_native
3826
from executorch.extension.llm.export.load import assign_one, iter_checkpoint, RawIter
3927
from torch.export import Dim, export
@@ -218,15 +206,6 @@ def _quantize_8da4w(
218206
)
219207

220208

221-
def _histogram(gm: torch.fx.GraphModule) -> collections.Counter:
222-
return collections.Counter(
223-
str(n.target)
224-
for n in gm.graph.nodes
225-
if n.op == "call_function"
226-
and n.target not in (executorch_call_delegate, operator.getitem)
227-
)
228-
229-
230209
def main() -> None:
231210
parser = argparse.ArgumentParser()
232211
parser.add_argument(
@@ -287,29 +266,7 @@ def main() -> None:
287266
dynamic_shapes={"input_ids": {1: seq}, "cache_position": {0: seq}},
288267
strict=not args.non_strict,
289268
)
290-
print("== exported aten ops ==", flush=True)
291-
for k, v in sorted(_histogram(ep.graph_module).items()):
292-
print(f" {v:4d} {k}")
293-
294-
edge = to_edge_transform_and_lower(
295-
ep,
296-
transform_passes=get_default_passes(),
297-
partitioner=[
298-
NativePartitioner(external_constants_tag=None, _serialize_as_ptn=True)
299-
],
300-
compile_config=get_default_compile_config(),
301-
)
302-
gm = edge.exported_program().graph_module
303-
lowered = get_lowered_submodules(gm)
304-
print(f"== {len(lowered)} native delegate(s) ==")
305-
delegated = collections.Counter()
306-
for _, module, _ in lowered:
307-
delegated += _histogram(module.original_module.graph_module)
308-
for k, v in sorted(delegated.items()):
309-
print(f" {v:4d} {k}")
310-
print("== residual (not delegated) ==")
311-
for k, v in sorted(_histogram(gm).items()):
312-
print(f" {v:4d} {k}")
269+
report_lowering(ep, "forward")
313270

314271
if args.output:
315272
to_native(ep).save(args.output)
File renamed without changes.
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
# All rights reserved.
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
"""Shared helpers for exporting Hugging Face models through the native backend.
8+
9+
The per-model exporters in this directory (decoder-only LMs, Whisper) build
10+
their ``torch.export`` programs differently, but lower and report them the
11+
same way: an op histogram of what the native partitioner delegated versus
12+
what it left behind.
13+
"""
14+
15+
import collections
16+
import operator
17+
18+
import torch
19+
from executorch.backends.native import get_default_compile_config
20+
from executorch.backends.native.partitioner import NativePartitioner
21+
from executorch.backends.native.passes import get_default_passes
22+
from executorch.exir import to_edge_transform_and_lower
23+
from executorch.exir.lowered_backend_module import (
24+
executorch_call_delegate,
25+
get_lowered_submodules,
26+
)
27+
from torch.export import ExportedProgram
28+
29+
30+
def histogram(gm: torch.fx.GraphModule) -> collections.Counter:
31+
"""Count call_function targets, ignoring delegate plumbing."""
32+
return collections.Counter(
33+
str(n.target)
34+
for n in gm.graph.nodes
35+
if n.op == "call_function"
36+
and n.target not in (executorch_call_delegate, operator.getitem)
37+
)
38+
39+
40+
def report_lowering(ep: ExportedProgram, label: str) -> None:
41+
"""Lower ``ep`` for PTN and print delegated vs. residual op histograms."""
42+
print(f"== {label}: exported aten ops ==", flush=True)
43+
for k, v in sorted(histogram(ep.graph_module).items()):
44+
print(f" {v:4d} {k}")
45+
46+
edge = to_edge_transform_and_lower(
47+
ep,
48+
transform_passes=get_default_passes(),
49+
partitioner=[
50+
NativePartitioner(external_constants_tag=None, _serialize_as_ptn=True)
51+
],
52+
compile_config=get_default_compile_config(),
53+
)
54+
gm = edge.exported_program().graph_module
55+
lowered = get_lowered_submodules(gm)
56+
print(f"== {label}: {len(lowered)} native delegate(s) ==")
57+
delegated: collections.Counter = collections.Counter()
58+
for _, module, _ in lowered:
59+
delegated += histogram(module.original_module.graph_module)
60+
for k, v in sorted(delegated.items()):
61+
print(f" {v:4d} {k}")
62+
print(f"== {label}: residual (not delegated) ==")
63+
residual = histogram(gm)
64+
if not residual:
65+
print(" (none)")
66+
for k, v in sorted(residual.items()):
67+
print(f" {v:4d} {k}")
File renamed without changes.

backends/native/examples/hf_llm/runtime/LlmRunner.cpp renamed to backends/native/examples/hf/runtime/LlmRunner.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
#include <utility>
1919
#include <vector>
2020

21-
#include <executorch/backends/native/examples/hf_llm/runtime/LlmRunner.h>
22-
#include <executorch/backends/native/examples/hf_llm/runtime/LlmRunnerUtils.h>
21+
#include <executorch/backends/native/examples/hf/runtime/LlmRunner.h>
22+
#include <executorch/backends/native/examples/hf/runtime/LlmRunnerUtils.h>
2323
#include <executorch/backends/native/examples/runner_utils/runner_utils.h>
2424
#include <executorch/backends/native/runtime/Program.h>
2525
#include <executorch/backends/native/runtime/deserialize/Package.h>
File renamed without changes.

backends/native/examples/hf_llm/runtime/LlmRunnerUtils.cpp renamed to backends/native/examples/hf/runtime/LlmRunnerUtils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// This source code is licensed under the BSD-style license found in the
55
// LICENSE file in the root directory of this source tree.
66

7-
#include <executorch/backends/native/examples/hf_llm/runtime/LlmRunnerUtils.h>
7+
#include <executorch/backends/native/examples/hf/runtime/LlmRunnerUtils.h>
88

99
#include <algorithm>
1010
#include <cctype>

backends/native/examples/hf_llm/runtime/LlmRunnerUtils.h renamed to backends/native/examples/hf/runtime/LlmRunnerUtils.h

File renamed without changes.

0 commit comments

Comments
 (0)