Skip to content

Commit 73aeb21

Browse files
committed
Merge branch 'main' into jz/cpp-no-op-tokenizer
2 parents 194c829 + c5dd476 commit 73aeb21

File tree

18 files changed

+495
-53
lines changed

18 files changed

+495
-53
lines changed

.github/workflows/_link_check.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
on:
2+
workflow_call:
3+
inputs:
4+
ref:
5+
type: string
6+
required: true
7+
8+
jobs:
9+
lint-urls:
10+
uses: pytorch/test-infra/.github/workflows/linux_job_v2.yml@main
11+
with:
12+
runner: linux.2xlarge
13+
docker-image: executorch-ubuntu-22.04-linter
14+
submodules: 'none'
15+
fetch-depth: 0
16+
ref: ${{ inputs.ref }}
17+
timeout: 90
18+
script: |
19+
./scripts/lint_urls.sh $(
20+
[ "${{ github.event_name }}" = "pull_request" ] \
21+
&& git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }} \
22+
|| [ "${{ github.event_name }}" = "push" ] \
23+
&& git diff --name-only ${{ github.event.before }} ${{ github.sha }}
24+
)
25+
26+
lint-xrefs:
27+
uses: pytorch/test-infra/.github/workflows/linux_job_v2.yml@main
28+
with:
29+
runner: linux.2xlarge
30+
docker-image: executorch-ubuntu-22.04-linter
31+
submodules: 'none'
32+
fetch-depth: 0
33+
ref: ${{ inputs.ref }}
34+
timeout: 90
35+
script: |
36+
./scripts/lint_xrefs.sh $(
37+
[ "${{ github.event_name }}" = "pull_request" ] \
38+
&& git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }} \
39+
|| [ "${{ github.event_name }}" = "push" ] \
40+
&& git diff --name-only ${{ github.event.before }} ${{ github.sha }}
41+
)

.github/workflows/lint.yml

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -64,29 +64,10 @@ jobs:
6464
6565
exit $RC
6666
67-
lint-urls:
68-
uses: pytorch/test-infra/.github/workflows/linux_job_v2.yml@main
67+
link-check:
68+
uses: ./.github/workflows/_link_check.yml
6969
with:
70-
runner: linux.2xlarge
71-
docker-image: executorch-ubuntu-22.04-linter
72-
submodules: 'none'
73-
fetch-depth: 0
7470
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
75-
timeout: 90
76-
script: |
77-
./scripts/lint_urls.sh
78-
79-
lint-xrefs:
80-
uses: pytorch/test-infra/.github/workflows/linux_job_v2.yml@main
81-
with:
82-
runner: linux.2xlarge
83-
docker-image: executorch-ubuntu-22.04-linter
84-
submodules: 'none'
85-
fetch-depth: 0
86-
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
87-
timeout: 90
88-
script: |
89-
./scripts/lint_xrefs.sh
9071

9172
android-java-format:
9273
uses: pytorch/test-infra/.github/workflows/linux_job_v2.yml@main

.github/workflows/nightly.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,9 @@ jobs:
3030
test-infra-ref: main
3131
updatebot-token: ${{ secrets.UPDATEBOT_TOKEN }}
3232
pytorchbot-token: ${{ secrets.GH_PYTORCHBOT_TOKEN }}
33+
34+
link-check:
35+
needs: update-pytorch-commit-hash
36+
uses: ./.github/workflows/_link_check.yml
37+
with:
38+
ref: ${{ github.sha }}

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ To get started you can:
5151

