koh1018 commited on
Commit
43bf256
·
1 Parent(s): effaff8

모델 양자화 및 교체, GGUF 사용으로 코드 전체 교체

Browse files
Files changed (2) hide show
  1. app.py +57 -79
  2. requirements.txt +3 -3
app.py CHANGED
@@ -1,101 +1,79 @@
1
- import torch
 
2
  from fastapi import FastAPI
3
  from pydantic import BaseModel
4
- from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
 
5
  import uvicorn
 
6
 
7
  # 1. FastAPI 앱 인스턴스 생성
8
  app = FastAPI()
9
 
10
- # 2. AI 모델과 토크나이저를 앱 시작 시 한번만 로딩 (매우 중요)
11
- MODEL_ID = "Qwen/Qwen1.5-1.8B-Chat"
12
-
13
- # 메모리 효율을 위해 bfloat16 사용하고, accelerate 라이브러리로 하드웨어 자동 할당
14
- tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
15
- model = AutoModelForCausalLM.from_pretrained(
16
- MODEL_ID,
17
- torch_dtype=torch.bfloat16,
18
- device_map="auto",
19
- )
20
-
21
- # Transformers 라이브러리의 pipeline을 사용하면 코드가 간결해짐
22
- pipe = pipeline(
23
- "text-generation",
24
- model=model,
25
- tokenizer=tokenizer,
 
26
  )
27
 
28
- # 3. 요청 본문(Request Body)의 데이터 형식을 지정
29
- # 프론트엔드에서 "text"라는 키에 번역할 문장을 담아서 보내야 한다는 규칙.
30
  class TranslationRequest(BaseModel):
31
- korean_text: str
32
- target_lang: str # 'en' 또는 'ja'
33
-
34
- # 발음 변환 API를 위한 주문서 양식
35
- class PronunciationRequest(BaseModel):
36
- japanese_text: str
37
 
38
- # 4. "/translate" API 엔드포인트 생성
39
  @app.post("/translate")
40
- async def translate(request: TranslationRequest):
41
- korean_text = request.korean_text
42
- target_lang = request.target_lang
43
-
44
- # 프롬프트 엔지니어링: 모델에게 원하는 결과물을 명확하게 지시
45
- if target_lang == 'en':
46
- prompt = f"Translate the following Korean sentence into natural, everyday English. Provide only the translated sentence, without any additional explanations or quotation marks.\n\nKorean: \"{korean_text}\"\n\nEnglish:"
47
- elif target_lang == 'ja':
48
- prompt = f"Translate the following Korean sentence into natural, everyday Japanese. Provide only the translated sentence, without any additional explanations or quotation marks.\n\nKorean: \"{korean_text}\"\n\nJapanese:"
49
- else:
50
- return {"error": "Invalid target language"}
51
 
52
- # Gemma/Qwen 같은 챗봇 모델을 위한 대화 형식
53
- messages = [
54
- {"role": "user", "content": prompt}
55
- ]
56
-
57
- # 파이프라인으로 텍스트 생성 실행
58
- outputs = pipe(
59
- messages,
60
- max_new_tokens=150,
61
- do_sample=True,
62
- temperature=0.7,
63
- top_k=50,
64
- return_full_text=False,
65
- )
66
-
67
- # 결과물에서 필요한 부분만 추출
68
- translated_text = outputs[0]["generated_text"].strip()
69
 
70
- # 프론트엔드에 번역된 텍스트를 JSON 형태로 반환
71
- return {"translated_text": translated_text}
72
 
73
- # 5. "/pronunciation" API 엔드포인트 생성
74
- @app.post("/pronunciation")
75
- async def get_pronunciation(request: PronunciationRequest):
76
- japanese_text = request.japanese_text
77
 
78
- # 발음 변환을 위한 새로운 프롬프트
79
- prompt = f"Provide the Korean pronunciation (Hangul) for the following Japanese sentence. Provide only the Hangul pronunciation, without any other text, labels, or quotation marks.\n\nJapanese: \"{japanese_text}\"\n\nKorean Pronunciation:"
80
 
81
- messages = [
82
- {"role": "user", "content": prompt}
83
- ]
84
-
85
- outputs = pipe(
86
- messages,
87
- max_new_tokens=150,
88
- do_sample=True,
89
- temperature=0.7,
90
- top_k=50,
91
- return_full_text=False,
92
  )
93
 
94
- pronunciation_text = outputs[0]["generated_text"].strip()
95
-
96
- return {"pronunciation_text": pronunciation_text}
 
 
 
 
 
 
 
97
 
98
- # 서버가 잘 작동하는지 확인하기 위한 기본 주소
99
  @app.get("/")
