LLM 엔지니어링14장 · Streamlit 화면과 Docker 컨테이너4 / 22← 이전목차다음 →MetaContents

14장. Streamlit 화면과 Docker 컨테이너

Streamlit 이 화면을 그리는 법

즉석 사진기는 단추를 누를 때마다 사진 한 장을 처음부터 새로 뽑습니다. Streamlit 도 사용자가 위젯을 건드릴 때마다 스크립트를 맨 위부터 다시 실행해 화면을 새로 그립니다. 그래서 코드는 위에서 아래로 읽는 보통 파이썬 스크립트처럼 쓰면 됩니다.

위젯 값이 바뀌면 스크립트를 처음부터 다시 실행하고, 위젯의 지금 값을 읽어, 화면을 새로 그리는 네 단계 흐름도

1번에서 사용자가 선택 상자를 바꾸거나 단추를 누릅니다. 2번에서 Streamlit 이 스크립트를 처음부터 다시 실행합니다. 3번에서 st.selectbox(...) 같은 줄이 위젯의 지금 값을 돌려줍니다. 4번에서 실행이 끝까지 가며 화면을 새로 그립니다. 여기서 즉석 사진 한 장이 다시 실행 한 번입니다. 사진과 달리 Streamlit 은 바뀐 부분만 화면에 고쳐 그려서, 깜빡이지 않습니다.

보통 웹 프로그램과 다른 점

견줄 것보통 웹 프로그램Streamlit
단추를 누르면그 단추에 붙은 함수만 실행스크립트 전체를 다시 실행
변수계속 남아 있다다시 실행할 때마다 처음부터
남겨야 할 값변수에 둔다st.session_state 에 둔다
무거운 준비한 번 해 둔다@st.cache_resource 로 한 번만

다시 실행을 흉내 내 보기

Python
# Streamlit 을 쓰지 않고 "사건마다 처음부터 다시 실행"을 흉내 낸다
session_state = {}                              # 다시 실행해도 남는 곳

def script(clicked):
    count = 0                                   # 보통 변수: 매번 0 으로 다시 시작한다
    session_state.setdefault("count", 0)        # 세션 상태: 처음 한 번만 0
    if clicked:
        count += 1
        session_state["count"] += 1
    return count, session_state["count"]

for clicked in [True, True, True]:              # 단추를 세 번 누른다 = 세 번 다시 실행
    print(script(clicked))

코드에 나오는 함수

코드쉬운 뜻
session_state = {}함수 바깥에 둔 빈 사전이다. 함수를 몇 번 불러도 사라지지 않아 Streamlit 의 st.session_state 역할을 흉내 낸다
def script(clicked):스크립트 한 번 실행을 함수 하나로 흉내 낸다. clicked 는 이번 실행에서 단추를 눌렀는지다
count = 0함수 안의 보통 변수다. 함수를 부를 때마다 새로 0 이 된다
session_state.setdefault("count", 0)set default(기본값 정하기)라는 뜻이다. "count" 가 아직 없을 때만 0 을 넣고, 있으면 그대로 둔다
session_state["count"] += 1세션 상태에 든 값을 1 늘린다. 다음 실행에도 이 값이 남는다

이 코드가 뜻하는 것

게임의 저장 슬롯에 견줄 수 있습니다. 게임을 껐다 켜면 화면 위의 점수는 0 부터 다시 시작하지만, 저장 슬롯에 적어 둔 기록은 남아 있습니다. 여기서 껐다 켜기가 다시 실행, 화면 위의 점수가 보통 변수 count, 저장 슬롯이 session_state 입니다.

줄하는 일쉽게 말하면
count = 0실행마다 0 부터 센다켤 때마다 0 점으로 시작하는 화면 점수
session_state.setdefault("count", 0)처음 한 번만 0 을 넣는다저장 슬롯이 비었을 때만 새로 만든다
if clicked: 아래 두 줄둘 다 1 씩 늘린다점수도 올리고 저장 슬롯에도 적는다
for clicked in [True, True, True]:단추를 세 번 누른다게임을 세 판 한다

결과 (1, 1), (1, 2), (1, 3) 에서 앞 숫자는 늘 1 이고 뒤 숫자만 1, 2, 3 으로 쌓입니다. 보통 변수는 다시 실행마다 처음으로 돌아가고, 세션 상태에 둔 값만 쌓인다는 뜻입니다. 비유와 다른 점은, Streamlit 의 세션 상태는 탭을 닫으면 사라진다는 것입니다.

작게 줄여서 눈으로 보기

st.button 처럼 "누른 그 실행에서만 True" 인 값을 흉내 냅니다. 단추를 누르고, 다른 칸을 두 번 바꾸고, 다시 단추를 누르는 순서는 설명을 위해 정한 것입니다.

Python
# st.button 처럼 "누른 그 실행에서만 True" 인 값을 흉내 낸다(설명용)
session_state = {"pressed": 0}

def script(button):
    if button:                                  # 이번 실행에서 눌렀을 때만 True
        session_state["pressed"] += 1           # 눌렀다는 사실은 세션 상태에 적는다
    return button, session_state["pressed"]

for button in [True, False, False, True]:       # 누름, 다른 칸 바꿈, 다른 칸 바꿈, 누름
    print(script(button))
출력
(True, 1)
(False, 1)
(False, 1)
(True, 2)
결과읽는 법
(True, 1)단추를 누른 실행이다. 단추 값은 True 이고, 누른 횟수를 1 로 적었다
(False, 1) 두 줄다른 칸을 바꿔 다시 실행됐다. 단추 값은 False 로 돌아갔지만 적어 둔 1 은 남았다
(True, 2)다시 누른 실행이다. 적어 둔 횟수가 2 가 됐다

단추 값만 믿으면 다른 칸을 건드리는 순간 "눌렀다"는 사실이 사라집니다. 그래서 남겨야 할 사실은 세션 상태에 적습니다.

주의할 점

  • 다시 실행 때문에, 스크립트의 위쪽에 무거운 일(모델 불러오기, 큰 파일 읽기)을 그냥 두면 단추를 누를 때마다 다시 합니다. 캐시를 씁니다(다음다음 절).
  • 위젯 값을 바꿀 때마다 다시 실행되는 것이 번거로우면, st.form 으로 칸들을 묶어 "제출" 단추를 누를 때만 다시 실행되게 합니다(실습 1).
← 이전 절14장 · 모델에 화면 붙이기다음 절 →14장 · 위젯과 배치