bab2min / kiwipiepy

Python API for Kiwi
Other
285 stars 27 forks source link

타모듈에서 std::length_error 에러 발생 #172

Closed justHungryMan closed 1 month ago

justHungryMan commented 2 months ago

안녕하세요. Datatrove 에서 한국어 토크나이즈시 kiwipiepy 모듈을 사용하고 있습니다. 간혹 commoncrawl 상의 한국어 문서를 파싱할때 아래와 같은 에러가 발생합니다.

terminate called after throwing an instance of 'std::length_error'
  what():  basic_string::_S_create

하지만 에러 위치를 알 수가 없고 python상에서 try catchable 문법에서 걸러지지 않고 있습니다. (https://github.com/huggingface/datatrove/issues/279) 혹시 관련해서 해결방법이 있을까요?

bab2min commented 2 months ago

@justHungryMan 안녕하세요 혹시 위 오류를 재현해볼수 있는 코드를 공유해주실 수 있을까요? 아마 common crawl에서 나오는 특정 지저분한 입력 데이터에 대해서 tokenizer가 오동작하는걸로 보이는데, 코드를 공유해주시면 해당 데이터를 찾는데 도움이 될 것 같습니다.

justHungryMan commented 2 months ago

에러 재현코드 전달드립니다. python3.12 에서 재현했습니다.

에러메시지

python reproduction.py
2024-09-03 22:35:22.123 | INFO     | datatrove.utils.logging:add_task_logger:58 - Launching pipeline for rank=0
2024-09-03 22:35:22.124 | INFO     | datatrove.utils.logging:log_pipeline:90 -
--- 🛠️ PIPELINE 🛠
📖 - READER: 🐿 Jsonl
🔻 - FILTER: 👤 Lambda
2024-09-03 22:35:22.133 | INFO     | datatrove.pipeline.readers.base:read_files_shard:191 - Reading input file , 1/1
libc++abi: terminating due to uncaught exception of type std::length_error: basic_string
[1]    402 abort      python3 reproduction.py
/Users/a13080/anaconda3/envs/kiwibug/lib/python3.12/multiprocessing/resource_tracker.py:254: UserWarning: resource_tracker: There appear to be 1 leaked semaphore objects to clean up at shutdown
  warnings.warn('resource_tracker: There appear to be %d '

requirements.txt

datatrove
kiwipiepy
orjson

재현코드

from datatrove.executor.local import LocalPipelineExecutor
from datatrove.pipeline.filters import LambdaFilter
from datatrove.pipeline.readers import JsonlReader
from datatrove.utils.typeshelper import Languages
from datatrove.utils.word_tokenizers import load_word_tokenizer

def check_korean_tokenizer_pass(doc):
        tokenizer = load_word_tokenizer(Languages.korean)
        try:
            text = doc.text
            words = tokenizer.word_tokenize(text)

            return True
        except:
            return False 

def main():
    executor = LocalPipelineExecutor(
        pipeline=[
            JsonlReader(
                "./02507.jsonl.gz",
            ),
            LambdaFilter(
                filter_function=check_korean_tokenizer_pass
            ),
        ],
        tasks=1,
    )
    executor.run()

if __name__ == '__main__':
    main()

재현 데이터

02507.jsonl.gz

Datatrove 내부에서 한국어의 경우 load_word_tokenizer에서 kiwipiepy 토크나이저를 불러와서 사용합니다.

bab2min commented 2 months ago

@justHungryMan 코드와 데이터 공유 감사합니다. 오류 분석 결과 다음과 같이 공백 문자 없이 26000여 글자가 연속해서 이어져 있는 스팸 텍스트를 분석할때 발생하던 메모리 문제로 확인되었습니다.

HOME > 커뮤니티 >\n묻고답하기\n작성일 : 17-07-18 07:56\n좋은채팅사이트《08455.wanggame9.com》좋은채팅사이트좋은채팅사이트좋은채팅사이트좋은채팅사이트좋은채팅사이트좋은채팅사이트좋은채팅사이트...

해당 문제를 해결하는 패치를 준비 중이지만 시간이 좀 걸릴 수 있습니다. 만약 그전에 이 문제를 회피하고 싶으시다면 공백 문자 없이 8000글자 이상이 연속해서 등장하는 텍스트는 kiwipiepy를 태우지 않고 별도의 처리를 하시는걸 추천해드립니다.

import re

if not re.search(r'[^\s]{8000,}', text):
    tokenizer.word_tokenize(text)
else:
    # Plan B
justHungryMan commented 2 months ago

빠른 대응 정말 감사합니다.

저희쪽 모듈에 알려주신 방법으로 버리는 문서없이 적용 가능할 것 같습니다.

justHungryMan commented 2 months ago

전체적으로 오류가 생겼던 파일들을 재점검하고 있는데 8000글자 반복의 텍스트에서도 같은 문제가 생기는 것을 발생했습니다. 해당 문제는 7000글자로 변경하여 해결하였습니다만 단순 반복글자수로 제한하는 것은 여러 문제가 발생할 것 같습니다.

우선 문제보고를 드리고 추가적으로 문제가 발생한다면 종합해서 공유드리겠습니다.

justHungryMan commented 1 month ago

commoncrawl 의 2017년도에서 2024년도까지 돌려본 결과 공백 문자 없이 6000글자로 수정시 문제없이 동작하는 것을 확인했습니다.

혹시 릴리즈되면 이슈에 써주실 수 있으실까요? 이 모듈을 사용하는 datatrove에도 문제가 해결되었다고 noti하려고 합니다.

bab2min commented 1 month ago

@justHungryMan 자세한 확인 감사합니다. 해당 오류를 수정하는 패치는 작업 완료되었고, 테스트도 통과한 상태라 이번 주말 안에는 0.18.1버전으로 릴리즈 가능할것 같습니다. 릴리즈되면 노티해드리도록 하겠습니다. 감사합니다!

bab2min commented 1 month ago

@justHungryMan 해당 이슈 해결된 0.18.1 버전 릴리즈 완료되었습니다~ 다시 한번 오류 제보에 감사드립니다!