100
  def read_root():
101
- return {"message": "Translation API is running"}
 
1
+ # app.py (GGUF + llama-cpp-python 버전)
2
+
3
  from fastapi import FastAPI
4
  from pydantic import BaseModel
5
+ from llama_cpp import Llama
6
+ from huggingface_hub import hf_hub_download
7
  import uvicorn
8
+ import json
9
 
10
  # 1. FastAPI 앱 인스턴스 생성
11
  app = FastAPI()
12
 
13
+ # 2. GGUF 모델 로딩 준비
14
+ # TheBloke의 SOLAR 모델을 예시로 사용.
15
+ # 'repo_id'는 모델이 있는 저장소, 'filename'은 그 안의 특정 GGUF 파일명.
16
+ model_repo_id = "TheBloke/SOLAR-10.7B-Instruct-v1.0-GGUF"
17
+ model_filename = "solar-10.7b-instruct-v1.0.Q4_K_S.gguf"
18
+
19
+ # Hugging Face Hub에서 GGUF 파일을 다운로드하고, 로컬 경로를 가져온다.
20
+ # 이 과정은 서버 시작 시 한번만 실행된다.
21
+ model_path = hf_hub_download(repo_id=model_repo_id, filename=model_filename)
22
+
23
+ # llama-cpp-python을 사용해 GGUF 모델을 메모리에 로드한다.
24
+ # n_gpu_layers=-1 GPU를 최대한 사용하라는 뜻. CPU만 쓰는 환경에서는 0으로 설정.
25
+ llm = Llama(
26
+ model_path=model_path,
27
+ n_ctx=4096, # 모델이 한번에 처리할 수 있는 최대 토큰 길이
28
+ n_threads=8, # 사용할 CPU 스레드 수
29
+ n_gpu_layers=0 # GPU에 올릴 레이어 수 (-1은 가능한 모두 올리라는 뜻)
30
  )
31
 
32
+ # 요청 본문 형식은 이전과 동일
 
33
  class TranslationRequest(BaseModel):
34
+ text: str
 
 
 
 
 
35
 
36
+ # 3. API 엔드포인트 수정
37
  @app.post("/translate")
38
+ async def translate_all_in_one(request: TranslationRequest):
39
+ korean_text = request.text
 
 
 
 
 
 
 
 
 
40
 
41
+ # GGUF 모델(Llama-2 Chat 형식)에 맞는 프롬프트 형식
42
+ prompt = f"""### User:
43
+ You are a helpful translation and pronunciation assistant.
44
+ Given the following Korean text, perform three tasks.
45
+ 1. Translate the text into natural, everyday English.
46
+ 2. Translate the text into natural, everyday Japanese.
47
+ 3. Provide the Korean pronunciation (Hangul) for the generated Japanese translation.
 
 
 
 
 
 
 
 
 
 
48
 
49
+ Format your response as a single, valid JSON object with the keys "english", "japanese", and "pronunciation".
 
50
 
51
+ Korean Text: "{korean_text}"
 
 
 
52
 
53
+ ### Assistant:
54
+ """
55
 
56
+ # 모델을 통해 텍스트 생성 실행
57
+ output = llm(
58
+ prompt,
59
+ max_tokens=512,
60
+ stop=["### User:", "</s>"], # 응답 생성을 멈출 특정 단어
61
+ temperature=0.7,
62
+ top_k=50,
63
+ echo=False # 프롬프트를 다시 출력하지 않도록 설정
 
 
 
64
  )
65
 
66
+ generated_output = output["choices"][0]["text"].strip()
67
+
68
+ try:
69
+ # GGUF 모델은 JSON을 깔끔하게 생성하는 경향이 있음
70
+ parsed_json = json.loads(generated_output)
71
+ return parsed_json
72
+ except (json.JSONDecodeError, IndexError) as e:
73
+ print(f"JSON 파싱 에러: {e}")
74
+ print(f"모델 원본 출력: {generated_output}")
75
+ return {"error": "Failed to parse model output as JSON", "raw_output": generated_output}
76
 
 
77
  @app.get("/")
78
  def read_root():
79
+ return {"message": "GGUF Translation API is running"}
requirements.txt CHANGED
@@ -2,7 +2,7 @@ fastapi
2
  uvicorn
3
  pydantic
4
  python-multipart
5
- transformers>=4.42.0
6
- torch>=2.3.0
7
  sentencepiece
8
- accelerate
 
 
2
  uvicorn
3
  pydantic
4
  python-multipart
5
+ torch
 
6
  sentencepiece
7
+ llama-cpp-python
8
+ huggingface-hub