1. DockerOperator를 사용하는 이유

- 상황에 따라 버전이 다른 라이브러리를 사용하는 경우가 많고, airflow에서 기본적으로 지원하지 않는 라이브러리를 사용하는 경우도 있다.

- 이럴때 운영 줄인 airflow 서버에 라이브러리를 설치해야하는데, 하나의 서버에서 다양한 라이브러리와 버전을 모두 제공할 수 없다.

- 그리고 특정 라이브러리를 설치하는 경우에 심각한 경우 Airflow가 작동하지 않는 경우도 있다.

- 따라서 Airflow와 머신 환경에 종속되지 않고 컨테이너 환경에서 dag를 실행하도록 하면 많은 문제가 해결된다.

 

2. 실습 환경

- airflow 3.1.0 버전에서 실행하였다.

- airflow 2.x.x 버전과 DockerOperator에서 auto_remove를 설정하는 것이 차이가 있다.

- 2버전에서는 true와 false로 자동 삭제를 설정한다.

- 3버전에서는 success, never, force로 설정한다.

- 아래의 링크에서 내용을 확인할 수 있다.

https://airflow.apache.org/docs/apache-airflow-providers-docker/stable/_api/airflow/providers/docker/operators/docker/index.html

 

airflow.providers.docker.operators.docker — apache-airflow-providers-docker Documentation

 

airflow.apache.org

 

3. DockerOperator 실행 실습

- 아래의 dag를 사용하여 실습을 진행한다.

from datetime import timedelta

from airflow import DAG
from airflow.providers.docker.operators.docker import DockerOperator
from airflow.operators.bash import BashOperator

default_args = {
    'owner': 'airflow',
    'depends_on_past': False,
    'start_date': '2025-09-20',
    'retries': 1,
    'retry_delay': 30,
}

dag = DAG(
    'docker_test',
    default_args=default_args,
    description='echo "hello, world!"',
    schedule=timedelta(days=1),
)

t1 = BashOperator(
    task_id='echo_host',
    bash_command='whoami',
    dag=dag
)

t2 = DockerOperator(
    task_id='echo_container',
    image='ubuntu:22.04',
    container_name='test_echo_container',
    auto_remove='success',
    command="whoami",
    hostname='docker_test',
    dag=dag
)
t1 >> t2

 

- 아마도 높은 확률로 BashOperator는 작동했지만 DockerOperator에서 문제가 발생할 것이다.

 

- 아래와 같은 에러메세지가 있을텐데 쉽게 말하자면 컨테이너를 생성할 docker와 통신하지 못해서 발생하는 문제이다.

ERROR - Failed to establish connection to Docker host unix://var/run/docker.sock: Error while fetching server API version: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))

 

- docker compose로 구축한 airflow의 컨테이너와 docker가 통신할 수 있도록 실습하는 pc에 설치되어있는 docker와 연결할 수 있도록 docker compose yaml에서 아래와 같은 설정을 하자.

x-airflow-common:
  &airflow-common
  ......
  environment:
    ......
  volumes:
    ......
    # 이 경로를 설정하자
    - /var/run/docker.sock:/var/run/docker.sock

 

- airflow를 아래의 명령어로 환경 변수 변경 값을 적용해 다시 실행하자

docker compose down && docker compose up -d

 

- 이제는 DockerOperator의 작업도 정상적으로 실행된 것을 알 수 있다.

- 만약 컨테이너가 제대로 실행됐는지 궁금하다면 dag에서 auro_remove='never'로 바꾸고 실행해서 확인할 수 있다.

- 변경 후 dag를 실행하면 실습하는 pc의 docker에 아래와 같은 종료된 컨테이너가 있는 것을 확인할 수 있다.

CONTAINER ID   IMAGE                  COMMAND                   CREATED          STATUS                      PORTS                                         NAMES
9f573e521d55   ubuntu:22.04           "whoami"                  39 seconds ago   Exited (0) 38 seconds ago

 

1. 문제 상황

- airflow 공식 홈페이지에서 제공하는 docker compose 환경이 3.1.0 버전으로 변경되었다.

- 설치 후 예제 dag 중에 pythonOperator 같은 당연히 실행되어야 하는 dag가 실행되지 않았다.

- airflow에서 확인한 에러로그는 다음과 같았다.

