728x90

실습 내용 자체는 앞서 수행한 과정과 거의 동일하다.
LLM이 Gemini로 바뀐것 뿐이다.

실습

from IPython.display import Markdown

import os
os.environ["GOOGLE_API_KEY"] = "YOUR_API_KEY"
%pip install -U --quiet langchain-google-genai
from langchain_google_genai import ChatGoogleGenerativeAI

LLM 정의 및 체크

llm = ChatGoogleGenerativeAI(model = "gemini-pro")
result = llm.invoke("네이버에 대해 보고서를 작성해줘")
Markdown(result.content)

Dependency 설치

%pip install -U --quiet langchain tiktoken pypdf sentence_transformers chromadb
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain.document_loaders import PyPDFLoader

PDF Loader & Text Splitter & Embedding

loader = PyPDFLoader("/content/drive/MyDrive/코딩/LangChain 실습(모두의AI)/data/[이슈리포트 2022-2호] 혁신성장 정책금융 동향.pdf")
pages = loader.load_and_split()

text_splitter = RecursiveCharacterTextSplitter(chunk_size = 500, chunk_overlap = 50)
texts = text_splitter.split_documents(pages)

from langchain.embeddings import HuggingFaceEmbeddings

model_name = "jhgan/ko-sbert-nli"
model_kwargs={'device':'cpu'}
encode_kwargs={'normalize_embeddings': True}
hf = HuggingFaceEmbeddings(
    model_name = model_name,
    model_kwargs = model_kwargs,
    encode_kwargs = encode_kwargs
)

docsearch = Chroma.from_documents(texts,hf)

Retriever

retriever = docsearch.as_retriever(
    search_type = 'mmr',
    search_kwargs={'k':3,'fetch_k':10}
)
retriever.get_relevant_documents("혁신성장 정책 금융에 대해서 설명해줘")

Prompt Template

from langchain.prompts import ChatPromptTemplate
from langchain.schema.runnable import RunnableMap

template = """Answer the question as based only on the following context:
{context}

Question: {question}
"""

prompt = ChatPromptTemplate.from_template(template)

chain 구성

gemini = ChatGoogleGenerativeAI(model = "gemini-pro", temperature=0)

chain = RunnableMap({
    "context":lambda x: retriever.get_relevant_documents(x['question']),
    "question":lambda x: x['question']
}) | prompt | gemini

RunnableMap으로 관련된 문서를 context로, 질문은 question으로 Prompt Template에 전달하고 이를 기반으로
LLM이 답변을 생성한다.

결과 출력

Markdown(chain.invoke({'question':"혁신성장 정책금융에 대해서 설명해줘"}).content)

LLM의 답변을 markdown 형식으로 출력해준다.

Reference

