Semantic Hints Cycle 02 KO - teamswyg/laya-tools GitHub Wiki

PDCA 02: ๊ฐ•ํ•œ ๊ฒ€์ƒ‰ ๊ธฐ์ค€์„ ๊ณผ ํ‹€๋ฆฐ ํžŒํŠธ์˜ ๋น„์šฉ ์ œํ•œ

English ยท ์ „์ฒด ๊ฒฐ๊ณผ ยท ๊ธฐํš

์ด๋ฒˆ์— ์“ธ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ

pkg/hintsearch๋Š” Go๋งŒ์œผ๋กœ BM25 ๊ฒ€์ƒ‰๊ณผ ์™ธ๋ถ€ ํžŒํŠธ์˜ ์ˆœ์„œ ์กฐํ•ฉ์„ ์ œ๊ณตํ•œ๋‹ค. cmd/riido-hints๋Š” ๊ฐ™์€ ๊ธฐ๋Šฅ์„ JSON ์ž…์ถœ๋ ฅ์œผ๋กœ ์ œ๊ณตํ•œ๋‹ค. ๋ชจ๋ธ ๋‹ค์šด๋กœ๋“œยทPythonยทGPU ์—†์ด ์‹คํ–‰ํ•œ๋‹ค. ๊ธฐ์กด ๋ผ์šฐํ„ฐ ์„ค์ •์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š”๋‹ค.

go run ./cmd/riido-hints < examples/hints/request.json

์˜ˆ์‹œ๋Š” ์˜๋„์ ์œผ๋กœ ํ‹€๋ฆฐ cache ํžŒํŠธ๋ฅผ ๋จผ์ € ์ค€๋‹ค. ์ถœ๋ ฅ์˜ ์ฒซ ํ›„๋ณด๋Š” cache, ๋‘ ๋ฒˆ์งธ๋Š” BM25๊ฐ€ ์ฐพ์€ payments๋‹ค. ๋ชจ๋“  ํ›„๋ณด๊ฐ€ ๋‚จ๊ณ  ์ƒํƒœ๋Š” ํ•ญ์ƒ unverified๋‹ค. bm25_score๋Š” ์›๋ž˜ ๋ฌธ์„œ ๊ด€๋ จ์„ฑ ์ ์ˆ˜์ด๋ฉฐ ์ตœ์ข… ์ˆœ์„œ์˜ ์‹ ๋ขฐ ํ™•๋ฅ ์ด ์•„๋‹ˆ๋‹ค. hints๋ฅผ ์ƒ๋žตํ•˜๋ฉด BM25 ์ˆœ์„œ๋งŒ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

์‚ฌ๋žŒ์€ JSON ๋ฌธ์„œ ๋ชฉ๋ก์„ ํŽธ์ง‘ํ•ด์„œ ์‹œํ—˜ํ•  ์ˆ˜ ์žˆ๊ณ , ์—์ด์ „ํŠธ๋Š” ๋™์ผํ•œ stdin/stdout ๊ณ„์•ฝ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์‹ค์ œ ์ €์žฅ์†Œ๋ฅผ ์ฝ๊ฑฐ๋‚˜ API๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š”๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๋ฌธ์„œ๋งŒ ๋„ฃ์–ด์•ผ ํ•˜๋ฉฐ snapshot ID๋Š” ํ˜ธ์ถœ์ž๊ฐ€ ์นดํƒˆ๋กœ๊ทธยท๊ถŒํ•œ ๋ณ€๊ฒฝ๋งˆ๋‹ค ๊ฐฑ์‹ ํ•ด์•ผ ํ•œ๋‹ค. CLI๊ฐ€ ์‹ค์ œ ๋‚ด์šฉ์˜ ๋ฒ„์ „์„ ์•”ํ˜ธํ•™์ ์œผ๋กœ ์ฆ๋ช…ํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค. ํžŒํŠธ์˜ query/snapshot ๋ถˆ์ผ์น˜, ์ค‘๋ณต/์•Œ ์ˆ˜ ์—†๋Š” ID๋Š” ์˜ค๋ฅ˜๋กœ ๊ฑฐ๋ถ€ํ•œ๋‹ค. ์ž…๋ ฅ ์˜ค๋ฅ˜๋Š” ๋น„์ •์ƒ ์ข…๋ฃŒํ•˜๋ฉฐ ์ผ๋ถ€ ๊ฒฐ๊ณผ๋ฅผ ๋จผ์ € ๋‚ด๋ณด๋‚ด์ง€ ์•Š๋Š”๋‹ค.

