File size: 4,396 Bytes
f5a3b55
 
 
 
 
4ef4a96
226a773
e611d39
 
 
 
f5a3b55
89ed063
e611d39
226a773
4ef4a96
f5a3b55
89ed063
 
 
4ef4a96
f5a3b55
89ed063
f5a3b55
4ef4a96
e611d39
4ef4a96
89ed063
f5a3b55
4ef4a96
f5a3b55
 
4ef4a96
f5a3b55
4ef4a96
89ed063
f5a3b55
e611d39
226a773
e611d39
 
 
 
4ef4a96
226a773
4ef4a96
 
f5a3b55
 
 
 
a509a74
 
 
 
 
 
f5a3b55
 
4ef4a96
f5a3b55
 
 
 
4ef4a96
f5a3b55
 
 
 
4ef4a96
 
f5a3b55
 
 
 
4fc3106
89ed063
10b4282
4ef4a96
226a773
 
 
f5a3b55
4ef4a96
f5a3b55
4ef4a96
89ed063
f5a3b55
 
4ef4a96
f3600a5
4ef4a96
f3600a5
4ef4a96
f5a3b55
226a773
4ef4a96
f5a3b55
226a773
4ef4a96
f5a3b55
4ef4a96
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
import gradio as gr  # Gradio: ์›น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
import requests       # API ์š”์ฒญ์„ ๋ณด๋‚ด๊ธฐ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
from openai import OpenAI  # Upstage Solar LLM ์‚ฌ์šฉ์„ ์œ„ํ•œ OpenAI ํ˜ธํ™˜ ํด๋ผ์ด์–ธํŠธ
from io import BytesIO      # ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ ์ƒ์—์„œ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋„๊ตฌ

def extract_text_from_image(image, api_key):
    """
    ์ด๋ฏธ์ง€์—์„œ ํ…์ŠคํŠธ๋ฅผ ์ถ”์ถœํ•˜๋Š” ํ•จ์ˆ˜ (Upstage Document OCR API ์‚ฌ์šฉ)
    """
    # Upstage API Endpoint ์ฃผ์†Œ
    url = "https://api.upstage.ai/v1/document-digitization"  

    # API Key ์ธ์ฆ์„ ์œ„ํ•œ ํ—ค๋” ์„ค์ •
    headers = {'Authorization': f'Bearer {api_key}'}  

    # ์ด๋ฏธ์ง€๋ฅผ ๋ฉ”๋ชจ๋ฆฌ ๋ฒ„ํผ์— ์ €์žฅ (JPEG ํ˜•์‹)
    buffer = BytesIO()
    image.save(buffer, format="JPEG")
    buffer.seek(0)

    # ํŒŒ์ผ๊ณผ ์ถ”๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญ ํ˜•์‹์— ๋งž๊ฒŒ ๊ตฌ์„ฑ
    files = {"document": ("image.jpg", buffer, "image/jpeg")}
    data = {"model": "ocr"}  # ์‚ฌ์šฉํ•  ๋ชจ๋ธ: OCR

    # POST ์š”์ฒญ ๋ณด๋‚ด๊ธฐ 
    response = requests.post(url, headers=headers, files=files, data=data)

    # ์š”์ฒญ ์„ฑ๊ณต ์‹œ ํ…์ŠคํŠธ ์ถ”์ถœ
    if response.status_code == 200:
        text = response.json().get("text", "")  # JSON ์‘๋‹ต์—์„œ ํ…์ŠคํŠธ ์ถ”์ถœ
        return text.strip()  # ์•ž๋’ค ๊ณต๋ฐฑ ์ œ๊ฑฐ ํ›„ ๋ฐ˜ํ™˜
    else:
        # ์‹คํŒจ ์‹œ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ๋ฐ˜ํ™˜
        return f"OCR ์‹คํŒจ: {response.status_code} - {response.text}"



