홍쌤의 인포클래스AI + X · 기술 블로그

← 목록

시나브로 데이터 랩을 만든 기록: Orange3처럼 위젯을 잇는 웹 분석 도구, 학교 서버 CPU로 계산하기

작성 2026.10.31 · 홍창민

10월 29일 저녁, 시나브로 데이터 랩(data.cmhong95.com)을 열었다. Orange3처럼 위젯을 캔버스에 놓고 선으로 이어 데이터를 분석하는 웹 도구다. 그날 밤 3차 배포로 선생님 수업 기능을 붙였고, 30일 오전에는 시나브로 AI를 붙였다. 무엇을 만들었는지, 어디서 틀렸고 어떻게 고쳤는지 적는다.

무엇을 만들었나

설치 없이 브라우저에서 위젯을 캔버스에 놓고 선으로 이어 분석한다. 다 만든 흐름은 파이썬(.py)이나 주피터(.ipynb) 코드로 내보낼 수 있어서, 위젯으로 해 본 분석을 코드로 이어 볼 수 있다.

항목 규모
위젯 119개
내장 데이터셋 57종(실제 공개 데이터 29, 합성 28). 재배포할 수 있는 라이선스만 넣었다
튜토리얼 30개. 2022 개정 교육과정의 데이터 과학·인공지능 기초에 맞췄다

계산은 학교 서버의 CPU에서 한다. 그림과 문장의 임베딩 모델도 같은 CPU에서 돌리고, 학생 데이터를 외부 AI 회사로 보내지 않는다. 같은 서버의 GPU는 학교 AI의 언어모델이 쓴다. 데이터 랩 서비스는 CPU 우선순위를 낮게(Nice 5, CPUWeight 50) 두고 메모리 상한을 8GB로 묶었다. 임베딩 서버는 따로 떠 있는 서비스이고 4GB 상한을 두었다. DB는 매일 새벽 백업해 14일치를 남기고, 배포 스크립트는 직전 버전을 보관해 명령 하나로 되돌릴 수 있다.

3차 배포에서는 선생님 기능을 더했다. 선생님이 신청하면 관리자가 승인하고, 승인된 선생님은 수업을 만들어 코드로 학생을 초대한다. 수업 화면에서는 학생별 튜토리얼 진행, 최근 오류, 제출물을 본다. 튜토리얼 퀴즈는 서버가 채점하고, 학생 화면에는 정답이 가지 않는다. 연관 규칙과 시계열 보간 위젯, 계정 삭제도 이때 넣었고, 보안 점검 문서 네 편(심각·높음 없음)에서 나온 것을 고쳤다. 로그인은 Firebase Auth의 Google 로그인을 쓰고, 서버가 토큰을 다시 확인한다.

문서도 함께 남겼다. 설계서(SPEC), Orange3의 기능과 사용 후기를 분석한 조사 문서, 교육과정 조사, 튜토리얼 교육과정표, 데이터셋별 라이선스 모음이 저장소에 있다. 데이터셋을 넣을 때마다 라이선스를 같이 넣어 두어야 나중에 재배포할 수 있는지 다시 찾지 않아도 된다.

54초 걸린 계산과 미리 계산해 둔 임베딩

처음 연 날 격리 인스턴스에서 부하 시험을 했다. 학생 30명이 기본 분석 흐름을 돌리고, AI 과제를 하는 학생 5명이 quickdraw 그림의 CLIP 임베딩과 nsmc 문장 전처리·감성 분석을 함께 했다. 요청 1,138개 중 오류는 0이었고 계산 중간값은 66ms였다. 그런데 계산의 95%가 끝나는 시간(p95)이 52초, 가장 늦은 계산이 54초였다.

원인은 같은 일을 셋이 동시에 한 것이었다. 학생 세 명이 같은 그림 800장의 임베딩을 동시에 계산했고, 같은 일꾼(worker)에 묶인 다른 학생들까지 기다렸다. 배포할 때 내장 그림 데이터셋 7,760장의 임베딩(CLIP·MobileNet)을 미리 계산해 캐시에 넣게 바꿨다. 계산에는 62초가 걸린다. 캐시를 채운 뒤 같은 시험을 하니 요청 798개 오류 0, p95 2.1초, 가장 늦은 계산 2.5초였다. 새 그림 데이터셋을 넣으면 배포할 때 캐시를 다시 채운다.

이 시험에서 CPU는 평소 2%에서 최대 54%까지 올랐고, 앱은 최대 2.8GB(일꾼 하나 최대 0.76GB), 임베딩 서버는 0.98GB를 썼다. 같은 서버의 학교 AI가 짧은 답(8토큰)을 내는 시간은 449ms에서 466ms로 거의 그대로였다.

3차 배포 뒤에는 같은 조건과 두 배로 늘린 조건으로 다시 쟀다. 학생 30명과 AI 과제를 하는 학생 5명일 때 요청 828개 오류 0, 계산 p95 2.6초였다. 학생 60명과 AI 과제를 하는 학생 10명일 때는 요청 1,733개 오류 0, 계산 p95 2.8초, 가장 늦은 계산 5.4초, 메모리 최대 3.9GB였다. 그동안 학교 AI의 상태 확인은 내내 정상이었다.

틀린 것은 시험과 배포 스크립트였다