๋ฐ˜ํ™˜ ๊ฒฐ๊ณผ๋ฅผ ์‹คํ–‰ ๋ช…๋ น์œผ๋กœ ์ทจ๊ธ‰ํ•˜์ง€ ์•Š๋Š”๋‹ค. ํ›„์† ๊ฒ€์ฆ๊ธฐ๋Š” ํ•˜๋‚˜์”ฉ ๊ฒ€์‚ฌํ•˜๊ณ , ์˜ˆ์‚ฐ ์ข…๋ฃŒ ์‹œ incomplete๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค. ์ด CLI ์ž์ฒด๋Š” ๊ฒ€์ฆยท์˜ˆ์‚ฐ ์ง‘ํ–‰ยท์บ์‹œ๋ฅผ ์•„์ง ๊ตฌํ˜„ํ•˜์ง€ ์•Š๋Š”๋‹ค.

์™œ ๋ฒˆ๊ฐˆ์•„ ํ™•์ธํ•˜๋‚˜

์›๋ž˜ ๊ฒ€์ƒ‰ ๋ชฉ๋ก B์™€ ํ•™์Šต๊ธฐ ๋“ฑ์˜ ํžŒํŠธ ๋ชฉ๋ก H์—์„œ ๋ฒˆ๊ฐˆ์•„ ํ•˜๋‚˜์”ฉ ๊บผ๋‚ด๋ฉฐ ์ด๋ฏธ ํ™•์ธํ•  ์˜ˆ์ •์ธ ํ›„๋ณด๋Š” ๊ฑด๋„ˆ๋›ด๋‹ค. H๋Š” ์ผ๋ถ€ ํ›„๋ณด๋งŒ ์ œ๊ณตํ•ด๋„ ๋œ๋‹ค. B๋Š” ์ „์ฒด ํ›„๋ณด๋ฅผ ์œ ์ง€ํ•ด์•ผ ํ•œ๋‹ค.

์ฆ๋ช… ๋ฒ”์œ„: ์›๋ž˜ r๋ฒˆ์งธ ํ›„๋ณด๋ณด๋‹ค ์•ž์„  B ํ›„๋ณด๋Š” rโˆ’1๊ฐœ๋‹ค. ๋งค ํšŒ์ „์€ H์—์„œ ์ตœ๋Œ€ 1๊ฐœ, B์—์„œ ์•„์ง ๋‚˜์˜ค์ง€ ์•Š์€ ํ›„๋ณด ์ตœ๋Œ€ 1๊ฐœ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. H๊ฐ€ B์˜ ์•ž ํ›„๋ณด๋ฅผ ๋จผ์ € ๋‚ด๋ณด๋‚ด๋ฉด B์˜ ์ง„๋„๋Š” ๋” ๋นจ๋ผ์ง„๋‹ค. ๋”ฐ๋ผ์„œ r๋ฒˆ์งธ ์›๋ž˜ ํ›„๋ณด๋Š” ๋Šฆ์–ด๋„ rํšŒ์ „, ์ฆ‰ min(N, 2r)๋ฒˆ์งธ๊นŒ์ง€ ๋‚˜์˜จ๋‹ค. ์ „์ฒด ์ˆœ์„œ์—๋Š” ์ค‘๋ณต์ด๋‚˜ ๋ˆ„๋ฝ์ด ์—†๋‹ค.