Executor CeleryExecutor(parallelism=32) reported that the task instance 
<TaskInstance: docker_test.echo_host scheduled__2025-09-28T13:10:24.732903+00:00 [queued]> 
finished with state failed, but the task instance's state attribute is queued. 
Learn more: https://airflow.apache.org/docs/apache-airflow/stable/troubleshooting.html#task-state-changed-externally

- 공식 홈페이지에서 딱히 도움이 될만한 내용은 없었다.

 

2. 문제 해결 방법

- aiflow에서 fernet key가 불일치하면 발생하는 문제로 확인되었다.

- fernet key가 일치해야 워커에서 실행할 태스크가 올바른 것이라고 스케쥴러가 관리를 할 수 있는데, 이게 불일치하는 문제가 생기는 것이다.

- 이전에 사용하던 2.x.x 버전의 에어플로우에서는 명시적으로 설정하지 않던 값을 설정해서 문제를 해결할 수 있다.

- docker compose 파일이 있는 경로에 .env를 생성하고 UID와 fernet key 값을 고정 값으로 넣어준다,

- 여기서 fernet key는 파이썬 라이브러리로 간단하게 만들 수 있고, 예제 코드는 아래와 같다.

from cryptography.fernet import Fernet
print(Fernet.generate_key().decode())

 

- .env 파일은 아래와 같이 만들자

FERNET_KEY=생성한 fernet key
AIRFLOW_UID=50000

 

- 만약에 이미 airflow를 한번 docker compose up으로 올렸었다면 다음과 같은 명령어로 볼륨과 생성됐던 컨테이너를 깨끗하게 삭제하고 다시 실행하자

docker-compose down --volumes --remove-orphans

 

- 다시 airflow를 실행하면 문제없이 dag가 실행되는 것을 알 수 있다.

 

3. 다음 게시물 내용

- DockerOperator로 dag를 실행하는 예제를 실습한다.

'데이터 시스템 구축 정보 공유 > airflow' 카테고리의 다른 글

4. DockerOperator로 dag 실행하기  (0) 2025.09.29
2. docker를 사용한 airflow 설치  (0) 2024.01.11
1. Airflow란?  (0) 2022.07.31

1. 실습내용

- 구성한 node에 k3s를 설치한다.

 

2. k3s 마스터노드 설치

- 마스터 노드를 먼저 세팅하자.

- k3s의 퀵스타트 가이드의 주소는 아래와 같다.

https://docs.k3s.io/quick-start

 

- 마스터 노드의 설치 커맨드를 우분투 가상머신에 입력해서 설치하자.

curl -sfL https://get.k3s.io | sh -

 

- 설치가 완료되면 kubectl로 노드가 정상적으로 잡혀있는지 확인하자

sudo kubectl get nodes

 

3. k3s 워커노드 설치

- 아래의 명령어로 K3S_TOKEN 값을 알아낼 수 있다.

sudo cat /var/lib/rancher/k3s/server/node-token

 

- K3S_URL은 가상 머신의 ip주소를 사용하면 된다.

- 아래 명령어에서 K3S_URL과 K3S_TOKEN 값을 넣고 k3s-worker1과 k3s-worker2에 아래 명령어로 설치한다.

# myserver : master의 ip
# mynodetoken : master의 토큰 값

curl -sfL https://get.k3s.io | K3S_URL=https://myserver:6443 K3S_TOKEN=mynodetoken sh -

 

- 설치가 모두 완료되면 master에서 아래의 명령어로 워커노드가 연결된 것을 확인할 수 있다.

sudo kubectl get nodes


# 출력 결과 예시
NAME          STATUS   ROLES                  AGE     VERSION
k3s-master    Ready    control-plane,master   3m42s   v1.33.4+k3s1
k3s-worker1   Ready    <none>                 81s     v1.33.4+k3s1
k3s-worker2   Ready    <none>                 55s     v1.33.4+k3s1

 

 

4. 다음 게시물 내용

- 구축한 쿠버네티스 환경에서 배포를 직접 해보자.

1. 실습 내용

- multipass로 VM을 3대 만든다.

- k3s를 실습할 수 있는 환경을 만든다.

 

2. multipass 설치와 VM 생성

- 공식 홈페이지에서 간단하게 설치하는 방법을 볼 수 있다.

- 아래의 페이지에서 설치 파일을 받아서 설치하자

https://canonical.com/multipass/install

 

- 예전에 사용했을 때는 gui가 없었는데, 이제는 gui가 제공돼서 쉽게 인스턴스를 만들 수 있다.

