Развертывание AI-модели для мостового крана: PyTorch до ONNX

Схема периферийного развёртывания AI-модели для мостового крана

Полный конвейер развёртывания: PyTorch ResNet-18 (FP32, 45MB, вывод на GPU 5мс) экспорт в ONNX (44MB, кросс-платформенный промежуточный формат, потеря точности <0,1%) квантование TensorRT INT8 (6MB, объём 87%, потеря точности <0,5%) периферийный вывод Jetson Orin NX (1,2мс/кадр, потребляемая мощность 15Вт). По сравнению с выводом на GPU-сервере (350Вт/5мс), потребляемая мощность Jetson снижена на 96%, скорость вывода увеличена в 4,2 раза. В статье представлены полный скрипт экспорта, метод INT8-калибровки, процедура проверки точности и архитектура многомодельного конвейера.

Как бы хорошо ни работала AI-модель для мостового крана на лабораторном GPU, без развёртывания на объекте её ценность равна нулю. Промышленные условия (вибрация, высокая температура, ограниченное пространство, отсутствие кондиционирования) не подходят для установки мощных GPU-серверов (350Вт+ требуют серверного кондиционера). Периферийное развёртывание (Edge Deployment) преобразует обученную модель PyTorch в промежуточный формат ONNX, затем с помощью квантования TensorRT INT8 оптимизирует её для работы на маломощных периферийных устройствах Jetson. В статье на примере модели ResNet-18 для обнаружения обрывов проволок каната мостового крана рассматривается полный инженерный конвейер — от экспорта до развёртывания; все шаги воспроизводимы. Экспериментальная среда: обучение NVIDIA A10 (48GB) / периферия Jetson Orin NX 16GB (15Вт) / PyTorch 2.1.0 / TensorRT 8.6 / JetPack 6.0.

Практика развёртывания AI-модели мостового крана: от PyTorch к ONNX/TensorRT и периферийному выводу Jetson

Экспорт модели PyTorch в формат ONNX

ONNX (Open Neural Network Exchange) — это «универсальный язык» развёртывания моделей. Функция torch.onnx.export() преобразует динамический вычислительный граф PyTorch в статический граф ONNX. Ключевые параметры: input_names=[“input”], output_names=[“output”], dynamic_axes={“input”:{0:”batch_size”,2:”height”,3:”width”}} (поддержка входных изображений переменного размера). После экспорта точность проверяется с помощью onnxruntime: разница между FP32-выводом и PyTorch составляет <0,1% (среднее по 20 изображениям валидационного набора).

import torch, torch.onnx model = torch.load("resnet18_crane.pth") # FP32Предобученная модель типа dummy = torch.randn(1, 3, 224, 224) torch.onnx.export(model, dummy, "resnet18_crane.onnx", input_names=["input"], output_names=["output"], dynamic_axes={"input": {0: "batch", 2: "h", 3: "w"}}, opset_version=17) # Точность проверки экспорта import onnxruntime as ort sess = ort.InferenceSession("resnet18_crane.onnx") out_ort = sess.run(None, {"input": dummy.numpy()})[0] out_pt = model(dummy).detach().numpy() print(f"Max diff: {abs(out_ort - out_pt).max():.6f}") # Приложение<1e-5

Квантование TensorRT INT8 для ускорения вывода

TensorRT — это оптимизированный движок вывода NVIDIA, который преобразует модель ONNX в движок TensorRT (.trt) за счёт слияния слоёв (Layer Fusion), калибровки точности (INT8 Calibration) и оптимизации памяти (Pool Allocation). Процесс INT8-квантования: веса и активации модели FP32 отображаются с 32-битных чисел с плавающей точкой на 8-битные целые (256 уровней точности). Для отображения требуется 100–500 калибровочных изображений (Calibration Dataset); используется метод энтропийной калибровки (Entropy Calibration) для поиска порога квантования с минимальной дивергенцией Кульбака–Лейблера.

Конкретная команда: trtexec –onnx=resnet18_crane.onnx –saveEngine=resnet18_int8.trt –int8 –calib=calibration_data –fp16 –workspace=4096. Пояснение ключевых параметров: –int8 включает INT8-квантование; –calib указывает каталог калибровочных изображений (500 шт.); –fp16 включает FP16-вычисления в промежуточных слоях (смешанная точность с INT8-весами); –workspace=4096 выделяет 4 ГБ рабочего пространства (Jetson Orin NX 16GB может выделить 8 ГБ). Время конвертации — около 11 минут (GPU A10), объём INT8-движка — 6,2 МБ (14% от объёма FP32 ONNX).

