isPowerfulBlog

[LangChain] multi query invoke, ainvoke 속도 비교하기 본문

Data Engineering

[LangChain] multi query invoke, ainvoke 속도 비교하기

왕밤빵도라에몽 2024. 4. 25. 20:11

MapReduce 방식으로 문서 요약 태스크를 진행하면, LLM에 많은 쿼리를 날려야 한다.
그리고 그 쿼리들을 날리는 시간이 너무 오래 걸려서 문제가 됐다.

찾아보니 invoke 말고 비동기로 invoke를 실행할 수 있는 ainvoke가 있다.

여러개의 query들을 실행해야하는 상황에서, 비동기로 invoke를 실행하면 병렬로 처리할 수 있게 된다.


invoke

def summary(self, split_docs):
    ...
    output = map_reduce_chain.invoke(split_docs)

    return output

임의의 문서를 요약하는 함수이다. 안에는 chunk들을 요약하는 chain이 구성되어있다.
이 chain을 invoke로 실행하면,

제목 없는 프레젠테이션 (7)

이렇게 순차적으로 inference를 하고, chunk 요약본들을 합쳐서 한 번 더 요약하는 과정을 거친다.
chunk가 n개라면 총 n+1번의 inference 시간이 걸리는 것이다.

속도가 꽤 중요한 태스크에서 inference n+1번의 시간을 그대로 안고 가는 것은 너무 오바였다. (이렇게 느리면 누가 쓰묘?)

ainvoke

async def summary(self, split_docs):
    ...
    output = await map_reduce_chain.ainvoke(split_docs)

    return output

그렇게 chain을 ainvoke로 비동기로 바꿔주면..

제목 없는 프레젠테이션 (3)

이렇게 약 1+1 번의 inference 시간으로 시간이 확 줄어든다.
이 차이는 chunk의 개수가 많으면 많을 수록 그 차이가 확연하게 나타난다.

시간 비교

하나의 문서에 대해 text split 때 chunk 사이즈를 다르게 주어 두 번의 실험을 했다.

실험 1.
image

  • chunk 사이즈를 크게 주어
  • splitted docs의 개수가 적을 때,
  • invoke와 async의 시간 차를 비교해보면
    async가 약간 더 빠르다.

실험 2.
image

  • chunk 사이즈를 작게 주어
  • splitted docs의 개수가 많을 때,
  • invoke와 async의 시간 차를 비교해보면
    async가 3배 가까이 빠름을 확인할 수 있다.

결론

쿼리를 여러개 날려야 할 때 비동기로 처리하면 훨씬 빠르다.

하지만!!!

요약 태스크에서 비동기처리가 과연 좋은 선택일까?
비동기로 처리하게 되면 chunk들이 요약되는 순서가 보장되지 않는다.
요약의 속도는 빨라지지만 전체 맥락의 순서가 변동될 수 있는 것이다.

다음엔 이걸... 보완해보는 시도(?)를 가져오겠습니다.~~ 아자자