톱니를 누르면 내가 원하는 옵션으로 인스턴스를 만들 수 있다.

- 인스턴스를 만들기 전에 왼쪽 사이드바 아래에 있는 톱니바퀴를 눌러서 설정으로 들어가자

- 용이한 실습을 위해 Bridged network를 en0로 잡아서 노드끼리 통신이 쉽게 되도록 하자.

en0은 일반적으로 와이파이 대역으로 되어있을 것이다.


- 우분투 24.04 LTS로 k3s-master, k3s-worker1, k3s-worker2로 VM를 띄워보자

- 톱니바퀴 모양을 누르면 VM의 이름, CPU, RAM, DISK를 설정해서 Launch 할 수 있다.

자신의 컴퓨터 스펙에 따라 적당히

 

- 잠시 기다리면 인스턴스가 작동하는 것을 확인할 수 있고, 멀티패스 gui에서 간단히 shell도 볼 수 있다.

각 VM을 클릭하면 터미널을 사용할 수 있다.
gui에서 간단하게 상태도 확인할 수 있다.

 

 

(추가) 윈도우즈에서 네트워크가 잡히지 않는 문제

- 네트워크가 잡혀도 설정이 되지 않는 경우가 있는데, 확인해보니 네트워크 이름이 한글이라서 문제가 발생했다.

- 맥북에서 할때는 네트워크 이름이 en0, en1 이런 방식으로 되어 있어서 몰랐는데 한글 윈도우즈에서는 문제가 발생했다.

- 처음에는 아래와 같은 명령어를 파워쉘로 실행했더니 깨진 이름의 네트워크 이름이 나왔다.

# 네트워크 확인하는 명령어
multipass networks


# 출력 결과
Name             Type       Description

�̴���            ethernet   Realtek PCIe GbE Family Controller

 

- 해결 방법으로는 윈도우 파워쉘을 관리자 권한으로 실행하고 네트워크 이름을 변경해서 문제를 해결했다.

# 네트워크 확인 명령어
Get-NetAdapter

# "이더넷"과 같은 이름으로 되어있는 네트워크 이름을 영어로 변경
Rename-NetAdapter -Name "이더넷" -NewName "Ethernet0"

- 변경이 잘 되었다면 Settings에서 변경된 이름으로 브릿지 네트워크가 잘 나오는 것을 확인할 수 있다.

 

 

3. 다음 게시물 내용

- 다음 게시물을 통해 k3s를 설치하고 마스터 노드와 워커 노드까지 세팅하는 실습을 진행해보자

1. 공부 계획을 다시 하는 이유

- 최근 1년 동안 새로운 기술도 사용하고 api도 만들어보고 새로운 일을 많이 해봤다.

- 그런데 옛날에 조금씩 업무를 했던 spark, 데이터레이크 구축 작업 같은 것들에 대한 기억이 희미해져간다.

- 요즘엔 ai로 공부할 수 있는 방법도 다양하고 쉬우니까 직접 구축하면서 잊었던 내 과거의 지식을 다시 메꾸려고 한다.

 

2. 계획 중인 공부 영역

- Airflow : 요즘 k8s를 쓰는 곳이 많다보니 k8s에서 운영하는 방법에 대해 테스트해봐야겠다.

- superset : redash 게시물의 조회수가 떨어진 것을 보니 슈퍼셋 쪽으로도 많이 수요가 옮겨간 것 같다.

- k8s : 22년도인가 그때만 해도 구축이 힘들었던 거 같은데 요즘엔 다시 쉽게 공부해볼 수 있을 것 같다.

- spark : 대용량 db 데이터를 분석용으로 변경하고 사용할 때 사용했었는데, 분석작업에서 멀어지다보니까 잘 안쓰게 돼서 다시 공부해봐야지

- kafka : 카프카는 지금 직장에서 잘 쓰고 있으니 평소에 업무 외에 궁금했던 부분을 작업해봐야겠다.

 

3. TIL로 공부할 때마다 글을 작성하자

- 작은 글이 모이면 큰 내용으로 다시 정리해도 좋지만... 작은 글을 자주 쓰는 것으로 바꿔보자

- 어차피 공부하는 우리 모두 하루마다 공부에 할애할 수 있는 정도가 비슷하지 않을까?

'잡담' 카테고리의 다른 글

