Linux for Makers

명령어 암기를 넘어, AIoT 장치를 오래 운영하는 리눅스

리눅스는 라즈베리파이 화면을 띄우기 위한 OS가 아니라, 센서 데이터를 모으고, 서비스를 자동 실행하고, 원격으로 고치고, AI 모델을 안정적으로 배포하기 위한 운영 기반입니다.

1. AIoT에서 리눅스가 필요한 이유

ESP32 같은 MCU는 실시간 제어에 강하지만, 카메라 처리, 웹 서버, 데이터베이스, AI 추론, 원격 업데이트까지 맡기에는 한계가 있습니다. 이때 Raspberry Pi나 Orange Pi 같은 SBC에 리눅스를 올려 작은 서버처럼 동작하는 장치를 만들 수 있습니다.

필요 기능 리눅스가 제공하는 것 AIoT 예시
자동 실행 systemd 서비스 전원 연결 후 카메라 분석 프로그램 자동 시작
원격 관리 SSH, VPN, 로그 확인 교실 밖에서도 로봇 상태 확인 및 코드 수정
데이터 저장 파일시스템, SQLite, 백업 도구 센서값을 날짜별 CSV 또는 DB로 저장
AI 배포 Python, Docker, 드라이버, 런타임 카메라 프레임을 객체 탐지 모델로 추론
하드웨어 접근 장치 파일, 커널 드라이버, GPIO 라이브러리 카메라, I2C 센서, 모터 제어 보드 연결

2. 배포판과 설치 전략

리눅스 배포판은 커널에 기본 도구, 패키지 관리자, 설정 방식, 데스크톱 환경을 더해 사용 가능한 OS로 묶은 것입니다. AIoT에서는 멋진 화면보다 드라이버 지원, 패키지 호환성, 장기 유지보수, 커뮤니티 자료가 더 중요합니다.

배포판 특징 추천 상황
Ubuntu 자료가 많고 Python, Docker, ROS 관련 문서가 풍부합니다. Orange Pi와 Radxa도 보드에 따라 제조사 또는 공식 문서 기반 Ubuntu 이미지를 제공합니다. 수업, 서버 실습, 로봇 개발, Ubuntu 이미지가 제공되는 Raspberry Pi·Orange Pi·Radxa 보드
Debian 안정성이 좋고 Raspberry Pi OS의 기반이 됩니다. 오래 켜둘 장치, 가벼운 서버, 보수적인 운영
Raspberry Pi OS 라즈베리파이에 맞춰 카메라, GPIO, 교육용 도구가 잘 정리되어 있습니다. Raspberry Pi 기반 AIoT 수업과 실습
Armbian 다양한 ARM SBC를 위한 커뮤니티 중심 빌드 프레임워크입니다. 서버형 최소 설치와 보드별 커널 지원을 확인할 때 유용합니다. 공식 Ubuntu 이미지가 없거나 오래된 보드, 가벼운 서버형 이미지가 필요한 ARM SBC
RHEL 계열 기업 서버 운영에서 많이 쓰는 계열입니다. 서버 관리, 보안 정책, 기업 인프라 학습
배포판 선택은 보드 브랜드로만 정하지 않습니다. Orange Pi와 Radxa도 Ubuntu 이미지를 제공하는 모델이 있으므로, 먼저 해당 보드의 공식 다운로드와 문서를 확인하고, 드라이버·NPU·카메라 지원이 더 안정적인 이미지를 고르는 것이 좋습니다.
처음 설치한 뒤 바로 할 일
# 패키지 목록과 설치된 패키지 업데이트
sudo apt update
sudo apt upgrade -y

# 시간대 확인 및 설정
timedatectl
sudo timedatectl set-timezone Asia/Seoul

# 장치 이름 변경
sudo hostnamectl set-hostname aiot-robot-01

# 재부팅
sudo reboot

여러 보드를 동시에 쓰면 호스트명이 중요합니다. raspberrypi가 여러 대 있으면 SSH 접속과 로그 관리가 금방 헷갈립니다.

3. 파일시스템과 권한

리눅스는 모든 것을 파일처럼 다루는 철학을 갖고 있습니다. 센서, 카메라, USB 장치도 실제 파일은 아니지만 /dev 아래 장치 파일로 접근하는 경우가 많습니다.

