網頁

顯示具有 docker 標籤的文章。 顯示所有文章
顯示具有 docker 標籤的文章。 顯示所有文章

2025年6月25日 星期三

更改 Docker Root Dir

參考 https://ithelp.ithome.com.tw/articles/10235112
參考 https://medium.com/@calvineotieno010/change-docker-default-root-data-directory-a1d9271056f4

$ docker info
$ vi /etc/docker/daemon.json
{
  "data-root": "/path/to/new/docker_data"
}
$ sudo systemctl stop docker
$ sudo systemctl stop docker.socket
$ sudo rsync -avh /var/lib/docker/* /path/to/new/docker_data
$ sudo systemctl start docker
$ sudo systemctl start docker.socket
$ docker info

2025年6月12日 星期四

安裝 Flux & ComfyUI

參考 https://www.jetson-ai-lab.com/tutorial_comfyui_flux.html

$ sudo jtop
CUDA: 12.2.140
cuDNN: 8.9.4.25
TensorRT: 8.6.2.3

因為需要從 cuda-12.2 更新到 cuda-12.6
而在更新的過程中,會移除 Deepstream-7.0
所以需要自己安裝 Deepstream-7.1

記錄下目前的版本資料
$ dpkg -l>dekg_jp6.0.txt

$ wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-aarch64.sh
$ chmod +x Miniconda3-latest-Linux-aarch64.sh
$ ./Miniconda3-latest-Linux-aarch64.sh
$ conda update conda
$ conda create -n comfyui python=3.10
$ conda init bash
$ cat .bashrc
$ conda activate comfyui
$ conda info --envs
$ conda deactivate
$ conda activate comfyui
$ conda list

$ wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/arm64/cuda-keyring_1.1-1_all.deb
$ sudo dpkg -i cuda-keyring_1.1-1_all.deb
$ sudo apt-get update
$ sudo apt-get -y install cuda-toolkit-12-6 cuda-compat-12-6
$ update-alternatives --list cuda
$ update-alternatives --display cuda
$ sudo update-alternatives --config cuda
cuda-12.6

$ sudo apt-get install cudnn=9.5.1-1
$ sudo apt-get install python3-libnvinfer=9.5.1-1
The following packages will be REMOVED:
  deepstream-7.0 libnvparsers-dev nvidia-tensorrt-dev
$ sudo apt-get install python3-libnvinfer-dev=10.6.0.26-1+cuda12.6
$ sudo jtop
CUDA: 12.6.77
cuDNN: 9.5.1
TensorRT: 10.6.0.26
$ wget --content-disposition 'https://api.ngc.nvidia.com/v2/resources/org/nvidia/deepstream/7.1/files?redirect=true&path=deepstream-7.1_7.1.0-1_arm64.deb' -O deepstream-7.1_7.1.0-1_arm64.deb
$ sudo apt-get install ./deepstream-7.1_7.1.0-1_arm64.deb

$ export BNB_CUDA_VERSION=126
$ export LD_LIBRARY_PATH=/usr/local/cuda-12.6/lib64:$LD_LIBRARY_PATH

$ git clone https://github.com/timdettmers/bitsandbytes.git
$ cd bitsandbytes

$ pip uninstall numpy
$ pip install "numpy<2.0"
$ mkdir -p build
$ cd build
$ cmake .. -DCOMPUTE_BACKEND=cuda -DCUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-12.6
$ make -j$(nproc)
$ cd ..
$ python setup.py install

$ pip install http://jetson.webredirect.org/jp6/cu124/+f/5fe/ee5f5d1a75229/torch-2.3.0-cp310-cp310-linux_aarch64.whl
$ pip install http://jetson.webredirect.org/jp6/cu124/+f/988/cb71323efff87/torchvision-0.18.0a0+6043bc2-cp310-cp310-linux_aarch64.whl
$ pip install http://jetson.webredirect.org/jp6/cu124/+f/0aa/a066463c02b4a/torchaudio-2.3.0+952ea74-cp310-cp310-linux_aarch64.whl

$ python3
>>> import bitsandbytes as bnb
>>> print(bnb.__version__)

$ git clone https://github.com/comfyanonymous/ComfyUI.git
$ cd ComfyUI
$ pip install -r requirements.txt
$ cd custom_nodes
$ git clone https://github.com/ltdrdata/ComfyUI-Manager.git
$ cd ..
$ mkdir workflows
$ cd workflows
$ wget https://www.jetson-ai-lab.com/assets/workflow_agx_orin_4steps.json
$ cd ..
到 https://huggingface.co/black-forest-labs/FLUX.1-schnell/tree/main
下載 flux1-schnell.safetensors 放到 models/unet
下載 ae.safetensors 放到 models/vae/FLUX1
到 https://huggingface.co/stabilityai/stable-diffusion-3-medium/tree/main/text_encoders
下載 clip_l.safetensors 和 t5xxl_fp8_e4m3fn.safetensors 放到 models/clip
$ python main.py --port=8080
http://127.0.0.1:8080/
Load workflow_agx_orin_4steps.json 時,需修改 "Load VAE" 的 vae_name 到 FLUX1/ae.safetensors

記錄下目前的版本資料
$ dpkg -l>dekg_jp6.0_cuda-12.6.txt

若需要將 cuda-12.6 還回 cuda-12.2
$ cd jetpack_6.0
$ ./download.sh
$ ./install.sh
參考記錄下來的版本資料 dekg_jp6.0.txt dekg_jp6.0_cuda-12.6.txt
移除不必要的 package
$ sudo apt-get remove --purge package

參考 https://catalog.ngc.nvidia.com/orgs/nvidia/containers/l4t-cuda/tags
$ xhost +
$ docker run -it --rm --net=host --runtime nvidia\
  -e DISPLAY=$DISPLAY \
  -v /tmp/.X11-unix/:/tmp/.X11-unix \
  nvcr.io/nvidia/l4t-cuda:11.4.19-runtime
$ docker run -it --rm --net=host --runtime nvidia\
  -e DISPLAY=$DISPLAY \
  -v /tmp/.X11-unix/:/tmp/.X11-unix \
  nvcr.io/nvidia/l4t-cuda:12.2.12-runtime
$ docker run -it --rm --net=host --runtime nvidia\
  -e DISPLAY=$DISPLAY \
  -v /tmp/.X11-unix/:/tmp/.X11-unix \
  nvcr.io/nvidia/l4t-cuda:12.6.11-runtime
docker: Error response from daemon: failed to create task for container: 
failed to create shim task: OCI runtime create failed: 
failed to create NVIDIA Container Runtime: failed to construct OCI spec modifier: 
requirements not met: unsatisfied condition: cuda>=12.6 (cuda=12.2): unknown.


$ docker run -it --rm --net=host --runtime nvidia\
  -e DISPLAY=$DISPLAY \
  -v /tmp/.X11-unix/:/tmp/.X11-unix \
  -w /opt/nvidia/deepstream/deepstream-7.0 \
  nvcr.io/nvidia/deepstream-l4t:7.0-samples-multiarch

docker run -it --rm --net=host --runtime nvidia\
  -e DISPLAY=$DISPLAY \
  -v /tmp/.X11-unix/:/tmp/.X11-unix \
  -w /opt/nvidia/deepstream/deepstream-7.1 \
  nvcr.io/nvidia/deepstream-l4t:7.1-samples-multiarch

2025年2月4日 星期二

ASR 語音辨識

參考 https://speaches-ai.github.io/speaches/
參考 https://github.com/speaches-ai/speaches/tree/master

curl --silent --remote-name https://raw.githubusercontent.com/speaches-ai/speaches/master/compose.yaml
curl --silent --remote-name https://raw.githubusercontent.com/speaches-ai/speaches/master/compose.cuda.yaml
curl --silent --remote-name https://raw.githubusercontent.com/speaches-ai/speaches/master/compose.cuda-cdi.yaml
export COMPOSE_FILE=compose.cuda-cdi.yaml

安裝使用 CUDA with CDI(Container Device Interface) feature enabled
sudo nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml

修改 compose.cuda-cdi.yaml, 加入 command, 並修改 devices
services:
  speaches:
    command: ["uvicorn", "--factory", "speaches.main:create_app", "--ws-ping-interval", "1000", "--ws-ping-timeout", "1200"]
          # WARN: requires Docker Compose 2.24.2
          # https://docs.docker.com/reference/compose-file/merge/#replace-value
          devices:
            - driver: nvidia
              device_ids: ['0']
              capabilities:
                - gpu

伺服器端 log 出現下列錯誤
websockets.exceptions.ConnectionClosedError: sent 1011 (internal error) keepalive ping timeout; no close frame received
compose.cuda-cdi.yaml 的 command 加入 ws-ping-interval ws-ping-timeout

$ docker compose up --detach
$ docker compose stop
$ docker compose rm
$ docker compose logs
$ docker inspect speaches
$ docker cp speaches:/home/ubuntu/speaches/speaches/config.py .

$ docker compose exec speaches sh
$ docker compose run -d speaches uvicorn --factory speaches.main:create_app --ws-ping-interval=10 --ws-ping-timeout=12

伺服器端 log 出現下列錯誤
INFO:speaches.routers.stt:audio_receiver:262:Not enough speech in the last 30.0 seconds.
$ vi speaches/src/speaches/config.py
inactivity_window_seconds: float = 1000.0

說明文件
http://localhost:8000/docs
http://localhost:8000/redoc

$ curl -X POST -F "file=@/mnt/Data/Whisper/examples/《大隋说书人 》 01.mp3" -F "prompt=歡迎收聽第一集處女觀大隨雍洲且墨城深秋夜" -F "language=zh" http://localhost:8000/v1/audio/transcriptions

ubuntu Settings/Sound:Input 選擇正確輸入源,螢幕上的音量可以顯示輸入音量
列出可用音源輸入
$ arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: ALCS1200A Analog [ALCS1200A Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 2: ALCS1200A Alt Analog [ALCS1200A Alt Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

使用 card 0
$ ffmpeg -f alsa -i hw:0 -acodec libmp3lame -b:a 128k -abr 1 aaa.mp3
按q, 停止

因為使用 -i hw:0, 無法錄到聲音, 改用 -i default
$ arecord -L
default
    Playback/recording through the PulseAudio sound server

使用預設音源輸入
$ ffmpeg -f alsa -i default -acodec libmp3lame -b:a 128k -abr 1 aaa.mp3
按q, 停止
$ ffmpeg -loglevel quiet -f alsa -i default -ac 1 -ar 16000 -f s16le aaa.wav
按q, 停止
去除 mp3 的 metadata
$ ffmpeg -hide_banner -i '/mnt/Data/Whisper/examples/《大隋说书人 》 01.mp3' -c:v copy -c:a copy -map_metadata -1 test.mp3
轉 mp3 到 pcm
$ ffmpeg -i test.mp3 -f s16le -ar 16000 -ac 1 test.pcm

$ cat test.pcm | pv -qL 32000 | websocat --no-close --binary 'ws://localhost:8000/v1/audio/transcriptions?language=zh'

客戶端出現下列錯誤
Closing WebSocket connection due to ping timeout
命令中加入 --ping-timeout 和 --ping-interval

$ cat test.pcm | pv -qL 32000 | websocat --no-close --binary --ping-timeout 12000 --ping-interval 10000 'ws://localhost:8000/v1/audio/transcriptions?language=zh'

由麥克風輸入,產生 pcm 檔
$ ffmpeg -f alsa -ar 16000 -i default -ac 1 -f s16le aaa.pcm
轉成 mp3
$ ffmpeg -f s16le -ar 16000 -ac 1 -i aaa.pcm -codec:a libmp3lame aaa.mp3
$ cat aaa.pcm | pv -aL 32000 | websocat --no-close --binary --ping-timeout 12000 --ping-interval 10000 'ws://localhost:8000/v1/audio/transcriptions?language=zh'

測試 CLI
export OPENAI_BASE_URL=http://localhost:8000/v1/
export OPENAI_API_KEY="cant-be-empty"
openai api audio.transcriptions.create -m Systran/faster-whisper-large-v3 -f '/mnt/Data/Whisper/examples/《大隋说书人 》 01.mp3' --response-format text


申請 OPENAI_API_KEY, 並測試 
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

curl https://api.openai.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer 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" \
  -d '{
    "model": "gpt-4o-mini",
    "store": true,
    "messages": [
      {"role": "user", "content": "write a haiku about ai"}
    ]
  }'

2024年9月26日 星期四

MMTracking 學習紀錄

參考 https://mmtracking.readthedocs.io/en/latest/index.html
參考 https://github.com/open-mmlab/mmtracking

$ git clone https://github.com/open-mmlab/mmtracking.git

$ docker run --gpus all -it --rm nvcr.io/nvidia/pytorch:21.05-py3
$ docker run --gpus all -it --name MMTracking nvcr.io/nvidia/pytorch:21.05-py3
$ docker start MMTracking
$ docker attach MMTracking
# <ctrl+p><ctrl+q>
$ docker attach MMTracking
$ docker stop MMTracking
$ docker rm MMTracking

$ echo $DISPLAY
$ export DISPLAY=:0
$ xhost +
$ docker run --gpus all -it --name MMTracking --shm-size=8G \
  --net=host -e DISPLAY=$DISPLAY -e XAUTHORITY=/tmp/xauth \
  -e QT_X11_NO_MITSHM=1 \
  -v /tmp/.X11-unix/:/tmp/.X11-unix \
  -v ~/.Xauthority:/tmp/xauth \
  -v /etc/localtime:/etc/localtime \
  -v /mnt/Data/MMTracking/mmtracking:/workspace/mmtracking \
  nvcr.io/nvidia/pytorch:21.05-py3

# pip install git+https://github.com/votchallenge/toolkit.git
# nvidia-smi
CUDA Version: 12.2
# pip list
opencv-python                    4.10.0.84
torch                            1.9.0a0+2ecb2c7

# pip install mmcv-full -f https://download.openmmlab.com/mmcv/dist/cu122/torch1.9.0/index.html
#### 出現下列錯誤
####    cv.gapi.wip.GStreamerPipeline = cv.gapi_wip_gst_GStreamerPipeline
####AttributeError: partially initialized module 'cv2' has no attribute 'gapi_wip_gst_GStreamerPipeline' (most likely due to a circular import)
#### 解決
# pip install opencv-python==4.5.1.48

# pip install mmdet==2.28.2
# pip install mmengine==0.10.4
# pip list
mmcv-full                        1.7.2
mmdet                            2.28.2
mmengine                         0.10.4
pillow                           10.4.0
# cd /workspace/mmtracking/
# pip install -r requirements/build.txt
# pip install -v -e .
# pip install git+https://github.com/JonathonLuiten/TrackEval.git
# pip install git+https://github.com/lvis-dataset/lvis-api.git
# pip install git+https://github.com/TAO-Dataset/tao.git

# python demo/demo_mot_vis.py configs/mot/deepsort/deepsort_faster-rcnn_fpn_4e_mot17-private-half.py \
  --input demo/demo.mp4 --output mot.mp4 --show
#### 出現下列錯誤
####    from .cv2 import *
####ImportError: libGL.so.1: cannot open shared object file: No such file or directory
#### 解決
# apt-get update
# apt-get install libgl1
#### 出現下列錯誤
####    NumpyArray = npt.NDArray[Any]
####AttributeError: module 'numpy.typing' has no attribute 'NDArray'
#### 解決
# pip install Pillow==9.5.0
#### 出現下列錯誤
#### Could not load the Qt platform plugin "xcb" in "/opt/conda/lib/python3.8/site-packages/cv2/qt/plugins" even though it was found.
####This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
#### 查詢錯誤所在
# export QT_DEBUG_PLUGINS=1
####Cannot load library /opt/conda/lib/python3.8/site-packages/cv2/qt/plugins/platforms/libqxcb.so: (libSM.so.6: cannot open shared object file: No such file or directory)
#### 解決
# apt-get install -y libsm6 libxext6 libxrender-dev
# pip install opencv-contrib-python==4.5.1.48

# wget https://download.openmmlab.com/mmtracking/mot/ocsort/mot_dataset/ocsort_yolox_x_crowdhuman_mot17-private-half_20220813_101618-fe150582.pth
# python demo/demo_mot_vis.py configs/mot/ocsort/ocsort_yolox_x_crowdhuman_mot17-private-half.py \
  --checkpoint ocsort_yolox_x_crowdhuman_mot17-private-half_20220813_101618-fe150582.pth \
  --input demo/demo.mp4 --output mot.mp4 --show

# wget https://download.openmmlab.com/mmtracking/vid/selsa/selsa_faster_rcnn_r101_dc5_1x_imagenetvid/selsa_faster_rcnn_r101_dc5_1x_imagenetvid_20201218_172724-aa961bcc.pth
# python demo/demo_vid.py configs/vid/selsa/selsa_faster_rcnn_r101_dc5_1x_imagenetvid.py \
  --checkpoint selsa_faster_rcnn_r101_dc5_1x_imagenetvid_20201218_172724-aa961bcc.pth \
  --input demo/demo.mp4 --show

# python demo/demo_sot.py configs/sot/siamese_rpn/siamese_rpn_r50_20e_lasot.py \
  --input demo/demo.mp4 --output sot.mp4 --show
#### 用滑鼠框出要追蹤的物件,按空白鍵

MMOCR 學習紀錄

參考 https://mmocr.readthedocs.io/en/dev-1.x/
參考 https://github.com/open-mmlab/mmocr

$ docker run --gpus all -it --rm nvcr.io/nvidia/pytorch:21.05-py3
$ docker run --gpus all -it --name MMOCR nvcr.io/nvidia/pytorch:21.05-py3
$ docker start MMOCR
$ docker attach MMOCR
# <ctrl+p><ctrl+q>
$ docker attach MMOCR
$ docker stop MMOCR
$ docker rm MMOCR
$ docker run --gpus all -it --name MMOCR --shm-size=8G \
  -v /mnt/Data/MMOCR/mmocr:/workspace/mmocr \
  -v /mnt/QNAP_A/ImageData/ICDAR:/mmocr/data \
  nvcr.io/nvidia/pytorch:21.05-py3

# pip install -U openmim
#### 出現下列錯誤
####ERROR: After October 2020 you may experience errors when installing or updating packages. This is because pip will change the way that it resolves dependency conflicts.
####We recommend you use --use-feature=2020-resolver to test your packages with the new resolver before it becomes the default.
#### 不用擔心

確認 https://mmocr.readthedocs.io/en/dev-1.x/get_started/install.html 底部的版本資訊
安裝正確版本套件
# mim list
# mim install mmengine==
# mim install mmengine
# mim install mmcv==2.0.1
#### 出現下列錯誤
####    cv.gapi.wip.GStreamerPipeline = cv.gapi_wip_gst_GStreamerPipeline
####AttributeError: partially initialized module 'cv2' has no attribute 'gapi_wip_gst_GStreamerPipeline' (most likely due to a circular import)
#### 解決
#### 因為目前 opencv-python 版本為 4.10.0.84, 降版本
# pip install opencv-python==4.5.1.48
# mim install mmcv==2.0.1
# mim install mmdet==3.1.0
# cd /workspace/mmocr/
# pip install -v -e .
# pip install opencv-python-headless==4.5.1.48
# pip install -r requirements/albu.txt
# pip install -r requirements.txt
# python tools/infer.py demo/images --det DBNet --rec CRNN --print-result \
  --save_pred --save_vis --out-dir='results/' --batch-size=2

2024年8月2日 星期五

有用的 docker 命令

$ sudo docker exec -i -t container_name /bin/bash
$ docker cp container_id:/path /host/path

2024年8月1日 星期四

docker change Root Dir

$ systemctl stop docker
$ sud rsync -a /var/lib/docker/ /mnt/Data/docker-data
$ sudo vi /etc/docker/daemon.json
{
    "data-root": "/mnt/Data/docker-data",
    "runtimes": {
        "nvidia": {
            "path": "nvidia-container-runtime",
            "runtimeArgs": []
        }
    }
}

$ systemctl start docker
$ systemctl status docker
$ sudo docker info


2023年10月11日 星期三

安裝 Ubuntu 20.04

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install ssh

$ sudo vi /etc/fstab
#中間的空格要使用 tab
ip:/share_folder /mnt/mount_folder nfs defaults,bg 0 0
$ cd /mnt
$ sudo mkdir QNAP_A QNAP_B
$ sudo mount -a

$ mkdir -p ~/.config/autostart
$ cp /usr/share/applications/vino-server.desktop ~/.config/autostart/
$ gsettings set org.gnome.Vino prompt-enabled false
$ gsettings set org.gnome.Vino require-encryption false
$ gsettings set org.gnome.Vino authentication-methods "['vnc']"
$ gsettings set org.gnome.Vino vnc-password $(echo -n 'ChangeToYourPasswd'|base64)
$ sudo vi /etc/gdm3/custom.conf
WaylandEnable=false
AutomaticLoginEnable = true
AutomaticLogin = UserLoginName
$ vi vino.sh
DISP=`ps -u $(id -u) -o pid= | \
    while read pid; do
        cat /proc/$pid/environ 2>/dev/null | tr '\0' '\n' | grep '^DISPLAY=:'
    done | grep -o ':[0-9]*' | sort -u`
echo $DISP
/usr/lib/vino/vino-server --display=$DISP
$ chmod +x vino.sh

依據 使用最新版本的 driver
CUDA Toolkit and Corresponding Driver Versions
https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html
dGPU Setup for Ubuntu
https://docs.nvidia.com/metropolis/deepstream/dev-guide/text/DS_Quickstart.html
Ubuntu 20.04
GStreamer 1.16.3
NVIDIA driver 525.125.06
CUDA 12.1
TensorRT 8.5.3.1

$ sudo ubuntu-drivers devices
$ sudo apt-get install nvidia-driver-535
$ sudo reboot
$ wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-keyring_1.1-1_all.deb
$ sudo dpkg -i cuda-keyring_1.1-1_all.deb
$ sudo apt-get update
$ sudo apt-get -y install cuda-12-2
$ sudo apt-get -y install cuda-12-1

安裝 cuDNN
參考 https://docs.nvidia.com/deeplearning/cudnn/install-guide/index.html
到 2.2. Downloading cuDNN for Linux(https://developer.nvidia.com/cudnn)
下載 Local Install for Ubuntu18.04 x86_64(Deb)
$ sudo apt-get install zlib1g
$ sudo dpkg -i cudnn-local-repo-ubuntu2004-8.9.5.29_1.0-1_amd64.deb
sudo cp /var/cudnn-local-repo-ubuntu2004-8.9.5.29/cudnn-local-98C06E99-keyring.gpg /usr/share/keyrings/
$ sudo apt-get update
$ apt list -a libcudnn8
$ sudo apt-get install libcudnn8=8.9.5.29-1+cuda12.2
$ sudo apt-get install libcudnn8-dev=8.9.5.29-1+cuda12.2
$ sudo apt-get install libcudnn8-samples=8.9.5.29-1+cuda12.2
$ update-alternatives --display libcudnn
$ cp -r /usr/src/cudnn_samples_v8/ .
$ cd cudnn_samples_v8/mnistCUDNN/
$ sudo apt-get install libfreeimage3 libfreeimage-dev
$ make clean && make
$ ./mnistCUDNN
...
Test passed!

安裝 TensorRT 8.6.1
https://docs.nvidia.com/deeplearning/tensorrt/archives/tensorrt-861/install-guide/index.html
$ sudo apt-get install python3-pip
$ sudo apt-get install python3.8.venv
$ python3 -m venv envs/tensorrt
$ source envs/tensorrt/bin/activate
$ pip3 install --upgrade pip
$ python3 -m pip install --extra-index-url https://pypi.nvidia.com tensorrt_libs
$ python3 -m pip install --extra-index-url https://pypi.nvidia.com tensorrt_bindings
$ python3 -m pip install --upgrade tensorrt
$ python3 -m pip install --upgrade tensorrt_lean
$ python3 -m pip install --upgrade tensorrt_dispatch
測試  TensorRT Python
$ python3
>>> import tensorrt
>>> print(tensorrt.__version__)
>>> assert tensorrt.Builder(tensorrt.Logger())
>>> import tensorrt_lean as trt
>>> print(trt.__version__)
>>> assert trt.Builder(trt.Logger())
>>> import tensorrt_dispatch as trt
>>> print(trt.__version__)
>>> assert trt.Builder(trt.Logger())

連結 https://developer.nvidia.com/tensorrt 按 GET STARTED
連結 https://developer.nvidia.com/tensorrt-getting-started 按 DOWNLOAD NOW
選擇 TensorRT 8
選擇 TensorRT 8.6 GA
TensorRT 8.6 GA for Ubuntu 20.04 and CUDA 12.0 and 12.1 DEB local repo Package
$ sudo dpkg -i nv-tensorrt-local-repo-ubuntu2004-8.6.1-cuda-12.0_1.0-1_amd64.deb
$ sudo cp /var/nv-tensorrt-local-repo-ubuntu2004-8.6.1-cuda-12.0/nv-tensorrt-local-9A1EDFBA-keyring.gpg /usr/share/keyrings/
$ sudo apt-get update
$ sudo apt-get install tensorrt
$ sudo apt-get install libnvinfer-lean8
$ sudo apt-get install libnvinfer-vc-plugin8
$ sudo apt-get install python3-libnvinfer-lean
$ sudo apt-get install python3-libnvinfer-dispatch
$ python3 -m pip install numpy
$ sudo apt-get install python3-libnvinfer-dev
$ python3 -m pip install protobuf
$ sudo apt-get install uff-converter-tf
$ python3 -m pip install numpy onnx
$ sudo apt-get install onnx-graphsurgeon
確認安裝
$ dpkg-query -W tensorrt
tensorrt        8.6.1.6-1+cuda12.0

安裝 DeepStream
$ sudo apt-get install libssl1.1
$ sudo apt-get install libgstreamer1.0-0
$ sudo apt-get install gstreamer1.0-tools
$ sudo apt-get install gstreamer1.0-plugins-good
$ sudo apt-get install gstreamer1.0-plugins-bad
$ sudo apt-get install gstreamer1.0-plugins-ugly
$ sudo apt-get install gstreamer1.0-libav
$ sudo apt-get install libgstreamer-plugins-base1.0-dev
$ sudo apt-get install libgstrtspserver-1.0-0
$ sudo apt-get install libjansson4
$ sudo apt-get install libyaml-cpp-dev
$ sudo apt-get install libjsoncpp-dev
$ sudo apt-get install protobuf-compiler
$ sudo apt-get install gcc
$ sudo apt-get install make
$ sudo apt-get install git
$ sudo apt-get install python3

$ git clone https://github.com/edenhill/librdkafka.git
$ cd librdkafka
$ git reset --hard 7101c2310341ab3f4675fc565f64f0967e135a6a
$ ./configure
$ make
$ sudo make install
$ sudo mkdir -p /opt/nvidia/deepstream/deepstream-6.3/lib
$ sudo cp /usr/local/lib/librdkafka* /opt/nvidia/deepstream/deepstream-6.3/lib

https://catalog.ngc.nvidia.com/orgs/nvidia/resources/deepstream
下載 deepstream-6.3_6.3.0-1_arm64.deb
$ wget --content-disposition 'https://api.ngc.nvidia.com/v2/resources/nvidia/deepstream/versions/6.3/files/deepstream-6.3_6.3.0-1_amd64.deb'
$ sudo apt-get install ./deepstream-6.3_6.3.0-1_amd64.deb
$ cd /opt/nvidia/deepstream/deepstream-6.3/samples/configs/deepstream-app
$ deepstream-app -c source4_1080p_dec_infer-resnet_tracker_sgie_tiled_display_int8.txt 

安裝 Docker
https://docs.docker.com/engine/install/ubuntu/
$ sudo apt-get update
$ sudo apt-get install ca-certificates curl gnupg
$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ sudo chmod a+r /etc/apt/keyrings/docker.gpg
$ echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
$ sudo docker run --rm hello-world

安裝 NVIDIA Container Toolkit
參考 https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html
$ curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
  && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
    sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
    sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list \
  && \
    sudo apt-get update
$ sudo apt-get install -y nvidia-container-toolkit
$ sudo nvidia-ctk runtime configure --runtime=docker
$ sudo systemctl restart docker
$ sudo groupadd docker
$ sudo usermod -a -G docker $USER
$ docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi

安裝 NGC CLI
參考 https://ngc.nvidia.com/setup/installers/cli
$ wget --content-disposition https://api.ngc.nvidia.com/v2/resources/nvidia/ngc-apps/ngc_cli/versions/3.30.1/files/ngccli_linux.zip -O ngccli_linux.zip && unzip ngccli_linux.zip
$ find ngc-cli/ -type f -exec md5sum {} + | LC_ALL=C sort | md5sum -c ngc-cli.md5
$ sha256sum ngccli_linux.zip
$ chmod u+x ngc-cli/ngc
$ echo "export PATH=\"\$PATH:$(pwd)/ngc-cli\"" >> ~/.bash_profile && source ~/.bash_profile
$ ngc config set
# 直接 enter 即可
$ docker login nvcr.io
Username: $oauthtoken
Password: <Your API Key>

用 Docker 開發 DeepStream 6.3
https://docs.nvidia.com/metropolis/deepstream/dev-guide/text/DS_docker_containers.html
$ sudo docker pull nvcr.io/nvidia/deepstream:6.3-gc-triton-devel
$ export DISPLAY=:0
$ xhost +
$ docker run -it --rm --net=host --gpus all -e DISPLAY=$DISPLAY --device /dev/snd -v /tmp/.X11-unix/:/tmp/.X11-unix nvcr.io/nvidia/deepstream:6.3-gc-triton-devel
# cd samples/configs/deepstream-app
# deepstream-app -c source4_1080p_dec_infer-resnet_tracker_sgie_tiled_display_int8.txt 
# exit
$ sudo docker ps -a
$ sudo docker stop container_id
$ sudo docker rm container_id
$ sudo docker image list
$ sudo docker image rm image_id

2023年6月21日 星期三

如何在 python 中使用 tao 產生的 yolov4 模型

參考 Nvidia TAO Computer Vision Sample Workflows 產生 yolov4-tiny 模型
此 模型 與 一般產生 的 模型 不一樣
一般產生的模型 參考 tensorrt_demos 即可在 python 中使用

只能將 
tao yolo_v4_tiny export 出的模型(.etlt)用於 DeepStream
而由 
tao  converter 產生的 trt.engine 不能使用於 DeepStream 也不能在 python 中使用

有說明如何使用 tao 產生的模型在 Triton 伺服器上
在 yolov3_postprocessor.py 中發現 tao 產生的 yolo
已經將輸出的 NMS 處理過, 並將內容置於 
BatchNMS(-1,1): 偵測出的數量
BatchNMS_1(-1,200,4): 座標
BatchNMS_2(-1,200): 信心
BatchNMS_3(-1,200): 類別
輸入的方式也有改變
cv2 讀出的圖 不需 cvtColor, 也不用除以 255.0
只需將 BHWC 轉成 BCHW
img = img.transpose((2, 0, 1)).astype(np.float32)

tao 的執行是在 docker 中,所以很難除錯
發現下列命令,可以直接進入 docker 中,執行 python, 查詢版本環境等
docker run -it --rm --gpus all \
  -v "/mnt/Data/tao/yolo_v4_tiny_1.4.1":"/workspace/tao-experiments" \
  -v "/mnt/Data/TensorRT/tensorrt_demos":"/workspace/tensorrt_demos" \
  -v "/mnt/CT1000SSD/ImageData/Light":"/workspace/Light" \
  nvcr.io/nvidia/tao/tao-toolkit:4.0.0-tf1.15.5 \
  bash

將模型轉換成 TensorRT 除了使用
!tao converter -k $KEY \
                   -p Input,1x3x416x416,8x3x416x416,16x3x416x416 \
                   -e $USER_EXPERIMENT_DIR/export/trt.engine \
                   -t fp32 \
                   $USER_EXPERIMENT_DIR/export/yolov4_cspdarknet_tiny_epoch_$EPOCH.etlt
外, 也可使用
!tao-deploy yolo_v4_tiny gen_trt_engine \
  -m $USER_EXPERIMENT_DIR/export/yolov4_cspdarknet_tiny_epoch_$EPOCH.etlt \
  -e $SPECS_DIR/yolo_v4_tiny_retrain_kitti.txt \
  -k $KEY \
  --data_type fp32 \
  --batch_size 1 \
  --engine_file $USER_EXPERIMENT_DIR/export/yolov4_tao_deplay.trt
但若是要在不同平台上轉換
參考 TAO Converter 下載安裝,並執行轉換
./tao-converter_v4.0.0_trt8.5.1.7 \
  -k nvidia_tlt \
  -p Input,1x3x416x416,2x3x416x416,4x3x416x416 \
  -e yolo_v4_tiny_1.4.1/yolo_v4_tiny/export/yolov4_tao_converter_fp32.engine \
  -t fp32 \
  yolo_v4_tiny_1.4.1/yolo_v4_tiny/export/yolov4_cspdarknet_tiny_epoch_080.etlt

參考 tensorrt_demos 修改 utils/yolo_with_plugins.py, 改名成 triton_yolo_with_plugins.py 如下
"""yolo_with_plugins.py
Implementation of TrtYOLO class with the yolo_layer plugins.
"""
from __future__ import print_function
import ctypes
import numpy as np
import cv2
import tensorrt as trt
import pycuda.driver as cuda

try:
    ctypes.cdll.LoadLibrary('./plugins/libyolo_layer.so')
except OSError as e:
    raise SystemExit('ERROR: failed to load ./plugins/libyolo_layer.so.  '
                     'Did you forget to do a "make" in the "./plugins/" '
                     'subdirectory?') from e

def _preprocess_yolo(img, input_shape, letter_box=False):
    """Preprocess an image before TRT YOLO inferencing.
    # Args
        img: int8 numpy array of shape (img_h, img_w, 3)
        input_shape: a tuple of (H, W)
        letter_box: boolean, specifies whether to keep aspect ratio and
                    create a "letterboxed" image for inference
    # Returns
        preprocessed img: float32 numpy array of shape (3, H, W)
    """
    if letter_box:
        img_h, img_w, _ = img.shape
        new_h, new_w = input_shape[0], input_shape[1]
        offset_h, offset_w = 0, 0
        if (new_w / img_w) <= (new_h / img_h):
            new_h = int(img_h * new_w / img_w)
            offset_h = (input_shape[0] - new_h) // 2
        else:
            new_w = int(img_w * new_h / img_h)
            offset_w = (input_shape[1] - new_w) // 2
        resized = cv2.resize(img, (new_w, new_h))
        img = np.full((input_shape[0], input_shape[1], 3), 127, dtype=np.uint8)
        img[offset_h:(offset_h + new_h), offset_w:(offset_w + new_w), :] = resized
    else:
        img = cv2.resize(img, (input_shape[1], input_shape[0]))

    #img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    img = img.transpose((2, 0, 1)).astype(np.float32)
    #img /= 255.0
    return img

class HostDeviceMem(object):
    """Simple helper data class that's a little nicer to use than a 2-tuple."""
    def __init__(self, host_mem, device_mem):
        self.host = host_mem
        self.device = device_mem

    def __str__(self):
        return "Host:\n" + str(self.host) + "\nDevice:\n" + str(self.device)

    def __repr__(self):
        return self.__str__()

def get_input_shape(engine):
    """Get input shape of the TensorRT YOLO engine."""
    binding = engine[0]
    assert engine.binding_is_input(binding)
    binding_dims = engine.get_binding_shape(binding)
    if len(binding_dims) == 4:
        return tuple(binding_dims[2:])
    elif len(binding_dims) == 3:
        return tuple(binding_dims[1:])
    else:
        raise ValueError('bad dims of binding %s: %s' % (binding, str(binding_dims)))

def allocate_buffers(engine, context):
    """Allocates all host/device in/out buffers required for an engine."""
    inputs = []
    outputs = []
    bindings = []
    stream = cuda.Stream()
    for binding in engine:
        binding_dims = engine.get_binding_shape(binding)
        binding_dtype = engine.get_tensor_dtype(binding)
        binding_format = engine.get_tensor_format_desc(binding)
        binding_loc = engine.get_tensor_location(binding)
        binding_mode = engine.get_tensor_mode(binding)
        binding_shape = engine.get_tensor_shape(binding)
        binding_shape_inference = engine.is_shape_inference_io(binding)
        print('binding_dims:{} {} {}'.format(binding, binding_dims, binding_dtype))
        print('  {}'.format(binding_format))
        print('  {} {} {} {}'.format(binding_loc, binding_mode, binding_shape, binding_shape_inference))
        size = trt.volume(binding_dims)
        if size < 0: size *= -1;
        print('  size:{}'.format(size))
        dtype = trt.nptype(engine.get_binding_dtype(binding))
        # Allocate host and device buffers
        host_mem = cuda.pagelocked_empty(size, dtype)
        device_mem = cuda.mem_alloc(host_mem.nbytes)
        # Append the device buffer to device bindings.
        bindings.append(int(device_mem))
        # Append to the appropriate list.
        if engine.binding_is_input(binding):
            #binding_pro_shape = engine.get_profile_shape(0, binding)
            #print('  {}'.format(binding_pro_shape))
            if binding_dims[0] == -1:
                alloc_dims = np.copy(binding_dims)
                alloc_dims[0] = 1
                context.set_binding_shape(0, alloc_dims)
            inputs.append(HostDeviceMem(host_mem, device_mem))
        else:
            outputs.append(HostDeviceMem(host_mem, device_mem))
    return inputs, outputs, bindings, stream

def do_inference(context, bindings, inputs, outputs, stream, batch_size=1):
    """do_inference (for TensorRT 6.x or lower)
    This function is generalized for multiple inputs/outputs.
    Inputs and outputs are expected to be lists of HostDeviceMem objects.
    """
    # Transfer input data to the GPU.
    [cuda.memcpy_htod_async(inp.device, inp.host, stream) for inp in inputs]
    # Run inference.
    context.execute_async(batch_size=batch_size,
                          bindings=bindings,
                          stream_handle=stream.handle)
    # Transfer predictions back from the GPU.
    [cuda.memcpy_dtoh_async(out.host, out.device, stream) for out in outputs]
    # Synchronize the stream
    stream.synchronize()
    # Return only the host outputs.
    return [out.host for out in outputs]

def do_inference_v2(context, bindings, inputs, outputs, stream):
    """do_inference_v2 (for TensorRT 7.0+)
    This function is generalized for multiple inputs/outputs for full
    dimension networks.
    Inputs and outputs are expected to be lists of HostDeviceMem objects.
    """
    # Transfer input data to the GPU.
    [cuda.memcpy_htod_async(inp.device, inp.host, stream) for inp in inputs]
    # Run inference.
    context.execute_async_v2(bindings=bindings, stream_handle=stream.handle)
    # Transfer predictions back from the GPU.
    [cuda.memcpy_dtoh_async(out.host, out.device, stream) for out in outputs]
    # Synchronize the stream
    stream.synchronize()
    # Return only the host outputs.
    return [out.host for out in outputs]

class TrtYOLO(object):
    """TrtYOLO class encapsulates things needed to run TRT YOLO."""
    def _load_engine(self):
        TRTbin = 'yolo/%s.trt' % self.model
        TRTbin = self.model
        with open(TRTbin, 'rb') as f, trt.Runtime(self.trt_logger) as runtime:
            return runtime.deserialize_cuda_engine(f.read())

    def __init__(self, model, category_num=80, letter_box=False, cuda_ctx=None):
        """Initialize TensorRT plugins, engine and conetxt."""
        self.model = model
        self.category_num = category_num
        self.letter_box = letter_box
        self.cuda_ctx = cuda_ctx
        if self.cuda_ctx:
            self.cuda_ctx.push()

        self.inference_fn = do_inference if trt.__version__[0] < '7' \
                                         else do_inference_v2
        self.trt_logger = trt.Logger(trt.Logger.INFO)
        # add for errors
        # IPluginCreator not found in Plugin Registry
        # getPluginCreator could not find plugin: BatchedNMSDynamic_TRT version: 1
        # Serialization assertion plan->header.magicTag == rt::kPLAN_MAGIC_TAG failed
        trt.init_libnvinfer_plugins(self.trt_logger, namespace="")
        self.engine = self._load_engine()

        self.input_shape = get_input_shape(self.engine)

        try:
            self.context = self.engine.create_execution_context()
            self.inputs, self.outputs, self.bindings, self.stream = \
                allocate_buffers(self.engine, self.context)
        except Exception as e:
            raise RuntimeError('fail to allocate CUDA resources') from e
        finally:
            if self.cuda_ctx:
                self.cuda_ctx.pop()

    def __del__(self):
        """Free CUDA memories."""
        del self.outputs
        del self.inputs
        del self.stream

    def detect(self, img, letter_box=None):
        """Detect objects in the input image."""
        letter_box = self.letter_box if letter_box is None else letter_box
        img_h, img_w, _ = img.shape
        img_resized = _preprocess_yolo(img, self.input_shape, letter_box)
        #print(img_resized.shape, img_resized.dtype)

        # Set host input to the image. The do_inference() function
        # will copy the input to the GPU before executing.
        self.inputs[0].host = np.ascontiguousarray(img_resized)
        if self.cuda_ctx:
            self.cuda_ctx.push()
        trt_outputs = self.inference_fn(
            context=self.context,
            bindings=self.bindings,
            inputs=self.inputs,
            outputs=self.outputs,
            stream=self.stream)
        if self.cuda_ctx:
            self.cuda_ctx.pop()

        y_pred = [i.reshape(1, -1,)[:1] for i in trt_outputs]
        keep_k, boxes, scores, cls_id = y_pred
        #print(keep_k.shape)
        #print(boxes.shape)
        keep_k[0,0] = 1
        locs = np.empty((0,4), dtype=np.uint)
        cids = np.empty((0,1), dtype=np.uint)
        confs = np.empty((0,1), dtype=np.float32)
        for idx, k in enumerate(keep_k.reshape(-1)):
            mul = np.array([img_w,img_h,img_w,img_h])
            loc = boxes[idx].reshape(-1, 4)[:k] * mul
            loc = loc.astype(np.uint)
            cid = cls_id[idx].reshape(-1, 1)[:k]
            cid = cid.astype(np.uint)
            conf = scores[idx].reshape(-1, 1)[:k]
            locs = np.concatenate((locs, loc), axis=0)
            cids = np.concatenate((cids, cid), axis=0)
            confs = np.concatenate((confs, conf), axis=0)
        #print(locs.shape, cids.shape, confs.shape)
        #print(locs, cids, confs)
        return locs, confs, cids

下列程式使用上列的程式
import cv2
import numpy as np
import tensorrt as trt
import pycuda.autoinit # This is needed for initializing CUDA driver
import pycuda.driver as cuda
from utils.triton_yolo_with_plugins import TrtYOLO

#MODEL_PATH = '/workspace/tao-experiments/yolo_v4_tiny/export/yolov4_tao_convert.engine'
MODEL_PATH = '/workspace/tao-experiments/yolo_v4_tiny/export/yolov4_tao_deplay.trt'
#MODEL_PATH = '/workspace/tao-experiments/yolo_v4_tiny/export/trt.engine'
        
def main():
    trt_yolo = TrtYOLO(MODEL_PATH, 5, True)
    img_org = cv2.imread('bb.jpg')
    img = np.copy(img_org)
    print(img.shape, img.dtype)
    boxes, confs, clss = trt_yolo.detect(img, False)
    print(boxes.shape, confs.shape, clss.shape)
    print(boxes, confs, clss)
    for box, conf, clss in zip(boxes, confs, clss):
        x_min, y_min, x_max, y_max = box[0], box[1], box[2], box[3]
        cv2.rectangle(img, (x_min, y_min), (x_max, y_max), (255, 255, 255), 2)
        print(box, conf, clss)
    cv2.imwrite('aa.jpg', img)
    print('aaa')

if __name__ == '__main__':
    main()

除錯說明
訊息: Serialization assertion plan->header.magicTag == rt::kPLAN_MAGIC_TAG failed
解決: TensorRt 的版本不一致,安裝不同版本,或利用 docker
訊息: IPluginCreator not found in Plugin Registry
訊息: getPluginCreator could not find plugin: BatchedNMSDynamic_TRT version: 1
解決: 需安裝 TensorRT OSS
在 load_engine() 之前加上
trt.init_libnvinfer_plugins(self.trt_logger, namespace="")

2022年7月27日 星期三

Build VideoLAN 3.0.17.4 on Ubuntu 18.04

參考 Build VideoLAN 3.0.16 on Ubuntu 18.04
原先想要在 Ubuntu 20.04 上建立,但發現不容易

$ cd ~/Data/VLC
$ sudo git clone https://code.videolan.org/videolan/vlc.git vlc-3.0
$ cd vlc-3.0
$ sudo git branch -a
$ sudo git log --tags --simplify-by-decoration --pretty="format:%ai %d"
$ sudo git checkout tags/3.0.17.4
$ sudo git describe --tags
// 完整地回復到最後版本,並且刪除不必要的檔案
$ sudo git reset --hard
$ sudo git clean -f -d


$ docker pull ubuntu:18.04
$ docker run --name=vlc -it -v ~/Data/VLC/vlc-3.0:/root/vlc-3.0 -v ~/Data/VLC/build_vlc:/root/build_vlc ubuntu:18.04 /bin/bash
# cd /root/vlc-3.0/
# apt-get update
# apt install software-properties-common
# add-apt-repository "deb http://archive.ubuntu.com/ubuntu/ xenial main restricted universe multiverse"
# apt-get update
# apt-cache showpkg gcc-mingw-w64-base
# apt-get install gcc-mingw-w64-base=5.3.1-8ubuntu3+17
# apt-get install gcc-mingw-w64-x86-64=5.3.1-8ubuntu3+17
# apt-get install g++-mingw-w64-x86-64=5.3.1-8ubuntu3+17
# apt-get install gcc-mingw-w64-i686=5.3.1-8ubuntu3+17
# apt-get install g++-mingw-w64-i686=5.3.1-8ubuntu3+17
# apt-get install mingw-w64-tools=5.0.3-1
# apt-get install lua5.2 libtool automake autoconf autopoint make gettext pkg-config
# apt-get install qt4-dev-tools qt5-default git subversion cmake cvs 
# apt-get install wine64-development-tools libwine-dev zip p7zip nsis bzip2
# apt-get install yasm ragel ant default-jdk protobuf-compiler dos2unix
# apt-get install subversion yasm cvs cmake ragel autopoint

以下的 HOST-TRIPLET 在 win32 時換成 i686-w64-mingw32, 在 win64 時換成 x86_64-w64-mingw32
build vlc contrib
# cd /root/vlc-3.0/
# mkdir -p contrib/win32
# cd contrib/win32
# ../bootstrap --host=HOST-TRIPLET
# make fetch
//問題
curl: (56) Recv failure: Connection reset by peer
../src/x264/rules.mak:81: recipe for target '../tarballs/x264-git.tar.bz2' failed
//解決 類似失敗,再 fetch 一次
# make fetch
# make
//問題
env: 'meson': No such file or directory
../src/fribidi/rules.mak:21: recipe for target '.fribidi' failed
make: *** [.fribidi] Error 127
//解決
# apt-get install meson
//問題
meson.build:1:0: ERROR: Meson version is 0.45.1 but project requires >= 0.48.
//解決
# apt-get install python3-pip
# python3 -m pip install meson
//問題
/root/vlc-3.0/contrib/win32/fontconfig/missing: line 81: gperf: command not found
WARNING: 'gperf' is missing on your system.
//解決
# apt-get install gperf
//問題
configure: error: BD-J requires ANT, but ant was not found. Install ant or disable jar file building (--disable-bdjava-jar)
../src/bluray/rules.mak:56: recipe for target '.bluray' failed
//解決
# apt-get install ant
//問題
[javac] /root/vlc-3.0/contrib/win32/bluray/src/libbluray/bdj/java-j2se/java/io/BDFileSystemImpl.java:21: error: BDFileSystemImpl is not abstract and does not override abstract method isInvalid(File) in FileSystem
[javac] error: Source option 5 is no longer supported. Use 6 or later.
[javac] error: Target option 1.5 is no longer supported. Use 1.6 or later.
//解決
# apt-get install openjdk-8-jdk
# update-alternatives --config java
//問題
Program nasm found: NO
meson.build:397:4: ERROR: Program 'nasm' not found or not executable
//解決
# apt-get install wget
# wget https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.gz
# tar xvf nasm-2.14.02.tar.gz
# cd nasm-2.14.02/
# ./configure
# make
# make install


build vlc
# cd /root/vlc-3.0
# ./bootstrap
//問題
ERROR: flex is not installed.
//解決
# apt-get install flex
//問題
ERROR: GNU bison is not installed.
//解決
# apt-get install bison
# mkdir win32 && cd win32
# export PKG_CONFIG_LIBDIR=/root/vlc-3.0/contrib/HOST-TRIPLET/lib/pkgconfig 
# ../extras/package/win32/configure.sh --host=HOST-TRIPLET --build=x86_64-pc-linux-gnu
# make
//問題
stream_out/chromecast/cast_channel.pb.h:17:2: error: 
#error This file was generated by an older version of protoc which is
//解決
# git clone https://github.com/protocolbuffers/protobuf.git
# cd protobuf
# git checkout tags/v3.1.0
# ./autogen.sh
# ./configure
# make
# make check
# make install
# ldconfig # refresh shared library cache.
# make package-win-common
//問題
/bin/bash: wget: command not found
Makefile:1043: recipe for target 'npapi-sdk' failed
//解決
# apt-get install wget
# make package-win32-zip


Build VideoLAN 3.0.16 on Ubuntu 18.04

參考 三 VideoLAN Compile 成熟篇

下載時要指定版本
$ cd ~/Data/VLC
$ git clone https://code.videolan.org/videolan/vlc.git vlc-3.0
$ cd vlc-3.0
$ git branch -a
$ git log --tags --simplify-by-decoration --pretty="format:%ai %d"
$ git checkout tags/3.0.16
$ git describe --tags
// 完整地回復到最後版本,並且刪除不必要的檔案
$ git reset --hard
$ git clean -f -d

利用 Docker 以利之後的重新建立
$ docker pull ubuntu:18.04
$ docker run --name=vlc -it -v ~/Data/VLC/vlc-3.0:/root/vlc-3.0 -v ~/Data/VLC/build_vlc:/root/build_vlc ubuntu:18.04 /bin/bash
# <ctrl+p><ctrl+q>
$ docker attach vlc
# <ctrl+p><ctrl+q>
$ docker stop vlc
$ docker start vlc
$ docker attach vlc
$ docker ps -a
$ docker container rm vlc
$ docker image ls
$ docker image rm <image_id>


若按照說明,不指定 mingw-w64 工具的版本,在 build 64 位元 VLC 時會產生下列問題
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):
(.text$_ZGTtNSt11logic_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+0x36) 
relocation truncated to fit: R_X86_64_PC32 against undefined symbol `_ITM_RU8'
解決需要指定 mingw-w64 工具的版本
# cd /root/vlc-3.0/
# apt-get update
# apt install software-properties-common
# add-apt-repository "deb http://archive.ubuntu.com/ubuntu/ xenial main restricted universe multiverse"
# apt-get update
# apt-cache showpkg gcc-mingw-w64-base
# apt-get install gcc-mingw-w64-base=5.3.1-8ubuntu3+17
# apt-get install gcc-mingw-w64-x86-64=5.3.1-8ubuntu3+17
# apt-get install g++-mingw-w64-x86-64=5.3.1-8ubuntu3+17
# apt-get install gcc-mingw-w64-i686=5.3.1-8ubuntu3+17
# apt-get install g++-mingw-w64-i686=5.3.1-8ubuntu3+17
# apt-get install mingw-w64-tools=5.0.3-1


其他工具
# apt-get install lua5.2 libtool automake autoconf autopoint make gettext pkg-config
# apt-get install qt4-dev-tools qt5-default git subversion cmake cvs 
# apt-get install wine64-development-tools libwine-dev zip p7zip nsis bzip2
# apt-get install yasm ragel ant default-jdk protobuf-compiler dos2unix
# apt-get install subversion yasm cvs cmake ragel autopoint


以下的 HOST-TRIPLET 在 win32 時換成 i686-w64-mingw32, 在 win64 時換成 x86_64-w64-mingw32
build vlc contrib
# cd /root/vlc-3.0/
# mkdir -p contrib/win32
# cd contrib/win32
# ../bootstrap --host=HOST-TRIPLET
# make fetch
//問題 (改 mingw-w64 版本後,沒問題)
../bootstrap: 393: ../bootstrap: python3: not found
//解決
# apt-get install python3
# make
//問題
env: 'meson': No such file or directory
../src/fribidi/rules.mak:22: recipe for target '.fribidi' failed
make: *** [.fribidi] Error 127
//解決
# apt-get install meson
//問題
/root/vlc-3.0/contrib/win32/fontconfig/missing: line 81: gperf: command not found
WARNING: 'gperf' is missing on your system.
//解決
# apt-get install gperf
//問題
configure: error: Package requirements (fribidi >= 0.19.0) were not met:
No package 'fribidi' found
//解決
# apt-get install python3-pip
# python3 -m pip install meson
//問題
[javac] /root/vlc-3.0/contrib/win32/bluray/src/libbluray/bdj/java-j2se/java/io/BDFileSystemImpl.java:21: error: BDFileSystemImpl is not abstract and does not override abstract method isInvalid(File) in FileSystem
//解決
# apt-get install openjdk-8-jdk
# update-alternatives --config java
//問題
meson.build:388:4: ERROR: Program 'nasm' not found or not executable
//解決
# apt-get install wget
# wget https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.gz
# tar xvf nasm-2.14.02.tar.gz
# cd nasm-2.14.02/
# ./configure
# make
# make install
文件上說明 build i686-w64-mingw32 時,要移除 moc, uic, rcc,但是不能刪
# cd /root/vlc-3/contrib/i686-w64-mingw32/bin
# mv moc moc.bak
# mv uic uic.bak
# mv rcc rcc.bak
# rm -f i686-w64-mingw32/bin/moc i686-w64-mingw32/bin/uic i686-w64-mingw32/bin/rcc


build vlc
# cd /root/vlc-3.0
# ./bootstrap
//問題
../../extras/package/win32/../../../autotools/ylwrap: line 176: yacc: command not found
//解決
# apt-get install flex
# apt-get install bison
//問題
ERROR: flex is not installed.
//解決
# apt-get install flex
//問題
ERROR: GNU bison is not installed.
//解決
# apt-get install bison
# mkdir win32 && cd win32
# export PKG_CONFIG_LIBDIR=/root/vlc-3.0/contrib/HOST-TRIPLET/lib/pkgconfig 
# ../extras/package/win32/configure.sh --host=HOST-TRIPLET --build=x86_64-pc-linux-gnu
# make
//問題
stream_out/chromecast/cast_channel.pb.h:17:2: error:
#error This file was generated by an older version of protoc which is
//解決
# git clone https://github.com/protocolbuffers/protobuf.git
# cd protobuf
# git checkout tags/v3.1.0
# ./autogen.sh
# ./configure
# make
# make check
# make install
# ldconfig # refresh shared library cache.
//問題
libprotoc.so.11: cannot open shared object file: No such file or directory
//解決
# export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
//問題
/bin/bash: wget: command not found
Makefile:1043: recipe for target 'npapi-sdk' failed
make[4]: *** [npapi-sdk] Error 127
//解決
# apt-get install wget
//問題
gui/qt/main_interface.moc.cpp:22:1: error: 'QT_WARNING_DISABLE_DEPRECATED' 
does not name a type; did you mean 'QT_WARNING_DISABLE_INTEL'?
QT_WARNING_DISABLE_DEPRECATED
//解決
# qmake -v
# qtchooser -install qt5.6.3 /root/vlc-3.0/contrib/win32/qt/bin/qmake
# qtchooser -l
# export QT_SELECT=qt5.6.3
# qmake -v
# make package-win-common
# ls vlc-3.0.16/
# make package-win32-zip
# ls vlc-3.0.16-win32.zip 
//成功

2022年6月1日 星期三

Integrate TAO model with DeepStream SDK In Docker

參考 DeepStream Platform and OS Compatibility
參考 TensorRT Open Source Software
參考 Ubuntu 安裝 DeepStream 使用 Docker 部分

在 DeepStream Platform and OS Compatibility 文件中
DS 6.0.1
CUDA 11.4.1
cuDNN 8.2+
TRT 8.0.1
Driver R470.63.01

在 nvcr.io/nvidia/deepstream:6.0.1-devel Docker 中
Deepstream 6.0.1
TensorRT 8.0.1-1 + cuda11.3

替換 nvidia driver,不然會產生錯誤
Failed to establish dbus connection
$ apt list --installed|grep nvidia
$ sudo ubuntu-drivers devices
$ sudo apt-get remove --purge nvidia-driver-495
$ sudo apt-get install nvidia-driver-470
$ sudo reboot

確認 CUDA, TensorRT 安裝的版本
$ dpkg -l | grep -i cuda-cuda
$ dpkg -L cuda-cudart-11-5
$ dpkg -l | grep TensorRT

準備 DeepStream 開發用 Docker
$ docker pull nvcr.io/nvidia/deepstream:6.0.1-devel
$ xhost +
access control disabled, clients can connect from any host
$ sudo docker run --gpus ""device=0"" -it --rm --net=host -v /tmp/.X11-unix:/tmp/.X11-unix -v /etc/localtime:/etc/localtime -e DISPLAY=$DISPLAY -w /opt/nvidia/deepstream/deepstream-6.0 nvcr.io/nvidia/deepstream:6.0.1-devel
# cd samples/configs/deepstream-app
# deepstream-app -c source4_1080p_dec_infer-resnet_tracker_sgie_tiled_display_int8.txt 
# cd /opt/nvidia/deepstream/deepstream-6.0/sources/apps/sample_apps
/deepstream-app
# export CUDA_VER=11.4
# make
# exit

準備 TensorRT OSS 編譯環境 Docker
$ git clone -b master https://github.com/nvidia/TensorRT TensorRT_OSS-8.0.1
$ cd TensorRT_OSS-8.0.1
$ git tag -n
$ git checkout 8.0.1
$ git describe --tags
8.0.1
$ git submodule update --init --recursive
$ cat docker/ubuntu-18.04.Dockerfile | grep CUDA_VERSION
ARG CUDA_VERSION=11.3.1
$ ./docker/build.sh --file docker/ubuntu-18.04.Dockerfile --tag tensorrt-ubuntu18.04-cuda11.3.1 --cuda 11.3.1
$ ./docker/launch.sh --tag tensorrt-ubuntu18.04-cuda11.3.1 --gpus all
$ cd TensorRT
$ mkdir -p build && cd build
$ cmake .. -DTRT_LIB_DIR=$TRT_LIBPATH -DTRT_OUT_DIR=`pwd`/out
$ make -j$(nproc)
$ exit

下載主要程式,須注意版本
$ git clone https://github.com/NVIDIA-AI-IOT/deepstream_tao_apps.git
$ sudo apt install gitk
$ git branch -r
$ git checkout release/tao3.0_ds6.0.1
$ git log -1
$ sudo docker run --gpus all -it --rm --net=host \
 -v /etc/localtime:/etc/localtime \
 -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=$DISPLAY \
 -v /your_path_to/Data/TensorRT/TensorRT_OSS-8.0.1:/home/TensorRT \
 -v /your_path_to/Data/DeepStream/deepstream_tao_apps:/home/deepstream_tao_apps \
 -w /opt/nvidia/deepstream/deepstream-6.0 nvcr.io/nvidia/deepstream:6.0.1-devel
# cd /home/deepstream_tao_apps/
# ./download_models.sh 
# export CUDA_VER=11.4
# make
# cp /home/TensorRT/build/out/libnvinfer_plugin.so.8.0.1 /usr/lib/x86_64-linux-gnu/
# ./apps/tao_detection/ds-tao-detection -c configs/frcnn_tao/pgie_frcnn_tao_config.txt -i /opt/nvidia/deepstream/deepstream-6.0/samples/streams/sample_720p.h264 -d

# cd /opt/nvidia/deepstream/deepstream-6.0/sources/gst-plugins/gst-nvdsvideotemplate/
# make
# cp libnvdsgst_videotemplate.so /opt/nvidia/deepstream/deepstream-6.0/lib/gst-plugins/
# rm -rf ~/.cache/gstreamer-1.0/

# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/nvidia/deepstream/deepstream/lib/cvcore_libs
# cd /home/deepstream_tao_apps/apps/tao_others/deepstream-gaze-app
# ./deepstream-gaze-app 3 ../../../configs/facial_tao/sample_faciallandmarks_config.txt $URI ./gazenet

# cd ../deepstream-gesture-app
# ./deepstream-gesture-app 3 3 ../../../configs/bodypose2d_tao/sample_bodypose2d_model_config.txt $URI ./gesture

# cd ../deepstream-bodypose2d-app/
# ./deepstream-bodypose2d-app 3 ../../../configs/bodypose2d_tao/sample_bodypose2d_model_config.txt $URI ./body2dout

# cd ../deepstream-faciallandmark-app/
# ./deepstream-faciallandmark-app 3 ../../../configs/facial_tao/sample_faciallandmarks_config.txt $URI ./landmarks

# cd ../deepstream-emotion-app/
# ./deepstream-emotion-app 3 ../../../configs/facial_tao/sample_faciallandmarks_config.txt $URI ./landmarks

在 Jeston 上測試
$ docker pull nvcr.io/nvidia/l4t-base:r32.4.3
$ xhost +
$ sudo docker run -it --rm --net=host --runtime nvidia  -e DISPLAY=$DISPLAY -v /tmp/.X11-unix/:/tmp/.X11-unix nvcr.io/nvidia/l4t-base:r32.4.3

# export URI=rtsp://user:passwd@192.168.0.108:554/live1s2.sdp
# gst-launch-1.0 uridecodebin uri=$URI name=d d. ! nvvidconv ! nvegltransform ! nveglglessink
# gst-launch-1.0 uridecodebin uri=$URI name=d d. ! nvvidconv ! nvoverlaysink

Docker 管理

$ docker container ls -a
$ docker container rm 25810a2d47ba
$ docker container prune
$ docker image ls
$ docker image rm 2ec708416bb8
$ docker image prune -a
$ docker volume ls
$ docker network ls

2021年11月22日 星期一

gitea on QNAP (設定 Auto Start, CPU Memory 限制)

參考: http://qnap-dev.github.io/container-station-api/index.html
因為使用 QNAP 的 container station api, 不能使用 QNAP 的 2-step verification

[/share/Dockers/gitea] # cat 0_run.sh
#mkdir -p data/git
#mkdir -p data/gitea

docker run -d --name=gitea \
-p 10022:22 -p 3000:3000 \
-v /share/Dockers/gitea/data/gitea:/data/gitea \
-v /share/Dockers/gitea/data/git:/data/git \
gitea/gitea:latest

[/share/Dockers/gitea] # cat cs_get.sh
CONTAINER_ID=$(docker ps -qf "name=gitea")
echo ${CONTAINER_ID}
CONTAINER_ID=$(cd /var/lib/docker/containers && ls -d ${CONTAINER_ID}*)
echo ${CONTAINER_ID}
QIP=127.0.0.1
QPORT=8080
curl -sq -XPOST -c cookies.txt -d '{"username": "admin", "password": "password"}' http://${QIP}:${QPORT}/container-station/api/v1/login
curl -sq -XGET -b cookies.txt http://${QIP}:${QPORT}/container-station/api/v1/container/docker/${CONTAINER_ID}/all

[/share/Dockers/gitea] # cat cs_set.sh
CONTAINER_ID=$(docker ps -qf "name=gitea")
echo ${CONTAINER_ID}
CONTAINER_ID=$(cd /var/lib/docker/containers && ls -d ${CONTAINER_ID}*)
echo ${CONTAINER_ID}
QIP=127.0.0.1
QPORT=8080
curl -sq -XPOST -c cookies.txt -d '{"username": "admin", "password": "password"}' http://${QIP}:${QPORT}/container-station/api/v1/login
curl -sq -XPUT -b cookies.txt http://${QIP}:${QPORT}/container-station/api/v1/container/docker/${CONTAINER_ID}/autostart/on
curl -sq -XPOST -b cookies.txt -d \
    '{
        "cputime": 500,
        "memory": "1024m"
    }' http://${QIP}:${QPORT}/container-station/api/v1/container/docker/${CONTAINER_ID}/resource/limit

2021年11月17日 星期三

gitea on QNAP

開啟 QNAP ssh
QNAP/Control Panel/Network & File Services/Telnet / SSH
Allow SSH connection
Apply

建立 docker 使用空間
QNAP/Control Panel/Privilege/Shared Folders
Create/Shared Folder
Folder Name: Dockers
Next/Next/Finish

建立 Gitea Docker
使用 ssh 登入 QNAP
Console Management - Main menu
>> q
>> y
# cd /share/Dockers
# mkdir -p /share/Dockers/gitea
# docker pull gitea/gitea:latest
# docker run -d --name=gitea -p 10022:22 -p 3000:3000 -v /share/Dockers/gitea:/data gitea/gitea:latest

設定 Gitea 帳號
網頁登入 http://qnap_ip:3000/
底部/管理員帳戶設定
輸入 管理員帳號 密碼 電子信箱
安裝 Gitea

進入 Gitea 建立 Repository
網頁登入 http://qnap_ip:3000/
右上/+/新增儲存庫
輸入 儲存庫名稱
建立儲存庫

由 Git 匯入 Gitea
進入 git host 的目錄
> git remote add gitea http://qnap_ip:3000/UserName/Repository.git
> git push gitea --all
Username for 'http://qnap_ip:3000':
Password for 'http://UserName@qnap_ip:3000':
> git push gitea --tags
Username for 'http://qnap_ip:3000':
Password for 'http://UserName@qnap_ip:3000':

Gitea 備份 兩種方法可選
(1.進入 docker)
QNAP/Container Station/Container
按 gitea 連結,開啟 console logs
按 >_ Terminal
/bin/sh
Connect
# su - git
$ gitea dump -c /data/gitea/conf/app.ini
產生 /data/git/gitea-dump-xxxxx.zip
位於 QNAP 的 /share/Dockers/gitea/git
(2.進入 QNAP)
使用 ssh 登入 QNAP
# docker exec -u git -it -w /data/git $(docker ps -qf "name=gitea") bash -c '/app/gitea/gitea dump -c /data/gitea/conf/app.ini'
產生 /share/Dockers/gitea/git/gitea-dump-xxxxx.zip
位於 docker 的 /data/git

Gitea 還原
QNAP/Container Station/Container
按 gitea 連結,開啟 console logs
按 Stop
使用 ssh 登入 QNAP
# mkdir -p /share/Dockers/backup
# mv /share/Dockers/gitea/git/gitea-dump-xxxxx.zip /share/Dockers/backup
# cd /share/Dockers/backup
# unzip gitea-dump-xxxxx.zip
# ls /share/Dockers/backup/data/
avatars/  gitea.db   jwt/     repo-archive/
conf/     indexers/  queues/  repo-avatars/
# ls /share/Dockers/gitea/gitea/
attachments/  conf/     indexers/  log/     repo-archive/  sessions/
avatars/      gitea.db  jwt/       queues/  repo-avatars/
移除 /share/Dockers/gitea/gitea/ 內相應 /share/Dockers/backup/data/ 的資料
# mv /share/Dockers/backup/data/* /share/Dockers/gitea/gitea/
# chown -R owner.group /share/Dockers/gitea/gitea/
# rm -rf /share/Dockers/gitea/git/repositories/*
# mv /share/Dockers/backup/repos/* /share/Dockers/gitea/git/repositories/
# chown -R owner.group /share/Dockers/gitea/git/repositories/
Gitea 文件上說明,還要搬 log, database
但 log 不見了, database 使用 sqlite3, 直接是一檔案, 搬 data/gitea.db 後不須重建
QNAP/Container Station/Container
按 gitea 連結,開啟 console logs
按 Start
# rm -rf /share/Dockers/backup

Gitea Migrations 遷移
在 Gitea 1.12 以前,可以遷移 程式碼 問題 等
但在之後,無法遷移程式碼
遷移預設無法在本地端執行,需在 /data/gitea/conf/app.ini
增加下列兩行
[migrations]
ALLOW_LOCALNETWORKS = true
要遷移 Wiki 里程碑 標籤 等,需要 Access Token
網頁登入 http://qnap_ip:3000/
右上/圖標/設定/應用程式
輸入 Token 名稱
產生 Token
網頁登入 http://qnap_ip:3000/
右上/+/遷移外部儲存庫