모두의 AI[https://www.youtube.com/@AI-km1yn]

'인공지능 > RAG' 카테고리의 다른 글

LangChain - RunnablePassTrough  (0) 2024.06.04
LangChain (11) 오픈소스 LLM으로 RAG 구현  (0) 2024.06.04
What is Elastic Search?  (0) 2024.06.03
Langchain - Ensemble Retriever  (1) 2024.05.31
Langchain - Hybrid Search 구현  (0) 2024.05.31
728x90

Elastic Search는 검색 엔진.

관계형 DB(RDBMS)와의 관계

관계형 데이터베이스에 대응되는 Elastic Search의 개념들

데이터 접근 방식

Elastic Search는 Rest API를 통한 데이터 조작이 가능하다.

Inverted Index

Elastic Search의 가장 큰 특징이라고 하면 inverted index이다.
일반적인 index는 문서를 빠르게 찾기 위해서 문서의 위치를 가르키지만

inverted index는 단어들에 대해서 어떤 단어가 어느 문서에 포함되어있는지를 기록합니다.

가령, 아래와 같은 데이터베이스가 있다고 합시다.

ID Name
1 Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks
2 Retrieval-Augmented Generation for Large Language Models: A Survey
3 A Survey on Retrieval-Augmented Text Generation
4 Benchmarking Large Language Models in Retrieval-Augmented Generation
5 Generation-Augmented Retrieval for Open-domain Question Answering
6 MEASURING MASSIVE MULTITASK LANGUAGE UNDERSTANDING

위 테이블에서 Retrieval 이라는 단어가 포함된 행을 가져오려면 ID = 1 부터 테이블의 끝까지 반복적으로 검색을 해야합니다.

따라서, 데이터의 개수가 많아질수록 검색할 대상이 늘어나고 row 안의 내용을 모두 읽어야하므로 검색 속도가 매우 느립니다.

반면에 아래와 같이 inverted index를 적용한 테이블을 구성하는 경우를 생각해 볼 수 있습니다.

Term ID
Retrieval 1,2,3,4,5
Augmented 1,2,3,4,5
Generation 1,2,3,4,5
MEASURING 6
Language 1,2,3,4,5,6
for 1,2,5
Open 5

Elastic Search에서는 위와 같은 inverted index를 구성해서 데이터가 늘어나더라도 큰 속도 저하 없이 빠르게 검색이 가능합니다.

Elastic Search에서는 추출된 각 키워드를 Term이라고 부릅니다.

Elastic Search의 특징

  • Elastic Search는 분산 처리를 통해 빠른 검색이 가능하고 대량의 비정형 데이터 검색이 가능하다.
  • 전문 검색과 구조 검색 모두를 지원한다.
  • 검색 엔진이지만 대용량 스토리지로 활용이 가능하다.

Elastic Search의 장점

  • 오픈소스
  • 전문 검색
    • 내용 전체를 indexing해서 특정 단어가 포함된 단어를 검색할 수 있다.
  • RESTful API
    • RestAPI 형식으로 요청하고 json format을 사용하기 때문에 개발 환경에 독립적으로 사용 가능하다.
  • Schemaless
    • 비정형 데이터에 대해서도 indexing과 검색이 가능
  • Inverted Index
    • 앞서 설명한대로 데이터의 양이 증가해도 검색 속도에 큰 영향이 없다.
  • Shard
    • 분산 구성이 가능해서 확장성이 높다.Elastic Search의 단점
  • Transaction Rollback 지원 X
    • 성능을 위해서 Rollback, Transaction을 지원하지 않는다..(??)
  • 데이터의 업데이트를 제공하지 않는다
    • 업데이터를 하는 경우 기존 문서를 제거하고 새로운 문서를 생성한다.

용어 설명

1. Indexing

  • 데이터를 검색 가능한 구조로 바꾸는 과정
  • 원본 문서를 검색어 토큰으로 변환 후 저장

2. Document

  • 단일 데이터 단위
  • RDBMS의 Row라고 생각하면 된다

3. Index

  • Document를 모아놓은 집합
  • Indexing이 완료된 데이터가 저장되는 공간
  • 문서들의 논리적인 집합 단위

4. Shard

  • index가 분리되는 단위
  • 각 노드에 분산되어 저장
  • 단일 검색 인스턴스
  • 클러스터에 노드를 추가하면 샤드들이 각 노드들로 분산되고 디폴트로 1개의 복제본을 생성
  • 처음 생성된 샤드를 primary shard라 하고, 이후에 생성된 샤드를 replica하 함
  • 노드가 1개인 경우 primary shard만 존재
  • primary shard와 replica는 필연적으로 동일한 데이터를 저장하고 데이터베이스 안전성을 위해 서로 다른 노드에 저장됩니다.

5. Master Node

  • 인덱스의 메타 데이터, 클러스터 상태 정보를 관리하는 노드.
  • 클러스터당 1개의 마스터 노드가 존재
  • 마스터 후보 노드가 존재하며 마스터 노드가 모종의 이유로 다운되면 후보 노드중 하나가 마스터 노드의 역할을 수행

6. Data Node

  • 실제 indexing된 데이터가 저장된 노드

Reference

  1. https://www.elastic.co/guide/en/elasticsearch/reference/current/elasticsearch-intro.html
  2. https://esbook.kimjmin.net/
  3. https://jaemunbro.medium.com/elastic-search-%EA%B8%B0%EC%B4%88-%EC%8A%A4%ED%84%B0%EB%94%94-ff01870094f0
728x90

Jenkins란?

  • 오픈소스 자동화된 서버(controller / master)
  • 자동화된 CI/CD 도구 : DevOps integrator
    • building, testing,delivering, deploying s/w
  • 1000개 이상의 plugin, Java 기반
  • maven/java project와 맞는다

장점

  • 개발자에게 빠른 피드백
  • 개발자가 문제를 찾고 고치기에 쉬움
  • 개발자 생산성 향상
  • 코드 퀄리티 향상
  • integration 과정을 자동화함
  • s/w release 프로세스 자동화
  • s/w 업데이트 release를 더 빠르게 할 수 있다.
  • Jenkinsfile을 통한 자동화된 CI/CD pipeline

Jenkins 특징

  • Jetty web server에 연동되어 웹서비스 형식으로 Jenkins 서비스 제공
    • Jenkins를 깔면 jetty가 같이 깔리고 request는 웹서버로 온다.
    • default port #가 8080
    • 실제에서 jenkins를 사용할때 기기이름:8080을 하면 jetty라는 서버가 받는다.
    • Jenkins가 일을 하고 최종 결과를 html로 바꾸는 역할을 한다.
  • Maven 등 build tool 연동
  • Selenium 등 test tool 연동
  • Container를 k8s cluster에 deploy
  • 1000개 이상의 자동화 툴 plugin 존재
  • 다양한 notification 툴 연동 - Jabler, IRC, Desktop notification …
728x90

문제 상황

Jenkins가 설치된 EC2 인스턴스를 중지 후 시작하자 Jenkins 웹서비스의 속도가 너무 느려짐

발생 이유

AWS Free Tier를 사용하는 경우 EC2 인스턴스를 중지 후 시작하면 public ip가 변경되는데 이를 설정해줘야함.

해결 방안

  1. Jenkins dashboard > Jenkins 관리 > System에서 Jenkins Location을 찾아야한다.
  2. Jenkins URL을 http://[EC2 인스턴스의 public ip]:8080 으로 변경해준다.
    왜냐하면 이 값은 중지 이전 public ip로 설정되어 있기 때문이다.

'개발 > CICD' 카테고리의 다른 글

Jenkins (1) - Jenkins란?  (0) 2024.06.03
Jenkins (3) - Java Project build with Maven  (1) 2024.06.03
Jenkins (2) - 설치  (1) 2024.06.03
728x90

EC2 instance를 중지 후에 다시 재개 해서 public ip가 변경되어도 동일하게 [public ip]:8080으로 접근하면 된다.

Java project를 build하는데는 maven을 사용하는게 보편적이었다. (요새는 Gradle 많이 씀)

우리는 Java project를 build 하기 위해 Jenkins에서 제공하는 샘플 Java code를 사용합니다.

🔥링크🔥

코드 확인

Simple Java Maven App

App.java

src 디렉토리를 가면 main, java 디렉토리가 있다.

main의 App.java 코드를 확인하면 진짜 기본적인 코드가 있다. (그냥 Hello world! 출력)

pom.xml

  • maven은 pom.xml 파일을 보고 java source code를 실행하는데 필요한 정보를 확인한다. dependency등.. (pom = project object model)
  • dependcy를 확인하면 junit이라는 도구가 있는데 이는 test시에 필요하다.
  • 본 코드에서는 test/AppTest.java를 unit test하는 코드가 있는데 여기서 활용한다. (@Test 어노테이션을 사용하기 위해 필요)
  • xml 파일 하단에 보면 Maven 버전도 확인이 가능하다.

maven 확인

위의 repository를 clone한 디렉토리에 들어가서 maven package를 하게 되면 java program이 실행될 수 있는 executable이 java 파일로 생성된다.

1. 수작업으로 Maven으로 Java Project Build하기

Git 설치

sudo apt-get update
sudo apt-get install git
sudo apt-get update
sudo systemctl daemon-reload

Maven 설치

mvn -v

위 코드로 maven 설치 여부를 확인한다. 아직 설치가 되어 있지 않으므로 아래와 같은 문구가 출력된다.

Command 'mvn' not found, but can be installed with:
sudo apt install maven

위 명령어를 사용하면 maven이 설치가 된다. 하지만, maven은 linux 운영체제에 의해 기본적으로 제공되는 프로그램이 아니고 third party 프로그램이다.

따라서, 이렇게 설치를 하게 되면 apt 리포지토리가 아는 maven을 설치하게 된다.

하지만 maven 특정 버전이라고 명시를 해주지 않으면 3.6 버전을 가져오게 된다. (우리에게 필요한건 3.8.6 이상.. 그냥 최신거 쓰면 됨)

따라서 우리는 이 🔥링크에 들어가서 설치를 하면 된다.

문제는 ubuntu에 설치해야하므로 curl이나 web get 하면 된다.

왼쪽 네비게이션 탭의 download에 들어가서 링크 주소를 복사한다.

[링크 주소] https://dlcdn.apache.org/maven/maven-3/3.9.7/binaries/apache-maven-3.9.7-bin.tar.gz

Maven 설치

linux에서는 s/w를 설치 할 때 관습적으로 특정 경로 ( /local or /opt ) 에 설치한다.

admin이 해당 s/w를 확인하고 ubuntu linux에 tight하게 bind 되어 있다면 /usr/local에 설치한다.

linux와 상관 없는 third party program은 /opt에 설치한다.

따라서, 우리는 /opt 폴더에 설치한다.

cd /opt
sudo wget <https://dlcdn.apache.org/maven/maven-3/3.9.7/binaries/apache-maven-3.9.7-bin.tar.gz>
sudo tar -xvf apache-maven-3.9.7-bin.tar.gz
sudo ln -s /opt/apache-maven-3.9.7 /opt/maven
sudo vi /etc/profile.d/maven.sh

이후 maven.sh 파일 안에 아래 문구를 추가한다.

export M2_HOME=/opt/maven
export MAVEN_HOME=/opt/maven
export PATH=${M2_HOME}/bin:${PATH}

아래 명령어를 마저 입력하고 mvn -v 로 maven 설치를 최종 확인한다.

sudo chmod +x /etc/profile.d/maven.sh
source /etc/profile.d/maven.sh
mvn -v

git clone

cd ~
mkdir maven-test && cd maven-test
git clone <https://github.com/jenkins-docs/simple-java-maven-app.git>

MVN complie

cd simple-java-maven-app
ls -al
mvn compile

mvn compile을 하면 많은 것들을 compile하고 download한다.

MVN Test

mvn test

우리는 미리 정의된 AppTest 파일이 있기 때문에 maven이 test 과정을 수행한다.

MVN Package

mvn package
ls -al

프로그램을 실행파일로 만드는 즉, package로 만드는 명령어.

이후 ls -al 로 파일 목록을 확인하면 target이라는 디렉토리가 생성된걸 확인할 수 있다.

maven이 target이라는 디렉토리를 만들어서 그 안에 실행파일을 넣은 것이다.

jar 파일 실행

java -jar my-app-1.0-SNAPSHOT.jar

위 명령어로 jar 파일을 실행하면 “Hello World!”가 출력되는 것을 확인할 수 있다.

2. Jenkins 활용해서 Maven 활용해서 Java Project build하기

Jenkins 관리 > Tools

나머지 건드리지말고 Maven Installation만 수정

Maven Installation

이름 설정. 개인적으로 mvn-3.9.7이라고 함

버전은 그대로 3.9.7

우리는 이미 maven을 설치했으므로 install automatically 체크 해제한다.

MAVEN_HOME

이 값으로는 /opt 폴더의 apache-maven-3.9.7 디렉토리의 주소를 전달하면 된다.

/opt/apache-maven-3.9.7

이후에 save하면 된다.

새로운 item 생성

이제 maven이라는 도구를 등록했으므로 새로운 item을 생성한다

item 이름은 개인적으로 설정(나는 simple-java-maven-app)

이후 freestyle project를 생성한다.

Configure

repository url

앞선 실습에서는 github에서 직접 ec2 인스턴스에 clone을 해서 작업을 했는데 이를 자동화한다.

우리는 소스코드를 github로부터 가져오므로 소스코드 관리에 github 리포지토리 url을 추가한다. <>code 부분 누르면 나오는 주소를 입력하면 된다. https://github.com/jenkins-docs/simple-java-maven-app.git

credentials

github의 코드를 가져올때 리포지토리가 private이라면 접근 권한을 추가해야한다.

우리는 public repository니까 none으로 유지한다.

Build Step

나머지는 다 스킵하고 build step으로 넘어간다.

invoke top-level maven targets를 설정한다.

maven version

우리는 3.9.7 버전을 설치하였으므로 설정한다.

Goals

우리의 목표는 java package를 만드는 것이므로 package라고 설정한다.

이후 저장한다.

빌드

좌측 네비게이션 탭에서 지금 빌드를 클릭한다.

빌드 결과

이후 좌하단 초록색 체크표시 링크를 클릭하면 console output을 확인 할 수 있다.

매우 길다.

jar 파일 생성 확인

console output을 쭉 내려보면 jar 파일의 경로를 확인할 수 있다.

 

해당 경로 ( /var/lib/jenkins/workspace/simple-java-maven-app/target/ ) 으로 이동해서 jar 파일을 실행해보자

ls -al
java -jar my-app-1.0-SNAPSHOT.jar

그러면 출력 결과로 “Hello World!”를 확인 할 수 있다.

 

'개발 > CICD' 카테고리의 다른 글

Jenkins (1) - Jenkins란?  (0) 2024.06.03
Jenkins Trouble Shooting - (1) 웹페이지 속도 저하 해결  (0) 2024.06.03
Jenkins (2) - 설치  (1) 2024.06.03
728x90

환경

AWS EC2 instance - free tier(t2.micro)

Ubuntu 24.02

Jenkins 설치

sudo wget -O /usr/share/keyrings/jenkins-keyring.asc \\
  <https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key>
echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc]" \\
  <https://pkg.jenkins.io/debian-stable> binary/ | sudo tee \\
  /etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt-get update