중요한 디렉터리

경로 의미 AIoT에서 보는 상황
/home/사용자 사용자 작업 공간 프로젝트 코드, 가상환경, 실험 데이터 저장
/etc 시스템 설정 네트워크, 서비스, SSH 설정 수정
/var/log 로그 파일 부팅 오류, 서비스 실패, 네트워크 문제 확인
/dev 장치 파일 /dev/video0, /dev/ttyUSB0, /dev/i2c-1
/sys 커널과 하드웨어 상태 GPIO, 전원, 온도, 장치 정보 확인
권한 읽는 법: rwx와 chmod
ls -l run_robot.sh
# -rwxr-xr-- 1 ubuntu ubuntu 320 Jun 11 10:00 run_robot.sh
#  소유자: rwx = 읽기, 쓰기, 실행
#  그룹:   r-x = 읽기, 실행
#  기타:   r-- = 읽기
  • chmod 755 run_robot.sh: 소유자는 모든 권한, 그룹/기타 사용자는 읽기와 실행 권한을 갖습니다.
  • chmod 644 config.yaml: 설정 파일처럼 실행할 필요 없는 파일에 적합합니다.
  • sudo chown ubuntu:ubuntu data.db: 파일 소유자를 바꿉니다. root로 만든 파일 때문에 앱이 저장하지 못할 때 필요합니다.
sudo chmod -R 777 /처럼 루트 전체 권한을 바꾸는 명령은 시스템을 망가뜨릴 수 있습니다. 권한 문제는 필요한 파일과 디렉터리만 좁혀서 해결합니다.

4. 핵심 CLI 명령어

CLI는 리눅스를 빠르게 다루는 조종석입니다. 모든 명령을 외울 필요는 없지만, 파일 탐색, 프로세스 확인, 로그 추적, 디스크 점검은 손에 익혀야 합니다.

위치와 파일

  • pwd: 현재 경로
  • ls -lah: 숨김 파일과 용량 포함 목록
  • cd ..: 상위 폴더 이동
  • mkdir logs: 폴더 생성
  • touch memo.txt: 빈 파일 생성

복사와 삭제

  • cp a.py b.py: 파일 복사
  • cp -r src backup: 폴더 복사
  • mv old new: 이동 또는 이름 변경
  • rm file.txt: 파일 삭제
  • rm -i file.txt: 확인 후 삭제

내용 확인

  • cat config.yaml: 전체 출력
  • head -n 20 app.log: 처음 20줄 보기
  • less app.log: 긴 파일 탐색
  • tail -f app.log: 실시간 로그 추적
  • grep ERROR app.log: 문자열 검색

시스템 상태

  • top, htop: CPU/RAM 확인
  • df -h: 디스크 용량
  • free -h: 메모리 사용량
  • vcgencmd measure_temp: 일부 보드의 온도 확인

파일 찾기와 용량

  • find . -name "*.py": 현재 폴더 아래 Python 파일 찾기
  • find logs -mtime +7: 7일보다 오래된 로그 찾기
  • du -sh *: 현재 폴더 항목별 용량
  • stat app.py: 파일 크기와 수정 시간 확인

편집과 텍스트 처리

  • nano config.yaml: 터미널에서 파일 편집
  • wc -l app.log: 줄 수 세기
  • sort data.csv: 줄 정렬
  • uniq events.txt: 연속 중복 줄 제거

압축과 백업

  • tar -czf logs.tar.gz logs/: 폴더 압축
  • tar -xzf logs.tar.gz: 압축 풀기
  • rsync -avh src/ backup/: 변경분 중심 복사
  • sha256sum model.onnx: 파일 무결성 확인

네트워크와 포트

  • hostname -I: 현재 IP만 간단히 보기
  • ip route: 기본 게이트웨이 확인
  • ss -lntp: 열려 있는 TCP 포트 확인
  • curl -I http://localhost:8000: 웹 서버 응답 헤더 확인
프로세스 찾고 종료하기
# python 프로세스 검색
ps -ef | grep python

# 포트 8000을 쓰는 프로세스 확인
sudo lsof -i :8000