처음 배포할 때 pytest가 732개 통과, 1개 건너뜀, 2개 실패였다. 실패한 둘은 합성 그림 데이터셋 두 개였는데, 다시 만든 PNG의 압축 바이트만 다르고 픽셀은 똑같았다. 처음에는 배포 스크립트가 이 둘을 '알려진 실패'로 빼고 진행하게 했다. 3차에서 시험이 PNG를 바이트가 아니라 픽셀로 비교하게 고치고, 알려진 실패 목록을 비웠다. 그 뒤 pytest는 913개 통과(1개 건너뜀), AI를 붙인 뒤에는 922개가 됐다. 브라우저 시험은 작업 흐름 25개, 수업 13개, 접근성 8개로 46개였고, 가짜 AI 서버로 도는 AI 시험 10개를 더해 56개가 됐다.

배포 스크립트에도 버그가 있었다. 스크립트는 명령 하나라도 실패하면 멈추게 짜 두었는데, 바뀐 항목 목록을 40줄까지만 보여 주는 줄에서 멈췄다. 목록이 길면 head가 먼저 끝나고, 앞쪽의 printf가 SIGPIPE(종료 코드 141)를 받는다. 스크립트는 이것을 실패로 보고 운영에 아무것도 넣지 않은 채 끝났다. 그 줄에 || true를 붙여 고쳤다.

# 바뀐 항목이 많으면 printf가 SIGPIPE(141)로 끝나고 set -e가 스크립트를 멈춘다
printf ... | head -40
# 고친 줄
printf ... | head -40 || true

Cloudflare도 한 번 끼어들었다. Cloudflare가 HTML에 방문 통계 스크립트를 자동으로 넣는데, 데이터 랩의 CSP가 이를 막아 콘솔에 오류가 났다. HTML 응답에 Cache-Control: no-transform을 붙여 Cloudflare가 HTML을 고치지 않게 했다.

AI 탭: 보내는 것과 보내지 않는 것

10월 30일 오전에 살펴보기 창의 네 번째 탭으로 [AI]를 넣었다. 결과 탭의 [결과 쉽게 설명]·[다음엔 뭘 해?], 오류 안내의 [왜 그래요?], 선을 잘못 이었을 때 뜨는 [시나브로 AI에게 묻기], 튜토리얼의 [시나브로 AI 힌트]에서도 부를 수 있다. 중요한 것은 AI에게 무엇을 보내느냐다.

보내는 것 보내지 않는 것
위젯 이름, 설정 값, 결과 한 줄 요약, 안내 문장 표의 실제 값(행)
열 이름과 종류, 이어진 위젯 그림, 올린 파일
튜토리얼 단계 설명 퀴즈 정답·해설·완성본

학생은 [AI에게 보내는 것 보기]로 보낼 내용을 그대로 볼 수 있고, 서버가 같은 칸만 다시 걸러 낸다. 질문에 전화번호, 주민등록번호, 이메일이 있으면 서버가 막는다. 학생은 하루 30번(수업 설정이 더 작으면 그 값), 선생님은 하루 200번, 1분에 6번, 한 번에 한 질문만 할 수 있다. 학교 AI 서버를 함께 쓰기 때문에 서버 전체에서 동시에 4개까지만 받는다. AI 서버가 멈추면 503 안내를 보이고 1분 뒤 다시 시도하게 하며, 이때는 횟수에 세지 않는다. 다른 기능은 그대로 쓸 수 있다.

선생님은 수업마다 AI를 켜고 끄고, 학생 하루 질문 수를 정하고, 그 수업에 들어온 뒤의 학생 질문과 답을 볼 수 있다. 질문과 답은 30일 보관하고, 학생 본인이 [내 질문 기록]에서 모두 지울 수 있으며, 계정을 지우면 함께 지워진다. 처리방침에도 이 내용을 2-2절로 더했다.

연결 방식은 처음 생각과 달라졌다. 처음에는 데이터 랩 서버가 시나브로 AI 게이트웨이를 부르는 방식을 제안했다. 그런데 시나브로 AI는 초대 코드로 만든 계정만 쓸 수 있고, 다른 서비스가 대신 물어보는 길은 다른 작업에서 아직 커밋하지 않은 코드뿐이었다. 그 코드는 건드리지 않고, 데이터 랩 서버가 같은 학교 AI 모델을 직접 부르게 했다. 횟수 제한, 개인정보 검사, 선생님 기록은 데이터 랩 안에서 한다. 학생이 시나브로 AI에 따로 가입할 필요가 없다.

실제 모델로 확인해 보니 결과 설명은 8.2초, 자유 질문은 5.6초 걸렸다. 결과를 기준선과 비교해 한국어로 설명했고, 퀴즈 힌트에서는 정답 번호를 말하지 않았다.

화면에서 고친 것

AI와 함께 화면도 손봤다. 오른쪽 살펴보기 창을 넣고 꺼낼 수 있게 했다. 창 가장자리의 › 단추나 ] 키로 접고 펴며, 새로고침해도 마지막 상태를 기억하고, 창을 접어도 캔버스의 그림은 가운데에 그대로 둔다. 단추, 탭, 창, 메뉴, 알림, 새 위젯이 놓일 때(톡), 새 선이 이어질 때(쓱), 확대와 화면 맞추기에 짧은 움직임을 넣었다. 운영체제에서 '움직임 줄이기'를 켠 사용자에게는 움직임이 나오지 않는다.

남은 것

실제 Google 계정으로 선생님 신청부터 관리자 승인까지 한 번 해 봐야 한다. 이 흐름은 아직 실제 계정으로 해 보지 않았다.

관련 주소