Skip to content

feat(noun): LRNounExtractor 멀티프로세싱 지원 (#160) - #161

Merged
lovit merged 4 commits into
refactor-2026from
feature/160
Mar 8, 2026
Merged

feat(noun): LRNounExtractor 멀티프로세싱 지원 (#160)#161
lovit merged 4 commits into
refactor-2026from
feature/160

Conversation

@lovit

@lovit lovit commented Mar 8, 2026

Copy link
Copy Markdown
Owner

Summary

  • LRNounExtractor.extract()n_workers 파라미터 추가
  • 표준 라이브러리(multiprocessing)만 사용, 외부 의존성 없음
  • n_workers=1(기본값) 시 기존 단일 프로세스 경로와 완전히 동일

변경 내용

soynlp/core/lrgraph.py

  • corpus_to_lrgraph(n_workers=1) 파라미터 추가
  • _build_partial_counter(): 텍스트 청크 → partial dict[str, dict[str, int]] 반환 (module-level, pickle 가능)
  • _merge_counters(): partial counter 리스트 병합

soynlp/noun/lr.py

  • LRNounExtractor.extract(n_workers=1) 파라미터 추가
  • train_lrgraph(n_workers=1) 파라미터 추가

tests/unit/test_multiprocessing.py (신규)

  • 단일/멀티 LRGraph 구축 결과 동일성 검증
  • 단일/멀티 명사 추출 결과 동일성 검증 (n_workers=4)
  • n_workers=-1 (auto) 동작 확인

사용법

extractor = LRNounExtractor()
nouns = extractor.extract(sents, n_workers=4)   # 4개 프로세스
nouns = extractor.extract(sents, n_workers=-1)  # CPU 코어 수 자동
nouns = extractor.extract(sents)                # 기존 단일 프로세스 (기본값)

Test plan

  • uv run pytest tests/unit/test_multiprocessing.py -v — 5개 신규 테스트 통과
  • uv run pytest tests/unit/ -q — 243개 전체 통과 (regression 없음)
  • uv run pyright soynlp/core/lrgraph.py soynlp/noun/lr.py — 0 errors

주의사항

  • macOS/Linux: fork start method로 LRGraph Copy-on-Write 공유
  • Windows: spawn start method로 인해 데이터 직렬화 오버헤드 발생 가능 (단, 동작은 보장)

Closes #160

🤖 Generated with Claude Code

@lovit lovit left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

셀프 리뷰 결과

발견된 문제 및 수정 완료 (c939571)

[수정] 오해 유발 로그 (noun/lr.py)
min_eojeol_frequency > 1이면 n_workers를 지정해도 내부적으로 EojeolCounter 단일 프로세스를 사용하는데, 기존 로그에는 n_workers={n} 이 찍혀 사용자가 병렬 처리되는 것으로 오해할 수 있었음. 로그를 n_workers 무시, 단일 프로세스로 LRGraph 구축으로 수정.

[수정] Pool lazy import (core/lrgraph.py)
from multiprocessing import Pool을 top-level에서 사용 함수 내부로 이동. 멀티프로세싱을 쓰지 않는 경우(n_workers=1) 모듈 import 시 불필요하게 로드되지 않도록 개선.

[수정] 테스트 추가
min_eojeol_frequency=2 + n_workers=4 케이스 추가 (6개 → 6개로 유지, 내용 보완).


알려진 한계 (follow-up 이슈 예정)

longer_first_prediction() 병렬화 미구현
이 함수는 LRGraph를 처리하면서 L-R 쌍을 순차적으로 제거하는 방식으로 동작해 데이터 의존성이 존재함. 단순 청크 분할로는 결과가 달라질 수 있으므로 이번 PR 범위에서 제외함. 후속 이슈에서 별도로 검토 필요.

현재 멀티프로세싱 효과: LR-Graph 구축 단계만 병렬화됨.

lovit and others added 2 commits March 9, 2026 04:56
corpus 구축 및 명사 추출에 n_workers 파라미터 추가.
표준 라이브러리(multiprocessing)만 사용하여 외부 의존성 없음.

- core/lrgraph.py: corpus_to_lrgraph()에 n_workers 파라미터 추가
  - n_workers=1: 기존 단일 프로세스 경로 (기본값, 변경 없음)
  - n_workers>1: texts를 청크 분할 → Pool.map() 병렬 처리 → 결과 병합
  - n_workers=-1: os.cpu_count() 자동 감지
  - _build_partial_counter(), _merge_counters() module-level 함수 추가
- noun/lr.py: extract(), train_lrgraph()에 n_workers 파라미터 전달
- tests/unit/test_multiprocessing.py: 단일/멀티 결과 동일성 검증 테스트 5개 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- core/lrgraph.py: Pool import를 lazy import로 변경 (모듈 로드 시 불필요한 import 방지)
- noun/lr.py: min_eojeol_frequency > 1이면 n_workers 무시하고 단일 프로세스로 동작함을 로그로 명시
- tests: min_eojeol_frequency=2 + n_workers=4 케이스 테스트 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
lovit and others added 2 commits March 9, 2026 05:04
실제 코퍼스(뉴스, 영화리뷰)에서 n_workers=4 결과가
단일 프로세스 결과와 동일함을 integration 수준에서 검증.

- extract_frequent_nouns/verify.py: 뉴스 코퍼스 n_workers=4 검증 추가
- movie_review_nouns/verify.py: 뉴스·리뷰 코퍼스 각각 n_workers=4 검증 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CI runner의 기본 Python이 3.14여서 scipy 등 의존성 wheel이 없어 빌드 실패.
pre-commit pyright hook에 language_version: python3.12를 명시하여 해결.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@lovit
lovit merged commit 057af93 into refactor-2026 Mar 8, 2026
2 checks passed
@lovit
lovit deleted the feature/160 branch March 8, 2026 20:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant