AI 탐구노트

Gradio WebRTC : Gradio로 실시간 오디오/비디오 스트리밍 본문

AI 기술

Gradio WebRTC : Gradio로 실시간 오디오/비디오 스트리밍

42morrow 2024. 10. 15. 19:59

 

 

Gradio란

 

Gradio는 머신러닝 모델을 손쉽게 웹 인터페이스로 배포할 수 있는 Python 라이브러리입니다. 복잡한 코드나 환경 구성 없이 손쉽게 몇 안 되는 코드만으로 웹 브라우저에서 다양한 기능을 구현하고 테스트할 수 있죠. 최근까지 많은 업그레이드가 진행되면서 이미지, 텍스트, 오디오, 비디오 등의 입력 타입을 지원해 주고 있습니다. 

 

Gradio 5에서 WebRTC 지원

 

그런데, 사용하면서 느꼈던 아쉬운 것은 완전 실시간 영상 처리는 어렵다는 것이었습니다. 그랬는데... Gradio 5가 나오면서 이 문제가 해결되었습니다. 다음은 Gradio 5를 소개하는 페이지에서 나오는 내용입니다. 

 

“I can’t build realtime apps in Gradio” → We have unlocked low-latency streaming in Gradio! We use base64 encoding and websockets automatically where it offers speedups, support WebRTC via custom components, and have also added significantly more documentation and example demos that are focused on common streaming use cases, such as webcam-based object detection, video streaming, real-time speech transcription and generation, and conversational chatbots. 🎤



gradio-webrtc 소개

gradio-webrtc는 gradio에서 WebRTC를 이용해 비디오와 오디오를 실시간 스트리밍하는 것을  편리하게 해 주는 모듈입니다. 

 

 

GitHub - freddyaboulton/gradio-webrtc

Contribute to freddyaboulton/gradio-webrtc development by creating an account on GitHub.

github.com

 

 

Gradio-webrtc의 특징은 다음과 같습니다. 

- MIT 라이선스

- 사용자의 웹캠에서 서버로 비디오를 스트리밍하고 다시 보내기

- 서버에서 클라이언트로 비디오 또는 오디오를 스트리밍하기

 

사진 : 개발자인 Freddy A Boulton가 브라우저 상에서 시연을 보이는 모습

 

 

 

직접 돌려보자

 

gradio-webrtc 공식 github에 공개된 내용대로만 하면 제대로 동작하지 않습니다. 데모 코드로 공개해 둔 것을 이용해서 약간의 손을 봐야 하죠. 대신 HuggingFace에 공개된 코드를 이용하면 수정없이 위의 화면처럼 동작하는 데모를 만들 수 있습니다. 

 

 

1.HuggingFace Repository 다운로드

# HuggingFace repository 다운로드
$ git clone https://huggingface.co/spaces/freddyaboulton/webrtc-yolov10n
$ cd webrtc-yolov10n

# 패키지 추가 설치
$ pip install -r requirements.txt

 

 

2.코드 확인

 

아래 코드에서 TWILIO 부분은 WebRTC 릴레이를 위한 것으로 향후 클라우드에 서비스를 배포할 상황이 되면 필요할 수도 있습니다. 

 

import gradio as gr
import cv2
from huggingface_hub import hf_hub_download
from gradio_webrtc import WebRTC
from twilio.rest import Client
import os
from inference import YOLOv10

model_file = hf_hub_download(
    repo_id="onnx-community/yolov10n", filename="onnx/model.onnx"
)

model = YOLOv10(model_file)

account_sid = os.environ.get("TWILIO_ACCOUNT_SID")
auth_token = os.environ.get("TWILIO_AUTH_TOKEN")

if account_sid and auth_token:
    client = Client(account_sid, auth_token)

    token = client.tokens.create()

    rtc_configuration = {
        "iceServers": token.ice_servers,
        "iceTransportPolicy": "relay",
    }
else:
    rtc_configuration = None


def detection(image, conf_threshold=0.3):
    image = cv2.resize(image, (model.input_width, model.input_height))
    new_image = model.detect_objects(image, conf_threshold)
    return cv2.resize(new_image, (500, 500))


css = """.my-group {max-width: 600px !important; max-height: 600 !important;}
                      .my-column {display: flex !important; justify-content: center !important; align-items: center !important};"""


