Main Goal : Find the model that can restore Korean Cipher ( Example : Lr๋ ใฑใ ๋ ๋๋ฌผ์ ํ๋ฆฐใทr... ) into the normal Korean
ย
Related Media: ChatGPT o1
โฃ*
ย
Test on AI Services
- Test Prompt
2O19.12์ ์ด ๊ธด ๊ธ ( ใ ใ ฃใ ใ ฃ์ธ ์ ใ ใ ฃ ใ ใ ) [ ์ฃฝ ์ ใทใ ใ ใ ใดใ ๋ฅผ ] ์ ํ ์คํธ๋ฅผ ์ ์์ ์ธ ํ๊ธ๋ก ๋ณต์ํด๋ด ( Restore above text into normal Korean )
Results
Model Name | Model Size | Model Type | Result | API |
GPT 4o / o1 / o1-mini | 70B + | Multimodal LLM | O | O |
Gemini 1.5 / 2.0 | 70B + | Multimodal LLM | O | O |
Clova AI | 204B | Multimodal LLM | O | O |
ใ
ค | ใ
ค | ใ
ค | ใ
ค | ใ
ค |
Detail Results
Local Model Test ( Ollama, Hugging Face )
- Spec : RTX A5000 * 6
Test Resources ( Prompt Engineering)
- Type A
PROMPT = '''You are a helpful AI assistant specializing in Korean text restoration. Please restore the following fragmented Korean text into its original form: ๋น์ ์ ํ๊ตญ์ด ํ ์คํธ ๋ณต์์ ํนํ๋ ์ ๋ฅํ AI ์ด์์คํดํธ์ ๋๋ค. ์๋ ์ฃผ์ด์ง ๋ถ๋ฆฌ๋ ํ๊ตญ์ด ํ ์คํธ๋ฅผ ์๋์ ํํ๋ก ๋ณต์ํด์ฃผ์ธ์.''' input_text = "2O19.12์ ์ด ๊ธด ๊ธ ( ใ ใ ฃใ ใ ฃ์ธ ์ ใ ใ ฃ ใ ใ ) [ ์ฃฝ ์ ใทใ ใ ใ ใดใ ๋ฅผ ]"
- Type B
prompt = ( "๋ค์ ๋ฌธ์ฅ์์ ํฌํจ๋ ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก ๋ด์ฉ์ ํด์ํ์ธ์:\n" "- ๋ ์ง: ์ฝํ ์ธ ๊ฐ ์ธ์ ์ฌ๋ผ์๋์ง.\n" "- ๋ฐฐ์ฐ: ๋ฑ์ฅํ๋ ๋ฐฐ์ฐ์ ์ด๋ฆ.\n" "- ์ ๋ชฉ: ์ฝํ ์ธ ์ ์ ๋ชฉ.\n\n" "์:\n" "์ ๋ ฅ: 2O19.12์ ์ด ๊ธด ๊ธ ( ใ ใ ฃใ ใ ฃ์ธ ์ ใ ใ ฃ ใ ใ ) [ ์ฃฝ ์ ใทใ ใ ใ ใดใ ๋ฅผ ]\n" "์ถ๋ ฅ: ์ด ์ฝํ ์ธ ๋ 2019๋ 12์ ์ด์ ์ฌ๋ผ์จ ๋ด์ฉ์ด๋ฉฐ, ๋ฐฐ์ฐ๋ ์ด์์ธ๊ณผ ์์งํ์ ๋๋ค. ์ ๋ชฉ์ \"์ฃฝ์๋ค ์๋ด๋ฅผ\"์ ๋๋ค.\n\n" f"์ ๋ ฅ: {pre_text}\n" "์ถ๋ ฅ:" )
- OCR TypeA

ย
- OCR TypeB

