Eat Study Love

먹고 공부하고 사랑하라

Data Science/Research

SQL2NL 모델 추가 실험(VectorDB, Embedding)[3]

eatplaylove 2025. 8. 18. 19:07

https://eglife.tistory.com/363

 

SQL2NL 모델 추가 실험(VectorDB, Embedding)[2]

https://eglife.tistory.com/362 SQL2NL 모델 추가 실험(VectorDB, Embedding)[1]https://eglife.tistory.com/361 SQL2NL 모델 실험진행(2)https://eglife.tistory.com/360 SQL2NL 모델 실험진행https://eglife.tistory.com/359 SQL2NL 모델 개선방안

eglife.tistory.com

이제 Embedding 추가하는 건 여기서 Stop하고

 

Embedding한 모델이 적절히 쓸만한지, Test를 진행해봐야 한다.

 

Test case를 어떻게 나눠야 할까?

 

그 전에 이 실험을 통해서 보여주고 싶은 것이 무엇인고...?

 

SQL-to-NL을 SQLGlot을 이용하면 Structure based Prompt를 통해 동일 Domain의 SQL data들 중 가장 적절한 Few-Shot Sample들을 취할 수 있다. 이것은 이미 증명된 것.

 

근데, 지금은 이 Process에 RAG를 써보는 것을 골자로 한다. 즉, 동일 Domain에 있는 SQL Data가 너무 많을 때 내가 만든 Embedding Function으로 Embedding된 VectorDB(FAISS)에서 RAG를 썼을 때, Input SQL과 구조가 비슷한 Few-shot examplar들을 적절히 추출하고 이것이 SQL2NL에 도움이 되는지를 체크한다.

 

위 Embedding Function에서도 SQLGlot을 사용해서 SQL을 Parsing하는 Process 중 일부를 갖고와 Fucntion을 만들었고 Vector의 Embedding feature는 모두 binary로 만들었다.( ex) FROM이 있냐 없냐, Inner Join이 있냐 없냐 등 )

 

K-DS에서 확인 한 두 가지 Case

 1) SQL2NL에서 Few-shot prompting은 효과가 있다.

 2) Few-shot을 SQLGlot을 기반으로 추출한 것은 더 효과적이다.

 

위 2번은 SQLGlot의 diff function 기반 Score로 Example을 추출한 것이라 추출된 Example들과 Input SQL과의 연관성은 높겠지만 모든 DB내 예시 Data들과 1:1로 for문을 돌며 Diff 계산을 하기에 계산시간이 # top - k * N = O(N)이다.

 

반면 RAG는 위 계산과정 없이 별도의 VectorDB Search 알고리즘 + RAG 기능으로 TOP-K를 빨리 추출하지만 diff function을 직접적으로 이용하지 않았으므로 정확도는 다소 떨어질 것으로 예상된다.

 

그래서,, 이번에 Check해볼 것이 무엇인고..

 

비교군을 이렇게 해보면 어떨까 싶다.
Schema Linking과 Fewshot Prompt는 동일하게 사용한다고 가정하되, Fewshot 추출방안에 변화를 주는 것이다.

 

1)  Naive - 그냥 Random fewshow sample 5ea SQL2NL

2)  RAG only - RAG를 통한 fewshot sample 5ea SQL2NL ( Ours 1 )

3)  RAG + SQLGlot - RAG를 통해 Sample 추출 후( >= 5ea ) 거기서 SQLGlot Diff score를 통해 Top-5 추출 ( Ours 2 )

 

RAG가 핵심이므로, 굳이 여기서 SQLGlot diff fucntion만을 써서 fewshot prompt를 만드는 실험은 추가하지 않겠다.(K-DS에서 이미 검증한 내용임)


실험 Data : BIRD JSON Data Parsing 完

Table Schema : BIRD 공식 Homepage 참고해서 txt파일로 준비 完

Model : Llama Naive는 처참한 수준이다. Fine-tuning이 없으니 최신 GPT5 - mini Model 사용

