Skip to content

Instantly share code, notes, and snippets.

@alexellis
Last active January 5, 2026 15:18
Show Gist options
  • Select an option

  • Save alexellis/852968c3bb5e5dcddd228455f00a1672 to your computer and use it in GitHub Desktop.

Select an option

Save alexellis/852968c3bb5e5dcddd228455f00a1672 to your computer and use it in GitHub Desktop.
Google Edge TPU with SlicerVM and Ubuntu 22.04
config:
host_groups:
- name: coral
userdata_file: ./userdata.sh
storage: image
storage_size: 25G
count: 1
vcpu: 2
ram_gb: 4
network:
bridge: brcm0
tap_prefix: cm
gateway: 192.168.138.1/24
pci:
coral-1: ["c1:00.0"]
image: "ghcr.io/openfaasltd/slicer-systemd-ch:5.10.240-x86_64-latest"
hypervisor: "cloud-hypervisor"
api:
port: 8080
bind_address: "127.0.0.1"
auth:
enabled: true
ssh:
port: 2222
bind_address: "0.0.0.0"
github_user: alexellis
#!/usr/bin/env bash
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
export TZ="Europe/London"
APT="apt-get -y --no-install-recommends"
log() { echo "[$(date -Is)] $*"; }
# Hard-coded user + paths (as requested)
USER_NAME="ubuntu"
USER_HOME="/home/ubuntu"
# Python build + venv locations (hard-coded)
PY_VER="3.9.20"
PY_PREFIX="/home/ubuntu/.local/python-3.9.20"
PY_BIN="/home/ubuntu/.local/python-3.9.20/bin/python3.9"
VENV_DIR="/home/ubuntu/venvs/coral39"
VENV_PY="/home/ubuntu/venvs/coral39/bin/python"
# pycoral repo (hard-coded)
REPO_DIR="/home/ubuntu/pycoral"
run_as_user() { sudo -H -u "$USER_NAME" bash -lc "$*"; }
log "0/11 Timezone (non-interactive)"
ln -snf "/usr/share/zoneinfo/$TZ" /etc/localtime
echo "$TZ" >/etc/timezone
apt-get update -y
$APT install tzdata
dpkg-reconfigure -f noninteractive tzdata
log "1/11 Base packages"
$APT install \
git curl ca-certificates gnupg \
build-essential dkms \
libssl-dev zlib1g-dev libbz2-dev libreadline-dev \
libsqlite3-dev libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev \
libusb-1.0-0
log "2/11 Coral APT repo"
install -d -m 0755 /etc/apt/keyrings
if [[ ! -f /etc/apt/keyrings/coral-edgetpu.gpg ]]; then
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg \
| gpg --dearmor -o /etc/apt/keyrings/coral-edgetpu.gpg
fi
cat >/etc/apt/sources.list.d/coral-edgetpu.list <<'EOF'
deb [signed-by=/etc/apt/keyrings/coral-edgetpu.gpg] https://packages.cloud.google.com/apt coral-edgetpu-stable main
EOF
apt-get update -y
log "3/11 Install EdgeTPU runtime + DKMS (M.2/PCIe)"
$APT install libedgetpu1-std gasket-dkms
ldconfig
log "4/11 Load modules + wait for /dev/apex_0"
modprobe gasket || true
modprobe apex || true
for i in {1..20}; do
[[ -e /dev/apex_0 ]] && break
sleep 0.5
done
lsmod | egrep '^(gasket|apex)\b' || true
ls -l /dev/apex_0 || true
dmesg | egrep -i 'gasket|apex' | tail -n 50 || true
log "5/11 Create apex group + udev rule + add ubuntu"
groupadd -f apex
cat >/etc/udev/rules.d/99-apex-permissions.rules <<'EOF'
KERNEL=="apex_*", GROUP="apex", MODE="0660"
EOF
udevadm control --reload-rules
udevadm trigger
usermod -aG apex ubuntu || true
log "6/11 Build Python 3.9.20 locally under ubuntu (no PGO tests)"
run_as_user "set -euo pipefail
if [[ ! -x '$PY_BIN' ]]; then
mkdir -p /home/ubuntu/src
cd /home/ubuntu/src
if [[ ! -f 'Python-${PY_VER}.tgz' ]]; then
curl -fsSLO 'https://www.python.org/ftp/python/${PY_VER}/Python-${PY_VER}.tgz'
fi
rm -rf 'Python-${PY_VER}'
tar -xzf 'Python-${PY_VER}.tgz'
cd 'Python-${PY_VER}'
./configure --prefix='$PY_PREFIX' --with-ensurepip=install
make -j\"\$(nproc)\"
make install
fi
'$PY_BIN' -V
"
log "7/11 Create venv + install pycoral (cp39 wheels) in venv"
run_as_user "set -euo pipefail
mkdir -p /home/ubuntu/venvs
if [[ ! -d '$VENV_DIR' ]]; then
'$PY_BIN' -m venv '$VENV_DIR'
fi
'$VENV_PY' -m pip install -U pip setuptools wheel
'$VENV_PY' -m pip install 'numpy==1.26.4'
'$VENV_PY' -m pip install --extra-index-url https://google-coral.github.io/py-repo/ \
'tflite-runtime==2.5.0.post1' \
'pycoral==2.0.0'
'$VENV_PY' -c 'import pycoral.pybind._pywrap_coral as m; print(\"pywrap OK\")'
"
log "8/11 Clone pycoral repo with submodules (for examples/test_data)"
run_as_user "set -euo pipefail
if [[ ! -d '$REPO_DIR/.git' ]]; then
git clone --recurse-submodules https://github.com/google-coral/pycoral.git '$REPO_DIR'
else
git -C '$REPO_DIR' pull --ff-only || true
git -C '$REPO_DIR' submodule update --init --recursive
fi
"
log "9/11 Run examples/install_requirements.sh (downloads a lot)"
run_as_user "set -euo pipefail
cd /home/ubuntu/pycoral/examples
bash ./install_requirements.sh
"
log "10/11 Delegate check as root (sanity) using venv python"
sudo -H /home/ubuntu/venvs/coral39/bin/python -c "from tflite_runtime.interpreter import load_delegate; load_delegate('libedgetpu.so.1'); print('delegate OK as root')"
log "11/11 Run classify as ubuntu WITH apex group (no reboot/logout needed; visible output)"
run_as_user "set -euo pipefail
cat >/tmp/apex_test.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
echo \"[apex-subshell] id: \$(id)\"
/home/ubuntu/venvs/coral39/bin/python -c 'from tflite_runtime.interpreter import load_delegate; load_delegate(\"libedgetpu.so.1\"); print(\"delegate OK as ubuntu\")'
OUT=\$(/home/ubuntu/venvs/coral39/bin/python /home/ubuntu/pycoral/examples/classify_image.py \
--input /home/ubuntu/pycoral/test_data/grace_hopper.bmp \
--model /home/ubuntu/pycoral/test_data/mobilenet_v2_1.0_224_quant_edgetpu.tflite \
--labels /home/ubuntu/pycoral/test_data/imagenet_labels.txt)
echo \"\$OUT\"
echo \"\$OUT\" | grep -q \"military uniform\" && echo \"classify OK\"
EOF
chmod +x /tmp/apex_test.sh
sg apex -c \"bash /tmp/apex_test.sh\"
"
log "SUCCESS"
echo "Venv (interactive): source /home/ubuntu/venvs/coral39/bin/activate"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment