Skip to content

Commit e9c861e

Browse files
authored
Merge branch 'main' into android-flavor-all
2 parents 8069800 + 793180f commit e9c861e

520 files changed

Lines changed: 10648 additions & 4052 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.ci/docker/build.sh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,14 @@ MINICONDA_VERSION=23.10.0-1
2323
BUCK2_VERSION=$(cat ci_commit_pins/buck2.txt)
2424

2525
case "${IMAGE_NAME}" in
26-
executorch-ubuntu-22.04-gcc9)
26+
executorch-ubuntu-22.04-gcc11)
27+
LINTRUNNER=""
28+
GCC_VERSION=11
29+
;;
30+
executorch-ubuntu-22.04-gcc9-nopytorch)
2731
LINTRUNNER=""
2832
GCC_VERSION=9
33+
SKIP_PYTORCH=yes
2934
;;
3035
executorch-ubuntu-22.04-clang12)
3136
LINTRUNNER=""
@@ -95,6 +100,7 @@ docker build \
95100
--build-arg "QNN_SDK=${QNN_SDK:-}" \
96101
--build-arg "MEDIATEK_SDK=${MEDIATEK_SDK:-}" \
97102
--build-arg "ANDROID_NDK_VERSION=${ANDROID_NDK_VERSION:-}" \
103+
--build-arg "SKIP_PYTORCH=${SKIP_PYTORCH:-}" \
98104
-f "${OS}"/Dockerfile \
99105
"$@" \
100106
.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0123293118efb08ac4ffc4fefe9d330201465c93
1+
de4f3c4978b4d36cc0bb8f87c6877a4a040d7ae7

.ci/docker/ubuntu/Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,10 @@ ENV SCCACHE_S3_KEY_PREFIX executorch
6464
ENV SCCACHE_REGION us-east-1
6565

6666
ARG TORCH_VERSION
67+
ARG SKIP_PYTORCH
6768
COPY ./common/install_pytorch.sh install_pytorch.sh
6869
COPY ./common/utils.sh utils.sh
69-
RUN bash ./install_pytorch.sh && rm install_pytorch.sh utils.sh
70+
RUN if [ -z "${SKIP_PYTORCH}" ]; then bash ./install_pytorch.sh; fi && rm install_pytorch.sh utils.sh
7071

7172
ARG LINTRUNNER
7273
# Install lintrunner if needed