sudo apt-get install jenkins
  1. jenkins 다운로드할때 key를 사용해서 설치 할 수 있도록 key를 받아온다.
  2. apt 프로그램을 사용하는데 jenkins는 linux에서 제공하는게 아니라 third party service다. 따라서, repository가 어디있는지 apt에게 알려준다.
  3. jenkins 설치 전 apt-get 을 update하고 설치

Java 설치

sudo apt update
sudo apt install fontconfig openjdk-17-jre
java -version
openjdk version "17.0.8" 2023-07-18
OpenJDK Runtime Environment(build 17.0.8+7-Debian-1deb12u1)
OpenJDK 64-Bit Server VM(build 17.0.8+7-Debian-1deb12u1, mixed mode, sharing)
  • 현재 모든 java 버전이 동작하는게 아니다. 현재는 openjdk-17 지원

설치된 패키지 버전 및 동작 확인

java -version
jenkins --version
sudo systemctl start jenkins
sudo systemctl status jenkins

다양한 소프트웨어 도구들을 연동시켜서(integration) worker node를 control 할 수 있는 CICD Controller.

Jenkins에서 제공하는 웹서비스를 통해서 jenkins를 사용할 수 있어서 편리하다

→ 하나하나 Worker node 들어가서 관리할 필요 x