5252
- Visit the [Step by Step Tutorial](https://pytorch.org/executorch/stable/getting-started.html) to get things running locally and deploy a model to a device
5353
- Use this [Colab Notebook](https://colab.research.google.com/drive/1qpxrXC3YdJQzly3mRg-4ayYiOjC6rue3?usp=sharing) to start playing around right away
54-
- Jump straight into LLM use cases by following specific instructions for [Llama](examples/models/llama/README.md) and [Llava](examples/models/llava/README.md)
54+
- Jump straight into LLM use cases by following specific instructions for popular open-source models such as [Llama](examples/models/llama/README.md), [Qwen 3](examples/models/qwen3/README.md), [Phi-4-mini](examples/models/phi_4_mini/README.md), and [Llava](examples/models/llava/README.md)
5555

5656
## Feedback and Engagement
5757

backends/apple/coreml/runtime/test/ETCoreMLModelManagerTests.mm

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
#import <XCTest/XCTest.h>
1616
#import <executorch/runtime/platform/runtime.h>
1717
#import <model_logging_options.h>
18+
#import <multiarray.h>
19+
20+
using namespace executorchcoreml;
1821

1922
@interface ETCoreMLModelManagerTests : XCTestCase
2023

@@ -148,4 +151,77 @@ - (void)testMulModelExecution {
148151
}
149152
}
150153

154+
// See https://github.com/pytorch/executorch/pull/10465
155+
- (void)testAutoreleasepoolError {
156+
NSURL *modelURL = [self.class bundledResourceWithName:@"add_coreml_all" extension:@"bin"];
157+
NSError *localError = nil;
158+
XCTAssertNotNil(modelURL);
159+
160+
NSData *modelData = [NSData dataWithContentsOfURL:modelURL];
161+
MLModelConfiguration *configuration = [[MLModelConfiguration alloc] init];
162+
configuration.computeUnits = MLComputeUnitsAll;
163+
ModelHandle *modelHandle = [self.modelManager loadModelFromAOTData:modelData
164+
configuration:configuration
165+
error:&localError];
166+
XCTAssert(modelHandle);
167+
168+
ETCoreMLModel *model = [self.modelManager modelWithHandle:modelHandle];
169+
XCTAssert(model);
170+
171+
NSArray<MLMultiArray *> *inputArrays =
172+
[ETCoreMLTestUtils inputsForModel:model repeatedValues:@[@(2), @(3)] error:&localError];
173+
XCTAssert(inputArrays);
174+
175+
std::vector<MultiArray> multiArrays;
176+
multiArrays.reserve(inputArrays.count + model.orderedOutputNames.count);
177+
for (MLMultiArray *array in inputArrays) {
178+
auto dataTypeOpt = to_multiarray_data_type(array.dataType);
179+
XCTAssert(dataTypeOpt.has_value());
180+
auto dataType = dataTypeOpt.value();
181+
182+
std::vector<size_t> dims;
183+
for (NSNumber *n in array.shape) {
184+
dims.push_back(n.unsignedLongValue);
185+
}
186+
187+
std::vector<ssize_t> strides(dims.size());
188+
ssize_t currentStride = 1;
189+
for (NSInteger i = dims.size() - 1; i >= 0; --i) {
190+
strides[i] = currentStride;
191+
currentStride *= dims[i];
192+
}
193+
194+
multiArrays.emplace_back(array.dataPointer,
195+
MultiArray::MemoryLayout(dataType, dims, strides));
196+
}
197+
198+
auto inputLayout = multiArrays[0].layout();
199+
size_t bufferSize = inputLayout.num_bytes();
200+
for (NSUInteger i = 0; i < model.orderedOutputNames.count; ++i) {
201+
multiArrays.emplace_back(calloc(1, bufferSize), inputLayout);
202+
}
203+
// corrupt first input shape to force error
204+
{
205+
auto originalLayout = multiArrays[0].layout();
206+
auto corruptedDims = originalLayout.shape();
207+
corruptedDims[0] += 1;
208+
multiArrays[0] = MultiArray(multiArrays[0].data(),
209+
MultiArray::MemoryLayout(originalLayout.dataType(),
210+
corruptedDims,
211+
originalLayout.strides()));
212+
}
213+
214+
BOOL success = [self.modelManager executeModelWithHandle:modelHandle
215+
argsVec:multiArrays
216+
loggingOptions:ModelLoggingOptions()
217+
eventLogger:nullptr
218+
error:&localError];
219+
XCTAssertFalse(success);
220+
XCTAssertNotNil(localError);
221+
222+
for (size_t i = inputArrays.count; i < multiArrays.size(); ++i) {
223+
free(multiArrays[i].data());
224+
}
225+
}
226+
151227
@end

docs/source/conf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
# add these directories to sys.path here. If the directory is relative to the
1919
# documentation root, use os.path.abspath to make it absolute, like shown here.
2020
#
21-
import distutils.file_util
2221
import glob
2322
import os
23+
import shutil
2424
import sys
2525
from typing import Any
2626

@@ -135,7 +135,7 @@
135135
# Copy .md files from source dir to gallery dir
136136
for f in glob.glob(os.path.join(source_dir, "*.md")):
137137

138-
distutils.file_util.copy_file(f, gallery_dir, update=True)
138+
shutil.copyfile(f, gallery_dir)
139139

140140
source_suffix = [".rst", ".md"]
141141

examples/models/llama/attention.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ def __init__(self, args: ModelArgs, layer_id: int, rope: Rope):
178178
self.dim = args.dim
179179
self.attention_qkv_bias = args.attention_qkv_bias
180180
self.use_qk_norm = args.use_qk_norm
181+
self.qk_norm_before_rope = args.qk_norm_before_rope
181182

182183
if self.use_qk_norm:
183184
q_norm_dim = self.head_dim
@@ -243,14 +244,18 @@ def forward(
243244
k = k.view(bsz, seqlen, self.n_local_kv_heads, self.head_dim)
244245
v = v.view(bsz, seqlen, self.n_local_kv_heads, self.head_dim)
245246

247+
if self.use_qk_norm and self.qk_norm_before_rope:
248+
q = self.q_norm_fn(q)
249+
k = self.k_norm_fn(k)
250+
246251
# RoPE relative positional embeddings
247252
q, k = self.rope.forward(q, k, freqs_cos, freqs_sin)
248253

249254
q = q.transpose(1, 2) # (bs, n_local_heads, seqlen, head_dim)
250255
k = k.transpose(1, 2)
251256
v = v.transpose(1, 2)
252257

253-
if self.use_qk_norm:
258+
if self.use_qk_norm and not self.qk_norm_before_rope:
254259
q = self.q_norm_fn(q)
255260
k = self.k_norm_fn(k)
256261

examples/models/llama/export_llama_lib.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@
100100
"llama3_2",
101101
"static_llama",
102102
"qwen2_5",
103+
"qwen3-0_6b",
104+
"qwen3-1_7b",
105+
"qwen3-4b",
103106
"phi_4_mini",
104107
"smollm2",
105108
]
@@ -108,6 +111,9 @@
108111
"qwen2_5": "Qwen/Qwen2.5-1.5B",
109112
"phi_4_mini": "microsoft/Phi-4-mini-instruct",
110113
"smollm2": "HuggingFaceTB/SmolLM-135M",
114+
"qwen3-0_6b": "Qwen/Qwen3-0.6B",
115+
"qwen3-1_7b": "Qwen/Qwen3-1.7B",
116+
"qwen3-4b": "Qwen/Qwen3-4B",
111117
}
112118

