• 【GPT‑4o】完整教程:LORA微调LLaMA3并结合RAG和Agent技术实现Text2SQL任务


    完整教程:LORA微调LLaMA3并结合RAG和Agent技术实现Text2SQL任务

    环境准备

    首先,安装必要的Python包

    pip install transformers peft datasets torch faiss-cpu
    
    • 1
    加载LLaMA3模型

    从Hugging Face加载LLaMA3模型和对应的tokenizer

    from transformers import AutoTokenizer, AutoModelForCausalLM
    
    tokenizer = AutoTokenizer.from_pretrained("meta-llama/Meta-Llama-3-8B")
    model = AutoModelForCausalLM.from_pretrained("meta-llama/Meta-Llama-3-8B")
    
    • 1
    • 2
    • 3
    • 4
    准备数据集

    加载Spider数据集:

    from datasets import load_dataset
    
    dataset = load_dataset("spider")
    train_data = dataset['train']
    valid_data = dataset['validation']
    
    • 1
    • 2
    • 3
    • 4
    • 5
    LORA微调配置

    配置LORA参数并应用到模型上:

    from peft import LoraConfig, get_peft_model
    
    lora_config = LoraConfig(
        r=16,
        lora_alpha=32,
        lora_dropout=0.1,
        target_modules=["q_proj", "v_proj"]
    )
    
    model = get_peft_model(model, lora_config)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    数据预处理

    定义数据预处理函数并处理训练和验证数据:

    def preprocess_function(examples):
        inputs = [f"translate English to SQL: {query}" for query in examples["question"]]
        targets = [sql for sql in examples["query"]]
        model_inputs = tokenizer(inputs, max_length=512, truncation=True, padding="max_length", return_tensors="pt")
        labels = tokenizer(targets, max_length=512, truncation=True, padding="max_length", return_tensors="pt")
        model_inputs["labels"] = labels["input_ids"]
        return model_inputs
    
    train_dataset = train_data.map(preprocess_function, batched=True)
    valid_dataset = valid_data.map(preprocess_function, batched=True)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    自定义训练循环

    实现自定义训练循环:

    import torch
    from torch.utils.data import DataLoader
    
    train_dataloader = DataLoader(train_dataset, batch_size=8, shuffle=True)
    valid_dataloader = DataLoader(valid_dataset, batch_size=8)
    
    optimizer = torch.optim.AdamW(model.parameters(), lr=5e-5)
    
    for epoch in range(3):  # 假设训练3个epoch
        model.train()
        for batch in train_dataloader:
            optimizer.zero_grad()
            outputs = model(input_ids=batch['input_ids'], labels=batch['labels'])
            loss = outputs.loss
            loss.backward()
            optimizer.step()
        
        model.eval()
        eval_loss = 0
        with torch.no_grad():
            for batch in valid_dataloader:
                outputs = model(input_ids=batch['input_ids'], labels=batch['labels'])
                eval_loss += outputs.loss.item()
        print(f"Epoch {epoch+1}, Validation Loss: {eval_loss / len(valid_dataloader)}")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    结合RAG技术

    设置FAISS检索器,并结合检索与生成:

    import faiss
    import numpy as np
    from transformers import AutoTokenizer
    
    
    # 假设我们有一个语料库
    corpus = ["Example sentence 1.", "Example sentence 2.", "Example sentence 3."]
    
    # 将语料库句子转换为token IDs
    corpus_inputs = tokenizer(corpus, return_tensors='pt', padding=True, truncation=True)
    
    # 使用模型生成语料库句子的embedding
    with torch.no_grad():
        corpus_outputs = model(**corpus_inputs)
    
    # 获取最后一层隐藏状态的平均值作为句子的embedding
    corpus_embeddings = torch.mean(corpus_outputs.last_hidden_state, dim=1).numpy()
    
    # 构建FAISS索引
    index = faiss.IndexFlatL2(corpus_embeddings.shape[1])
    index.add(corpus_embeddings)
    
    # 结合RAG技术与检索
    def retrieve_and_generate(query, context_size=3, max_length=128, num_return_sequences=1):
        # 使用FAISS检索最相关的文档
        query_inputs = tokenizer(query, return_tensors='pt', padding=True, truncation=True)
        with torch.no_grad():
            query_embedding = model(**query_inputs).last_hidden_state.mean(dim=1).numpy()
        D, I = index.search(query_embedding, k=context_size)
        retrieved_docs = [corpus[i] for i in I[0]]
        context = " ".join(retrieved_docs)
        
        # 将检索到的文档与查询结合
        input_with_context = f"{context} {query}"
        
        # 生成查询的SQL
        inputs = tokenizer(input_with_context, return_tensors="pt", max_length=max_length, truncation=True)
        with torch.no_grad():
            outputs = model.generate(**inputs, num_return_sequences=num_return_sequences)
        
        # 返回生成的SQL查询
        return tokenizer.decode(outputs[0], skip_special_tokens=True)
    
    
    # 示例
    query = "Show all users"
    sql_query = retrieve_and_generate(query)
    print(sql_query)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    结合Agent技术

    实现NLU组件和对话管理:

    from transformers import pipeline
    
    nlu = pipeline("ner")
    
    def parse_input(user_input):
        entities = nlu(user_input)
        if "users" in user_input.lower():
            return "SELECT * FROM users"
        else:
            return "Query not recognized"
    
    class Agent:
        def __init__(self):
            self.context = ""
        
        def handle_input(self, user_input):
            self.context += f" {user_input}"
            sql_query = parse_input(self.context)
            return sql_query
    
    agent = Agent()
    user_input = "Show all users"
    response = agent.handle_input(user_input)
    print(response)  # 输出: SELECT * FROM users
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    模型保存与部署

    保存微调后的模型:

    model.save_pretrained("./finetuned_llama3")
    tokenizer.save_pretrained("./finetuned_llama3")
    
    • 1
    • 2

    总结

    通过以上步骤,我们从头到尾实现了使用LORA微调LLaMA3模型,并结合RAG和Agent技术进行Text2SQL任务。这个流程包括环境准备、数据预处理、自定义训练循环、RAG技术整合、Agent实现,以及最终的模型保存。

  • 相关阅读:
    VR模拟仿真实验课件可视化编辑,提高学员实操水平
    Vue3中使用provide和inject依赖注入完成父组件和孙子组件之间参数传递
    记录 K8S 挂了的解决经过
    Linux 之网络相关命令及配置文件
    什么是设计模式?你了解的设计模式是什么?
    MySQL_05:排序和分页
    cv2的方法报黄色解决办法(OpenCV)
    Python 实现Excel自动化办公(上)
    建模的常用手段:组合和聚合
    金属带宽度测量方案
  • 原文地址:https://blog.csdn.net/weixin_43982238/article/details/139126858