Local에서 Jenkins 접근

[EC2 instance의 public ip 주소] : 8080 을 웹브라우저에 입력하고 실행하면 unlock jenkins라는 화면이 나온다. 이는 우리가 jenkins 웹에 처음 접근해서 그렇다.

기계가 돌고있는 ip 주소만 알면 8080 포트로 접근해서 Jenkins 웹서비스를 사용할 수 있다.

비밀 번호 확인

sudo cat /var/lib/jenkins/secrets/initialAdminPassword

위 명령어로 나온 비밀번호를 웹에 입력한다.

여기서 install suggested plugins를 클릭

좌측을 클릭하면 다양한 Plugin들을 설치하게 된다.

 

계정명 암호 이름 이메일등을 작성하게 되면 URL 설정하는 화면이 나오는데 EC2 instance를 종료시키기 전까지는 Public IP는 그대로이므로 그대로 진행하면 된다.

 

아래는 Jenkins 웹서비스 화면이다.

Test, build, Containerize, deploy 등의 모든 과정을 job으로 해서 Jenkins에 할당할 수 있다.

이러한 job을 실행시키는걸 Jenkins에서는 build 한다고 한다.

Tools

Maven

code를 compile하고 build하는 도구. 널리 쓰이는 다양한 라이브러리들을 관리하는 도구를 build 도구라고 하는데 maven도 이 중에서 하나. Maven은 java로 작성한 코드를 build하는 도구.

다양한 dependency들을 maven repository가 관리해준다. 따라서, 사용자들은 maven에 뭐가 필요한지 표시만 해주면 된다. 표시를 해주면 maven의 Repository에 가서 가져온다.

Gradle이라는 도구도 java & springboot framework 사용시 자주 사용되는 빌더인데 gradle도 maven repository에서 가져온다.

Jenkins는 Java로 만들어져있다. Jenkins가 Java Framework를 사용하는 프로젝트를 컨트롤하는 소프트웨어로 시작했지만 현재는 확장이 되어 다른 프로그래밍 언어에 대해서도 관리가 가능하다. 따라서, Maven Configuration이 default로 제공된다.

JDK

Worker node에서 다른 버전의 JDK를 사용하는 경우 JDK를 Add해줘야한다. 하지만 우리는 앞서 JDK 17을

설치했으므로 따로 필요가 없다.

Git installation

Name은 본인이 알아서 설정하면 된다.

Github에 source code가 등재되면 github에서 git clone을 해서 CICD flow를 구성해준다.

새로운 item

item은 Jenkins job이다. Job의 종류는 freestyle, pipeline 등 다양하다.

Jenkins도 모든 s/w 도구들을 plugin으로 install 해서 적용 가능하다.

코드 개발부터 테스트, 배포까지 자동적으로 이루어질 수 있게 한다.

github에 새 코드가 들어오면 어떤 기기에서 테스트하게도 할 수 있다.

 

이제 freestyle project를 하나 만들어보자.

이름을 임의로 정하고 OK를 눌러주면 새로운 job이 생성된다.

세부 설정은 이후에 정하고 우선은 다 넘어가고 build step으로 가자

Build Step

우리는 Ubuntu 환경이니까 execute Shell을 설정한다.

pwd
echo "Hello World!"

이후 저장을 누르면 첫번째 job이 생성된다.

이후 좌측 네비게이션 탭에서 지금 빌드를 클릭하자

좌측 하단에 초록색 체크표시가 있다면 제대로 동작하는 것이다.

그리고 #1 #2 #3으로 보이는 링크를 클릭하면 콘솔 출력도 확인할 수 있다.

