2025, Oct 31 23:17
Ошибка _ctypes при импорте tflite_runtime на Raspberry Pi OS Bookworm с Edge TPU — как решить через libffi-dev и пересборку Python (pyenv)
Решаем ошибку '_ctypes' при импорте tflite_runtime на Raspberry Pi OS Bookworm с Edge TPU: установите libffi-dev и пересоберите Python 3.9 через pyenv.
При запуске TensorFlow Lite с Edge TPU на Raspberry Pi OS Bookworm 12, на первый взгляд безобидный импорт может развалить всю конфигурацию. Если на Raspberry Pi 5 при попытке загрузить tflite_runtime Python выдаёт «No module named '_ctypes'», проблема вовсе не в TFLite — отсутствует зависимость, пропущенная на этапе сборки самого Python.
Как воспроизвести сбой
Ситуация проявляется, когда pycoral поддерживает только Python 3.6–3.9, поэтому Python 3.9 собирается через pyenv. Затем TFLite проверяют минимальным скриптом-интерпретатором с делегатом Edge TPU. Импорт падает ещё до загрузки модели.
#!/usr/bin/env python3
from pathlib import Path
from tflite_runtime.interpreter import Interpreter as TflInterpreter, load_delegate as get_delegate
model_file = Path("/home/USER/models/efficientdet_lite1_int8_edgetpu.tflite")
edge_tpu = get_delegate("/usr/lib/aarch64-linux-gnu/libedgetpu.so.1")
engine = TflInterpreter(model_path=str(model_file), experimental_delegates=[edge_tpu])
engine.allocate_tensors()
print("allocate_tensors completed; interpreter is ready")
Сбой возникает прямо во время импорта и выглядит так:
ModuleNotFoundError: No module named '_ctypes'
Что на самом деле пошло не так
Ошибка означает, что модуль _ctypes для Python не был собран. На Pi OS Bookworm 64‑бит это обычно происходит, если при компиляции Python через pyenv не было установлено libffi-dev. Без libffi-dev на этапе сборки Python пропускает сборку _ctypes, и любая библиотека, зависящая от ctypes, сразу перестаёт работать. Особенно заметно это с tflite_runtime, который подключает ctypes на раннем этапе.
Усложняет ситуацию то, что в этой конфигурации пакет libffi-dev может вообще не отображаться в apt. Поиск через apt-cache ничего не даёт, а apt сообщает об отсутствии кандидата на установку — даже при подключённых репозиториях Debian и Raspberry Pi.
Исправляем окружение и пересобираем Python
Надёжный путь — установить libffi-dev вручную, а затем пересобрать Python, чтобы _ctypes собрался корректно. Сначала скачайте .deb пакет libffi-dev с сайта Debian и установите его. После этого переустановите Python 3.9 через pyenv, убедившись, что процесс сборки видит заголовки и библиотеки в /usr/local.
CFLAGS="-I/usr/local/include" \
LDFLAGS="-L/usr/local/lib" \
PKG_CONFIG_PATH="/usr/local/lib/pkgconfig" \
pyenv install 3.9.18
После пересборки проблема с отсутствующим _ctypes исчезнет, и tflite_runtime будет успешно импортироваться.
Проверяем установку
Запустите тот же тест повторно, чтобы убедиться, что интерпретатор инициализируется с делегатом Edge TPU и без ошибок выделяет тензоры.
#!/usr/bin/env python3
from pathlib import Path
from tflite_runtime.interpreter import Interpreter as TflInterpreter, load_delegate as get_delegate
model_file = Path("/home/USER/models/efficientdet_lite1_int8_edgetpu.tflite")
edge_tpu = get_delegate("/usr/lib/aarch64-linux-gnu/libedgetpu.so.1")
engine = TflInterpreter(model_path=str(model_file), experimental_delegates=[edge_tpu])
engine.allocate_tensors()
print("allocate_tensors completed; interpreter is ready")
Почему это важно
На платах вроде Raspberry Pi 5 среды выполнения часто собирают вручную под ограничения библиотек. Если отсутствует базовый модуль вроде _ctypes, целые стеки рушатся самым неожиданным образом. В задачах с tflite_runtime и Coral Edge TPU сбой возникает уже на этапе импорта, поэтому быстрая диагностика экономит часы бесполезной отладки не того уровня.
Выводы
Если Python собирается через pyenv ради совместимости с пакетами вроде pycoral, убедитесь, что libffi-dev доступен на этапе сборки. Если apt не находит libffi-dev в Pi OS Bookworm 64‑бит, скачайте .deb с сайта Debian, установите его и пересоберите Python, указав пути к заголовкам и библиотекам. Как только _ctypes появится, проблема с импортом tflite_runtime исчезнет, и делегат Edge TPU будет подключаться как положено.
Материал основан на вопросе на StackOverflow от mightye77 и ответе от Sambrown02.