# 일반 종료 요청
kill PID

# 마지막 수단: 강제 종료
kill -9 PID

kill -9는 저장 중인 파일을 정리할 기회를 주지 않습니다. 먼저 일반 kill이나 서비스 종료 명령을 사용합니다.

명령 조합 예시
# 로그에서 ERROR가 들어간 줄만 번호와 함께 보기
grep -n "ERROR" logs/app.log

# 최근 수정된 파일 10개 확인
find . -type f -printf "%T@ %p\n" | sort -nr | head -n 10

# 디스크를 많이 쓰는 폴더부터 정렬
du -sh * | sort -hr | head

# 1초마다 온도 또는 상태 명령 반복 실행
watch -n 1 vcgencmd measure_temp

# 특정 포트를 쓰는 프로세스 찾기
sudo lsof -i :8000
ss -lntp | grep 8000

파이프(|)는 앞 명령의 결과를 다음 명령으로 넘깁니다. 로그 분석, 용량 점검, 네트워크 확인처럼 결과를 좁혀 볼 때 자주 씁니다.

5. 패키지, 서비스, 로그

리눅스 운영의 핵심은 설치와 실행을 재현 가능하게 만드는 것입니다. "터미널에서 직접 실행하면 되는데요" 상태를 넘어, 부팅 후 자동으로 켜지고 실패하면 로그가 남도록 구성해야 합니다.

apt 패키지 관리
# 패키지 목록 갱신
sudo apt update

# 설치된 패키지 업그레이드
sudo apt upgrade -y

# 패키지 검색과 설치
apt search mosquitto
sudo apt install -y mosquitto mosquitto-clients

# 더 이상 필요 없는 패키지 정리
sudo apt autoremove -y
systemd 서비스 만들기

AIoT 프로그램은 보통 전원이 켜지면 자동으로 시작해야 합니다. systemd 유닛 파일을 만들면 재부팅 뒤에도 자동 실행되고, 실패 로그도 추적할 수 있습니다.

# /etc/systemd/system/aiot-camera.service
[Unit]
Description=AIoT Camera Inference Service
After=network-online.target
Wants=network-online.target