로그를 확인하면 Building in workspace [경로] 를 확인할 수 있는데 이는 실제 작업이 해당 [경로]에서 이루어진다는 의미이다.

 

Reference Site

https://www.jenkins.io/doc/book/installing/linux/

728x90

Metric Learning

목적 : 각 sample(하나의 데이터)를 설명할 수 있는 feature를 뽑는 것.

  • 이렇게 추출한 feature는 서로 다른 정보로 구성(?)
  • 이러한 feature의 유사성을 검토해서 샘플을 분리하는게 목적 → 약간 KNN, clustering 느낌?
  • 유사도는 Euclidean Distance를 기반으로 측정 → L2 Distance

검색 알고리즘

  • 검색을 목적으로 하는 학습 방법은 서로 다른 두 객체 간의 유사도를 검증하는 것에 있다.
  • 과거에는 두 샘플간 유사도를 측정하기 위해 유클리드 거리를 구함 근데 성질이 매우 다른게 아니라면 분류에 어려움이 있음.

→ SIFT 등장

  • SIFT와 CNN의 차이는?
    • 둘 다 Feature extractor, feature encoding, feature analytics 단계를 거침
    • 근데 Feature extractor 부분이 다름
    • SIFT는 local extraction, CNN은 학습에 의한 표현 공간에 feature를 mapping

Feature Extractor

Local Extraction

  • SIFT에서 사용되는 방법으로 이미지 처리 시에 이미지 내 변화된 공간 추적 & 검출
  • 각 feature들의 값의 변화가 크지 않으면 유사성 이미지로 검출
  • 각 이미지 내 정보의 구조적 관점에서 서술되는 feature의 유사성 판별

CNN feature extraction

  • feature를 공간에 분포하기 위해 학습 수행
  • feature를 공간에 어떻게 분포시킬지 가중치를 이용해서 결정. 가중치를 학습시켜서 분류 기준을 찾는다

정리

  • CNN의 기법은 어디까지나 High Dimensional Data 에서 적용할 때 그 효과가 극대화
  • 저차원 영역에서는 오히려 SIFT의 기법이 더 좋은 성능을 발휘하기도 함
  • Feature extractor를 기반하여 Metric Learning에서는 다음 두 가지 네트워크(Embedding Network, Fisher Vector/VLAD)를 추가로 구성
  • CNN은 모양에 따른 서로 다른 분류는 가능하지만, 각 모양 내 서로 다른 패턴별로 이미지를 분류하는 것은 매우 어려움

Triplet Network

figure 1 : FaceNet: A Unified Embedding for Face Recognition and Clustering

  • Metric Learning의 목적은 이처럼 서로 다른 특징으로 분류해야만 하지만, Texture 구조가 유사하여 같은 공간 내 있는 데이터를 떨어뜨리는 것
  • Triplet Network의 목적은 기준 데이터로부터 근사한 데이터는 가깝게, 근사하지 않은 데이터는 멀리 떨어뜨려서 적절한 분리 공간에 배치하도록 하는 것이 목적이다.
  • 이게 가능한건 딥러닝이 가중치를 업데이트해서.

figure 2 : DEEP METRIC LEARNING USING TRIPLET NETWORK

학습 방법

  • 동일한 CNN 모델에서 기준이 되는 이미지(Anchor Image)와 이를 비교할 두 개의 이미지(Positive and Negative Image)를 사용.
  • 기준 이미지에 대한 유클리드 거리를 계산하고 L2-Norm을 적용한 뒤 loss 값을 계산한다.
  • Margin이라는 요소가 들어가는데, 각각의 distance의 값에 변화를 줌으로서 최적의 Loss 계산

모델 설명

figure 3 : distance equation

  • 위 식에서 Postivie Distance는 작을 수록 학습이 잘된 것이고 Negative Distance는 클 수록 학습이 잘된 것.
  • 식에 따르면 Positive Distance는 항상 Negative Distance보다 작아야한다.
  • 알파는 bias와 같은 개념으로 앞서 학습방법에서 언급한 margin이다

Loss Function

figure 4 : Loss function

  • Loss Function으로 구성하기 위해 figure 3의 식을 확인하면 우변의 값을 좌변으로 넘겨 Loss Function을 구성한다.
  • 최적의 거리를 찾아낸다면 Positive Distance = 0, Negative distance = 1이므로 $0 - 1 + \alpha = \alpha-1$이 된다. 이때 margin이 1이면 Loss = 0.

Triplet Loss의 예