2024년 블로그 계획  (0) 2024.01.11

1. PromptTemplate란?

- 사용자에게 간단한 입력만 받아서 프롬프트를 통해 llm으로 결과를 도출할 때 사용한다.

- 프롬프트에 일부 인자만 받도록 해서 프롬프트를 특정 용도로 사용하고 관리할 수 있다.

- 예를 들어 일부 정해진 답변만 받을 수 있는 경우 사용할 수 있고, 제한된 입력을 받기 원할 때 사용할 수 있다.

 

2. 예제 코드

- 아래와 같은 예제 코드를 사용하면

 
from langchain_google_genai import GoogleGenerativeAI
from langchain_core.prompts import PromptTemplate
from langchain_core.messages import HumanMessage

# GEMINI_API_KEY는 발급 받은 gemini key
model = GoogleGenerativeAI(model="gemini-1.5-flash", google_api_key=GEMINI_API_KEY)

template = PromptTemplate(
template="""{programming_language}가 주로 어떤 개발에 쓰이는지 예시를 3개만 알려줘""",
input_variables="programming_language"
)

message = template.format(programming_language="파이썬")
result = model.invoke(message)
 

 

- 결과에서 아래의 결과를 받을 수 있다.

파이썬은 다양한 분야에 사용되지만, 주요 용도 3가지 예시는 다음과 같습니다.

1. **웹 개발:** 파이썬은 웹 애플리케이션을 구축하는 데 널리 사용됩니다.  Django와 Flask와 같은 강력한 웹 프레임워크를 통해 개발자는 효율적으로 웹사이트와 웹 서비스를 만들 수 있습니다.  예를 들어, Instagram이나 Pinterest와 같은 대규모 웹사이트도 파이썬을 기반으로 구축되었습니다.

2. **데이터 과학 및 머신러닝:** 파이썬은 과학적 계산과 데이터 분석에 필요한 풍부한 라이브러리를 제공합니다. NumPy, Pandas, Scikit-learn, TensorFlow, PyTorch 등의 라이브러리를 사용하여 데이터를 처리, 분석하고, 머신러닝 모델을 개발 및 배포할 수 있습니다.  예를 들어,  데이터 분석, 예측 모델링, 이미지 인식 등의 작업에 파이썬이 널리 활용됩니다.

3. **스크립팅 및 자동화:** 파이썬의 간결하고 읽기 쉬운 문법은 스크립트 작성 및 자동화 작업에 매우 적합합니다.  반복적인 작업을 자동화하거나, 시스템 관리 작업을 수행하거나, 파일을 처리하는 등 다양한 용도로 사용됩니다. 예를 들어, 파일 백업 스크립트 작성, 웹 스크래핑, 시스템 모니터링 등에 파이썬을 이용할 수 있습니다.

 

3. 템플릿을 json 파일로 저장해서 관리하기

- 위에서 설정한 템플릿을 save로 저장하면 파일이 생성된다

 
template.save("programming_language_template.json")
 

 

- 아래와 같은 예시 코드로 파일을 불러서 사용할 수 있다.

 
from langchain_core.prompts import load_prompt

loaded_prompt = load_prompt("programming_language_template.json")
message = loaded_prompt.format(programming_language="코틀린")

result = model.invoke(message)
print(result)
 
코틀린은 다양한 분야에서 사용되지만, 주요 활용 분야 3가지 예시는 다음과 같습니다.

1. **Android 앱 개발:**  구글이 공식적으로 지원하는 Android 앱 개발 언어이기 때문에 가장 널리 쓰입니다.  Java보다 간결하고 현대적인 문법을 제공하여 개발 생산성을 높이고 코드 유지보수를 용이하게 합니다.  많은 안드로이드 앱들이 코틀린으로 개발되거나, 기존 자바 코드를 코틀린으로 리팩토링하여 사용하고 있습니다.

2. **서버측 개발 (Backend):**  Spring Boot와 같은 프레임워크와의 호환성이 뛰어나 서버 애플리케이션 개발에 효과적입니다.  Java와 비교하여 더 간결하고 안전한 코드를 작성할 수 있으며,  Kotlin Coroutines를 이용한 비동기 프로그래밍을 통해 성능 향상을 기대할 수 있습니다.  웹 서비스, API, 마이크로서비스 등 다양한 서버 애플리케이션 구축에 사용됩니다.