์ด๊ฒƒ์€ ๋™์ผ ๋‹จ์œ„ ๋น„์šฉ์˜ ์ •ํ™•ํ•œ ๋‹จ์ผ ํ›„๋ณด ๊ฒ€์ฆ ํšŸ์ˆ˜์— ๋Œ€ํ•œ ๋ณด์žฅ์ด๋‹ค. ๋А๋ฆฐ ํ›„๋ณด, ์—ฌ๋Ÿฌ ๊ทผ๊ฑฐ๋ฅผ ๋ชจ์œผ๋Š” ์ž‘์—…, ํžŒํŠธ ์ƒ์„ฑ๋น„, LLM ํ† ํฐ, ์ด ์‘๋‹ต ์‹œ๊ฐ„์—๋Š” ๊ทธ๋Œ€๋กœ ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค. ๋ถˆ์™„์ „ํ•œ ๊ฒ€์ฆ๊ธฐ์˜ ์˜ค๋‹ต๋„ ํ•ด๊ฒฐํ•˜์ง€ ์•Š๋Š”๋‹ค. ์™ธ๋ถ€ ํžŒํŠธ ์ƒ์„ฑ์— ๋ณ„๋„ ์‹œ๊ฐ„/๋ฉ”๋ชจ๋ฆฌ ํ•œ๋„๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ํšจ์œจ ํ–ฅ์ƒ ๋ณด์žฅ์ด ์•„๋‹ˆ๋ผ ์†ํ•ด๋ฅผ ์ œํ•œํ•˜๋Š” ์žฅ์น˜๋‹ค.

๊ตฌํ˜„๊ณผ ๊ฒ€์ฆ

  • BM25 k1=1.2, b=0.75. ๋‹จ์–ด ๋นˆ๋„ยท๋ฌธ์„œ ๊ธธ์ดยทํฌ๊ท€๋„๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. query ์ค‘๋ณต ๋‹จ์–ด๋Š” ํ•œ ๋ฒˆ๋งŒ ๊ณ„์‚ฐํ•œ๋‹ค. ์˜๋ฏธ ๋ชจ๋ธ์ด ์•„๋‹ˆ๋‹ค.
  • ์ •๋ ฌ๋œ ์–ดํœ˜์™€ ์—ฐ์†๋œ posting ์—ด ๋ฐฐ์—ด(doc ์œ„์น˜, ๋นˆ๋„), ๋ฌธ์„œ ์ •๊ทœํ™” ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•œ๋‹ค. ๊ณต์œ  index๋Š” ๋ถˆ๋ณ€์ด๋ฉฐ query ๊ฒฝ๋กœ์— mapยทlock์ด ์—†๋‹ค. ๊ฒฐ๊ณผ ๋ฐฐ์—ด์€ ํ˜ธ์ถœ๋ณ„๋กœ ์†Œ์œ ํ•œ๋‹ค. Go ๋Ÿฐํƒ€์ž„ ๋‚ด๋ถ€ ๋™๊ธฐํ™”๊ฐ€ ์—†๋‹ค๋Š” ๋œป์€ ์•„๋‹ˆ๋‹ค.
  • 1..4096๋ฌธ์„œ, ๋ฌธ์„œ ๋ณธ๋ฌธ ํ•ฉ๊ณ„ 2MiB, query 8192B, ์ธ์ฝ”๋”ฉ๋œ CLI JSON 16MiB ํ•œ๋„. ์ž…๋ ฅ ํ•œ๋„๊ฐ€ ์ „์ฒด RSS ํ•œ๋„์™€ ๊ฐ™์ง€๋Š” ์•Š๋‹ค.
  • ์ˆ˜์‹ ์ˆ˜์น˜ ๋Œ€์กฐ, ๋นˆ ๋ฌธ์„œยทํ•œ๊ตญ์–ด ํ† ํฐ, query/catalog ํ•œ๋„, ๋™์‹œ ํ˜ธ์ถœ, stale ํžŒํŠธ ๊ฑฐ๋ถ€๋ฅผ ๊ฒ€์‚ฌํ•œ๋‹ค. ํ•œ๊ตญ์–ด ํ† ํฐํ™” ํ†ต๊ณผ๋Š” ํ•œ๊ตญ์–ด ์˜๋ฏธ ๊ฒ€์ƒ‰ ํ’ˆ์งˆ์˜ ์ฆ๊ฑฐ๊ฐ€ ์•„๋‹ˆ๋‹ค.
  • ์ตœ๋Œ€ 7ํ›„๋ณด์˜ ๋ชจ๋“  ํžŒํŠธ ์ˆœ์—ด๊ณผ ๋ชจ๋“  ๊ธธ์ด์˜ prefix๋ฅผ ์—ด๊ฑฐํ•ด 2r ํ•œ๊ณ„์™€ ๋ณด์กด์„ ๊ฒ€์ฆํ–ˆ๋‹ค. ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ์™€๋Š” ๋‹ค๋ฅด๋‹ค.