with gr.Blocks(css=css) as demo:
    gr.HTML(
        """
    <h1 style='text-align: center'>
    YOLOv10 Webcam Stream (Powered by WebRTC ⚡️)
    </h1>
    """
    )
    gr.HTML(
        """
        <h3 style='text-align: center'>
        <a href='https://arxiv.org/abs/2405.14458' target='_blank'>arXiv</a> | <a href='https://github.com/THU-MIG/yolov10' target='_blank'>github</a>
        </h3>
        """
    )
    with gr.Column(elem_classes=["my-column"]):
        with gr.Group(elem_classes=["my-group"]):
            image = WebRTC(label="Stream", rtc_configuration=rtc_configuration)
            conf_threshold = gr.Slider(
                label="Confidence Threshold",
                minimum=0.0,
                maximum=1.0,
                step=0.05,
                value=0.30,
            )

        image.stream(
            fn=detection, inputs=[image, conf_threshold], outputs=[image], time_limit=10
        )

if __name__ == "__main__":
    demo.launch()

 

 

 

3.실행 및 결과 확인

 

# 실행
$ python app.py

 

 

 

Recording 버튼을 누르면 WebRTC 전송이 시작되고 감지된 객체에 bbox 가 그려진 화면이 리턴됩니다. 반환되는 비율이 500x500이라 입력 영상의 화면과 비율이 달라 세로로 길쭉한 영상이 보일 것입니다. 

 

역시 모델 자체도 가벼워 추론에서도 지연이 없고, WebRTC라 네트워크 전송 부분도 지연이 없어 결과적으로 아주 빠릿빠릿하게 처리 됩니다. 현재는 로컬서버이지만 이 부분은 원격 서버로 하더라도 크게 차이가 나진 않을 것 같긴 합니다. 

 


참고) 오류 발생

 

위 명령을 실행하면 TensorRT library가 없다며 오류가 발생합니다. (오류는 나지만 실행은 됩니다! TensorRT가 없더라도 워낙 가벼운 Yolov10n 모델을 사용하는터라 CPU로도 충분히 실시간을 달성합니다.)

 

$ python app.py

2024-10-15 19:14:05.731136195 [E:onnxruntime:Default, provider_bridge_ort.cc:1978 TryGetProviderInfo_TensorRT] /onnxruntime_src/onnxruntime/core/session/provider_bridge_ort.cc:1637 onnxruntime::Provider& onnxruntime::ProviderLibrary::Get() [ONNXRuntimeError] : 1 : FAIL : Failed to load library libonnxruntime_providers_tensorrt.so with error: libnvinfer.so.10: cannot open shared object file: No such file or directory

*************** EP Error ***************
EP Error /onnxruntime_src/onnxruntime/python/onnxruntime_pybind_state.cc:490 void onnxruntime::python::RegisterTensorRTPluginsAsCustomOps(PySessionOptions&, const onnxruntime::ProviderOptions&) Please install TensorRT libraries as mentioned in the GPU requirements page, make sure they're in the PATH or LD_LIBRARY_PATH, and that your GPU is supported. when using ['TensorrtExecutionProvider', 'CUDAExecutionProvider', 'CPUExecutionProvider'] Falling back to ['CUDAExecutionProvider', 'CPUExecutionProvider'] and retrying.
****************************************
* Running on local URL: http://127.0.0.1:7860

To create a public link, set `share=True` in `launch()`.

 

 

해당 오류를 없애기 위해서는 AI모델의 추론 가속을 위해 Nvidia가 개발한 라이브러리인데, CUDA, cuDNN 환경만 구성되어 있는 경우에는 TensorRT를 별도로 추가 설치해야 합니다. 설치 방식은 apt를 이용하거나 NVIDIA TensorRT 다운로드 사이트에서 자신의 운영체제, CUDA 버전에 맞는 버전을 받아서 진행하게 됩니다. 

 

 

pip로 설치하는 방식

# pip를 이용해 python 패키지로 설치하는 경우
$ python3 -m pip install --upgrade tensorrt

 

 

NVIDIA 개발자 사이트에서 받아서 설치하는 방식 - 아래 URL 확인해 주세요.

 

 

NVIDIA TensorRT

An SDK with an optimizer for high-performance deep learning inference.

developer.nvidia.com

 

 

이번 글에서는 Gradio5에서 지원하게 된 WebRTC를 손쉽게 적용할 수 있도록 만든 'gradio-webrtc' 패키지의 사용 사례를 확인해 봤습니다. 사용하지 않고 놀고 있는 스마트폰 카메라를 이용해서 원격지에서 AI를 적용한 결과를 받아서 볼 수 있는 장난감 서비스를 만들어 볼 수도 있을 것 같네요. 

 

다음 번에도 재미난 기술이 있으면 소개해 드리겠습니다. :-)