3. **데이터 사이언스/머신러닝:**  JVM 기반이기 때문에  Apache Spark와 같은 데이터 처리 프레임워크와 잘 통합됩니다.  간결한 문법과 null safety 기능은 데이터 분석 및 머신러닝 모델 개발 과정에서 발생할 수 있는 오류를 줄이는 데 도움이 됩니다.  데이터 분석 스크립트 작성 및 머신러닝 모델 구축에 사용될 수 있습니다.


이 외에도, 데스크탑 애플리케이션, 웹 프론트엔드(Kotlin/JS), 게임 개발 등 다양한 분야에서 코틀린이 사용되고 있지만, 위 세 가지가 가장 대표적인 활용 분야라고 할 수 있습니다.

 

1. langchain이 무엇일까?

- llm을 직접 호출하고 다양한 방식으로 사용하는 파이프라인을 만들려면 어떻게 해야할까?

- llm으로 특정 애플리케이션과 파이프하인을 만들때 사용하는 프레임워크 중에 하나가 langchain이다.

- 우리가 복잡한 머신러닝 기법을 직접 구현하지 않고 라이브러리를 사용하는 것과 같은 것이라고 생각하면 된다.

 

2. langchain으로 gemini 모델을 사용한 llm 응답 함수를 만들어보자

- 직접 gemini의 sdk를 사용하는 것이 아니라 langchain으로 기능을 만들어보자.

- 시스템 프롬프트는 이전 글에서 사용한 것을 그대로 사용한다.

from langchain_google_genai import GoogleGenerativeAI
from langchain_core.messages import HumanMessage, SystemMessage

GEMINI_API_KEY = '발급받은 gemini api key'

system_prompt = \
"""
1. 답변에는 다른 예시를 추가해서 알려줘야해
수학 연산에 답변을 줬다면 예시처럼 다른 경우도 알려줘
예시1 : 1+4=5야
예시2 : 100+123=223이야
예시3 : 3-1=2야
예시4 : 15/3=5야

2. 너는 학교선생님처럼 친절하게 설명해줘야해.
짧은 답변이 아니라 자세히 친절하게 설명해줘야해.
질문자에게 공부를 잘 할 수 있다는 격려도 해줘야해.

예시1 : 3+3에서 +은 더하기로 앞의 숫자와 뒤의 숫자를 합치는 거야. 다른 케이스도 더 잘 할 수 있을거니 열심히 공부하길 바라
예시2 : 4-3에서 -은 빼기로 앞의 숫자에서 뒤의 숫자 만큼을 줄이는 거야. 다른 연산법도 잘 이해할 수 있도록 내가 잘 알려줄게
"""

model = GoogleGenerativeAI(model="gemini-1.5-flash", google_api_key=GEMINI_API_KEY)

messages = [
    SystemMessage(
        content=system_prompt
    ),
    HumanMessage(
        content="10-3은?"
    )
]

print(model.invoke(messages))

 

- 결과는 이전 글과 동일하게 나온다.

- 이걸 함수로 만든다면 아래와 같이 단순하게 만들 수 있을 것이다.

from langchain_google_genai import GoogleGenerativeAI
from langchain_core.messages import HumanMessage, SystemMessage

system_prompt = \
"""
1. 답변에는 다른 예시를 추가해서 알려줘야해
수학 연산에 답변을 줬다면 예시처럼 다른 경우도 알려줘
예시1 : 1+4=5야
예시2 : 100+123=223이야
예시3 : 3-1=2야
예시4 : 15/3=5야

2. 너는 학교선생님처럼 친절하게 설명해줘야해.
짧은 답변이 아니라 자세히 친절하게 설명해줘야해.
질문자에게 공부를 잘 할 수 있다는 격려도 해줘야해.

예시1 : 3+3에서 +은 더하기로 앞의 숫자와 뒤의 숫자를 합치는 거야. 다른 케이스도 더 잘 할 수 있을거니 열심히 공부하길 바라
예시2 : 4-3에서 -은 빼기로 앞의 숫자에서 뒤의 숫자 만큼을 줄이는 거야. 다른 연산법도 잘 이해할 수 있도록 내가 잘 알려줄게
"""

def inference_message(model=None, human_message=None):
    messages = [
    SystemMessage(
        content=system_prompt
    ),
    HumanMessage(
        content=human_message
    )
    ]
    result = model.invoke(messages)
    return result

 