.ci/scripts/build-qnn-sdk.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,10 @@ set_up_aot() {
4242
-DEXECUTORCH_BUILD_EXTENSION_TENSOR=ON \
4343
-DEXECUTORCH_ENABLE_EVENT_TRACER=ON \
4444
-DPYTHON_EXECUTABLE=python3
45-
cmake --build $PWD --target "PyQnnManagerAdaptor" "PyQnnWrapperAdaptor" -j$(nproc)
45+
cmake --build $PWD --target "PyQnnManagerAdaptor" -j$(nproc)
4646
# install Python APIs to correct import path
4747
# The filename might vary depending on your Python and host version.
4848
cp -f backends/qualcomm/PyQnnManagerAdaptor.cpython-310-x86_64-linux-gnu.so $EXECUTORCH_ROOT/backends/qualcomm/python
49-
cp -f backends/qualcomm/PyQnnWrapperAdaptor.cpython-310-x86_64-linux-gnu.so $EXECUTORCH_ROOT/backends/qualcomm/python
5049
popd
5150

5251
# Workaround for fbs files in exir/_serialize

.ci/scripts/setup-samsung-linux-deps.sh

Lines changed: 175 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,61 +8,199 @@
88

99
set -ex
1010

11+
API_KEY=$SAMSUNG_AI_LITECORE_KEY
12+
if [[ -z "${API_KEY}" ]]; then
13+
echo "ERROR: It didn't set up SAMSUNG_AI_LITECORE_KEY." >&2
14+
exit 1
15+
fi
16+
17+
OS_NAME="Ubuntu 22.04"
18+
LITECORE_BASE="https://soc-developer.semiconductor.samsung.com/api/v1/resource/ai-litecore/download"
19+
DEVICEFARM_BASE="https://soc-developer.semiconductor.samsung.com/api/v1/resource/remotelab/download"
20+
21+
parse_url() {
22+
local json="$1"
23+
if command -v jq >/dev/null 2>&1; then
24+
jq -r '.data // empty' <<<"$json"
25+
else
26+
sed -n 's/.*"data":[[:space:]]*"\([^"]*\)".*/\1/p' <<<"$json"
27+
fi
28+
}
1129

12-
download_ai_lite_core() {
13-
API_BASE="https://soc-developer.semiconductor.samsung.com/api/v1/resource/ai-litecore/download"
14-
API_KEY=$SAMSUNG_AI_LITECORE_KEY
15-
16-
VERSION="0.7"
17-
OS_NAME="Ubuntu 22.04"
18-
OUT_FILE="/tmp/exynos-ai-litecore-v${VERSION}.tar.gz"
19-
TARGET_PATH="/tmp/exynos_ai_lite_core"
20-
21-
mkdir -p ${TARGET_PATH}
22-
# Presigned issue URL
23-
JSON_RESP=$(curl -sS -G \
24-
--location --fail --retry 3 \
30+
download_and_extract() {
31+
local base_url="$1"
32+
local version="$2"
33+
local out_dir="$3"
34+
local out_file="$4"
35+
36+
local resp
37+
resp=$(curl -fsSL -G \
2538
-H "apikey: ${API_KEY}" \
26-
--data-urlencode "version=${VERSION}" \
39+
--data-urlencode "version=${version}" \
2740
--data-urlencode "os=${OS_NAME}" \
28-
"${API_BASE}")
41+
"${base_url}")
42+
43+
local download_url
44+
download_url=$(parse_url "$resp")
45+
if [[ -z "${download_url}" ]]; then
46+
echo "ERROR: It failed to download from ${base_url} ."
47+
echo "Response: $resp" >&2
48+
exit 1
49+
fi
50+
51+
curl -fsSL -L --retry 3 -o "${out_file}" "${download_url}"
52+
echo "Download completed: ${out_file}"
2953

30-
DOWNLOAD_URL=$(echo "$JSON_RESP" | sed -n 's/.*"data":[[:space:]]*"\([^"]*\)".*/\1/p')
54+
mkdir -p "${out_dir}"
55+
case "${out_file##*.}" in
56+
tar|tgz|gz)
57+
echo "Extracting TAR.GZ..."
58+
tar -C "${out_dir}" --strip-components=1 -xzvf "${out_file}"
59+
;;
3160

32-
if [[ -z "$DOWNLOAD_URL" ]]; then
33-
echo "Failed to extract download URL"
34-
echo "$JSON_RESP"
61+
zip)
62+
echo "Extracting ZIP..."
63+
unzip -q -d "${out_dir}" "${out_file}"
64+
;;
65+
66+
*)
3567
exit 1
68+
;;
69+
esac
70+
echo "Extracted to: ${out_dir}"
71+
}
72+
73+
download_ai_lite_core() {
74+
local litecore_version="${1:-1.0}"
75+
local litecore_out="/tmp/exynos-ai-litecore-v${litecore_version}.tar.gz"
76+
local litecore_dir="/tmp/exynos_ai_lite_core"
77+
78+
download_and_extract \
79+
"${LITECORE_BASE}" \
80+
"${litecore_version}" \
81+
"${litecore_dir}" \
82+
"${litecore_out}"
83+
84+
export EXYNOS_AI_LITECORE_ROOT="${litecore_dir}"
85+
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH:-}:${EXYNOS_AI_LITECORE_ROOT}/lib/x86_64-linux"
86+
}
87+
88+
install_devicefarm_cli() {
89+
local cli_version="${1:-beta-1.0.8}"
90+
local cli_out="/tmp/devicefarm-cli-v${cli_version}.zip"
91+
local cli_dir="/tmp/devicefarm_cli"
92+
93+
download_and_extract \
94+
"${DEVICEFARM_BASE}" \
95+
"${cli_version}" \
96+
"${cli_dir}" \
97+
"${cli_out}"
98+
99+
export PATH="${PATH%:}:${cli_dir}"
100+
chmod +x "${cli_dir}/devicefarm-cli"
101+
}
102+
103+
reserve_if_needed() {
104+
if ! command -v devicefarm-cli >/dev/null 2>&1; then
105+
echo "[WARN] devicefarm-cli is not installed." >&2
106+
return 1
36107
fi
37108

38-
# Download LiteCore
39-
curl -sS -L --fail --retry 3 \
40-
--output "$OUT_FILE" \
41-
"$DOWNLOAD_URL"
109+
local raw_info info_lines
110+
raw_info="$(devicefarm-cli -I)"
111+
112+
info_lines="$(printf '%s\n' "$raw_info" | grep -v '^\\[INFO\\]')"
42113

43-
echo "Download done: $OUT_FILE"
114+
local found_count
44115

116+
found_count=$(printf '%s\n' "$info_lines" \
117+
| grep -Eo 'Found available reservations *: *[0-9]+' \
118+
| grep -Eo '[0-9]+')
119+
[[ -z "$found_count" ]] && found_count=0
45120

46-
tar -C "${TARGET_PATH}" --strip-components=1 -xzvf "${OUT_FILE}"
121+
echo "[INFO] Current Reserved Count: $found_count"
122+
123+
local THRESHOLD_SECONDS=12600
124+
local any_below_threshold=0
125+
126+
if (( found_count > 0 )); then
127+
local table_body
128+
table_body=$(printf '%s\n' "$info_lines" | sed -n '2,$p')
129+
130+
while IFS= read -r line; do
131+
if [[ "$line" =~ ^[0-9]+[[:space:]]+([0-9]{1,2}:[0-9]{2}:[0-9]{2}) ]]; then
132+
local time_str="${BASH_REMATCH[1]}"
133+
IFS=: read -r hh mm ss <<<"$time_str"
134+
(( seconds = 10#$hh * 3600 + 10#$mm * 60 + 10#$ss ))
135+
if (( seconds <= THRESHOLD_SECONDS )); then
136+
any_below_threshold=1
137+
break
138+
fi
139+
fi
140+
done <<<"$table_body"
141+
else
142+
any_below_threshold=1
143+
fi
47144

48-
export EXYNOS_AI_LITECORE_ROOT=${TARGET_PATH}
49-
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:-}:${EXYNOS_AI_LITECORE_ROOT}/lib/x86_64-linux
145+
if (( any_below_threshold )); then
146+
echo "[INFO] Reserving now."
147+
devicefarm-cli -R
148+
else
149+
echo "[INFO] Don't need to be reserved."
150+
fi
151+
152+
local info_after reservation_id max_seconds=0 max_id
153+
154+
info_after="$(devicefarm-cli -I)"
155+
156+
local body_after
157+
body_after=$(printf '%s\n' "$info_after" | grep -v '^\\[INFO\\]' | sed -n '2,$p')
158+
159+
while IFS= read -r line; do
160+
if [[ "$line" =~ ^[0-9]+[[:space:]]+([0-9]{1,2}:[0-9]{2}:[0-9]{2})[[:space:]].*([0-9a-f-]{36})$ ]]; then
161+
local time_str="${BASH_REMATCH[1]}"
162+
local id="${BASH_REMATCH[2]}"
163+
IFS=: read -r hh mm ss <<<"$time_str"
164+
(( seconds = 10#$hh * 3600 + 10#$mm * 60 + 10#$ss ))
165+
if (( seconds > max_seconds )); then
166+
max_seconds=$seconds
167+
max_id=$id
168+
fi
169+
fi
170+
done <<<"$body_after"
171+
172+
reservation_id=$max_id
173+
174+
if [[ -n "$reservation_id" ]]; then
175+
devicefarm-cli -C "$reservation_id"
176+
devicefarm-cli -E "ls /"
177+
else
178+
echo "[WARN] There is no available devices."
179+
fi
50180
}
51181

52182
install_enn_backend() {
53-
NDK_INSTALLATION_DIR=/opt/ndk
54-
rm -rf "${NDK_INSTALLATION_DIR}" && sudo mkdir -p "${NDK_INSTALLATION_DIR}"
55-
ANDROID_NDK_VERSION=r28c
183+
local ndk_dir="/opt/ndk"
184+
local ndk_version="r28c"
185+
186+
if [[ ! -d "${ndk_dir}" ]]; then
187+
sudo mkdir -p "${ndk_dir}"
188+
sudo chown "$(whoami)":"$(whoami)" "${ndk_dir}"
189+
fi
190+
191+
export ANDROID_NDK_ROOT="${ndk_dir}"
192+
echo "NDK will be installed/used at: ${ANDROID_NDK_ROOT}"
56193

57-
# build Exynos backend
58-
export ANDROID_NDK_ROOT=${ANDROID_NDK_ROOT:-/opt/ndk}
59194
bash backends/samsung/build.sh --build all
60-
# set env variable
61-
export EXECUTORCH_ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd)"
62-
export PYTHONPATH=${PYTHONPATH:-}:${EXECUTORCH_ROOT}/..
195+
196+
export EXECUTORCH_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
197+
export PYTHONPATH="${PYTHONPATH:-}:${EXECUTORCH_ROOT}/.."
63198
}
64199

65-
AI_LITE_CORE_VERSION=0.7.0
200+
litecore_ver="1.0"
201+
devicefarm_ver="beta-1.0.8"
66202

67-
download_ai_lite_core ${AI_LITE_CORE_VERSION}
203+
download_ai_lite_core ${litecore_ver}
204+
install_devicefarm_cli "${devicefarm_ver}"
68205
install_enn_backend
206+
reserve_if_needed

.ci/scripts/test_backend.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ if [[ "$FLOW" == *arm* ]]; then
6464
else
6565
.ci/scripts/setup-arm-baremetal-tools.sh
6666
fi
67-
source examples/arm/ethos-u-scratch/setup_path.sh
67+
source examples/arm/arm-scratch/setup_path.sh
6868

6969
if [[ "$FLOW" == *ethos_u* ]]; then
7070
# Prepare a test runner binary that can run on the Corstone-3x0 FVPs

.ci/scripts/test_huggingface_optimum_model.py

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,35 @@ def test_text_generation(model_id, model_dir, recipe, *, quantize=True, run_only
170170
assert check_causal_lm_output_quality(model_id, generated_tokens) is True
171171

172172

173+
def get_tokenizer_path(model_dir: str, saved_files: tuple) -> str:
174+
"""
175+
Determine the tokenizer path based on files saved by tokenizer.save_pretrained().
176+
177+
Args:
178+
model_dir: The directory where tokenizer files were saved
179+
saved_files: Tuple of file paths returned by tokenizer.save_pretrained()
180+
181+
Returns:
182+
The path to use for loading the tokenizer (either a specific file or directory)
183+
184+
Raises:
185+
ValueError: If no supported tokenizer file format is found
186+
"""
187+
saved_filenames = {Path(f).name for f in saved_files}
188+
189+
if "tokenizer.model" in saved_filenames:
190+
return f"{model_dir}/tokenizer.model"
191+
192+
if "tokenizer.json" in saved_filenames:
193+
return model_dir
194+
195+
# No supported tokenizer format found
196+
raise ValueError(
197+
f"Unsupported tokenizer format. Expected 'tokenizer.model' (SentencePiece) "
198+
f"or 'tokenizer.json' (HuggingFace) but found: {saved_filenames}"
199+
)
200+
201+
173202
def test_llm_with_image_modality(
174203
model_id, model_dir, recipe, *, quantize=True, run_only=False
175204
):
@@ -196,7 +225,8 @@ def test_llm_with_image_modality(
196225
cli_export(command, model_dir)
197226

198227
tokenizer = AutoTokenizer.from_pretrained(model_id)
199-
tokenizer.save_pretrained(model_dir)
228+
saved_files = tokenizer.save_pretrained(model_dir)
229+
tokenizer_path = get_tokenizer_path(model_dir, saved_files)
200230

201231
# input
202232
processor = AutoProcessor.from_pretrained(model_id)
@@ -232,7 +262,7 @@ def test_llm_with_image_modality(
232262

233263
from executorch.extension.llm.runner import GenerationConfig, MultimodalRunner
234264

235-
runner = MultimodalRunner(f"{model_dir}/model.pte", f"{model_dir}/tokenizer.model")
265+
runner = MultimodalRunner(f"{model_dir}/model.pte", tokenizer_path)
236266
generated_text = runner.generate_text_hf(
237267
inputs,
238268
GenerationConfig(max_new_tokens=128, temperature=0, echo=False),

.ci/scripts/test_llama.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ if [[ "${MODE}" =~ .*qnn.* ]]; then
130130
cp schema/program.fbs exir/_serialize/program.fbs
131131
cp schema/scalar_type.fbs exir/_serialize/scalar_type.fbs
132132
cp -f build-x86/backends/qualcomm/PyQnnManagerAdaptor.cpython-310-x86_64-linux-gnu.so backends/qualcomm/python
133-
cp -f build-x86/backends/qualcomm/PyQnnWrapperAdaptor.cpython-310-x86_64-linux-gnu.so backends/qualcomm/python
134133

135134
else
136135
QNN=OFF

.ci/scripts/test_model_e2e.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ case "$HF_MODEL" in
8686
MODEL_NAME="voxtral"
8787
RUNNER_TARGET="voxtral_runner"
8888
RUNNER_PATH="voxtral"
89-
EXPECTED_OUTPUT="poem"
89+
EXPECTED_OUTPUT="existence"
9090
PREPROCESSOR="voxtral_preprocessor.pte"
9191
TOKENIZER_URL="https://huggingface.co/mistralai/Voxtral-Mini-3B-2507/resolve/main" # @lint-ignore
9292
TOKENIZER_FILE="tekken.json"

.ci/scripts/test_qnn_static_llama_eval.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ export PYTHONPATH=".."
2121
cp schema/program.fbs exir/_serialize/program.fbs
2222
cp schema/scalar_type.fbs exir/_serialize/scalar_type.fbs
2323
cp -f build-x86/backends/qualcomm/PyQnnManagerAdaptor.cpython-310-x86_64-linux-gnu.so backends/qualcomm/python
24-
cp -f build-x86/backends/qualcomm/PyQnnWrapperAdaptor.cpython-310-x86_64-linux-gnu.so backends/qualcomm/python
2524

2625
if [[ -z "${PYTHON_EXECUTABLE:-}" ]]; then
2726
PYTHON_EXECUTABLE=python3

0 commit comments

Comments
 (0)