나쁘지 않은 가격대이다.

 

위 3가지 케이스에 대해서 실험을 돌리자

 

80차원의 Vector로 Embedding하는 것 완료! Sample은 아래와 같다.

 

일단 어찌어찌 Test는 돌려봤는데..

나름 소량(?)의 Data set_1400ea 에서 돌려서 그런가 RAG 추출 효과가 잘 없다.

 

Score도 좀 더 Normalize가 필요할 거 같고, Data-set도 좀 더 많은 양을 다루도록 실험세팅을 다시 좀 정교하게 다듬어야겠다.

 

그리고 Schema Linking의 경우도 지금 매번 LLM Call 할 때마다 비효율적으로 포함되고 있는데 그냥 Globally 전역으로 사용될 수 있도록 Prompt 쪽도 좀 다듬어야 겠다.


Schema Linking 최적화와, Prompt 최적화를 동시에 진행해보고

 

Large Scale에 대해서도 Test를 돌려보자.

 

DB Table Schema의 경우 양이 적지 않다. 거의 1000줄에 가까운 txt파일인데, 모든 input SQL의 db schema를 다 포함하고 있다.

    # 실행 루프 안에서 (entry 처리 시)
    db_id = (entry.get("db_id") or "").strip()
    per_db_schema = schema_index.get(db_id, "")  # 없으면 빈 문자열
    
    ################
    
    def build_schema_index(schema_text: str) -> dict:
    """
    '=== Database: NAME ===' 블록 단위로 파싱하여
    {NAME: 그 블록 전문(헤더 포함)} 딕셔너리로 반환.
    """
    if not schema_text:
        return {}
    # 헤더를 캡처하면서 다음 헤더 전까지 포함
    pattern = r"(===\s*Database:\s*([^\n=]+?)\s*===)([\s\S]*?)(?=(?:\n===\s*Database:)|\Z)"
    index = {}
    for m in re.finditer(pattern, schema_text):
        header = m.group(1).strip()
        name   = m.group(2).strip()
        body   = m.group(3).rstrip()
        # 헤더+본문을 그대로 보존(모델이 context에서 DB 이름을 명확히 보게 함)
        index[name] = f"{header}\n{body}".strip()
    return index

 

그리 하여, 이 Schema에도 index를 부여해서 input SQL마다 이에 Pair되는 Schema만 따로 Parsing해서 Prompt에 부여하기로 했다.

 

수 많은 Prompting test를 해봤을 때, 너무 많은 정보가 LLM에 제공되어도 되려 정확도가 낮아지는 경우가 있었다. 정확히 LLM의 Reasoning에 필요한 정보만을 제공하는 것이 중요하다.

 

실험 Case가 좀 적어서 그런지 결과가 째끔 애매하긴 하다.

 

 

지금까진 DB 1400개 정도에서 test data를 5개만 다뤘는데, 이번엔  test data 100개정도로 설정해서 test를 다시 진행해봐야겠다.

 

이렇게 하니까 일단 Random보다 RAG를 쓰는 경우가 모든 case에서 좋다.

 

근데.. 크기가 그렇게 비약적으로 커보이진 않는게 단점이다;;

 

Test case 100ea 다룬 ver.

 

이번엔 다른 9400ea dataset으로 Train / Test case를 나눠서 또 실험 진행해봐야겠다.

 

위는 BIRD DEV set이고 이번엔 BIRD Train set이다.

 

Test case는 100ea, GPT-5-mini는 그대로 똑같이 맞췄다.

 

결과는 더 이상함.. 어떻게 RAG보다 Random 추출이 더 좋을 수 있지..;;

 

 

Search해보니 BIRD의 Train set은 Error가 많아서 연구자들이 다루기를 보통 꺼려한다고 하긴 하던데,,,

 

정 애매하면 여기서 RAG_Hybrid는 일단 제외하고 RAG만 Random보다 효과가 좋다는 내용에 집중해서 실험내용 정리하는 것도 좋겠다.