- 그리고 이 함수를 통해 llm으로 결과를 받으려면 아래와 같이 사용하면 된다.

model = GoogleGenerativeAI(model="gemini-1.5-flash", google_api_key="발급받은 gemini api 키")

result = inference_message(
    model=model,
    human_message="112+34는?"
)

print(result)

 

3. langchain 프레임워크로 간단히 기능을 만들어보자.

- 이미 추상화된 기능을 사용해 llm 기능을 구현하면 편리하게 애플리케이션을 구현할 수 있다.

- 특히 최신 llm 기술에서 사용하는 것도 langchain에서 사용할 수 있기 때문에 langchain을 활용한 개발에 익숙해지자.

1. 시스템 프롬프트란?

- 쉽게 말해서 llm이 특정 명령을 수행할 수 있는 역할을 주는 것이라고 할 수 있다.

- 주로 기본적인 동작방식과 대화의 방식 등을 설정하는데 사용한다.

- api로 결과를 호출할 때 어떤 시스템 프롬프트를 거칠지 설정할 수 있다.

- 이를 파이썬으로 사용하려면 일부 패키지 설치를 통해 쉽게 사용할 수 있다.

- gemini에서는 공식 문서에서 기본적으로 필요한 패키지를 설치하는 과정을 설명해주고 있으니 참고해서 설치해보자.

- https://ai.google.dev/gemini-api/docs/get-started/tutorial?lang=python&hl=ko#install_the_python_sdk

 

튜토리얼: Gemini API 시작하기  |  Google AI for Developers

텍스트 생성 및 채팅 기능을 포함하여 Gemini API 및 Gemini 1.5 Flash를 시작합니다.

ai.google.dev

 

 

2. 라이브러리 설치와 단순한 사용 방법

- 아래의 패키지를 설치한다.

- 주피터 노트북을 사용한다면 설치 후 커널을 재실행하자

pip install -q -U google-generativeai

 

- GEMINI_API_KEY에 발급받은 api key를 할당하고, genai.configure에 등록하면 llm에 호출 할 수 있다.

import google.generativeai as genai

GEMINI_API_KEY = "발급받은 gemini api key"
# api key를 설정
genai.configure(api_key=GEMINI_API_KEY)
# 모델 설정
model = genai.GenerativeModel('gemini-1.5-flash')
# 결과 요청
response = model.generate_content("3+3은 뭐야?")
# 결과 확인
print(response.text)

# 결과 : 3 + 3 = 6 입니다.

 

3. 시스템 프롬프트를 설정해서 내가 원하는 방식의 결과를 받아보자.

- 단순히 결과만 나오는 것이 아니라 내가 원하는 추가 설명이 있는 결과를 받도록 설정해보자.

- 아래와 같이 다른 예시를 하나 추가해주고, 학교 선생님처럼 친절하게 설명해달라는 예시를 붙여보자.

system_prompt = \
"""
1. 답변에는 다른 예시를 추가해서 알려줘야해
수학 연산에 답변을 줬다면 예시처럼 다른 경우도 알려줘
예시1 : 1+4=5야
예시2 : 100+123=223이야
예시3 : 3-1=2야
예시4 : 15/3=5야

2. 너는 학교선생님처럼 친절하게 설명해줘야해.
짧은 답변이 아니라 자세히 친절하게 설명해줘야해.
질문자에게 공부를 잘 할 수 있다는 격려도 해줘야해.

예시1 : 3+3에서 +은 더하기로 앞의 숫자와 뒤의 숫자를 합치는 거야. 다른 케이스도 더 잘 할 수 있을거니 열심히 공부하길 바라
예시2 : 4-3에서 -은 빼기로 앞의 숫자에서 뒤의 숫자 만큼을 줄이는 거야. 다른 연산법도 잘 이해할 수 있도록 내가 잘 알려줄게
"""
# 시스템 프롬프트를 모델 설정에 추가
model=genai.GenerativeModel(
  model_name="gemini-1.5-flash",
  system_instruction=system_prompt)

# 결과 요청
response = model.generate_content("100-73은 뭐야?")
# 결과 확인
print(response.text)

 

- 위와 같은 세팅을 통해 아래와 같은 친절하고 예시가 있는 답변을 얻을 수 있다.

안녕하세요! 100 - 73을 계산하는 방법을 알려드릴게요.  '-' 기호는 빼기를 의미하며, 앞의 수에서 뒤의 수를 빼는 연산입니다.

