-
Notifications
You must be signed in to change notification settings - Fork 444
186 lines (165 loc) · 7.47 KB
/
ci-build.yml
File metadata and controls
186 lines (165 loc) · 7.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
name: "CI"
on:
push:
tags:
- v*.*.*
pull_request:
branches:
- main
schedule:
- cron: "0 10 * * *" # Run at 2am PST (10am UTC) every day to refresh the cache.
workflow_dispatch: # Manual trigger
inputs:
REFRESH_CACHE:
description: 'Refresh cache to remove unused files'
type: boolean
default: true
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
jobs:
presubmit:
name: "Presubmit"
runs-on: LiteRT_Linux_x64
permissions:
actions: write # For gh cache delete.
contents: write # For gh release upload.
env:
MODEL_KEY: gemma-3-1b-it-v1
MODEL_PATH: ./models/gemma3-1b-it-int4.litertlm
MODEL_URL: https://huggingface.co/litert-community/Gemma3-1B-IT/resolve/main/gemma3-1b-it-int4.litertlm
GH_TOKEN: ${{ github.token }} # For gh release upload.
REFRESH_CACHE: ${{ github.event_name == 'schedule' ||
(github.event_name == 'workflow_dispatch' && inputs.REFRESH_CACHE) }}
steps:
- name: Checkout code.
uses: actions/checkout@v4
with:
lfs: true
- name : Set up cache keys.
id: cache-keys
run: |
CACHE_RESTORE_KEY_2="${{ github.workflow }}"
CACHE_RESTORE_KEY_1="$CACHE_RESTORE_KEY_2-${{ hashFiles('**/WORKSPACE', '**/.bazelrc') }}"
CACHE_RESTORE_KEY_0="$CACHE_RESTORE_KEY_1-${{ hashFiles('**/BUILD*') }}"
# If it's not a pull request, then it will be the same as $CACHE_RESTORE_KEY_1-.
CACHE_RESTORE_KEY_HEAD="$CACHE_RESTORE_KEY_0-${{ github.event.pull_request.base.sha }}"
CACHE_KEY="$CACHE_RESTORE_KEY_0-${{ github.sha }}"
echo "CACHE_RESTORE_KEY_2=$CACHE_RESTORE_KEY_2" >> "$GITHUB_OUTPUT"
echo "CACHE_RESTORE_KEY_1=$CACHE_RESTORE_KEY_1" >> "$GITHUB_OUTPUT"
echo "CACHE_RESTORE_KEY_0=$CACHE_RESTORE_KEY_0" >> "$GITHUB_OUTPUT"
echo "CACHE_RESTORE_KEY_HEAD=$CACHE_RESTORE_KEY_HEAD" >> "$GITHUB_OUTPUT"
echo "CACHE_KEY=$CACHE_KEY" >> "$GITHUB_OUTPUT"
- name: Clean build outputs if cache is being refreshed.
if: env.REFRESH_CACHE == 'true'
run: bazel clean --expunge
- name: Restore bazel cache if cache is not being refreshed.
id: bazel-cache
if: env.REFRESH_CACHE != 'true'
uses: actions/cache/restore@v4
with:
path: |
~/.cache/bazel-linux
~/.cache/bazel-android
key: ${{ steps.cache-keys.outputs.CACHE_KEY }}
restore-keys: |
${{ steps.cache-keys.outputs.CACHE_RESTORE_KEY_HEAD }}
${{ steps.cache-keys.outputs.CACHE_RESTORE_KEY_0 }}-
${{ steps.cache-keys.outputs.CACHE_RESTORE_KEY_1 }}-
${{ steps.cache-keys.outputs.CACHE_RESTORE_KEY_2 }}-
- name: Check cache hit.
run: |
echo "Cache Hit: ${{ steps.bazel-cache.outputs.cache-hit }}"
echo "Cache Primary Key: ${{ steps.bazel-cache.outputs.cache-primary-key }}"
echo "Cache Matched Key: ${{ steps.bazel-cache.outputs.cache-matched-key }}"
- name: Download Model
env:
HF_TOKEN: ${{ secrets.HF_TOKEN }}
run: |
mkdir -p ./models
echo "Downloading model from Hugging Face..."
curl -L --retry 5 -f \
-H "Authorization: Bearer $HF_TOKEN" \
-o ${{ env.MODEL_PATH }} \
"${{ env.MODEL_URL }}"
ls -lh ${{ env.MODEL_PATH }}
- name: Run bazel build on Linux.
run: |
bazel build --disk_cache=~/.cache/bazel-linux --config=linux_x86_64 \
//... \
//runtime/engine:litert_lm_main
- name: Check if litert_lm_main doesn't link libLiteRt.so.
# Return exit code 1 if libLiteRt.so is required.
run: |
! readelf -d bazel-bin/runtime/engine/litert_lm_main | grep libLiteRt.so
- name: Update litert_lm_main prebuilt for Linux if new version tag is pushed.
if: github.ref_type == 'tag'
run: |
cp bazel-bin/runtime/engine/litert_lm_main litert_lm_main.linux_x86_64
gh release upload ${{ github.ref_name }} litert_lm_main.linux_x86_64 --clobber
- name: Run bazel test on Linux.
run: |
bazel test --disk_cache=~/.cache/bazel-linux --config=linux_x86_64 \
--test_output=errors \
//...
- name: Run bazel build on Linux with dynamic linking.
run: |
bazel build --config=linux_x86_64 \
--define=litert_link_capi_so=true \
--define=resolve_symbols_in_exec=false \
//runtime/engine:litert_lm_main
- name: Install pytest
run: python3 -m pip install --break-system-packages pytest==8.3.4
- name: Run pytest
run: pytest tools/test/ --model-path=${{ env.MODEL_PATH }} --build-system=bazel
- name: Check if litert_lm_main has only LiteRt symbols undefined.
# Return exit code 1 if libLiteRt.so has LiteRt symbols except for LiteRtTopK
# and some exceptions listed explictly here.
# TODO b/453859132: Remove OpaqueOptions.
run: |
! readelf -sW bazel-bin/runtime/engine/litert_lm_main \
| grep " LiteRt" | grep -v " UND LiteRt" | grep -v " LiteRtTopK" \
| grep -v -e LiteRtIsSameLayout -e LiteRtGetNumLayoutElements \
-e "LiteRt.*Logger" -e "LiteRt.*Metric" -e "LiteRt.*OpaqueOptions" \
-e "LiteRt.*EnvironmentOptions" -e LiteRtGetLogSeverityName \
-e LiteRtCompareApiVersion -e LiteRtGetStatusString \
-e LiteRtGetNumModelSignatures -e LiteRtGetModelSignature \
-e LiteRtGetSignatureKey -e LiteRtGetSignatureOutputTensor \
-e LiteRtGetQuantizationTypeId -e LiteRtGetPerTensorQuantization \
-e TensorBufferRequirements
- name: Setup Android NDK.
uses: nttld/setup-ndk@v1
id: setup-ndk
with:
ndk-version: r28b
add-to-path: false
- name: Run bazel build for Android.
run: |
bazel build --disk_cache=~/.cache/bazel-android --config=android_arm64 \
//... \
//runtime/engine:litert_lm_main \
@litert//litert/vendors/mediatek/dispatch:dispatch_api_so \
@litert//litert/vendors/qualcomm/dispatch:dispatch_api_so \
-- \
-//python/... \
-//schema/py:* \
-//kotlin/java/com/google/ai/edge/litertlm/example/...
env:
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
- name: Update litert_lm_main prebuilt for Android if new version tag is pushed.
if: github.ref_type == 'tag'
run: |
cp bazel-bin/runtime/engine/litert_lm_main litert_lm_main.android_arm64
gh release upload ${{ github.ref_name }} litert_lm_main.android_arm64 --clobber
- name: Remove cache if cache is being refreshed.
if: env.REFRESH_CACHE == 'true'
continue-on-error: true # Ignore errors when cache is not found.
run: gh cache delete ${{ steps.cache-keys.outputs.CACHE_KEY }}
- name: Save bazel cache if it's new or being refreshed.
uses: actions/cache/save@v4
if: env.REFRESH_CACHE == 'true' || steps.bazel-cache.outputs.cache-hit != 'true'
with:
path: |
~/.cache/bazel-linux
~/.cache/bazel-android
key: ${{ steps.cache-keys.outputs.CACHE_KEY }}