๊ฐ™์€ 52๊ฐœ ๊ฐœ๋ฐœ ์š”์ฒญ์œผ๋กœ ์ธก์ •

๋ฐฉ๋ฒ• Recall@1 Recall@4 ํ‰๊ท  oracle ๊ฒ€์ฆ BM25 ๋Œ€๋น„ ์ตœ๋Œ€ ๊ฐœ๋ณ„ ๊ฒ€์ฆ ๋น„์œจ
BM25 52.08% 75.00% 4.615 1.0
token ํžŒํŠธ + BM25 ๊ต๋Œ€ 52.08% 75.00% 4.615 1.0
๊ณ ์ • ๋‚œ์ˆ˜ ํžŒํŠธ + BM25 ๊ต๋Œ€ 6.25% 75.00% 5.308 2.0
BM25 ์—ญ์ˆœ ํžŒํŠธ + BM25 ๊ต๋Œ€ 2.08% 75.00% 5.385 2.0

๋ชจ๋“  ๋ฐฉ๋ฒ•์˜ ์ •๋‹ต ์—†์Œ 4๊ฑด์€ 16๋ฒˆ ๋ชจ๋‘ ํ™•์ธํ–ˆ๋‹ค. BM25๋„ ์ง์ ‘ ํ‘œํ˜„ 16/16, paraphrase 1/16, ๋Œ€์กฐ 8/16์œผ๋กœ, ๊ธฐ์กด ์ •ํ™• ํ† ํฐ ๊ธฐ์ค€์„ ๊ณผ ๋™์ผํ•˜๋‹ค. ์ด๊ฒƒ์€ ์˜๋ฏธ ํ•™์Šต ๊ฐœ์„ ์ด ์•„๋‹ˆ๋‹ค. ๋ถ€์‹คํ•œ ํžŒํŠธ๋Š” ํ‰๊ท  ๋น„์šฉ์„ ์•…ํ™”์‹œ์ผฐ์œผ๋ฉฐ, ์•„๋ฌด ํžŒํŠธ๋‚˜ ์ถ”๊ฐ€ํ•˜๋ฉด ์ด๋“์ด๋ผ๋Š” ๊ฐ€์„ค์€ ์ง€์ง€๋˜์ง€ ์•Š๋Š”๋‹ค. ๊ฐ™์€ ๊ฐœ๋ฐœ ์ž๋ฃŒ๋ฅผ ์žฌ์‚ฌ์šฉํ–ˆ์œผ๋ฏ€๋กœ ์ƒˆ final ์„ฑ๊ณผ๋กœ ๋ณด๊ณ ํ•˜์ง€ ์•Š๋Š”๋‹ค.