def translate_text_with_solar(english_text, api_key):
    """
    ์˜์–ด ํ…์ŠคํŠธ๋ฅผ ํ•œ๊ตญ์–ด๋กœ ๋ฒˆ์—ญํ•˜๋Š” ํ•จ์ˆ˜ (Upstage Solar Pro API ์‚ฌ์šฉ)
    """
    # Solar LLM ํ˜ธ์ถœ์„ ์œ„ํ•œ OpenAI ํด๋ผ์ด์–ธํŠธ ์ดˆ๊ธฐํ™”
    client = OpenAI(
        api_key=api_key,
        base_url="https://api.upstage.ai/v1"
    )

    # print("== ์ฑ„ํŒ… ํ•จ์ˆ˜ ํ˜ธ์ถœ๋จ ==")  # ๋กœ๊ทธ์šฉ ์ถœ๋ ฅ

    # ์‚ฌ์šฉ์ž์—๊ฒŒ ์ „๋‹ฌํ•  ํ”„๋กฌํ”„ํŠธ ๊ตฌ์„ฑ
    prompt = f"""
    ๋‹ค์Œ์€ ์˜์–ด ์†๊ธ€์”จ ํŽธ์ง€ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.\n
    {english_text} \n
    ์˜์–ด๋ฅผ ํ•œ๊ตญ์–ด๋กœ ๋ฒˆ์—ญํ•ด์ฃผ์„ธ์š”.\n\n  
    ํ•œ๊ตญ์–ด๋กœ ๋ณ€์—ญ๋œ ํŽธ์ง€ ๋‚ด์šฉ: "
    """

    # Solar LLM ํ˜ธ์ถœํ•˜์—ฌ ๋ฒˆ์—ญ ์ˆ˜ํ–‰
    response = client.chat.completions.create(
        model="solar-pro",  # ์‚ฌ์šฉํ•  ๋ชจ๋ธ ์ด๋ฆ„
        messages=[{"role": "user", "content": prompt}],  # ์‚ฌ์šฉ์ž ๋ฉ”์‹œ์ง€ ์„ค์ •
        temperature=0.5,     # ์ฐฝ์˜์„ฑ ์ •๋„ (0.0~1.0)
        max_tokens=1024      # ์ตœ๋Œ€ ์‘๋‹ต ๊ธธ์ด ์„ค์ •
    )

    # print(response)  # ์ „์ฒด ์‘๋‹ต ๋กœ๊ทธ๋กœ ์ถœ๋ ฅ

    # ๋ฒˆ์—ญ๋œ ๊ฒฐ๊ณผ ํ…์ŠคํŠธ ๋ฐ˜ํ™˜
    return response.choices[0].message.content


# Gradio ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌ์„ฑ
with gr.Blocks() as demo:
    # ์ƒ๋‹จ ์„ค๋ช… ๋ถ€๋ถ„
    gr.Markdown("# ๐Ÿ’Œ ์†๊ธ€์”จ ํŽธ์ง€ ๋ฒˆ์—ญ๊ธฐ")
    gr.Markdown("ํŽธ์ง€ ์ด๋ฏธ์ง€๋ฅผ ์—…๋กœ๋“œํ•˜๋ฉด Upstage Docuemnt OCR์ด ์˜์–ด ํ…์ŠคํŠธ๋ฅผ ์ถ”์ถœํ•˜๊ณ ,\n๐ŸŒ ๋ฒˆ์—ญํ•˜๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด Solar LLM์„ ํ˜ธ์ถœํ•˜์—ฌ ํ•œ๊ตญ์–ด๋กœ ๋ฒˆ์—ญํ•ฉ๋‹ˆ๋‹ค!")
    gr.Markdown("์˜ˆ์ œ ์ด๋ฏธ์ง€๋Š” GenAI๋ฅผ ํ†ตํ•ด ์ƒ์„ฑ๋œ ์ด๋ฏธ์ง€์ด๋ฉฐ, Files ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ํ™•์ธ ๋ฐ ๋‹ค์šด๋กœ๋“œ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.")

    # โœ… API Key ์ž…๋ ฅ์ฐฝ ์ถ”๊ฐ€
    api_key_input = gr.Textbox(label="๐Ÿ”‘ Upstage API Key", type="password", placeholder="Paste your API key here")

    # ๋ ˆ์ด์•„์›ƒ: ์ขŒ์šฐ 2๋‹จ ๊ตฌ์„ฑ
    with gr.Row():
        # ์™ผ์ชฝ ์—ด: ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ
        with gr.Column(scale=1):
            image_input = gr.Image(type="pil", label=" ๐Ÿ’Œ ํŽธ์ง€ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ")

        # ์˜ค๋ฅธ์ชฝ ์—ด: ์ถ”์ถœ๋œ ํ…์ŠคํŠธ ๋ฐ ๋ฒˆ์—ญ ๊ฒฐ๊ณผ
        with gr.Column(scale=2):
            english_box = gr.Textbox(label="๐Ÿ“ ์ถ”์ถœ๋œ ์˜์–ด ํ…์ŠคํŠธ", lines=10)
            translate_button = gr.Button("๐ŸŒ ๋ฒˆ์—ญํ•˜๊ธฐ")
            korean_box = gr.Textbox(label="๐Ÿ‡ฐ๐Ÿ‡ท ๋ฒˆ์—ญ๋œ ํ•œ๊ตญ์–ด ํ…์ŠคํŠธ", lines=10)

    # Step 1: ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ์‹œ OCR ํ•จ์ˆ˜ ์‹คํ–‰ โ†’ ์ถ”์ถœ๋œ ํ…์ŠคํŠธ๋ฅผ ์˜์–ด ํ…์ŠคํŠธ ๋ฐ•์Šค์— ํ‘œ์‹œ
    image_input.change(fn=extract_text_from_image, inputs=[image_input, api_key_input], outputs=english_box)

    # Step 2: ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ๋ฒˆ์—ญ ํ•จ์ˆ˜ ์‹คํ–‰ โ†’ ๋ฒˆ์—ญ๋œ ๊ฒฐ๊ณผ๋ฅผ ํ•œ๊ตญ์–ด ํ…์ŠคํŠธ ๋ฐ•์Šค์— ํ‘œ์‹œ
    translate_button.click(fn=translate_text_with_solar, inputs=[english_box, api_key_input], outputs=korean_box)

# ์•ฑ ์‹คํ–‰
if __name__ == "__main__":
    demo.launch()