cardstream
소개

핵심은 프레임마다가 아니라 카드 한 장당 한 번만 묻는 것

카드 인식은 이미 실용 단계에 있습니다. 좋은 모델에 트레이딩 카드를 보여 주면 이름, 세트, 번호가 약 0.5초 만에 돌아옵니다. 문제는 그것을 영상에 적용할 때 생깁니다. 기술적인 한계가 아니라, 순전히 양의 문제입니다.

영상은 대부분 반복입니다. 카드 한 장을 4초 동안 들고 있으면 초당 15프레임 기준으로 같은 카드 사진 60장이 됩니다. 식별 엔드포인트에 60번 물어보면 같은 답이 60번 돌아올 뿐입니다. 단순한 스트리밍 파이프라인은 하나같이 정확히 이렇게 동작하고, 그래서 스트리밍 분석은 자금이 넉넉한 플랫폼만 운영할 수 있는 것이라는 인식이 생겼습니다.

cardstream은 그 반복을 없애기 위해 존재합니다. 영상과 인식 호출 사이에 놓이는 작은 상태 머신으로, 거의 전부 스스로 계산해 낸 신호만으로 만들어졌습니다. 장면이 안정되었는가, 이것이 조금 전과 같은 카드인가, 애초에 프레임 안에 카드가 있는가. 호출은 정말로 새로운 카드가 자리를 잡았을 때만 나가고, 그 밖의 경우에는 나가지 않습니다. 나머지는 모두 이미 갖고 있는 하드웨어에서 돌아갑니다.

계산해 보면

프레임마다가 아니라 카드 한 장당 한 번

초당 15프레임(이 프로젝트가 검증한 프레임 레이트의 상한)으로 한 시간 방송을 하면서 서로 다른 카드 약 100장을 렌즈 앞에 보여 준다고 합시다. 정확히 같은 영상을 분석하는 두 가지 방법:

프레임마다 54,000

회의 식별 호출. 프레임당 한 번이며, 대부분은 조금 전에 답이 나온 질문을 다시 묻는 것입니다.

cardstream을 쓰면 ~100

회의 식별 호출. 서로 다른 카드 한 장당 한 번이며, 프레임 레이트가 얼마든, 카드를 얼마나 오래 들고 있든 변하지 않습니다.

호출이 약 540배 줄어듭니다. 이 차이는 숫자 놀음이 아니라 설계 그 자체입니다. 카드를 가만히 들고 있어도 횟수는 늘지 않습니다. 카메라를 더 빠르게 돌려도 횟수는 늘지 않습니다. 호출 횟수를 결정하는 것은 방송한 시간이 아니라 보여 준 카드의 수입니다.

운영

누가 계속 돌아가게 하는가

인식 서비스를 실제로 출시하는 사람들이 만들었습니다

cardstream은 Ximilar의 수집품 인식을 만든 팀에서 나왔습니다. cardstream이 호출하는 식별 엔드포인트는 저희가 프로덕션에서 운영하는 바로 그것이므로, 클라이언트와 서비스를 같은 사람들이 유지보수합니다.

모든 작업이 공개되어 있습니다

전체 패키지가 GitHub에 있습니다. 상태 머신, 두 가지 배포 형태, 브라우저 UI 모두입니다. 판단 로직의 어떤 부분도 들여다볼 수 없는 서비스 뒤에 숨겨져 있지 않습니다.

네트워크 없이 테스트됩니다

전체 테스트 스위트가 오프라인에서 돌아갑니다. 모델 파일과 HTTP 호출은 페이크가 대신합니다. API 키가 없는 노트북에서 저장소를 포크해도 무언가를 망가뜨렸는지 여전히 알 수 있습니다.

원칙