ПоказательPyTorch FP32(GPU)ONNX FP32(GPU)TensorRT INT8(Jetson)степень оптимизации
объём модели45MB44MB6.2MB86%
задержка вывода5.0ms4.8ms1.2ms4.2x
энергопотребление350W350W12~15W96%
стоимость оборудования¥80,000+¥80,000+¥3,50096%
Top-1Точность94.0%93.9%93.6%0.4%
F1оценка0.930.930.920.01

Шаг 3: Проверка точности

После INT8-квантизации необходимо убедиться, что потеря точности находится в допустимых пределах. Процедура проверки: на тестовом наборе из 1 000 изображений последовательно запускаются PyTorch FP32 (базовый уровень) и TensorRT INT8 (проверяемый режим), сравниваются Top-1 точность, F1-мера и матрица ошибок для каждого класса. В данном эксперименте INT8 против FP32: Top-1 снизилась с 94,0% до 93,6% (Δ = 0,4%), F1 — с 0,93 до 0,92 (Δ = 0,01). Потеря точности на уровне классов сконцентрирована в категории «обрыв проволок каната» (доля пропусков выросла с 2,3% до 3,1%, Δ = +0,8%), тогда как по остальным 4 классам снижение точности не превысило 0,3%. Если потеря точности INT8 превышает 1%, рекомендуется перейти на FP16-квантизацию (объём 12 МБ, потеря точности <0,1%) как компромиссный вариант.


Шаг 4: Развёртывание на Jetson и конвейер обработки

Файл TensorRT Engine записывается непосредственно на Jetson Orin NX (JetPack 6.0 с предустановленным TensorRT 8.6). Для инференса используется Python API TensorRT (или C++ API для минимальной задержки). В многомодельном конвейере (например, YOLO-детекция + ResNet-классификация) применяется асинхронный инференс через CudaStream, при этом CPU-постобработка (NMS) перекрывается с GPU-инференсом следующей модели. Сквозная задержка конвейера составляет примерно 60% от суммы задержек отдельных моделей (в данном эксперименте YOLOv8s 3,8 мс + ResNet18 1,2 мс ≈ 5 мс сквозной задержки).

import tensorrt as trt, pycuda.driver as cuda # ЗагрузкаINT8 engine with open("resnet18_int8.trt", "rb") as f, trt.Runtime(trt.Logger()) as r: engine = r.deserialize_cuda_engine(f.read()) ctx = engine.create_execution_context() # РаспределениеGPUПамять d_input = cuda.mem_alloc(1*3*224*224*4) # FP32Вход(Практическое применениеINT8Предварительная обработка) d_output = cuda.mem_alloc(1*6*4) stream = cuda.Stream() # Цикл вывода for img in camera_stream(): cuda.memcpy_htod_async(d_input, preprocess(img), stream) ctx.execute_async_v2([int(d_input), int(d_output)], stream.handle) cuda.memcpy_dtoh_async(output, d_output, stream) stream.synchronize() result = postprocess(output) # Категория+Уверенность push_to_hmi(result) # Отправка на мостовой кранHMIОтображение

Практический пример внедрения

В проекте AI-визуального контроля стальных канатов на 17 мостовых кранах металлургического завода (номер проекта KL-EDGE-2024-003) на каждом кране установлен один Jetson Orin NX (¥3 500/шт.). На каждом кране смонтированы 2 промышленные камеры (Basler acA2440-75um, захват изображения по всей длине каната). Jetson выполняет конвейер YOLOv8s+ResNet18 (обнаружение мест обрыва проволок + классификация класса серьёзности). Сквозная задержка инференса — 5,0 мс (двухмодельный конвейер), ежедневно обрабатывается около 14 400 изображений (2 камеры × 1 кадр каждые 5 секунд × 10 часов). За 14 месяцев непрерывной работы (январь 2025 г. — февраль 2026 г.): система зафиксировала 328 случаев обрыва проволок, ручная проверка подтвердила 307 случаев (точность 93,6%), пропущено 8 случаев (полнота 97,5%). По сравнению с ежедневным ручным осмотром (визуальная проверка каждого крана 1 раз в день, доля обнаружения обрывов около 40%), автоматическое обнаружение повышает долю выявления в 2,3 раза.


Сравнение вариантов развёртывания: GPU-сервер против периферийного инференса

Выбор варианта развёртывания зависит от ограничений, накладываемых условиями объекта. Ниже приведено сравнение преимуществ и недостатков четырёх вариантов:

параметр сравнения вариант решенияA:GPUсервер вариант решенияB:ONNX Runtime CPU вариант решенияC:TensorRT FP16 вариант решенияD:TensorRT INT8
аппаратная платформаNVIDIA A10/RTX 4090промышленныйPC (i7-12700)Jetson Orin NX 16GBJetson Orin NX 16GB
объём модели45MB (FP32)44MB (ONNX FP32)12MB (FP16)6.2MB (INT8)
задержка вывода~5ms(одиночное изображение224×224)~25ms~2.5ms~1.2ms
энергопотребление350W65W12~15W12~15W
Top-1Точность94.0%93.9%93.8%93.6%
стоимость оборудования¥80,000+¥8,000~15,000¥3,500¥3,500
место развёртываниясерверная(требуется кондиционирование)помещение управления/распределительный щитэлектрошкаф мостового кранавнутриэлектрошкаф мостового кранавнутри
сложность эксплуатациивысокая(совместимость драйверов/управление средой)средняя(операционная системаобслуживание)низкая(готов к работе после прошивки)низкая(готов к работе после прошивки)
рекомендуемый сценарийобучение модели/пакетный офлайн-выводсуществующийпромышленный компьютери нечувствительный к задержкеТочностьприоритетное периферийное развёртываниеоптимальный выбор по соотношению цена/качество

Условия тестирования: ResNet-18, вход 224×224, batch=1. GPU-сервер: NVIDIA A10 (48GB), CUDA 12.1, PyTorch 2.1.0. ONNX Runtime CPU: i7-12700, ONNX Runtime 1.16. Jetson: Orin NX 16GB, JetPack 6.0, TensorRT 8.6. Задержка — среднее значение по 1000 прогонам.

Частые вопросы по оптимизации моделей ИИ

В: Приемлема ли потеря точности при INT8-квантизации TensorRT?

О: В данном эксперименте Top-1 точность INT8 относительно FP32 снизилась с 94.0% до 93.6% (потеря 0.4%), F1 — с 0.93 до 0.92 (потеря 0.01). В промышленных условиях потеря точности 0.4% в обмен на сжатие объёма в 7.5 раз и ускорение инференса в 4.2 раза — вполне оправдана. Если потеря точности по какому-либо классу дефектов превышает 1% (например, обрыв проволок каната стального — с 92% до 90%), рекомендуется для данного класса использовать FP16-инференс или увеличить долю таких примеров в калибровочном наборе данных INT8.

В: Как организовать конвейер для многомодельного каскада (YOLO-детекция + ResNet-классификация) на Jetson?

О: Используйте CudaStream и CUDA Graph из TensorRT для организации конвейера. Шаги: ① создайте 2 потока CudaStream (stream1 = YOLO, stream2 = ResNet); ② YOLO выполняется в stream1, NMS (Non-Maximum Suppression, ~0.5 мс) — на CPU, затем вырезанные области подаются в ResNet в stream2; ③ синхронизация потоков через CUDA Event. Сквозная задержка составляет около 60% от суммы задержек каждой модели (за счёт перекрытия GPU-инференса и CPU-постобработки).

В: Какие типичные ошибки возникают при экспорте в ONNX?

О: Три основные проблемы: ① динамические размеры — ONNX по умолчанию фиксирует входные размеры, необходимо задать параметр dynamic_axes для поддержки переменных размеров (например, переключение между 224×224 и 416×416); ② управляющие конструкции — циклы if/for в PyTorch необходимо заменять на torch.where/torch.arange (ONNX не поддерживает Python-контроль потока); ③ пользовательские операторы — для torch.autograd.Function требуется регистрация ONNX symbolic. Рекомендуется использовать новый бэкенд torch.onnx.export(…, dynamo=True) (PyTorch 2.1+).

В: Может ли устройство Jetson стабильно работать в шкафу управления краном?

О: Да. Промышленная версия Jetson Orin NX (JetPack 6.0) поддерживает расширенный температурный диапазон от -25°C до 80°C, влажность 5–95% без конденсации, вибростойкость 50G. В реальном развёртывании используется пассивное охлаждение (алюминиевый ребристый радиатор 145×80×35 мм) + защитный кожух IP54, установленный на внутренней стенке электрошкафа. Устройства развёрнуты на 17 мостовых кранах (проект KL-EDGE-2024-003), максимальная непрерывная наработка — 14 месяцев без отказов (по состоянию на февраль 2026 г.). Температура CPU стабильноподдерживать на уровне 65–72°C (при температуре окружающей среды 35°C внутри электрошкафа).

Похожие статьи

contact

contact us

phone:
+86 13903802779

mail:3915269@qq.com

Working hours: Monday to Friday

Wechat
Wechat
SHARE
TOP