figure 6 : example

  • 위 이미지에서 입력된 이미지들을 각각 A,P,N라 하고 A를 기준 이미지(anchor image)라 하자
  • A,P는 같은 인물이므로 같은 클래스이며, P는 Positive Sample이다.
  • A, N는 서로 다른 인물이므로 다른 클래스이며, N는 Negative Sample이다.
  • 따라서, 거리를 측정하는 함수 d(x, y)가 있을때 d(A,P)는 최소화 하고, d(A,N)은 최대화하는 것이 Triplet Network의 목적이다.

'인공지능 > 딥러닝' 카테고리의 다른 글

Pytorch - Tutorials(파이토치 모델 학습 코드 설명)  (1) 2024.04.09
Transformer  (2) 2024.03.17
Attention Mechanism  (1) 2024.03.17
인공 신경망 종류 (3) Seq2Seq  (0) 2024.03.17
인공 신경망의 종류 (2) LSTM  (0) 2024.03.17
728x90

1. Deep Learning Primitive란?

프로그래머가 사용할 수 있는 가장 작은 실행 단위이다. 하지만, Triton에서 사용된 의미는 특정 연산의 단위로 해석하는게 적절한듯 하다. 예를 들어, 순방향 컨볼루션 계산, 역방향 lstm 계산 등이 있을 수 있다.

primitive와 함수의 가장 큰 차이는 primitive가 상태(state)를 저장함에 있다. 2가지 상태가 존재하는데 불변(immutable)하는 상태의 경우 계산의 용이성을 위해서 tensor shape등을 저장한다. 이러한 불변 상태를 반복적으로 사용해서 계산 시간을 줄일 수 있다.

Primitive 상태의 가변부의 경우 scratchpad라고 부르고, 계산시에 필요한 값들을 임시로 저장하는 메모리 버퍼로 사용한다. Scratchpad는 primitive 객체에 속할수도 있고 실행시간 매개변수로 사용할 수 도 있다.

출처 1. https://www.ml-science.com/primitive
출처 2. https://oneapi-src.github.io/oneDNN/v1.3/dev_guide_basic_concepts.html

2. PyPy

파이썬은 인터프리터 언어기 때문에 C, C++같은 컴파일러 언어에 비해 속도가 느리다.

이러한 속도의 한계를 극복하고자 성능이 중요한 작업을 C로 완성하고 C 코드를 파이썬으로 랩핑하는 방식을 사용해왔다. 또한, 파이썬에 런타임 형식 정보를 섞어 C로 컴파일할 수 있게 만드는 Cython 프로젝트도 존재한다.

  • PyPy는 기존의 파이썬 인터프리터 CPython을 대체.
  • Cpython은 python → 바이트코드 → VM 인터프리트
  • 반면 PyPy는 JIT(Just-In-Time) 컴파일로 python → Machine Native 어셈블리어
  • PyPy는 파이썬 언어 지원 + pip + venv등 다양한 툴과 호환 가능.

3. tl.constexpr

constexpr : 코드를 사용해야 하는 경우 컴파일 시간에 반환 값을 계산할 수 있는 함수입니다.

tl.constexpr는 Triton에서 상수를 정의하는 데 사용되는 함수입니다. 이를 통해 컴파일 시간에 상수 값을 설정할 수 있어, 런타임이 아닌 컴파일 타임에 상수 값을 사용할 수 있게 됩니다. 이는 특히 배열 크기와 같은 고정된 값에 유용합니다. tl.constexpr를 사용하면 성능 최적화와 코드 최적화를 돕습니다. 예를 들어, 블록 크기와 같은 값을 tl.constexpr로 정의하면, 해당 값을 컴파일 타임에 고정하여 더 효율적인 코드를 생성할 수 있습니다.

컴파일 시간 (Compile Time)

  • 정의: 소스 코드를 기계어 코드로 변환하는 동안의 시간.
  • 활동: 구문 분석, 코드 최적화, 오류 검출.
  • 예시: 코드가 수정되었을 때 컴파일러가 코드를 컴파일하여 실행 파일을 생성하는 과정.
  • 장점: 컴파일러가 코드를 최적화하여 실행 시간을 단축시킬 수 있음, 코드의 일부 오류를 미리 검출 가능.

런타임 (Runtime)

  • 정의: 프로그램이 실제로 실행되는 시간.
  • 활동: 메모리 할당, 입력/출력 처리, 런타임 오류 발생 가능.
  • 예시: 사용자 입력에 따라 프로그램이 동작하고 결과를 출력하는 과정.
  • 장점: 동적 데이터 처리 가능, 다양한 입력에 대응할 수 있는 유연성 제공.

차이점 요약

  • 컴파일 시간: 코드 작성 후, 실행 전 발생, 정적 분석 및 최적화.
  • 런타임: 프로그램 실행 중 발생, 동적 데이터 처리 및 유연성 제공.

컴파일 시간에 값을 결정하면, 즉 이때 tl.constexpr 로 정의된 값은 컴파일러가 컴파일러는 상수 값을 알고 있기 때문에 코드 최적화를 수행할 수 있습니다. 불필요한 계산을 제거하고 더 효율적인 기계어 코드를 생성할 수 있습니다.

또, 런타임에 값을 결정하지 않아서 오버헤드 감소, 컴파일 시간에 배열이나 데이터 구조의 크기가 고정되어 있어 더 빠른 메모리 접근과 관리가 가능합니다.

반면에, 런타임에 값을 결정하면 프로그램 실행 중에 값이 결정되므로 다양한 입력 값이나 조건에 따라 동적으로 대응할 수 있다. 또한, 실행중에 크기가 바뀔 수 있는 데이터에 적합하다.

출처 : https://learn.microsoft.com/ko-kr/cpp/cpp/constexpr-cpp?view=msvc-170

4. launch grid 혹은 grid

런치 그리드(launch grid)는 GPU 커널을 실행할 때 병렬로 실행되는 스레드 블록의 배치를 정의하는 것입니다. 이는 CUDA와 Triton에서 커널을 실행할 때 중요한 개념입니다. 각 블록은 특정 데이터를 처리하며, 그리드는 이러한 블록이 어떻게 배열되고 배치되는지를 결정합니다. 예를 들어, 1D 그리드는 1차원 배열 형태로 블록을 배치하며, grid = lambda meta: (triton.cdiv(n_elements, meta['BLOCK_SIZE']), )처럼 정의하여 병렬 실행을 최적화합니다.

이를 통해 병렬 처리를 최대화하고, 성능을 향상시킬 수 있습니다.

출처 1 : https://junstar92.tistory.com/244
출처 2 : https://junstar92.tistory.com/245

'인공지능 최적화 > triton' 카테고리의 다른 글

Triton (2) - Triton 설치  (0) 2024.05.31
Triton (1) - Triton 이란?  (0) 2024.05.31
728x90

가상환경 설정

우선 가상환경을 설정한다. 괜히 뭐 잘못 설치하면 골치아프다.

conda create -n [가상환경 이름] python=3.10
conda activate [가상환경 이름]

[가상환경 이름] 부분은 본인이 설정한다. 나는 triton으로 했다.
파이썬 버전은 공식문서에 따르면 CPython 3.8-3.12를 지원한다. Python 버전도 이 사이로 설정하면 된다. 무난하게 3.10 ㄱㄱ

패키지 설치

이제 아래 코드로 triton 패키지를 설치한다.

pip install triton

직접 git clone해서 설치하는 방법도 있긴하지만.... 굳이?

추가 설치 사항

언제나 그렇듯이 공식문서 외에 필요한 dependency가 존재한다.

우선 torch를 설치하자

pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu117

추가적으로 우리는 파이썬을 위한 C 컴파일러가 필요하다.

sudo apt update
sudo apt install build-essential

이후에 또 오류 발생하면 환경변수에 CC를 추가하자

본인 컴파일러 경로부터 확인하자

나는 gcc이기 때문에(terminal에 python 찍으면 python 버전 밑에 GCC 라고 뜬다)

이후에 경로를 CC로 설정한다

which gcc
which clang

export CC=/usr/bin/gcc 

'인공지능 최적화 > triton' 카테고리의 다른 글

Triton (3) - Triton을 이해하기 위한 잡지식  (0) 2024.05.31
Triton (1) - Triton 이란?  (0) 2024.05.31
728x90

Triton이란?

  • 효율적인 커스텀 Deep Learning Primitive를 구현하기 위한 언어 및 컴파일러
  • 목표 : Cuda보다 더 빠르고 더 높은 생산성있는 코드 + 현존 DSL(Domain-Specific Language) 보다 큰 유연성
  • 환경 : Linux + NVIDIA GPUs (Compute Capability 7.0+)

https://www.reddit.com/r/OpenAI/comments/18nf310/openai_triton_coursetutorial_recommendations/

Unsloth 이라는 llm fine-tuning의 속도를 높여주는 프레임워크도 Triton으로 구현됨

요약

  • Cuda는 C언어를 사요하지만 Triton은 python을 사용한다.

  • Triton을 사용하면 인공지능 뿐만 아니라 병렬적인 gpu 연산이 필요한 task에서 성능을 향상시킬 수 있다.

'인공지능 최적화 > triton' 카테고리의 다른 글

Triton (3) - Triton을 이해하기 위한 잡지식  (0) 2024.05.31
Triton (2) - Triton 설치  (0) 2024.05.31

+ Recent posts