웹환경에서 인공지능을 만들수 있는 사이트
https://mediapipe-studio.webapps.google.com/home
Pytriton
모델 서빙 방법 살펴보기
Model serving pattern
- web single pattern
단순하기 때문에 관리가 쉬움
문제 발생 시 해결이 더쉬움
웹 서버, 전처리 및 추론에 python과 같은 하나의 프로그래밍 언어를 사용 가능
- sychronous pattern
단순함으로 관리가 쉬움
트랜잭션 추적, 모니터링 등과 같은 모든 운영 측면이 쉬워짐
예측이 완료될 때까지 프로세스가 진행되지 않으므로 서비스 워크플로우가 단순해짐
파이썬으로 하면 유지보수 측면에서 부족하기 때문에 자바로 사용도 가능
예측 지연시간은 성능 병목 현상이 될수 있음,
예측 지연시간으로 인해 사용자 경험이 저하되지 않도록 해결방법을 고려해야함
- preprocess-prediction pattern
장애 격리를 통해 리소스를 효율적으로 사용할 수있음
리소스 사용 및 확정성의 유연성
각 구성 요소에 대한 라이브러리 및 언어 버전을 선택할 수 있음
리소스가 복잡해져 운영 비용이 증가
전처리와 예측사이의 네트워크 연결이 병목 현상이 발생할 수 있음
동시요청 시 파이프라인 효과로 균등하게 시간을 처리함
전처리와 모델처리를 구분하는데 처리
음성처리에 사용
- microservice vertical pattern
여러 예측을 순서대로 실행할 수 있음
이전 예측에 따라 다음 예측서비스를 선택할 수 있음
순차적으로 해서 예외가 있으면 리턴처리
- microservice horizontal pattern
리소스 사용량을 독립적으로 조정하고 장애를 격리할 수 있음
다른 모델에 종속되지않고 모델과 시스템을 개발할 수있음
앙상블로 처리
시스템이 복잡해질 수 이음
동기식 사용 사례의 경우 가장느린 추론이 병목현상이 발생함
Model Serving with python web framework
model > deeplearning framework > fast API > Uvicorn > Gunicorn > Docker Pyrhon Image
**gunicorn은 실질적으로 쓰면안된다.
비동기식 특성이 있기 때문에 일단 다 접수 비어있으면 무조건 채움, 로드 밸런서 역할이 없다.
그래서 느려진다
기술 면접을 위해 cs, 네트워크 지식을 배워야한다.
- 라운드로빈은 언제 쓰는가??
Concurrent Model Execution
cpu의 스레드
동시에 사용가능
GPU의 스트림
움직여야하는 스트림(줄기)만들어 주어야함
스트림을 늘려주면 동시추론이 가능하다
> 쉽게하는 방법 파이썬의 멀티프로세스를 사용함 or 도커 컨테이너를 여러개 띄움
Dynamic Batching
GPU메모리가 많기 떄문에 입력데이터를 한번에 처리 , 동시 일괄처리 > BATCH 처리
웹에서는 처리하기 어렵기 때문에
Dynamic Batiching 을 사용하면 최초유저에게는 조금 느려 질 수 있지만 대기했다가 동시 일괄 처리해준다.
가상환경 만들기
가상환경 프레임워크 > 추론에 사용
<윈도우>
<mac>
vscode 들어가서 proj1 가상환경 실행
fast API 설치
uvicorn 설치
main.py 생성
fastAPI예제 > main.py에 붙여넣기
정상적으로 실행되는 지 확인!
main.py
###########################################################
# STEP 1: Import the necessary modules.
import mediapipe as mp
from mediapipe.tasks import python
from mediapipe.tasks.python.components import processors
from mediapipe.tasks.python import vision
# STEP 2: Create an ImageClassifier object.
base_options = python.BaseOptions(model_asset_path='models/classification/efficientnet_lite0.tflite')
options = vision.ImageClassifierOptions(
base_options=base_options, max_results=5)
classifier = vision.ImageClassifier.create_from_options(options)
############################################################
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
# STEP 3: Load the input image.
image = mp.Image.create_from_file("cat.jpg")
# STEP 4: Classify the input image.
classification_result = classifier.classify(image)
# STEP 5: Process the classification result. In this case, visualize it.
top_category = classification_result.classifications[0].categories[4]
print(f"{top_category.category_name} ({top_category.score:.2f})")
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
미디어 파이프 설치
pip install mediapipe
넘파이 라이브러리 설치
pip install numpy
form데이터로 클라이언트에서 요청한 사진 넘겨주기
fast API > 배우기 > 파일요청
pip install python-multipart
클라이언트에서 이미지 올려보기
try out 클릭!
files로 이미지 올리기
files는 용량이 출력
업로드파일은 파일이름이 출력!
업로드파일과 파일즈가 결과가 다르다
파일즈는 바이트로 받으면 os에서 파일을 읽어줌
업로드 파일은 넘어오기 전에 메타정보만 넘어오기 때문에 한번 더 파일을 읽어주어야함
파일즈에 스텝3-5를 붙여넣기
서버 에러가 뜸
- 파일의 전송원리
브라우저에서 이미지를 올렸다.
만약 500kb의 이미지를 보내면
byte는 바이너리를 담을 수 있는 자료형: 이미 데이터가 넘어온것 500kb가 넘어왔다.
업로드 파일에는 메타정보만 있기 때문에 0kb이다. 업로드파일을 한번더 읽어주어야한다.
비동기로 await로 걸어주면 비로소 500 kb가 담긴다. > 좀 더 효율적으로 데이터처리가 가능하다.
files에서는 에러가 뜨는 이유
통신으로 받을 때는 byte 타입으로 받아야한다.
추론 메소드(mp.Image.create_from_file)를 써서 로컬에 있는 파일을 읽는다.
cat.jpt를 바이트로 바꿀 때 쓰는 함수는 File.open("cat.jpg") 이다 > 굳이 file.open을 할 필요없다. 느려진다.
mp.Image.create_from_file 를 byte로 변경하는 3단계
mp.Image.create_from_file 디스크에 있는 파일을 오픈 > 비트맵으로 연산처리 decode() > 미디어파일에서 추론할 수 있는 mp.Image로 변경
추가설명
http 파일을 주고받는 통신규약
업로드에서 파일을 쏴줌 > fastapi > files: byte이미지를 코드로 변환, fileupload: 업로드는 메타정보만 날라오고 실질적으로 파일의 내용은 오지않음 > file.read()로 해야 실질적인 파일이 넘어옴
이미지 용량이 클 경우
비동기를 걸어주면서 await를 사용하면 파이프라인을 형성할 수있어서 빠르게 받을 수 있음
결론!
content:byte > mp.Image로 바꾸어주어야함 > 바로 추론해서 결과를 내보낼 수 있다.
미디어파이프에서 mp.Image를 바꿀 수 있음
file에서 업로드할 때 오류가 안 나려면 file:byte > content:byte로 변경해주어야함
미디어파이프 > 솔루션즈 > API
uvicorn main:app 으로 다시 실행
오류없이 잘 되는것을 볼 수 있다.
######################################################################
# STEP 1: Import the necessary modules.
import mediapipe as mp
from mediapipe.tasks import python
from mediapipe.tasks.python.components import processors
from mediapipe.tasks.python import vision
# STEP 2: Create an ImageClassifier object.
base_options = python.BaseOptions(model_asset_path='models/classification/efficientnet_lite0.tflite')
options = vision.ImageClassifierOptions(
base_options=base_options, max_results=5)
classifier = vision.ImageClassifier.create_from_options(options)
######################################################################
from typing import Union
from fastapi import FastAPI,File, UploadFile
app = FastAPI()
from PIL import Image
import numpy as np
import io
@app.post("/files/")
async def create_file(file: bytes = File()):
# STEP 3: Load the input image.
# image = mp.Image.create_from_file(file)
# decode image from byte
pil_img = Image.open(io.BytesIO(file))
# pil_img = Image.new('RGB', (60, 30), color = 'red')
# create mp Image
image = mp.Image(
image_format=mp.ImageFormat.SRGB, data=np.asarray(pil_img))
# STEP 4: Classify the input image.
classification_result = classifier.classify(image)
# STEP 5: Process the classification result. In this case, visualize it.
top_category = classification_result.classifications[0].categories[4]
print(f"{top_category.category_name} ({top_category.score:.2f})")
return {"Hello": f"{top_category.category_name} ({top_category.score:.2f})"}
@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):
return {"filename": file.filename}
@app.get("/")
def read_root():
# STEP 3: Load the input image.
image = mp.Image.create_from_file("cat.jpg")
# STEP 4: Classify the input image.
classification_result = classifier.classify(image)
# STEP 5: Process the classification result. In this case, visualize it.
top_category = classification_result.classifications[0].categories[4]
print(f"{top_category.category_name} ({top_category.score:.2f})")
return {"Hello": f"{top_category.category_name} ({top_category.score:.2f})"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
인사이트 페이스 이용해보기
안면인식 프로그램
안면인식 과정
1. 박스로 얼굴 찾기
얼라이어먼트(점5개)
https://github.com/deepinsight/insightface
insightface 설치
에러가 뜬다 (mac은 컴파일러가 있기때문에 안뜬다)
out of output 링크 클릭
수정 > c++ 선택 후 설치
가상환경 나가기
https://github.com/JaidedAI/EasyOCR
글자를 찾고 인식하는 프로그램
easyocr 설치하기
pip install easyocr
시간이 오래걸리기 때문에 proj2 에서 다시 설치
ocr.py 파일 생성
이미지 찾아서 이미지 변경
ocreasy 실행
python ocr.py
한글을 인식한다.
import easyocr
reader = easyocr.Reader(['ko']) # this needs to run only once to load the model into memory
result = reader.readtext('ocr_img1.jpg')
print(result)
이미지 주소 복사를 이용해서 바로 사용할 수 있다.
main2.py 에 설치
pip install fastapi
pip install "uvicorn[standard]"
pip install python-multipart
pip install mediapipe
main2.py
uvicorn main2:app 서버 실행
uvicorn main2:app 다시 실행하면 된다.
문자인식 성공!
proj1 로 가상환경 다시 연결하고 인사이트페이스 설치
face.py 파일 생성
메뉴얼
https://pypi.org/project/insightface/
import cv2
import numpy as np
import insightface
from insightface.app import FaceAnalysis
from insightface.data import get_image as ins_get_image
app = FaceAnalysis(providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])
app.prepare(ctx_id=0, det_size=(640, 640))
img = ins_get_image('t1')
faces = app.get(img)
rimg = app.draw_on(img, faces)
cv2.imwrite("./t1_output.jpg", rimg)
#STEP 1
import cv2
import numpy as np
import insightface
from insightface.app import FaceAnalysis
from insightface.data import get_image as ins_get_image
#STEP 2
app = FaceAnalysis(providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])
app.prepare(ctx_id=0, det_size=(640, 640))
#STEP 3
img = ins_get_image('t1')
#STEP 4
faces = app.get(img)
#STEP 5 사진 저장
rimg = app.draw_on(img, faces)
cv2.imwrite("./t1_output.jpg", rimg)
실행하면 에러가 뜬다
오닉스 런타임이라는 추론기를 설치해야함
GPU 없으면 CPU를 선택해야함
#파이썬에 설치
pip install onnxruntime-gpu
GPU 가없으면
pip install onnxruntime-cpu
face.py 실행
python face.py
에러가 뜸
윈도우 - gpu버전에서 설치는 됐지만 쿠다 자체에대한 설치가 안되서 에러가 남
문제는 다른 환경이 꼬이게 됨 > 윈도우에서 gpu를 사용하기 어려움
두번째 오류가 뜸
numpy 버전 충돌로 버전을 낮추어야 해결이됨
AttributeError: module 'numpy' has no attribute 'int'
없어진 기능을 사용하기 때문에 에러가 생김
numpy 삭제
pip uninstall numpy
numpy 낮은 버전으로 재설치
pip install numpy==1.23.0
python face.py 재실행
t1_output.jpg 이미지가 생성 되었다!
불필요한 부분 지우기
이미지 커스텀해보기
원하는 사진 이미지 컴퓨터에 저장
안면인식 성공!
main3.py 파일 생성
#STEP 1
import cv2
import numpy as np
import insightface
from insightface.app import FaceAnalysis
# from insightface.data import get_image as ins_get_image > 인사이트페이스에서 제공해주는 이미지
#STEP 2
app = FaceAnalysis(providers=['CPUExecutionProvider'])
app.prepare(ctx_id=0, det_size=(640, 640))
########################################
from typing import Union
from fastapi import FastAPI, File, UploadFile
app = FastAPI()
from PIL import Image
import numpy as np
import io
@app.post("/files/")
async def create_file(file: bytes = File()):
#STEP 3
# img = ins_get_image('t1')
img = cv2.imread("twice.jpg", cv2.IMREAD_COLOR)
#STEP 4
faces = app.get(img)
#STEP 5 사진 저장
rimg = app.draw_on(img, faces)
cv2.imwrite("./t2_output.jpg", rimg)
바이너리로 변환
step2에서 app > face 모두 변경
step4 에서 print(result[0].bbox)
step5에서 return{"result":result[0].bbox} 변경
uvicorn main3:app 실행
파일을 두개 받아보기
step3,4 이미지와 result 추가
face에서 얼굴유사도를 측정하는 임베드 값을 꺼낼것임
uvicorn main3:app 실행
result 값이 1에 가까울 수록 닮았다.
main3.py
#STEP 1
import cv2
import numpy as np
import insightface
from insightface.app import FaceAnalysis
# from insightface.data import get_image as ins_get_image > 인사이트페이스에서 제공해주는 이미지
#STEP 2
face = FaceAnalysis(providers=['CPUExecutionProvider'])
face.prepare(ctx_id=0, det_size=(640, 640))
########################################
from typing import Union
from fastapi import FastAPI, File, UploadFile
app = FastAPI()
from PIL import Image
import numpy as np
import io
@app.post("/files/")
async def create_file(file: bytes = File(),
file2: bytes = File()):
#STEP 3
# img = cv2.imread("twice.jpg", cv2.IMREAD_COLOR)
nparr = np.fromstring(file, np.uint8)
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
nparr2 = np.fromstring(file2, np.uint8)
img2 = cv2.imdecode(nparr2, cv2.IMREAD_COLOR)
# img = ins_get_image('t1')
#STEP 4
result = face.get(img)
result2 = face.get(img2)
#예외처리
if result == None or result2 == None:
return {"result":"fail"}
face1 = result[0]
face2 = result2[0]
emb1 = face1.normed_embedding
emb2 = face2.normed_embedding
#임베딩 값을 비교하기위해서 np.dot메소드를 써서 sim 값에 대입
sim = np.dot(emb1, emb2)
#STEP 5
return{"result": float(sim)}
예외처리 코드오류 수정
#예외처리
if len(result) == 0 or len(result2) == 0:
return {"result":"fail"}
face1 = result[0]
face2 = result2[0]
두 데이터간 유사도 측정
embedding 은 계산 방식이 항상 똑같음
Euclidean 두 점간의 사이 거리를 측정
https://en.wikipedia.org/wiki/Similarity_measure
word-embedding : 문자간 거리를 측정하여 문자 유사도 측정
이미지임베디드 - 텍스트 임베디드
텍스트로 이미지를 검색 가능함 : 예를 들어 텍스트로 풍경 묘사를 하면 풍경이미지로 검색됨
main3.py
#STEP 1
import cv2
import numpy as np
import insightface
from insightface.app import FaceAnalysis
# from insightface.data import get_image as ins_get_image > 인사이트페이스에서 제공해주는 이미지
#STEP 2 추론기 할당
face = FaceAnalysis(providers=['CPUExecutionProvider'])
face.prepare(ctx_id=0, det_size=(640, 640))
########################################
from typing import Union
from fastapi import FastAPI, File, UploadFile
app = FastAPI()
from PIL import Image
import numpy as np
import io
@app.post("/files/")
async def create_file(file: bytes = File(),
file2: bytes = File()):
#STEP 3
# img = cv2.imread("twice.jpg", cv2.IMREAD_COLOR)
nparr = np.fromstring(file, np.uint8)
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
nparr2 = np.fromstring(file2, np.uint8)
img2 = cv2.imdecode(nparr2, cv2.IMREAD_COLOR)
# img = ins_get_image('t1')
#STEP 4 추론결과
result = face.get(img)
result2 = face.get(img2)
#예외처리
if len(result) == 0 or len(result2) == 0:
return {"result":"fail"}
face1 = result[0]
face2 = result2[0]
#유사도 측정
emb1 = face1.normed_embedding
emb2 = face2.normed_embedding
#임베딩 값을 비교하기위해서 np.dot메소드를 써서 sim 값에 대입
sim = np.dot(emb1, emb2)
#STEP 5 후처리로 비즈니스로직 처리
return{"result": float(sim)}
참고 자료
https://if.kakao.com/2022/session/13
'☭DEVELOPER > #6 인공지능(AI-X) 프로젝트' 카테고리의 다른 글
[AI]자연어 (0) | 2024.02.03 |
---|---|
[BACKEND]파이썬_콘다 (0) | 2024.02.03 |
[BACKEND]형상관리①_웹어플리케이션_구성도예시 (0) | 2024.02.01 |