ย
Results summary (get model from HuggingFace)
Model Name | Model Size | Model Type | Result |
KETI-AIR/ke-t5-small | ~220M | Text 2 Text Generation | โ |
ddobokki/ko-trocr | ~370M | Image-to-Text | โ |
gogamza/kobart-base-v2 | ~125M | Text 2 Text Generation | โ |
hyunwoongko/kobart | ~125M | Text 2 Text Generation | โ |
google/flan-t5-base | ~248M | Text 2 Text Generation | โ |
naver-clova-ix/donut-base | ~1.1B | Image-to-Text | โ |
MLP-KTLim/llama-3-Korean-Bllossom-8B | ~8.03B | Text Generation | โ |
LGAI-EXAONE/EXAONE-3.5-2.4B-Instruct | ~2.4B | Text Generation | ๐ข |
The Best Result ( LGAI-EXAONE - 2.4B model )
Original Text | Restored Text | GPU Usage |
2O19.12์ ์ด ๊ธด ๊ธ ( ใ
ใ
ฃใ
ใ
ฃ์ธ ์ ใ
ใ
ฃ ใ
ใ
) [ ์ฃฝ ์ ใทใ
ใ
ใ
ใดใ
๋ฅผ ] | 2019๋
12์ ์ด ๊ธด๊ธ ์กฐ์น (์ด์์ธ ์์งํ)๋ก ์ธํด ์๋ด๋ฅผ ์ฃฝ์๋ค | Allocated: 4685.94, Reserved: 4844.00 |
2019.02์ S.F ํํ์ง [โ ใ
ใ
ฃ . ๊ณต . ๊ฐ . ใ
ใ
ฃ . ๋ โ]ํ๊ธ์๋ง ์ด๊ณ ํ์ง 1080P | 2019๋
2์ SF ํํ์ง [โ์๊ฐ ์ด๋โ] ๊ณ ํ์ง 1080P ์๋ง ์ด๊ณ ํ์ง | Allocated: 4685.94, Reserved: 4880.00 |
โกOโกO.01์ - ๊ธด์ฅ๊ฐ ์ต๊ณ ์น - [ - ๋ธ.๋.์ค.๋.๋ธ.๋ฃจ - ] ์จ์๊ณณ์๋ค | ์ ๊ธด์ฅ๊ฐ ์ต๊ณ ์น [-๋ธ๋์ค๋๋ธ๋ฃจ] ์จ์ ๊ณณ ์๋คTo make it more coherent:2์ ๊ธด์ฅ๊ฐ ์ต๊ณ [-๋ธ๋์ค๋๋ธ๋ฃจ] ์จ ์ด ๊ณณ ์์ด | Allocated: 4685.94, Reserved: 4880.00 |
- After inference - Allocated: 4685.94 MB, Reserved: 4880.00 MB
Before inference - Allocated: 4685.94 MB, Reserved: 4844.00 MB original text: 2O19.12์ ์ด ๊ธด ๊ธ ( ใ ใ ฃใ ใ ฃ์ธ ์ ใ ใ ฃ ใ ใ ) [ ์ฃฝ ์ ใทใ ใ ใ ใดใ ๋ฅผ ] decoded text: |system|]You are EXAONE model from LG AI Research, a helpful assistant specialized in restoring distorted Korean text. [|user|]Restore the following text into normal Korean: 2O19.12์์ด๊ธด๊ธ(์ด์์ธ์์งํ)[์ฃฝ์๋ค์๋ด๋ฅผ] [|assistant|]2019๋ 12์ ์ด ๊ธด๊ธ ์กฐ์น (์ด์์ธ ์์งํ)๋ก ์ธํด ์๋ด๋ฅผ ์ฃฝ์๋ค. original text: 2019.02์ S.F ํํ์ง [--- ใ ใ ฃ . ๊ณต . ๊ฐ . ใ ใ ฃ . ๋ ---]ํ๊ธ์๋ง ์ด๊ณ ํ์ง 1080P decoded text: [|system|]You are EXAONE model from LG AI Research, a helpful assistant specialized in restoring distorted Korean text. [|user|]Restore the following text into normal Korean: 2019.02์S.Fํํ์ง[---์.๊ณต.๊ฐ.์ด.๋---]ํ๊ธ์๋ง์ด๊ณ ํ์ง1080P [|assistant|]2019๋ 2์ SF ํํ์ง [---์๊ฐ ์ด๋---] ๊ณ ํ์ง 1080P ์๋ง ์ด๊ณ ํ์ง original text: โกOโกO.01์ - ๊ธด์ฅ๊ฐ ์ต๊ณ ์น - [ - ๋ธ.๋.์ค.๋.๋ธ.๋ฃจ - ] ์จ์๊ณณ์๋ค decoded text: [|system|]You are EXAONE model from LG AI Research, a helpful assistant specialized in restoring distorted Korean text. [|user|]Restore the following text into normal Korean: 2O2O.01์-๊ธด์ฅ๊ฐ์ต๊ณ ์น-[-๋ธ.๋.์ค.๋.๋ธ.๋ฃจ-]์จ์๊ณณ์๋ค [|assistant|]The restored text in normal Korean appears as follows: 2์ ๊ธด์ฅ๊ฐ ์ต๊ณ ์น [-๋ธ๋์ค๋๋ธ๋ฃจ] ์จ์ ๊ณณ ์๋ค or 2์ ๊ธด์ฅ๊ฐ ์ต๊ณ [-๋ธ๋์ค๋๋ธ๋ฃจ] ์จ ์ด ๊ณณ ์์ด After inference - Allocated: 4685.94 MB, Reserved: 4880.00 MB
Test Results
Detail results
- MLP-KTLim/llama-3-Korean-Bllossom-8B
python3 korean_blossom_llama.py # input_text = "2O19.12์ ์ด ๊ธด ๊ธ ( ใ ใ ฃใ ใ ฃ์ธ ์ ใ ใ ฃ ใ ใ ) [ ์ฃฝ ์ ใทใ ใ ใ ใดใ ๋ฅผ ]" Loading checkpoint shards: 100%|โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ| 4/4 [00:00<00:00, 5.74it/s] The attention mask and the pad token id were not set. As a consequence, you may observe unexpected behavior. Please pass your input's `attention_mask` to obtain reliable results. Setting `pad_token_id` to `eos_token_id`:128009 for open-end generation. The attention mask is not set and cannot be inferred from input because pad token is same as eos token. As a consequence, you may observe unexpected behavior. Please pass your input's `attention_mask` to obtain reliable results. ๋ณต์๋ ํ ์คํธ: 2020๋ 1์ ์ด ๊ธด ํด์(์ด์ฌ์ค ์ ์๊ณ ๋ง๊ณ ์ฌ์๋ค) [ ์ฃฝ์๋ค๊ณ ๋ค์๋ค๋ ๊ฒ ]
python3 korean_blossom_llama.py # input_text = "2O19๋ 12์ ((Oi์๋ฉ๊ทธใน1๊ฑฐ)) []ใ ก ๋ฅ . Eใ . ์ฌ . ๋ฆฝ ใ ก[] -์ดํ์ค๋ฅ๋ ฅ์- ์๋ฒฝ์์ฒด" Loading checkpoint shards: 100%|โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ| 4/4 [00:00<00:00, 5.55it/s] The attention mask and the pad token id were not set. As a consequence, you may observe unexpected behavior. Please pass your input's `attention_mask` to obtain reliable results. Setting `pad_token_id` to `eos_token_id`:128009 for open-end generation. The attention mask is not set and cannot be inferred from input because pad token is same as eos token. As a consequence, you may observe unexpected behavior. Please pass your input's `attention_mask` to obtain reliable results. ๋ณต์๋ ํ ์คํธ: Output: "2019๋ 12์ ((Oi์๋ฒฝํ1๋ฑ)) [์ด๊ฒ ๋ค. ์ฌ๊ธฐ. ์ฌํ๋ค. ๋ฆฝ ์ํด[] -์ดํ์ค๋ฅ๋ ฅ์- ์๋ฒฝ์์ฒด"
ย
ex. KETI-AIR ke-t5-small
from transformers import T5ForConditionalGeneration, T5Tokenizer # ๋ชจ๋ธ๊ณผ ํ ํฌ๋์ด์ ๋ก๋ model_name = "KETI-AIR/ke-t5-small" # Hugging Face์์ ์ ๊ณตํ๋ ํ๊ตญ์ด T5 ๋ชจ๋ธ tokenizer = T5Tokenizer.from_pretrained(model_name) model = T5ForConditionalGeneration.from_pretrained(model_name) def restore_text_ai(text): # ์ ๋ ฅ ํ ์คํธ๋ฅผ T5 ์ ๋ ฅ ํ์์ผ๋ก ๋ณํ input_text = f"๋ณต์: {text}" inputs = tokenizer(input_text, return_tensors="pt", padding=True, truncation=True) # ๋ชจ๋ธ ์ถ๋ก outputs = model.generate(inputs["input_ids"], max_length=512, num_beams=5, early_stopping=True) # ๊ฒฐ๊ณผ ๋์ฝ๋ฉ restored_text = tokenizer.decode(outputs[0], skip_special_tokens=True) return restored_text # ํ ์คํธ test_text = "2O19.12์ ์ด ๊ธด ๊ธ ( ใ ใ ฃใ ใ ฃ์ธ ์ ใ ใ ฃ ใ ใ ) [ ์ฃฝ ์ ใทใ ใ ใ ใดใ ๋ฅผ ]" restored = restore_text_ai(test_text) print("๋ณต์๋ ํ ์คํธ:", restored)
โ Fail, No response
ย
- google-t5/t5-small : Fail, No response
- KETI-AIR/ke-t5-small : Fail, Hallucinated
raw_text = "2O19.12์ ์ด ๊ธด ๊ธ ( ใ
ใ
ฃใ
ใ
ฃ์ธ ์ ใ
ใ
ฃ ใ
ใ
) [ ์ฃฝ ์ ใทใ
ใ
ใ
ใดใ
๋ฅผ ]โ
๋ณต์๋ ํ
์คํธ: ๋ง์ฐฌ๊ฐ์ง๋คๅๅๅ ๋ง์ฐฌ๊ฐ์ง์
๋๋คๅๅฑฑๅๅhankookilbohankookilbohankookilbo ๋ฏผ์ ์์hankookilbohankookilbo ์ข๊ฒ ์ง๋งhankookilbohankookilbo ๋ง๊ฒ๋hankookilbohankookilbo ์๋ฉํhankookilbohankookilbo accidenthankookilbohankookilbo ํนํ๋นhankookilbohankookilbo Stamfordhankookilbohankookilbo ๋ฐ๋ฅด์
๋ก๋hankookilbohankookilboํฌ์คhankookilbohankookilbo ridehankookilbohankookilbo ํน์ํ๋๋นhankookilbohankookilbo ๊ธ๊ณ hankookilbohankookilbo ์กฐ์นํ๋คhankookilbohankookilbo ๋ฌผ๊ฐhankookilbohankookilbo WTO Stamfordhankookilbo Orange Stamford Stamfordhankookilbo ํ์ Stamfordgnradhankookilbohankookilbo door Stamford Stamford Stamford Bangkokhankookilbohankookilbo workshophankookilbohankookilbo ๊ฐ์ฌ์์hankookilbohankookilbo ship Stamfordhankookilbo ์ธ๊ณ๋ญํนhankookilbohankookilbo ์ํ์งhankookilbohankookilbo Numberhankookilbohankookilbo ๊ทhankookilbohankookilbo LHhankookilbohankookilbo wheneverhankookilbohankookilbo ํ์ฐฝhankookilbohankookilbo ์๋hankookilbohankookilbo ๋ชจ๋ํฐhankookilbohankookilbo ์์ง๋งhankookilbohankookilbo ์์๋ฃ๋ฅผhankookilbohankookilbo ์ฐ๋ฆฌ๊ธ์ต์ง์ฃผhankookilbohankookilbo Princetonhankookilbohankookilbo ์ผ์ผํค Stamfordhankookilbognradhankookilbo Stamford
ย
- model_name = "hyunwoongko/kobartโ, Fail
You passed along `num_labels=3` with an incompatible id to label map: {'0': 'NEGATIVE', '1': 'POSITIVE'}. The number of labels wil be overwritten to 2. ์๋ต ์ต์๊ธธ์ด : 18, ์ต๋ ๊ธธ์ด : 58 ์ ๋ ฅ: 2O19.12์ ์ด ๊ธด ๊ธ ( ใ ใ ฃใ ใ ฃ์ธ ์ ใ ใ ฃ ใ ใ ) [ ์ฃฝ ์ ใทใ ใ ใ ใดใ ๋ฅผ ] ๋ณต์ ๊ฒฐ๊ณผ: ๋ค์ ๋ค์ ๋ฌธ์ฅ์ ์ฌ๋ฐ๋ฅธ ํ๊ตญ์ด๋ก ๋ณต์ํ์ธ์: ์ ๋ ฅ: 201912์์ด๊ธด๊ธ์ด์์ธ์ด๋ก ๋ณตํ์ธ์:0 ์ถ๋ ฅ. ์๋ต ์ต์๊ธธ์ด : 27, ์ต๋ ๊ธธ์ด : 67 ์ ๋ ฅ: 2019.02์ S.F ํํ์ง [--- ใ ใ ฃ . ๊ณต . ๊ฐ . ใ ใ ฃ . ๋ ---]ํ๊ธ์๋ง ์ด๊ณ ํ์ง 1080P ๋ณต์ ๊ฒฐ๊ณผ: ๋ค์ ๋ค์ ๋ฌธ์ฅ์ ์ฌ๋ฐ๋ฅธ ํ๊ตญ์ด๋ก ๋ณต์ํ์ธ์: ์ ๋ ฅ: 201902์SFํํ์ง---์๊ณต๊ฐ์ด๋---1-ํ๊ธ์๋ง์ด๊ณ ๊ณ -- ํ๊ธ ์๋ง ์ด๊ณ ๊ณ ๊ณ ํ์ง1080P
ย
ย
OCR test (Fail)
ย