์ด๋ฒˆ ๋‹จ์ผ run์—์„œ BM25 warm p95๋Š” 0.625ยตs, ์ „์ฒด 9๋ฐฉ๋ฒ• ๋น„๊ต ํ”„๋กœ์„ธ์Šค ์ตœ๋Œ€ RSS๋Š” 11,862,016B(11.31MiB), peak footprint๋Š” 9,732,576B, wall 0.48์ดˆ, user CPU 0.10์ดˆ, swap 0์ด์—ˆ๋‹ค. 16ํ›„๋ณด query ํ† ํฐํ™”ยท์ ์ˆ˜ยท์ •๋ ฌ์„ ํฌํ•จํ•˜๊ณ  ์ดˆ๊ธฐ index ์ƒ์„ฑ๊ณผ ๊ฒ€์ฆ์€ ์ œ์™ธํ•œ๋‹ค. ๊ณ ์ • ์ˆœ์„œ ๋ฒค์น˜๋งˆํฌ์˜ ์ž‘์€ ์‹œ๊ฐ„ ์ฐจ์ด๋Š” ์‹คํ–‰ ์ˆœ์„œ/๋…ธ์ด์ฆˆ ์˜ํ–ฅ์„ ๋ฐ›์œผ๋ฏ€๋กœ CPU ๊ฐ€์† ๋น„์œจ์„ ์ฃผ์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค.

64๊ฐœ ๋™์ผ ๋ฌธ์„œ๋กœ ๋งŒ๋“  ๋ณ„๋„ dense-posting microbenchmark๋Š” 523.7ns/op, 1128B/op, 5allocs/op์ด์—ˆ๋‹ค. ์‹ค์ œ ์ €์žฅ์†Œ ํ’ˆ์งˆยท์‹ค์ œ ๋ถ€ํ•˜๋ฅผ ๋Œ€ํ‘œํ•˜์ง€ ์•Š๋Š”๋‹ค. pprof ํ‘œ๋ณธ์˜ ๋Œ€๋ถ€๋ถ„์ด Go ๋Ÿฐํƒ€์ž„ ๋Œ€๊ธฐ/๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์— ์žˆ์–ด SIMD๋‚˜ ์ƒˆ lock ์ตœ์ ํ™”์˜ ๊ทผ๊ฑฐ๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜๋‹ค. ์›์‹œ CPU/heap ํ”„๋กœํŒŒ์ผ์€ ๊ณต๊ฐœํ•˜์ง€ ์•Š๋Š”๋‹ค. GPU ์‚ฌ์šฉยท์ „๋ ฅ ์ ˆ๊ฐยทLLM ๋น„์šฉ์€ ์ธก์ •ํ•˜์ง€ ์•Š์•˜๋‹ค.

๋‹ค์Œ ๋‹จ๊ณ„

์ด์ œ ํ•™์Šต ๋ชจ๋ธ์˜ ํžŒํŠธ ์ˆœ์„œ๋ฅผ ๋™์ผ CLI์™€ ๊ฒ€์ฆ ๊ณ„์•ฝ์— ๋ผ์šธ ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์•„์ง ํ•™์Šต ๋ชจ๋ธ์€ ์—†๊ณ  HF ๋ฆด๋ฆฌ์Šค๋„ ์—†๋‹ค. ๋‹ค์Œ ์‚ฌ์ดํด์€ ๊ฐ€์กฑ ๋ถ„๋ฆฌ๋œ ๊ณต๊ฐœ ๋ฐ์ดํ„ฐ, BM25ยท๊ฐ€๋ฒผ์šด ํ•™์Šต ๊ธฐ์ค€์„ , FP32/INT8/3์ง„ ๋น„๊ต๋‹ค. ์ƒˆ๋กœ์šด ์˜๋ฏธ ๊ฐ€์กฑ final์„ ๋ด‰์ธํ•˜๊ณ , ๋‹จ์ˆœ ํ† ํฐ/BM25๋ณด๋‹ค ์‹ค์ œ๋กœ ๊ฒ€์ฆ ๋น„์šฉ์ด ์ค„์–ด๋“œ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. ํ˜„์žฌ ๋ชฉํ‘œ๋Š” ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜๋‹ค.