[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu/aiot-project
ExecStart=/home/ubuntu/aiot-project/.venv/bin/python app.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable aiot-camera
sudo systemctl start aiot-camera
systemctl status aiot-camera
journalctl -u aiot-camera -f
국내 미러 서버 선택 기준

패키지 다운로드가 느리면 국내 미러를 쓰면 좋습니다. 다만 미러는 "무조건 빠른 서버"가 아니라 동기화 상태, 학교/집 네트워크 경로, 사용하는 Ubuntu 버전에 따라 체감이 달라집니다. 수정 전에는 반드시 원본 설정을 백업합니다.

미러 주소 추천 상황
KAIST https://ftp.kaist.ac.kr/ubuntu/ 국내 대학망/교육망 환경에서 빠른 경우가 많습니다. KAIST FTP Mirror에서 Ubuntu와 여러 오픈소스 미러를 제공합니다.
Kakao https://mirror.kakao.com/ubuntu/ 일반 가정/학교망에서 안정적으로 빠른 경우가 많습니다. Ubuntu releases 미러도 별도로 제공합니다.
보드 제조사가 제공한 Armbian, Orange Pi OS, Radxa OS 이미지는 Ubuntu처럼 보여도 저장소 구성이 다를 수 있습니다. Ubuntu 공식 저장소만 바꾸고, 보드 전용 저장소는 그대로 두는 것이 안전합니다.

참고 링크: KAIST FTP Mirror, Kakao Ubuntu Releases Mirror

KAIST 서버로 변경하기

Ubuntu 22.04 이하 또는 구형 이미지처럼 /etc/apt/sources.list를 쓰는 경우입니다.

sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup
sudo sed -i 's|http://archive.ubuntu.com/ubuntu|https://ftp.kaist.ac.kr/ubuntu|g' /etc/apt/sources.list
sudo sed -i 's|http://kr.archive.ubuntu.com/ubuntu|https://ftp.kaist.ac.kr/ubuntu|g' /etc/apt/sources.list
sudo sed -i 's|http://security.ubuntu.com/ubuntu|https://ftp.kaist.ac.kr/ubuntu|g' /etc/apt/sources.list
sudo apt update

Ubuntu 24.04 계열처럼 Deb822 형식의 ubuntu.sources를 쓰는 경우입니다.

sudo cp /etc/apt/sources.list.d/ubuntu.sources /etc/apt/sources.list.d/ubuntu.sources.backup
sudo sed -i 's|http://archive.ubuntu.com/ubuntu|https://ftp.kaist.ac.kr/ubuntu|g' /etc/apt/sources.list.d/ubuntu.sources
sudo sed -i 's|http://kr.archive.ubuntu.com/ubuntu|https://ftp.kaist.ac.kr/ubuntu|g' /etc/apt/sources.list.d/ubuntu.sources
sudo sed -i 's|http://security.ubuntu.com/ubuntu|https://ftp.kaist.ac.kr/ubuntu|g' /etc/apt/sources.list.d/ubuntu.sources
sudo apt update

문제가 생기면 백업 파일을 되돌립니다.

sudo cp /etc/apt/sources.list.backup /etc/apt/sources.list
sudo apt update
Kakao 서버로 변경하기

Ubuntu 22.04 이하 또는 구형 이미지처럼 /etc/apt/sources.list를 쓰는 경우입니다.

sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup
sudo sed -i 's|http://archive.ubuntu.com/ubuntu|https://mirror.kakao.com/ubuntu|g' /etc/apt/sources.list
sudo sed -i 's|http://kr.archive.ubuntu.com/ubuntu|https://mirror.kakao.com/ubuntu|g' /etc/apt/sources.list
sudo sed -i 's|http://security.ubuntu.com/ubuntu|https://mirror.kakao.com/ubuntu|g' /etc/apt/sources.list
sudo apt update

Ubuntu 24.04 계열처럼 Deb822 형식의 ubuntu.sources를 쓰는 경우입니다.

sudo cp /etc/apt/sources.list.d/ubuntu.sources /etc/apt/sources.list.d/ubuntu.sources.backup
sudo sed -i 's|http://archive.ubuntu.com/ubuntu|https://mirror.kakao.com/ubuntu|g' /etc/apt/sources.list.d/ubuntu.sources
sudo sed -i 's|http://kr.archive.ubuntu.com/ubuntu|https://mirror.kakao.com/ubuntu|g' /etc/apt/sources.list.d/ubuntu.sources
sudo sed -i 's|http://security.ubuntu.com/ubuntu|https://mirror.kakao.com/ubuntu|g' /etc/apt/sources.list.d/ubuntu.sources
sudo apt update

현재 어떤 저장소를 쓰는지 확인하려면 다음 명령을 사용합니다.

grep -R "URIs\\|deb " /etc/apt/sources.list /etc/apt/sources.list.d/*.sources 2>/dev/null

6. 네트워크와 원격 접속

AIoT 장치는 현장에 놓인 뒤 모니터와 키보드 없이 관리되는 경우가 많습니다. 따라서 IP 확인, SSH, 방화벽, VPN을 기본 운영 도구로 익혀야 합니다.

명령/도구 용도 예시
ip addr 보드의 IP 주소 확인 Wi-Fi가 wlan0, 유선이 eth0로 보이는 경우가 많습니다.
ping 연결 확인 ping 8.8.8.8, ping google.com
ssh 터미널 원격 접속 ssh ubuntu@192.168.0.24
scp 파일 복사 scp app.py ubuntu@192.168.0.24:/home/ubuntu/
ufw 방화벽 설정 sudo ufw allow 22/tcp
SSH 키 기반 접속
# 내 컴퓨터에서 키 생성
ssh-keygen -t ed25519

# 공개키를 보드에 복사
ssh-copy-id ubuntu@192.168.0.24

# 이후 비밀번호 없이 접속
ssh ubuntu@192.168.0.24

공개된 네트워크에서 비밀번호 SSH만 켜두는 것은 위험합니다. 키 기반 접속을 쓰고, 가능하면 공유기 포트포워딩 대신 VPN을 씁니다.

Tailscale 같은 개인 VPN이 유용한 이유

학교, 집, LTE 환경은 사설 IP와 방화벽 때문에 직접 접속이 어렵습니다. 개인 VPN을 쓰면 각 장치가 같은 가상 네트워크에 있는 것처럼 보이므로 포트포워딩 없이 SSH, VNC, 웹 대시보드에 접근하기 쉽습니다.

7. Python 환경과 Docker

AIoT에서는 Python 패키지 버전 충돌이 자주 일어납니다. 수업용 노트북, 라즈베리파이, 서버가 모두 같은 패키지를 쓰도록 하려면 환경을 분리해야 합니다.

venv로 Python 프로젝트 격리
cd ~/aiot-project
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install opencv-python paho-mqtt numpy
pip freeze > requirements.txt

.venv는 프로젝트별 Python 패키지 상자입니다. 다른 프로젝트의 라이브러리 버전과 섞이지 않게 해 줍니다.

Docker가 필요한 상황

venv는 Python 패키지만 잘 분리합니다. 하지만 OpenCV 시스템 라이브러리, CUDA/NPU 런타임, Node.js, ffmpeg처럼 OS 패키지까지 포함하려면 Docker가 유리합니다.

# 간단한 Dockerfile 예시
FROM python:3.11-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .

CMD ["python", "app.py"]
docker build -t aiot-app .
docker run --rm --name aiot-app aiot-app
방식 분리 범위 추천 상황
venv Python 패키지 가벼운 센서 수집, 데이터 분석, 수업 실습
conda Python과 일부 네이티브 라이브러리 과학 계산, 머신러닝 실험, PC 환경
Docker 앱, 라이브러리, 런타임, OS 패키지 서버 배포, 팀 프로젝트, AI 추론 서비스

8. GPIO, 카메라, 장치 파일

리눅스에서 하드웨어를 다룰 때는 "핀 번호"와 "장치 파일"을 구분해야 합니다. 같은 센서라도 I2C, SPI, UART, USB에 따라 확인 명령이 다릅니다.

I2C, SPI, UART 장치 확인
# I2C 도구 설치
sudo apt install -y i2c-tools

# I2C 버스에서 장치 주소 스캔
sudo i2cdetect -y 1

# USB 시리얼 장치 확인
ls /dev/ttyUSB*
ls /dev/ttyACM*

# 커널 메시지에서 새 장치 확인
dmesg | tail -50
GPIO 제어 방식
  • libgpiod 최신 리눅스 커널에서 권장되는 GPIO 제어 방식입니다. gpiodetect, gpioinfo, gpioset 같은 도구를 제공합니다.
  • 보드 전용 라이브러리 Raspberry Pi의 gpiozero, 일부 SBC의 Wiring 계열 라이브러리는 교육용으로 편합니다.
  • sysfs GPIO 오래된 방식입니다. 새 프로젝트에서는 가능하면 피합니다.
sudo apt install -y gpiod
gpiodetect
gpioinfo
카메라와 영상 입력
# 비디오 장치 확인
ls /dev/video*

# USB 장치 목록
lsusb

# 카메라가 인식되는지 커널 로그 확인
dmesg | grep -i video

USB 카메라는 보통 /dev/video0로 보입니다. CSI 카메라는 보드별 설정 도구와 드라이버가 필요할 수 있습니다.

9. 온디바이스 AI/NPU 운영

클라우드 API는 다양한 모델을 쓸 수 있지만 네트워크 지연, 비용, 개인정보 문제가 있습니다. 카메라 기반 안전 감지, 음성 명령, 간단한 객체 분류처럼 현장에서 즉시 반응해야 하는 기능은 보드 안에서 추론하는 온디바이스 AI가 유리합니다.

방식 장점 주의점
CPU 추론 설치가 비교적 쉽고 호환성이 좋습니다. 큰 모델은 느리고 발열이 큽니다.
GPU 추론 병렬 연산에 강하고 모델 지원이 넓습니다. 전력 소모와 드라이버 버전 관리가 부담입니다.
NPU 추론 전력 대비 추론 성능이 좋습니다. 모델 변환, 양자화, 전용 SDK가 필요합니다.
클라우드 API 대형 모델을 쉽게 사용할 수 있습니다. 인터넷 연결, 지연 시간, 비용, 개인정보를 고려해야 합니다.
AI 모델을 보드에 올릴 때의 순서
  1. PC에서 모델이 원하는 입력과 출력을 내는지 먼저 확인합니다.
  2. 입력 크기, 프레임률, 전처리 방식을 줄여 실시간 목표를 정합니다.
  3. ONNX, TFLite, RKNN, RKLLM 등 보드가 지원하는 형식으로 변환합니다.
  4. 보드에서 샘플 이미지 10장 이상으로 결과가 같은지 비교합니다.
  5. 추론 시간, CPU 사용률, 메모리, 온도, 전력 소모를 기록합니다.
  6. 실패 시 안전 모드로 내려가는 로직을 넣습니다.
Rockchip NPU: RKNN, RKLLM, rkllama

Orange Pi 5/5 Plus/5 Pro, Radxa 계열 등 RK3588/RK3576 보드는 내장 NPU를 활용할 수 있습니다. 여기서 중요한 점은 일반 PyTorch 모델을 그대로 NPU에 올리는 것이 아니라, Rockchip 런타임이 이해하는 형식으로 변환하고 전용 서버/런타임으로 실행한다는 것입니다.

구성요소 역할 사용 위치
rknn-toolkit2 ONNX, TensorFlow, PyTorch 계열 모델을 RKNN 형식으로 변환하고 성능을 평가합니다. 대개 x86 Ubuntu PC 또는 변환용 개발 환경
RKNN Runtime 변환된 .rknn 모델을 보드의 NPU에서 실행합니다. RK3588/RK3576 보드
rkllm-toolkit Hugging Face LLM을 RKLLM 형식으로 변환하고 W4A16, W8A8 같은 양자화를 적용합니다. 대개 x86 Ubuntu PC
RKLLM Runtime 변환된 .rkllm 모델을 Rockchip NPU에서 실행합니다. RK3588/RK3576/RK3562 계열 보드
rkllama Rockchip NPU용 Ollama 대안 서버입니다. RKLLM 기반 모델을 로컬 서버처럼 띄워 앱에서 호출할 수 있게 합니다. Orange Pi/Radxa 같은 Rockchip SBC

설치 흐름 예시는 아래처럼 잡으면 됩니다. 실제 명령은 보드 이미지, 커널, NPU 드라이버, rkllama 릴리스에 따라 달라질 수 있으므로 프로젝트 README와 보드 제조사 문서를 함께 확인합니다.

# 1. 보드 정보와 커널 확인
uname -a
cat /etc/os-release

# 2. NPU/드라이버 장치가 보이는지 확인
ls /dev | grep -Ei 'rknpu|npu'
dmesg | grep -Ei 'rknpu|rkllm|npu'

# 3. 기본 개발 도구 설치
sudo apt update
sudo apt install -y git cmake build-essential python3 python3-venv python3-pip

# 4. rkllama는 릴리스/README 기준으로 설치
git clone https://github.com/NotPunchnox/rkllama.git
cd rkllama
# 이후 과정은 저장소의 README에 맞춰 빌드 또는 릴리스 바이너리 설치

운영 단계에서는 rkllama를 직접 터미널에서 실행해 본 뒤, 안정적으로 동작하면 systemd 서비스로 등록합니다. 앱은 이 서버를 HTTP API로 호출하게 만들면 모델 서버와 로봇 제어 코드를 분리할 수 있습니다.

# 예시: 포트가 열렸는지 확인
ss -lntp | grep -E '8080|11434|8000'

# 예시: 서비스 로그 추적
journalctl -u rkllama -f

참고 링크: rkllama GitHub, Rockchip RKNN Toolkit2, Radxa RKLLM Installation

LLM을 보드에서 돌릴 때 현실적인 기준

소형 보드에서 대형 언어 모델을 돌릴 때는 모델 크기보다 RAM, 양자화 형식, 초당 토큰 수, 발열 지속성이 중요합니다. 실습에서는 작은 모델로 명령 분류, 요약, 장치 상태 설명처럼 범위를 좁히는 편이 좋습니다.

  • 대화형 챗봇보다 "센서 이상 상태를 자연어로 설명" 같은 좁은 작업이 성공률이 높습니다.
  • 모델 파일은 SD카드보다 eMMC/NVMe에 두면 로딩이 안정적입니다.
  • 모델 서버를 systemd로 등록하고, 앱은 HTTP API로 호출하면 교체와 재시작이 쉽습니다.
Orange Pi 5 Pro 계열: RK3588 6 TOPS NPU 운영 메모

RK3588 계열은 6 TOPS급 NPU를 갖고 있어 객체 탐지, 이미지 분류, 일부 LLM 추론 실험에 적합합니다. 예전 문서에서 강조했던 것처럼, Qwen 계열 소형 모델이나 Llama 계열 경량 모델을 RKLLM 형식으로 변환한 뒤 rkllama 같은 서버로 구동하는 흐름이 핵심입니다.

  • 비전 모델: PyTorch/ONNX 모델 → rknn-toolkit2.rknn → 보드의 RKNN Runtime에서 추론.
  • LLM 모델: Hugging Face 모델 → rkllm-toolkit.rkllm → 보드의 RKLLM Runtime 또는 rkllama에서 추론.
  • 앱 연동: 로봇 제어 앱이 직접 모델을 로드하지 말고, 로컬 모델 서버에 요청을 보내는 구조가 유지보수에 좋습니다.
  • 성능 판단: "실행된다"보다 초당 토큰 수, 첫 토큰 지연, 메모리 사용량, 10분 이상 연속 실행 시 온도가 중요합니다.
Ollama 자체는 사용하기 쉽지만 Rockchip NPU를 항상 바로 활용하는 것은 아닙니다. Rockchip NPU 가속을 목표로 할 때는 rkllama, RKLLM Runtime, 보드 제조사 SDK 문서를 별도로 확인해야 합니다.
Radxa Cubie A7Z: Allwinner A733 / Vivante VIP9000 NPU 운영 메모

Radxa Cubie A7Z는 Allwinner A733 SoC와 Vivante VIP9000 계열 3 TOPS@INT8 NPU를 쓰는 보드입니다. 따라서 Rockchip 보드처럼 .rknn, .rkllm, rkllama를 쓰는 흐름이 아니라, Radxa Cubie NPU 문서의 ACUITY Toolkit → NBG(Network Binary Graph) → VIPLite/vpm_run 흐름으로 이해해야 합니다.

구성 요소 역할 사용 위치
ACUITY Toolkit ONNX, TensorFlow, TFLite, PyTorch, Caffe, DarkNet, Keras 모델을 IR로 변환하고 양자화한 뒤 NPU용 코드와 NBG를 만듭니다. X86 Linux PC의 Docker 환경
network_binary.nb Vivante NPU에서 바로 실행할 수 있는 사전 컴파일된 NBG 파일입니다. A7Z 보드로 복사
VIPLite / vpm_run 보드에서 NBG 모델을 로드하고 입력 텐서로 추론을 시험합니다. A7Z 보드
nbinfo NBG의 입력·출력 shape, 양자화 정보, 메모리 사용량, 레이어 통계를 확인합니다. X86 Linux PC
uint8, pcq, int16 성능과 정확도의 균형을 맞추는 양자화 선택지입니다. uint8 정확도가 떨어지면 pcq 또는 int16을 다시 시험합니다. ACUITY 변환 단계
  1. X86 Linux PC에 Docker를 설치하고 A733용 ACUITY Docker 이미지(ubuntu-npu:v2.0.10.1)를 불러옵니다.
  2. 컨테이너 안에서 ai-sdk를 내려받고, A733용 환경인 source env.sh v3를 적용합니다.
  3. ONNX/TFLite/Keras 같은 모델과 보정 데이터를 준비한 뒤 parse, inference, quantization 단계를 거칩니다.
  4. 정확도가 낮으면 uint8만 고집하지 말고 pcqint16으로 다시 비교합니다.
  5. pegasus_export_ovx.sh 모델폴더 양자화방식으로 내보내고, 생성된 *_nbg_unify/network_binary.nb를 확보합니다.
  6. nbinfo로 입력 크기, 출력 개수, 메모리 요구량을 확인한 뒤 A7Z 보드로 .nb 파일과 입력 텐서를 복사합니다.
  7. 보드에서 vpm_run을 A733 옵션으로 빌드하고, VIPLite 라이브러리 경로를 잡은 뒤 sample.txt로 추론을 실행합니다.

X86 Linux PC에서 변환 환경을 만드는 예시

# A733용 ACUITY Docker 이미지 준비
unzip docker_images_v2.0.x.zip
cd docker_images_v2.0.x
unzip ubuntu-npu_v2.0.10.1.tar.zip
sudo docker load -i ubuntu-npu_v2.0.10.1.tar

# 작업 폴더를 컨테이너 /workspace로 연결
mkdir docker_data
cd docker_data
sudo docker run --ipc=host -itd -v ${PWD}:/workspace --name allwinner_v2.0.10.1 ubuntu-npu:v2.0.10.1 /bin/bash
sudo docker exec -it allwinner_v2.0.10.1 /bin/bash

# 컨테이너 안: A733은 v3 환경 사용
git clone https://github.com/ZIFENG278/ai-sdk.git
cd ai-sdk/models
source env.sh v3
cp ../scripts/* .

# 모델별 parse/quantization 후 NBG 내보내기
pegasus_inference.sh MobileNetV2_Imagenet/ pcq
pegasus_export_ovx.sh MobileNetV2_Imagenet pcq

A7Z 보드에서 NBG를 시험하는 예시

git clone https://github.com/ZIFENG278/ai-sdk.git
cd ai-sdk/examples/vpm_run
make AI_SDK_PLATFORM=a733
make install AI_SDK_PLATFORM=a733 INSTALL_PREFIX=./

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/rock/ai-sdk/viplite-tina/lib/aarch64-none-linux-gnu/v2.0
cd ./etc/npu/vpm_run

# sample.txt에는 network_binary.nb와 입력 tensor/dat 파일 경로를 적습니다.
./vpm_run -s sample.txt -l 10 -d 1
시험 대비 핵심: A7Z의 NPU 활용은 "Ollama를 설치하면 NPU가 자동으로 돈다"가 아닙니다. 공식 흐름은 비전·음성·센서 모델을 ACUITY로 변환하고, NBG 파일을 보드에서 VIPLite/vpm_run 또는 관련 API로 실행하는 방식입니다. LLM 실험은 먼저 CPU 또는 검증된 런타임으로 가능성을 확인하고, NPU 지원 여부는 모델 형식과 SDK 문서를 따로 확인해야 합니다.

공식 문서 출처: Radxa Cubie A7Z, Vivante NPU SDK guide, ACUITY environment, ACUITY usage, vpm_run, NBinfo, Model Zoo

10. 장애 대응 체크리스트

문제 해결은 추측이 아니라 관찰 순서입니다. 전원, 부팅, 네트워크, 서비스, 앱 로그 순서로 좁혀 가면 대부분의 AIoT 장애를 찾을 수 있습니다.

증상 확인 명령 볼 것
부팅 후 접속 안 됨 ip addr, 공유기 접속 목록 IP가 바뀌었는지, Wi-Fi가 연결됐는지 확인합니다.
서비스가 자동 실행되지 않음 systemctl status 서비스명 경로, 권한, 가상환경 Python 경로가 맞는지 봅니다.
프로그램이 바로 종료됨 journalctl -u 서비스명 -n 100 모듈 없음, 설정 파일 없음, 장치 권한 오류를 찾습니다.
카메라가 안 잡힘 ls /dev/video*, dmesg 장치 인식, 케이블, 드라이버 로딩 여부를 확인합니다.
디스크가 꽉 참 df -h, du -sh * 로그, 영상, 모델 캐시가 공간을 차지하는지 봅니다.
느려지거나 멈춤 top, free -h, 온도 확인 CPU 100%, 메모리 부족, 발열 스로틀링을 확인합니다.
운영용 장치에는 최소한 부팅 로그, 앱 로그, 설정 파일 백업, 마지막 정상 이미지가 있어야 합니다. 수업 프로젝트라도 이 습관이 있으면 발표 직전 복구가 훨씬 쉬워집니다.