코드가 잊어서는 안 되는 것

  1. 프레임마다가 아니라 카드 한 장당 한 번

    모든 설계 결정은 여기서 출발합니다. 로컬에서 계산할 수 있는 신호라면, 머신 밖으로 나가는 단 한 번의 호출보다 먼저 실행됩니다.

  2. 판단 로직의 사본은 하나뿐

    언제 호출할지는 정확히 하나의 모듈에만 있습니다. 드라이버, 전송 계층, UI에 흩어져 세 사람이 세 가지 방식으로 바꿀 수 있는 상태가 아니라, 한자리에서 읽어 내릴 수 있는 파일 하나입니다.

  3. 드라이버는 얇게 유지합니다

    스케줄링, 로깅, I/O는 드라이버의 몫이고, 무엇을 새 카드로 볼지는 엔진의 몫입니다. 프레임이 들어오는 방식을 바꿔도 호출이 나가는 시점이 슬그머니 달라지는 일은 없습니다.

  4. 프레임 루프를 막는 것은 없습니다

    디코딩, 감지, HTTP, 디스크 I/O는 모두 루프 밖에서 돌아갑니다. 식별이 느리면 프레임 하나가 떨어질 뿐, 방송의 지연 시간이 계속 쌓이는 일은 절대 없습니다.

  5. 공급자 종속 없음, 저희 자신을 포함해서

    식별 호출은 작은 인터페이스 뒤에 있는 교체 가능한 단계 하나입니다. 완전히 다른 곳으로 향하게 해도 모든 게이트, 스로틀, 캐시는 그대로 동작합니다.

  6. 기본이 셀프호스팅

    여러분의 하드웨어, 여러분의 키, 여러분의 영상. 클라이언트 측 모드에서는 방송을 여러분의 Ximilar 계정에 저장하기로 직접 선택하지 않는 한, 머신 밖으로 나가는 것은 서로 다른 카드 한 장당 크롭 한 장뿐입니다.

현장 노트

카드가 가르쳐 준 것들

이 중 몇 가지는 직관에 반하기 때문에, 다음 사람이 찾을 수 있는 곳에 적어 둡니다. 저장소 안, 그것이 제약하는 코드 바로 옆에.

친절한 힌트가 정확도를 떨어뜨릴 수 있습니다

엔드포인트에 카드가 어느 게임 것인지 알려 주면 엔드포인트 자체의 문자 체계 분류기가 꺼지고 라틴 문자로 되돌아갑니다. 그러면 일본어 카드가 조용히 영어판에 매칭됩니다. 추측이 아니라 측정한 결과이며, 그래서 문자 체계 없이 게임만 지정하는 것은 실수로 취급합니다.

살짝 여유 있는 크롭이 더 잘 매칭됩니다

카드에 딱 맞게 자르면 보기에는 맞아 보여도 결과는 더 나쁩니다. 전송되는 크롭에는 의도적으로 여백을 둡니다. 깔끔한 테두리보다 약간의 주변 맥락이 더 효과적이기 때문입니다.

얼버무리기보다 복구하기

호출이 타임아웃을 넘겨도 응답하지 않으면, 파이프라인은 영영 오지 않을지도 모르는 결과를 기다리는 대신 스스로 막힌 곳을 풀고 다음으로 넘어갑니다. 이 제약은 덮어 두지 않고 저장소에 명시해 두었습니다.

소스와 기여

읽고, 실행하고, 패치를 보내세요

저장소는 공개되어 있습니다. 독립적인 extras를 가진 설치 가능한 Python 패키지 하나와 브라우저 UI입니다. 로케이터와 임베딩 가중치는 저희가 직접 학습시킨 것으로, 릴리스와 함께 Apache-2.0으로 공개합니다. 이슈와 풀 리퀘스트를 환영합니다. 특히 실제 방송에서 온 제보는 어떤 테스트 장비로도 찾을 수 없는 것들을 드러내 줍니다.

인식 자체는 Ximilar 엔드포인트이며 앞으로도 그럴 것입니다. 카드 데이터베이스가 뒤에 있는 부분이 바로 그곳이기 때문입니다. 그 주변의 모든 것은 자유롭게 바꾸셔도 됩니다.

오픈소스. 자체 호스팅. 여러분의 방송, 여러분의 스택.

중간에 끼는 플랫폼도, 좌석 라이선스도 없습니다. Ximilar API 또는 자체 식별 시스템을 연결하면 cardstream은 프레임마다가 아니라 서로 다른 카드 한 장당 한 번만 호출합니다. Whatnot에서 브레이크를 하든, Fanatics Live 같은 쇼를 진행하든, 자체 라이브 커머스 환경을 방송하든, 이미 가진 하드웨어로 오늘 밤 cardstream을 실행해 보세요.