100에서 73을 빼려면,  우리는 자릿수(일의 자리, 십의 자리, 백의 자리)별로 빼기를 해야 합니다.

* **일의 자리:** 0에서 3을 뺄 수 없으므로, 십의 자리에서 10을 빌려와야 합니다.  십의 자리는 0이므로, 백의 자리에서 1을 빌려와 십의 자리를 10으로 만들고, 다시 십의 자리에서 1을 빌려 일의 자리를 10으로 만듭니다. 이제 일의 자리는 10 - 3 = 7이 됩니다.

* **십의 자리:** 십의 자리는 10에서 1을 빌려줬으므로 9가 됩니다.  9에서 7을 빼면 2가 됩니다.

* **백의 자리:** 백의 자리는 100에서 1을 빌려줬으므로 9가 됩니다.  9에서 아무것도 빼지 않으므로 9가 그대로 남습니다.

따라서, 100 - 73 = 27 입니다.

다른 예시를 통해 더 연습해 볼까요?

* **예시 1:** 55 - 22 = ?  (십의 자리와 일의 자리 모두 뺄 수 있으므로, 각 자릿수별로 빼면 됩니다.)
* **예시 2:** 80 - 35 = ? (일의 자리에서 뺄 수 없으므로 십의 자리에서 10을 빌려와야 합니다.)
* **예시 3:** 125 - 48 = ? (백의 자리, 십의 자리, 일의 자리 모두 계산해야 합니다.  자릿수를 잘 나눠서 생각하면 쉽게 풀 수 있어요!)

이러한 연습을 통해 빼기 연산에 대한 이해도를 높일 수 있습니다.  수학은 조금씩 연습하면 누구든 잘 할 수 있어요!  열심히 노력하면 분명 실력이 향상될 거예요.  힘내세요!

 

4. 시스템 프롬프트를 사용하면 좋은 점

- 우리가 원하는 방식으로 답변을 얻을 수 있도록 튜닝할 수 있다.

- 서비스를 만들거나 원하는 결과를 도출하기 위해서는 이런 프롬프팅을 사용해야만 좋은 결과를 얻을 수 있다.

- 일반적으로 우리들이 사용하고 있는 chatGPT도 프롬프팅이 되어 있어서 우리가 편리하게 사용하고 있는 것이다.

- llm을 사용한 서비스를 만들기 위해 시스템 프롬프트를 잘 사용해보자.

1. 구글 gemini 무료로 사용하기

- 하루 마다 사용할 수 있는 요청 수에 제한이 있고, 분당 요청 수도 제한이 있다.

- 가격 정책을 보면 어느 정도 하루에 무료로 사용할 수 있는지 알 수 있다.

- 사용하는 방식은 

- 관련 사용 문서를 보면 api에 특정 요청을 보내는 것으로 간단히 사용할 수 있는 것을 알 수 있다.

- https://ai.google.dev/gemini-api/docs/get-started/tutorial?lang=python&hl=ko#install_the_python_sdk

- https://ai.google.dev/pricing?hl=ko#1_5flash

 

Gemini API 가격 책정  |  Google AI for Developers

개발자를 위한 Gemini API는 확장할 때 강력한 무료 등급과 유연한 가격 책정을 제공합니다.

ai.google.dev

 

튜토리얼: Gemini API 시작하기  |  Google AI for Developers

텍스트 생성 및 채팅 기능을 포함하여 Gemini API 및 Gemini 1.5 Flash를 시작합니다.

ai.google.dev

 

2. 간단히 요청 보내고 확인해보기

- api키를 생성하면 간단히 요청을 보내는 예제를 확인할 수 있다.

- 요청 주소에서 GEMINI_API_KEY 부분을 발급받은 키로 바꾸면 LLM으로 부터 보낸 요청에 대한 답을 받을 수 있다.

- 보내는 요청은 아래에서 "Explain how AI works" 부분이다.

curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=GEMINI_API_KEY" \
-H 'Content-Type: application/json' \
-X POST \
-d '{
  "contents": [{
    "parts":[{"text": "Explain how AI works"}]
    }]
   }'

 

- 요청을 보내면 아래와 비슷한 결과를 볼 수 있다.

- text에 llm으로 생성된 response가 나오는 것을 확인할 수 있다.