113119

@@ -544,6 +550,10 @@ def export_llama(args) -> str:
544550
from executorch.examples.models.qwen2_5 import ( # pyre-ignore[21]
545551
convert_weights,
546552
)
553+
elif args.model.startswith("qwen3"):
554+
from executorch.examples.models.qwen3 import ( # pyre-ignore[21]
555+
convert_weights,
556+
)
547557
elif args.model == "phi_4_mini":
548558
from executorch.examples.models.phi_4_mini import ( # pyre-ignore[21]
549559
convert_weights,

examples/models/llama/model_args.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class ModelArgs:
3838
apply_embedding: bool = True # Use embedding inside the transformer
3939
apply_output: bool = True # Use output layer (unembedding) inside the transformer
4040
use_qk_norm: bool = False # apply normalization to q and k in the attention
41+
qk_norm_before_rope: bool = False # when to apply qk norm
4142
use_hf_rope: bool = False # Use HuggingFace's RoPE implementation
4243
partial_rotary_factor: float = 1.0
4344
rope_theta: Optional[float] = (
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"dim": 1024,
3+
"ffn_dim_multiplier": 1,
4+
"hidden_dim": 3072,
5+
"n_heads": 16,
6+
"head_dim": 128,
7+
"n_kv_heads": 8,
8+
"n_layers": 28,
9+
"norm_eps": 1e-06,
10+
"rope_theta": 1000000.0,
11+
"use_scaled_rope": false,
12+
"vocab_size": 151936,
13+
"use_hf_rope": true,
14+
"attention_qkv_bias": false,
15+
"use_qk_norm": true,
16+
"qk_norm_before_rope": true
17+
}

0 commit comments

Comments
 (0)