ย

ย
ย
ย
ย
ย
ย
ย
If not using AI ?
- Need all type of regex matching dictionary for cipher transformed Korean words.
- sample
############################################################################### # 0) ํ๊ธ ์๋ชจ ๋ฆฌ์คํธ (Korean Jamo Lists for composition) ############################################################################### CHOSUNG_LIST = list("ใฑใฒใดใทใธในใ ใ ใ ใ ใ ใ ใ ใ ใ ใ ใ ใ ใ ") JUNGSEONG_LIST = list("ใ ใ ใ ใ ใ ใ ใ ใ ใ ใ ใ ใ ใ ใ ใ ใ ใ ใ ใ กใ ขใ ฃ") JONGSEONG_LIST = [""] + list("ใฑใฒใณใดใตใถใทในใบใปใผใฝใพใฟใ ใ ใ ใ ใ ใ ใ ใ ใ ใ ใ ใ ใ ") ############################################################################### # 0-1) ๋ณํ ๊ธฐํธ -> ์๋ชจ ๋งคํ (Variant symbols to Jamo) ############################################################################### VARIANT_JAMO_MAP = { 'ใ ': ['o','O','0'], 'ใน': ['l','L','|','I'], 'ใฑ': ['g','G'], 'ใ ': ['s','S'], 'ใ ': ['j','J','z','Z'], 'ใ ': ['h','H'], # ๋ชจ์ ์์ (Add more if needed) 'ใ ฃ': ['i','I','|'], 'ใ ': ['a','A'], 'ใ ': ['eo','EO'], 'ใ ': ['O','o'], # ์ฃผ์: ใ (โOโ)๊ณผ ํผ๋๋ ์ ์์ผ๋ ์ํฉ์ ๋ง๊ฒ ์กฐ์ }
import re def restore_text(text): # 1. ์์/๋ชจ์ ๋ถ๋ฆฌ -> ํฉ์น๊ธฐ # ์์๊ณผ ๋ชจ์์ด ๋ถ๋ฆฌ๋ ๊ฒฝ์ฐ ์ ๋์ฝ๋ ์กฐํฉ def combine_jamo(chars): CHO = "ใฑใดใทในใ ใ ใ ใ ใ ใ ใ ใ ใ ใ " JUNG = "ใ ใ ใ ใ ใ ใ ใ ใ ใ กใ ฃ" JONG = "ใฑใฒใณใดใตใถใทในใบใปใผใฝใพใฟใ ใ ใ ใ ใ ใ ใ ใ ใ ใ ใ ใ ใ " if len(chars) == 2: # ์ด์ฑ + ์ค์ฑ cho, jung = chars return chr(0xAC00 + CHO.index(cho) * 588 + JUNG.index(jung) * 28) elif len(chars) == 3: # ์ด์ฑ + ์ค์ฑ + ์ข ์ฑ cho, jung, jong = chars return chr(0xAC00 + CHO.index(cho) * 588 + JUNG.index(jung) * 28 + JONG.index(jong) + 1) return ''.join(chars) text = re.sub(r'\s+', '', text) # ๊ณต๋ฐฑ ์ ๊ฑฐ text = re.sub(r'[^\w๊ฐ-ํฃ]', '', text) # ํน์๋ฌธ์ ์ ๊ฑฐ text = re.sub(r'[O]', '0', text) # O โ 0 text = re.sub(r'[lI]', '1', text) # l/I โ 1 text = re.sub(r'[B]', '8', text) # B โ 8 # ์์/๋ชจ์ ๋ถ๋ฆฌ๋ ๋ฌธ์ ํฉ์น๊ธฐ result = [] temp = [] for char in text: if 'ใฑ' <= char <= 'ใ ' or 'ใ ' <= char <= 'ใ ฃ': # ํ๊ธ ์๋ชจ temp.append(char) if len(temp) == 3 or (len(temp) == 2 and temp[1] in "ใ ใ ใ ใ ใ ใ ใ ใ ใ กใ ฃ"): result.append(combine_jamo(temp)) temp = [] else: if temp: result.extend(temp) temp = [] result.append(char) if temp: result.extend(temp) return ''.join(result) # ํ ์คํธ test_text = "2O19.12์ ์ด ๊ธด ๊ธ ( ใ ใ ฃใ ใ ฃ์ธ ์ ใ ใ ฃ ใ ใ ) [ ์ฃฝ ์ ใทใ ใ ใ ใดใ ๋ฅผ ]" restored = restore_text(test_text) print("๋ณต์๋ ํ ์คํธ:", restored)