{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "text": "AI, or Artificial Intelligence, doesn't work in a single, unified way.  Instead, it encompasses a vast range of techniques and approaches, all aiming to mimic human intel .....

1. Dockerfile로 특정 작업을 실행하는 이미지를 만들면 좋은점

- 특정 작업을 실행하는 이미지를 만들어 해당 작업을 어디서든 실행시킬 수 있다.

- 도커컨테이너로 작업하면 실행 환경이 보장되기 때문에 안정적인 배포가 가능하다.

- 이를 통해 CI/CD를 할 수 있다.

 

2. Dockerfile를 만드는 법

- 실습을 위해 폴더를 하나 만들고 아래와 같이 main.py와 Dockerfile이라는 파일을 만들자.

# main.py
# argparse로 특정 인자를 실행할 때 받는 코드

import argparse

parser = argparse.ArgumentParser(description="Process two arguments.")
parser.add_argument("arg1", help="The first argument.")
parser.add_argument("arg2", help="The second argument.")
args = parser.parse_args()

print(f"arg1: {args.arg1}, arg2: {args.arg2}")
# Dockerfile (확장자가 없는 파일입니다.)
FROM python:3.9-slim

# 작업 디렉토리 설정
WORKDIR /app

# main.py 복사
COPY main.py .

# 파이썬 로그가 보이게 버퍼 설정
ENV PYTHONUNBUFFERED=1

# 실행 설정
ENTRYPOINT ["python", "main.py"]

- 평소에 argparse를 사용했다면 main.py에 arg가 2개 들어가야 한다는 것을 알것이다.

- 해당 arguments는 이미지를 실행(run) 할 때 넣으면 된다.

 

3. Dockerfile로 image 만들기

- Dockerfile이 있는 경로에서 아래와 같은 명령어를 실행한다.

# main-with-args라는 이름과 1.0이라는 tag를 가지고 docker image가 생긴다
docker build -t main-with-args:1.0

# build가 성공적으로 완료되면 설정한 이름으로 이미지가 생성됐는지 본다.
docker image list

성공했다면 이렇게 조회된다.

 

4. arguments를 써서 컨테이너를 실행하기

- 단순히 컨텐이너를 실행할 때 arguments를 붙이면 된다.

# test-arguments라는 컨테이너 이름으로 first와 second라는 arguments를 붙여서 실행한다.
docker run --name test-arguments main-with-args:1.0 first second

# 실행이 완료되면 docker logs로 확인하자
docker logs test-arguments

아래와 같은 로그가 나오면 성공이다.

 

5. arguments가 아니라 환경변수 값으로는 안될까?

- arguments가 아니라 환경변수를 인자로 받아서 실행하고 싶은 경우도 있을 것이다.

- 그런경우 아래와 같이 환경 변수를 Dockerfile에서 줄 수 있고 실행해서 확인할 수 있다.

# MY_ARG1, MY_ARG2라는 이름으로 설정된 환경 변수를 가져온다.
import os

print(f"MY_ARG1: {os.environ.get('MY_ARG1')}, MY_ARG2: {os.environ.get('MY_ARG2')}")
# 환경 변수를 설정했으니 main.py에 환경변수를 받는 코드가 있으면 된다.
FROM python:3.9-slim

# 작업 디렉토리 설정
WORKDIR /app

# main.py 복사
COPY main.py .

# 파이썬 로그가 보이게 버퍼 설정
ENV PYTHONUNBUFFERED=1

# 환경 변수 설정
ENV MY_ARG1="first my env"
ENV MY_ARG2="second my env"

# 실행 설정
ENTRYPOINT ["python", "main.py"]

 

6. 위와 동일하게 이미지를 만들고 실행해보자

- 명령어는 동일한 방식으로 사용하면 된다.

- 물론 이번에는 arguments를 받는 경우가 아니므로 컨테이너를 그냥 실행하기만 하면 된다.

# 이미지를 생성한다.
docker build -t main-with-envs:1.0 .

# arguments를 주는 코드가 아니므로 실행만한다.
docker run --name test-envs main-with-envs:1.0

# 로그를 살펴보자!
docker logs test-envs

정상적으로 적용된 것을 알 수 있다.

 

7. 결론

- 상황에 따라 적절하게 이미지를 생성해서 사용하자.

- 주로 환경변수로 작업을 진행할테지만 상황에 따라 arguments를 부여해야하는 경우가 있으니 적절히 사용해보자!

+ Recent posts