From ebed0efb8856a44333c0d192c559f940aaa3acb7 Mon Sep 17 00:00:00 2001 From: jeffxtang Date: Tue, 24 Jun 2025 18:13:50 -0700 Subject: [PATCH 01/78] text2sql eval and ft tools --- .../coding/text2sql/tool/README.md | 127 ++++++ .../text2sql/tool/data/download_dev_unzip.sh | 9 + .../tool/data/download_train_unzip.sh | 9 + .../tool/fine_tuning/create_sft_dataset.py | 169 +++++++ .../text2sql/tool/fine_tuning/trl_sft.py | 83 ++++ .../coding/text2sql/tool/llama_eval.sh | 54 +++ .../coding/text2sql/tool/llama_text2sql.py | 416 ++++++++++++++++++ .../coding/text2sql/tool/requirements.txt | 19 + .../coding/text2sql/tool/text2sql_eval.py | 199 +++++++++ 9 files changed, 1085 insertions(+) create mode 100644 end-to-end-use-cases/coding/text2sql/tool/README.md create mode 100644 end-to-end-use-cases/coding/text2sql/tool/data/download_dev_unzip.sh create mode 100644 end-to-end-use-cases/coding/text2sql/tool/data/download_train_unzip.sh create mode 100644 end-to-end-use-cases/coding/text2sql/tool/fine_tuning/create_sft_dataset.py create mode 100644 end-to-end-use-cases/coding/text2sql/tool/fine_tuning/trl_sft.py create mode 100644 end-to-end-use-cases/coding/text2sql/tool/llama_eval.sh create mode 100644 end-to-end-use-cases/coding/text2sql/tool/llama_text2sql.py create mode 100644 end-to-end-use-cases/coding/text2sql/tool/requirements.txt create mode 100644 end-to-end-use-cases/coding/text2sql/tool/text2sql_eval.py diff --git a/end-to-end-use-cases/coding/text2sql/tool/README.md b/end-to-end-use-cases/coding/text2sql/tool/README.md new file mode 100644 index 000000000..519b14f03 --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/tool/README.md @@ -0,0 +1,127 @@ +# Text2SQL Evaluation and Fine-Tuning Tools for Llama Models + +This folder contains the scripts for evaluating Llama models on Text2SQL tasks, preparing supervised and reasoning datasets, fine-tuning Llama 3.1 8B with the datasets, and evaluating the fine-tuned model. The original dataset and scripts are from the BIRD-SQL [benchmark](https://bird-bench.github.io) and [repo](https://github.com/AlibabaResearch/DAMO-ConvAI/tree/main/bird), but we have significantly simplified and streamlined them for Llama models hosted via Meta's [Llama API](https://llama.developer.meta.com) or [Together.ai](https://together.ai), so you can quickly evaluate how well different Llama models perform Text2SQL tasks and how to fine-tune the models for better accuracy. + +## Quick Start on Evaluating Llama on Text2SQL + +First, `cd llama-cookbook/getting-started/llama-tools/text2sql` and run `pip install -r requirements.txt` to install all the required packages. + +Then, follow the steps below to evaluate Llama 3 & 4 models on Text2SQL using the BIRD benchmark: + +1. Get the DEV dataset: +``` +cd data +sh download_dev_unzip.sh +``` + +2. Open `llama_eval.sh` and set `YOUR_API_KEY` to your [Llama API](https://llama.developer.meta.com/) key or [Together](https://api.together.ai/) API key, then uncomment a line that starts with `model=` to specify the Llama model to use for the text2sql eval. + +3. Run the evaluation script `sh llama_eval.sh`, which will use the BIRD DEV dataset (1534 examples in total) with external knowledge turned on to run the Llama model on each text question and compare the generated SQL with the gold SQL. + +After the script completes, you'll see the accuracy of the Llama model on the BIRD DEV text2sql. For example, the total accuracy is about 54.24% with `YOUR_API_KEY` set to your Llama API key and `model='Llama-3.3-70B-Instruct'`, or about 35.07% with `YOUR_API_KEY` set to your Together API key and `model=meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo`. + +*Note:* To compare your evaluated accuracy of your selected Llama model with other results in the BIRD Dev leaderboard, click [here](https://bird-bench.github.io/). + +### Supported Models + +#### Together AI Models +- meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo +- meta-llama/Llama-3.3-70B-Instruct-Turbo +- meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8 +- meta-llama/Llama-4-Scout-17B-16E-Instruct +- other Llama models hosted on Together AI + +#### Llama API Models +- Llama-3.3-8B-Instruct +- Llama-3.3-70B-Instruct +- Llama-4-Maverick-17B-128E-Instruct-FP8 +- Llama-4-Scout-17B-16E-Instruct-FP8 +- other Llama models hosted on Llama API + +## Evaluation Process + +1. **SQL Generation**: `llama_text2sql.py` sends natural language questions to the specified Llama model and collects the generated SQL queries. + +2. **SQL Execution**: `text2sql_eval.py` executes both the generated SQL and ground truth SQL against the corresponding databases, then continues with steps 3 and 4 below. + +3. **Result Comparison**: The results from executing the generated SQL are compared with the results from the ground truth SQL to determine correctness. + +4. **Accuracy Calculation**: Accuracy scores are calculated overall and broken down by difficulty levels (simple, moderate, challenging). + +## Data Format + +The evaluation data should be in JSON format with the following structure: + +```json +[ + { + "question": "Natural language question", + "db_id": "database_name", + "evidence": "External knowledge (optional)", + "SQL": "Ground truth SQL query", + "difficulty": "simple|moderate|challenging" + }, + ... +] +``` + +## Output + +The evaluation produces: +- Generated SQL queries saved to the specified output directory +- Accuracy scores printed to the console, broken down by difficulty level + + + +## Preparing Fine-tuning Dataset + +### Using the TRAIN to prepare for supervised fine-tuning + +1. Get the TRAIN dataset: +``` +cd data +sh download_train_unzip.sh +``` + +2. Create the dataset + +``` +cd fine_tuning +python create_sft_dataset.py --input_json ../data/train/train.json --db_root_path ../data/train/train_databases +``` +This will create `train_text2sql_sft_dataset.json` and `test_text2sql_sft_dataset.json` using the TRAIN set. Each line in the json files is in the conversation format ready for fine-tuning: + +``` +{"messages":[{"content":"You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement.","role":"system"},{"content":"-- DB Schema: \n\n-- External Knowledge: \n\n-- Question: ","role":"user"},{"content":"","role":"assistant"}]} +``` + +3. Supervised Fine-tuning + +First, you need to login to HuggingFace (via running `huggingface-cli login` and enter your [HF token](https://huggingface.co/settings/tokens)) and have been granted access to the [Llama 3.1 8B Instruct](https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct) model. + +Then run `python trl_sft.py` + +### Creating a reasoning dataset from the TRAIN dataset +(text2sql) jeffxtang@devgpu005:~/repos/DAMO-ConvAI/bird/llm$ python create_reasoning_dataset.py --input_json data/train/train.json --db_root_path data/train/train_databases + +(trl) jeffxtang@devgpu005:~/repos/DAMO-ConvAI/bird/llm$ python convert_dataset.py +to use ./src/text2sql_cot_dataset_train_filtered (6400) generate train_dataset_filtered.json (4480) and test_dataset_filtered.json (1920) + +Now running: +(trl) jeffxtang@devgpu005:~/repos/DAMO-ConvAI/bird/llm$ CUDA_VISIBLE_DEVICES=1 nohup with-proxy python trl_sft.py +which uses HF meta-llama/Llama-3.1-8B-Instruct and train_dataset_filtered.json and GPU 25GB: +25707MiB / 97871MiB +1%|▏ | 66/5121 [02:20<2:58:39, 2.12s/it] + +### Filtering the reasoning dataset to only include examples where the predicted SQL matches the ground truth SQL +Done: created a text2sql_cot_dataset_train_filtered dataset with 6400 examples of the predicted SQL in reasoning matching the ground truth SQL: +(text2sql) jeffxtang@devgpu005:~/repos/DAMO-ConvAI/bird/llm/src$ nohup python reasoning_ground_diff.py --input_json ../data/train/train.json --db_root_path ../data/train/train_databases + + +## Fine-tuning + +## Evaluating the fine-tuned model + +(trl) jeffxtang@devgpu005:~/repos/DAMO-ConvAI/bird/llm$ python trl_sft_infer.py + +uses test_dataset_filtered.json diff --git a/end-to-end-use-cases/coding/text2sql/tool/data/download_dev_unzip.sh b/end-to-end-use-cases/coding/text2sql/tool/data/download_dev_unzip.sh new file mode 100644 index 000000000..606696d89 --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/tool/data/download_dev_unzip.sh @@ -0,0 +1,9 @@ +wget https://bird-bench.oss-cn-beijing.aliyuncs.com/dev.zip +unzip dev.zip +rm dev.zip +rm -rf __MACOSX +cd dev_20240627 +unzip dev_databases.zip +rm dev_databases.zip +rm -rf __MACOSX +cd .. diff --git a/end-to-end-use-cases/coding/text2sql/tool/data/download_train_unzip.sh b/end-to-end-use-cases/coding/text2sql/tool/data/download_train_unzip.sh new file mode 100644 index 000000000..ea785ca50 --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/tool/data/download_train_unzip.sh @@ -0,0 +1,9 @@ +wget https://bird-bench.oss-cn-beijing.aliyuncs.com/train.zip +UNZIP_DISABLE_ZIPBOMB_DETECTION=TRUE unzip train.zip +rm train.zip +rm -rf __MACOSX +cd train +unzip train_databases.zip +rm train_databases.zip +rm -rf __MACOSX +cd .. diff --git a/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/create_sft_dataset.py b/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/create_sft_dataset.py new file mode 100644 index 000000000..d0664016a --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/create_sft_dataset.py @@ -0,0 +1,169 @@ +import argparse +import json +import os +import pdb +import pickle +import re +import sqlite3 +from typing import Dict, List, Tuple + +import sqlparse +from datasets import Dataset + +from tqdm import tqdm + + +def new_directory(path): + if not os.path.exists(path): + os.makedirs(path) + + +def nice_look_table(column_names: list, values: list): + rows = [] + # Determine the maximum width of each column + widths = [ + max(len(str(value[i])) for value in values + [column_names]) + for i in range(len(column_names)) + ] + + # Print the column names + header = "".join( + f"{column.rjust(width)} " for column, width in zip(column_names, widths) + ) + # print(header) + # Print the values + for value in values: + row = "".join(f"{str(v).rjust(width)} " for v, width in zip(value, widths)) + rows.append(row) + rows = "\n".join(rows) + final_output = header + "\n" + rows + return final_output + + +def generate_schema_prompt(db_path, num_rows=None): + # extract create ddls + """ + :param root_place: + :param db_name: + :return: + """ + full_schema_prompt_list = [] + conn = sqlite3.connect(db_path) + # Create a cursor object + cursor = conn.cursor() + cursor.execute("SELECT name FROM sqlite_master WHERE type='table'") + tables = cursor.fetchall() + schemas = {} + for table in tables: + if table == "sqlite_sequence": + continue + cursor.execute( + "SELECT sql FROM sqlite_master WHERE type='table' AND name='{}';".format( + table[0] + ) + ) + create_prompt = cursor.fetchone()[0] + schemas[table[0]] = create_prompt + if num_rows: + cur_table = table[0] + if cur_table in ["order", "by", "group"]: + cur_table = "`{}`".format(cur_table) + + cursor.execute("SELECT * FROM {} LIMIT {}".format(cur_table, num_rows)) + column_names = [description[0] for description in cursor.description] + values = cursor.fetchall() + rows_prompt = nice_look_table(column_names=column_names, values=values) + verbose_prompt = "/* \n {} example rows: \n SELECT * FROM {} LIMIT {}; \n {} \n */".format( + num_rows, cur_table, num_rows, rows_prompt + ) + schemas[table[0]] = "{} \n {}".format(create_prompt, verbose_prompt) + + for k, v in schemas.items(): + full_schema_prompt_list.append(v) + + schema_prompt = "-- DB Schema: " + "\n\n".join(full_schema_prompt_list) + + return schema_prompt + + +def generate_comment_prompt(question, knowledge=None): + knowledge_prompt = "-- External Knowledge: {}".format(knowledge) + question_prompt = "-- Question: {}".format(question) + + result_prompt = knowledge_prompt + "\n\n" + question_prompt + + return result_prompt + + +def generate_combined_prompts_one(db_path, question, knowledge=None): + schema_prompt = generate_schema_prompt(db_path, num_rows=None) + comment_prompt = generate_comment_prompt(question, knowledge) + + combined_prompts = schema_prompt + "\n\n" + comment_prompt + + return combined_prompts + + +def create_conversation(sample): + return { + "messages": [ + {"role": "system", "content": sample["messages"][0]["content"]}, + {"role": "user", "content": sample["messages"][1]["content"]}, + {"role": "assistant", "content": sample["messages"][2]["content"]}, + ] + } + + +def create_sft_dataset(input_json, db_root_path): + ds = [] + SYSTEM_PROMPT = "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement." + + for i, item in tqdm(enumerate(input_json)): + print(f"processing #{i+1}") + db_id = item["db_id"] + question = item["question"] + external_knowledge = item["evidence"] + SQL = item["SQL"] + db_path = db_root_path + "/" + item["db_id"] + "/" + item["db_id"] + ".sqlite" + print(f"{db_path=}") + prompt = generate_combined_prompts_one( + db_path, + question, + knowledge=external_knowledge, + ) + + example = { + "messages": [ + {"role": "system", "content": SYSTEM_PROMPT}, + {"role": "user", "content": prompt}, + {"role": "assistant", "content": SQL}, + ] + } + + ds.append(example) + + dataset_dict = {key: [d[key] for d in ds] for key in ds[0]} + dataset = Dataset.from_dict(dataset_dict) + # dataset.save_to_disk(f"text2sql_sft_dataset") + + dataset = dataset.map( + create_conversation, remove_columns=dataset.features, batched=False + ) + dataset = dataset.train_test_split(test_size=0.3) + + dataset["train"].to_json("train_text2sql_sft_dataset.json", orient="records") + dataset["test"].to_json("test_text2sql_sft_dataset.json", orient="records") + + +if __name__ == "__main__": + args_parser = argparse.ArgumentParser() + args_parser.add_argument("--input_json", type=str, required=True) + args_parser.add_argument("--db_root_path", type=str, required=True) + args = args_parser.parse_args() + + input_json = json.load(open(args.input_json, "r")) + db_root_path = args.db_root_path + + create_sft_dataset(input_json, db_root_path) + +# python create_sft_dataset.py --input_json ../data/train/train.json --db_root_path ../data/train/train_databases diff --git a/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/trl_sft.py b/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/trl_sft.py new file mode 100644 index 000000000..0c74180db --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/trl_sft.py @@ -0,0 +1,83 @@ +# Source: https://www.philschmid.de/fine-tune-llms-in-2024-with-trl + +import torch +from datasets import load_dataset +from peft import LoraConfig +from transformers import ( + AutoModelForCausalLM, + AutoTokenizer, + BitsAndBytesConfig, + TrainingArguments, +) +from trl import setup_chat_format, SFTTrainer + +dataset = load_dataset( + "json", data_files="train_text2sql_sft_dataset.json", split="train" +) + +model_id = "meta-llama/Llama-3.1-8B-Instruct" + +bnb_config = BitsAndBytesConfig( + load_in_4bit=True, + bnb_4bit_use_double_quant=True, + bnb_4bit_quant_type="nf4", + bnb_4bit_compute_dtype=torch.bfloat16, +) + +model = AutoModelForCausalLM.from_pretrained( + model_id, + device_map="auto", + torch_dtype=torch.bfloat16, + quantization_config=bnb_config, +) +tokenizer = AutoTokenizer.from_pretrained(model_id) + +tokenizer.padding_side = "right" + +if tokenizer.pad_token is None: + tokenizer.add_special_tokens({"pad_token": "[PAD]"}) + model.resize_token_embeddings(len(tokenizer)) + +peft_config = LoraConfig( + lora_alpha=128, + lora_dropout=0.05, + r=256, + bias="none", + target_modules="all-linear", + task_type="CAUSAL_LM", +) + +args = TrainingArguments( + output_dir="llama31-8b-text2sql-epochs-3", # directory to save and repository id + num_train_epochs=3, # number of training epochs + per_device_train_batch_size=3, # batch size per device during training + gradient_accumulation_steps=2, # number of steps before performing a backward/update pass + gradient_checkpointing=True, # use gradient checkpointing to save memory + optim="adamw_torch_fused", # use fused adamw optimizer + logging_steps=10, # log every 10 steps + save_strategy="epoch", # save checkpoint every epoch + learning_rate=2e-4, # learning rate, based on QLoRA paper + bf16=True, # use bfloat16 precision + tf32=True, # use tf32 precision + max_grad_norm=0.3, # max gradient norm based on QLoRA paper + warmup_ratio=0.03, # warmup ratio based on QLoRA paper + lr_scheduler_type="constant", # use constant learning rate scheduler + push_to_hub=True, # push model to hub + report_to="tensorboard", # report metrics to tensorboard +) + +max_seq_length = 4096 + +trainer = SFTTrainer( + model=model, + args=args, + train_dataset=dataset, + max_seq_length=max_seq_length, + tokenizer=tokenizer, + peft_config=peft_config, + packing=True, +) + +trainer.train() + +trainer.save_model() diff --git a/end-to-end-use-cases/coding/text2sql/tool/llama_eval.sh b/end-to-end-use-cases/coding/text2sql/tool/llama_eval.sh new file mode 100644 index 000000000..4f3382b3f --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/tool/llama_eval.sh @@ -0,0 +1,54 @@ +eval_path='./data/dev_20240627/dev.json' +db_root_path='./data/dev_20240627/dev_databases/' +ground_truth_path='./data/' + +#YOUR_API_KEY='xxx' +#YOUR_API_KEY='yyy' + +# Llama model on Hugging Face Hub +# https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct +YOUR_API_KEY='huggingface' +model='meta-llama/Llama-3.1-8B-Instruct' + +# Fine-tuned Llama model locally +# YOUR_API_KEY='finetuned' +# model='fine_tuning/llama31-8b-text2sql-epochs-3' + +# Llama models on Together +#model='meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo' +#model='meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo' +#model='meta-llama/Llama-3.3-70B-Instruct-Turbo' +#model='meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8' +#model='meta-llama/Llama-4-Scout-17B-16E-Instruct' + +# Llama models on Llama API +#model='Llama-3.3-8B-Instruct' +#model='Llama-3.3-70B-Instruct' +#model='Llama-4-Maverick-17B-128E-Instruct-FP8' +#model='Llama-4-Scout-17B-16E-Instruct-FP8' + +#model="llama31-8b-text-sql-epochs-25" +#model="llama31-8b-text-sql-epochs-3" +#model="llama31-8b-text-sql" + +#data_output_path="./output/$model/run_500/no_ft/v3/" +#data_output_path="./output/$model/run_500/ft_epochs-25/v3/" +data_output_path="./output/$model/" + +echo "Text2SQL using $model" +python3 -u llama_text2sql.py --db_root_path ${db_root_path} --api_key ${YOUR_API_KEY} \ +--model ${model} --eval_path ${eval_path} --data_output_path ${data_output_path} + +# Check if llama_text2sql.py exited successfully +if [ $? -eq 0 ]; then + echo "llama_text2sql.py completed successfully. Proceeding with evaluation..." + python3 -u text2sql_eval.py --db_root_path ${db_root_path} --predicted_sql_path ${data_output_path} \ + --ground_truth_path ${ground_truth_path} \ + --diff_json_path ${eval_path} + + echo "Done evaluating $model." + +else + echo "Error: llama_text2sql.py failed with exit code $?. Skipping evaluation." + exit 1 +fi diff --git a/end-to-end-use-cases/coding/text2sql/tool/llama_text2sql.py b/end-to-end-use-cases/coding/text2sql/tool/llama_text2sql.py new file mode 100644 index 000000000..e91e16f02 --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/tool/llama_text2sql.py @@ -0,0 +1,416 @@ +import argparse +import fnmatch +import json +import os +import pdb +import pickle +import re +import sqlite3 +from typing import Dict, List, Tuple + +import pandas as pd +import sqlparse + +import torch +from datasets import Dataset, load_dataset +from peft import AutoPeftModelForCausalLM +from tqdm import tqdm +from transformers import ( + AutoModelForCausalLM, + AutoTokenizer, + BitsAndBytesConfig, + pipeline, +) + + +def local_llama(prompt, pipe): + SYSTEM_PROMPT = "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement." + + messages = [ + {"content": SYSTEM_PROMPT, "role": "system"}, + {"role": "user", "content": prompt}, + ] + + raw_prompt = pipe.tokenizer.apply_chat_template( + messages, + tokenize=False, + add_generation_prompt=True, + ) + + print(f"local_llama: {raw_prompt=}") + + outputs = pipe( + raw_prompt, + max_new_tokens=10240, + do_sample=False, + temperature=0.0, + top_k=50, + top_p=0.1, + eos_token_id=pipe.tokenizer.eos_token_id, + pad_token_id=pipe.tokenizer.pad_token_id, + ) + + generated_answer = outputs[0]["generated_text"][len(raw_prompt) :].strip() + + print(f"{generated_answer=}") + return generated_answer + + +def new_directory(path): + if not os.path.exists(path): + os.makedirs(path) + + +def get_db_schemas(bench_root: str, db_name: str) -> Dict[str, str]: + """ + Read an sqlite file, and return the CREATE commands for each of the tables in the database. + """ + asdf = "database" if bench_root == "spider" else "databases" + with sqlite3.connect( + f"file:{bench_root}/{asdf}/{db_name}/{db_name}.sqlite?mode=ro", uri=True + ) as conn: + # conn.text_factory = bytes + cursor = conn.cursor() + cursor.execute("SELECT name FROM sqlite_master WHERE type='table';") + tables = cursor.fetchall() + schemas = {} + for table in tables: + cursor.execute( + "SELECT sql FROM sqlite_master WHERE type='table' AND name='{}';".format( + table[0] + ) + ) + schemas[table[0]] = cursor.fetchone()[0] + + return schemas + + +def nice_look_table(column_names: list, values: list): + rows = [] + # Determine the maximum width of each column + widths = [ + max(len(str(value[i])) for value in values + [column_names]) + for i in range(len(column_names)) + ] + + # Print the column names + header = "".join( + f"{column.rjust(width)} " for column, width in zip(column_names, widths) + ) + # print(header) + # Print the values + for value in values: + row = "".join(f"{str(v).rjust(width)} " for v, width in zip(value, widths)) + rows.append(row) + rows = "\n".join(rows) + final_output = header + "\n" + rows + return final_output + + +def generate_schema_prompt(db_path, num_rows=None): + # extract create ddls + """ + :param root_place: + :param db_name: + :return: + """ + full_schema_prompt_list = [] + conn = sqlite3.connect(db_path) + # Create a cursor object + cursor = conn.cursor() + cursor.execute("SELECT name FROM sqlite_master WHERE type='table'") + tables = cursor.fetchall() + schemas = {} + for table in tables: + if table == "sqlite_sequence": + continue + cursor.execute( + "SELECT sql FROM sqlite_master WHERE type='table' AND name='{}';".format( + table[0] + ) + ) + create_prompt = cursor.fetchone()[0] + schemas[table[0]] = create_prompt + if num_rows: + cur_table = table[0] + if cur_table in ["order", "by", "group"]: + cur_table = "`{}`".format(cur_table) + + cursor.execute("SELECT * FROM {} LIMIT {}".format(cur_table, num_rows)) + column_names = [description[0] for description in cursor.description] + values = cursor.fetchall() + rows_prompt = nice_look_table(column_names=column_names, values=values) + verbose_prompt = "/* \n {} example rows: \n SELECT * FROM {} LIMIT {}; \n {} \n */".format( + num_rows, cur_table, num_rows, rows_prompt + ) + schemas[table[0]] = "{} \n {}".format(create_prompt, verbose_prompt) + + for k, v in schemas.items(): + full_schema_prompt_list.append(v) + + schema_prompt = "-- DB Schema: " + "\n\n".join(full_schema_prompt_list) + + return schema_prompt + + +def generate_comment_prompt(question, knowledge=None): + knowledge_prompt = "-- External Knowledge: {}".format(knowledge) + question_prompt = "-- Question: {}".format(question) + + result_prompt = knowledge_prompt + "\n\n" + question_prompt + + return result_prompt + + +def generate_combined_prompts_one(db_path, question, knowledge=None): + schema_prompt = generate_schema_prompt(db_path, num_rows=None) + comment_prompt = generate_comment_prompt(question, knowledge) + + combined_prompts = schema_prompt + "\n\n" + comment_prompt + + return combined_prompts + + +def cloud_llama(api_key, model, prompt, max_tokens, temperature, stop): + try: + if model.startswith("meta-llama/"): + llm = ChatTogether( + model=model, + temperature=0, + ) + answer = llm.invoke(prompt).content + else: + client = LlamaAPIClient() + + response = client.chat.completions.create( + model=model, + messages=[{"role": "user", "content": prompt}], + temperature=0, + ) + answer = response.completion_message.content.text + + pattern = re.compile(r"```sql\n*(.*?)```", re.DOTALL) + matches = pattern.findall(answer) + if matches != []: + result = matches[0] + else: + result = answer + + print(result) + except Exception as e: + result = "error:{}".format(e) + print(f"{result=}") + return result + + +def huggingface_finetuned(api_key, model): + if api_key == "finetuned": + model_id = model + model = AutoPeftModelForCausalLM.from_pretrained( + model_id, device_map="auto", torch_dtype=torch.float16 + ) + tokenizer = AutoTokenizer.from_pretrained(model_id) + + # TODO: uncomment to see if it makes a difference + tokenizer.padding_side = "right" # to prevent warnings + + if tokenizer.pad_token is None: + tokenizer.add_special_tokens({"pad_token": "[PAD]"}) + model.resize_token_embeddings(len(tokenizer)) + + elif api_key == "huggingface": + model_id = model + bnb_config = BitsAndBytesConfig( + load_in_4bit=True, + bnb_4bit_use_double_quant=True, + bnb_4bit_quant_type="nf4", + bnb_4bit_compute_dtype=torch.bfloat16, + ) + model = AutoModelForCausalLM.from_pretrained( + model_id, + device_map="auto", + # attn_implementation="flash_attention_2", + torch_dtype=torch.bfloat16, + quantization_config=bnb_config, + ) + tokenizer = AutoTokenizer.from_pretrained(model_id) + + pipe = pipeline("text-generation", model=model, tokenizer=tokenizer) + return pipe + + +def collect_response_from_llama( + db_path_list, question_list, api_key, model, knowledge_list=None +): + """ + :param db_path: str + :param question_list: [] + :return: dict of responses + """ + responses_dict = {} + response_list = [] + + if api_key in ["huggingface", "finetuned"]: + pipe = huggingface_finetuned(api_key=api_key, model=model) + + for i, question in tqdm(enumerate(question_list)): + print( + "--------------------- processing question #{}---------------------".format( + i + 1 + ) + ) + print("the question is: {}".format(question)) + + if knowledge_list: + cur_prompt = generate_combined_prompts_one( + db_path=db_path_list[i], question=question, knowledge=knowledge_list[i] + ) + else: + cur_prompt = generate_combined_prompts_one( + db_path=db_path_list[i], question=question + ) + + if api_key in ["huggingface", "finetuned"]: + plain_result = local_llama(prompt=cur_prompt, pipe=pipe) + else: + plain_result = cloud_llama( + api_key=api_key, + model=model, + prompt=cur_prompt, + max_tokens=4096, + temperature=0, + stop=["--", "\n\n", ";", "#"], + ) + if type(plain_result) == str: + sql = plain_result + else: + sql = "SELECT" + plain_result["choices"][0]["text"] + + # responses_dict[i] = sql + db_id = db_path_list[i].split("/")[-1].split(".sqlite")[0] + sql = ( + sql + "\t----- bird -----\t" + db_id + ) # to avoid unpredicted \t appearing in codex results + response_list.append(sql) + + return response_list + + +def question_package(data_json, knowledge=False): + question_list = [] + for data in data_json: + question_list.append(data["question"]) + + return question_list + + +def knowledge_package(data_json, knowledge=False): + knowledge_list = [] + for data in data_json: + knowledge_list.append(data["evidence"]) + + return knowledge_list + + +def decouple_question_schema(datasets, db_root_path): + question_list = [] + db_path_list = [] + knowledge_list = [] + for i, data in enumerate(datasets): + question_list.append(data["question"]) + cur_db_path = db_root_path + data["db_id"] + "/" + data["db_id"] + ".sqlite" + db_path_list.append(cur_db_path) + knowledge_list.append(data["evidence"]) + + return question_list, db_path_list, knowledge_list + + +def generate_sql_file(sql_lst, output_path=None): + result = {} + for i, sql in enumerate(sql_lst): + result[i] = sql + + if output_path: + directory_path = os.path.dirname(output_path) + new_directory(directory_path) + json.dump(result, open(output_path, "w"), indent=4) + + return result + + +if __name__ == "__main__": + args_parser = argparse.ArgumentParser() + args_parser.add_argument("--eval_path", type=str, default="") + args_parser.add_argument("--mode", type=str, default="dev") + args_parser.add_argument("--test_path", type=str, default="") + args_parser.add_argument("--use_knowledge", type=str, default="True") + args_parser.add_argument("--db_root_path", type=str, default="") + args_parser.add_argument("--api_key", type=str, required=True) + args_parser.add_argument("--model", type=str, required=True) + args_parser.add_argument("--data_output_path", type=str) + args = args_parser.parse_args() + + if not args.api_key in ["huggingface", "finetuned"]: + if args.model.startswith("meta-llama/"): # Llama model on together + + os.environ["TOGETHER_API_KEY"] = args.api_key + llm = ChatTogether( + model=args.model, + temperature=0, + ) + try: + response = llm.invoke("125*125 is?").content + print(f"{response=}") + except Exception as exception: + print(f"{exception=}") + exit(1) + else: # Llama model on Llama API + os.environ["LLAMA_API_KEY"] = args.api_key + + try: + client = LlamaAPIClient() + + response = client.chat.completions.create( + model=args.model, + messages=[{"role": "user", "content": "125*125 is?"}], + temperature=0, + ) + answer = response.completion_message.content.text + + print(f"{answer=}") + except Exception as exception: + print(f"{exception=}") + exit(1) + + eval_data = json.load(open(args.eval_path, "r")) + # '''for debug''' + # eval_data = eval_data[:3] + # '''for debug''' + + question_list, db_path_list, knowledge_list = decouple_question_schema( + datasets=eval_data, db_root_path=args.db_root_path + ) + assert len(question_list) == len(db_path_list) == len(knowledge_list) + + if args.use_knowledge == "True": + responses = collect_response_from_llama( + db_path_list=db_path_list, + question_list=question_list, + api_key=args.api_key, + model=args.model, + knowledge_list=knowledge_list, + ) + else: + responses = collect_response_from_llama( + db_path_list=db_path_list, + question_list=question_list, + api_key=args.api_key, + model=args.model, + knowledge_list=None, + ) + + output_name = args.data_output_path + "predict_" + args.mode + ".json" + + generate_sql_file(sql_lst=responses, output_path=output_name) + + print("successfully collect results from {}".format(args.model)) diff --git a/end-to-end-use-cases/coding/text2sql/tool/requirements.txt b/end-to-end-use-cases/coding/text2sql/tool/requirements.txt new file mode 100644 index 000000000..7a0b1496b --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/tool/requirements.txt @@ -0,0 +1,19 @@ +llama_api_client +langchain-together +sqlparse +torch==2.4.1 +tensorboard +liger-kernel==0.4.2 +setuptools +deepspeed==0.15.4 +# openai +# lm-eval[api]==0.4.5 +transformers==4.46.3 +datasets==3.6.0 +accelerate==1.1.1 +bitsandbytes==0.44.1 +trl==0.12.1 +peft==0.13.2 +lighteval==0.6.2 +hf-transfer==0.1.8 +func_timeout \ No newline at end of file diff --git a/end-to-end-use-cases/coding/text2sql/tool/text2sql_eval.py b/end-to-end-use-cases/coding/text2sql/tool/text2sql_eval.py new file mode 100644 index 000000000..2b582d9af --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/tool/text2sql_eval.py @@ -0,0 +1,199 @@ +import argparse +import json +import multiprocessing as mp +import re +import sqlite3 +import sys + +from func_timeout import func_timeout, FunctionTimedOut + + +def load_json(dir): + with open(dir, "r") as j: + contents = json.loads(j.read()) + return contents + + +def result_callback(result): + exec_result.append(result) + + +def execute_sql(predicted_sql, ground_truth, db_path): + conn = sqlite3.connect(db_path) + # Connect to the database + cursor = conn.cursor() + cursor.execute(predicted_sql) + predicted_res = cursor.fetchall() + cursor.execute(ground_truth) + ground_truth_res = cursor.fetchall() + res = 0 + if set(predicted_res) == set(ground_truth_res): + res = 1 + else: + print( + f"\n\n==== INCORRECT SQL GENERATED ====\n{predicted_sql=}\n{predicted_res=}\n{ground_truth=}\n{ground_truth_res=}\n======\n\n" + ) + + return res + + +def execute_model(predicted_sql, ground_truth, db_place, idx, meta_time_out): + try: + res = func_timeout( + meta_time_out, execute_sql, args=(predicted_sql, ground_truth, db_place) + ) + except KeyboardInterrupt: + sys.exit(0) + except FunctionTimedOut: + result = [(f"timeout",)] + res = 0 + except Exception as e: + result = [(f"error",)] # possibly len(query) > 512 or not executable + res = 0 + result = {"sql_idx": idx, "res": res} + return result + + +def package_sqls(sql_path, db_root_path, mode="gpt", data_mode="dev"): + clean_sqls = [] + db_path_list = [] + if mode == "gpt": + sql_data = json.load(open(sql_path + "predict_" + data_mode + ".json", "r")) + for idx, sql_str in sql_data.items(): + if type(sql_str) == str: + sql, db_name = sql_str.split("\t----- bird -----\t") + else: + sql, db_name = " ", "financial" + clean_sqls.append(sql) + + db_path_list.append(db_root_path + db_name + "/" + db_name + ".sqlite") + + elif mode == "gt": # ground truth + items = json.load(open(db_root_path + "/../dev.json")) + + for item in items: + sql = item["SQL"] + db_name = item["db_id"] + clean_sqls.append(sql) + db_path_list.append(db_root_path + db_name + "/" + db_name + ".sqlite") + + return clean_sqls, db_path_list + + +def run_sqls_parallel(sqls, db_places, num_cpus=1, meta_time_out=30.0): + pool = mp.Pool(processes=num_cpus) + for i, sql_pair in enumerate(sqls): + + predicted_sql, ground_truth = sql_pair + pool.apply_async( + execute_model, + args=(predicted_sql, ground_truth, db_places[i], i, meta_time_out), + callback=result_callback, + ) + pool.close() + pool.join() + + +def sort_results(list_of_dicts): + return sorted(list_of_dicts, key=lambda x: x["sql_idx"]) + + +def compute_acc_by_diff(exec_results, diff_json_path): + num_queries = len(exec_results) + results = [res["res"] for res in exec_results] + contents = load_json(diff_json_path) + + simple_results, moderate_results, challenging_results = [], [], [] + + for i, content in enumerate(contents): + if content["difficulty"] == "simple": + simple_results.append(exec_results[i]) + + if content["difficulty"] == "moderate": + moderate_results.append(exec_results[i]) + + if content["difficulty"] == "challenging": + challenging_results.append(exec_results[i]) + + simple_acc = sum([res["res"] for res in simple_results]) / len(simple_results) + moderate_acc = sum([res["res"] for res in moderate_results]) / len(moderate_results) + challenging_acc = ( + 0 + if len(challenging_results) == 0 + else sum([res["res"] for res in challenging_results]) / len(challenging_results) + ) + all_acc = sum(results) / num_queries + count_lists = [ + len(simple_results), + len(moderate_results), + len(challenging_results), + num_queries, + ] + return ( + simple_acc * 100, + moderate_acc * 100, + challenging_acc * 100, + all_acc * 100, + count_lists, + ) + + +def print_data(score_lists, count_lists): + levels = ["simple", "moderate", "challenging", "total"] + print("{:20} {:20} {:20} {:20} {:20}".format("", *levels)) + print("{:20} {:<20} {:<20} {:<20} {:<20}".format("count", *count_lists)) + + print( + "====================================== ACCURACY =====================================" + ) + print( + "{:20} {:<20.2f} {:<20.2f} {:<20.2f} {:<20.2f}".format("accuracy", *score_lists) + ) + + +if __name__ == "__main__": + args_parser = argparse.ArgumentParser() + args_parser.add_argument( + "--predicted_sql_path", type=str, required=True, default="" + ) + args_parser.add_argument("--ground_truth_path", type=str, required=True, default="") + args_parser.add_argument("--data_mode", type=str, default="dev") + args_parser.add_argument("--db_root_path", type=str, required=True, default="") + args_parser.add_argument("--num_cpus", type=int, default=1) + args_parser.add_argument("--meta_time_out", type=float, default=30.0) + args_parser.add_argument("--mode_gt", type=str, default="gt") + args_parser.add_argument("--mode_predict", type=str, default="gpt") + args_parser.add_argument("--difficulty", type=str, default="simple") + args_parser.add_argument("--diff_json_path", type=str, default="") + args = args_parser.parse_args() + exec_result = [] + + pred_queries, db_paths = package_sqls( + args.predicted_sql_path, + args.db_root_path, + mode=args.mode_predict, + data_mode=args.data_mode, + ) + # generate gt sqls: + gt_queries, db_paths_gt = package_sqls( + args.ground_truth_path, args.db_root_path, mode="gt", data_mode=args.data_mode + ) + + query_pairs = list(zip(pred_queries, gt_queries)) + run_sqls_parallel( + query_pairs, + db_places=db_paths, + num_cpus=args.num_cpus, + meta_time_out=args.meta_time_out, + ) + exec_result = sort_results(exec_result) + + print("Evaluating statistics...") + simple_acc, moderate_acc, challenging_acc, acc, count_lists = compute_acc_by_diff( + exec_result, args.diff_json_path + ) + score_lists = [simple_acc, moderate_acc, challenging_acc, acc] + print_data(score_lists, count_lists) + print( + "===========================================================================================" + ) From edcf746ed9556eabcc5a90d791ee6b1b7962a3a4 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Wed, 25 Jun 2025 13:19:01 -0700 Subject: [PATCH 02/78] script and README update --- .../coding/text2sql/tool/README.md | 52 +++++++++++++++---- .../text2sql/tool/fine_tuning/trl_sft.py | 4 +- .../coding/text2sql/tool/llama_eval.sh | 20 ++++--- .../coding/text2sql/tool/llama_text2sql.py | 3 +- 4 files changed, 54 insertions(+), 25 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/tool/README.md b/end-to-end-use-cases/coding/text2sql/tool/README.md index 519b14f03..905b9a605 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/README.md +++ b/end-to-end-use-cases/coding/text2sql/tool/README.md @@ -22,6 +22,11 @@ After the script completes, you'll see the accuracy of the Llama model on the BI *Note:* To compare your evaluated accuracy of your selected Llama model with other results in the BIRD Dev leaderboard, click [here](https://bird-bench.github.io/). +Llama 3.3 70b: 54.69% - Llama API: 54.11%; Together: 54.63% +Llama-3.1-405B: Together: 55.80% - Together: 57.17% +Llama 4 Scout: 43.94% - Llama API: 44.39% +Llama 4 Maverick: 41.46% - Llama API: 44.00% + ### Supported Models #### Together AI Models @@ -99,7 +104,43 @@ This will create `train_text2sql_sft_dataset.json` and `test_text2sql_sft_datase First, you need to login to HuggingFace (via running `huggingface-cli login` and enter your [HF token](https://huggingface.co/settings/tokens)) and have been granted access to the [Llama 3.1 8B Instruct](https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct) model. -Then run `python trl_sft.py` +Then run `python trl_sft.py`. After the fine-tuning completes, you'll see the fine-tuned model saved to `llama31-8b-text2sql-fine_tuning`. + +After running `tensorboard --logdir ./llama31-8b-text2sql-fine_tuning` you can open `http://localhost:6006` to see the train loss chat etc: + +```markdown +![train loss](train_loss.png) + + +## Evaluating the fine-tuned model + +First, modify `llama_eval.sh` to use the fine-tuned model: + + +```markdown +YOUR_API_KEY='finetuned' +model='fine_tuning/llama31-8b-text2sql' + + +Then run `sh llama_eval.sh` to evaluate the fine-tuned model. The accuracy on the first 500 examples of the BIRD DEV dataset is about 25.60%. This is a significant improvement over the original Llama 3.1 8B Instruct model, which has an accuracy of about 10.60% on the same examples - you can confirm this by comparing the fine-tuned model's accuracy above with the original model's accuracy by first modifying `llama_eval.sh` to use the original model: + +```markdown +YOUR_API_KEY='huggingface' +model='meta-llama/Llama-3.1-8B-Instruct' + + +Then running `sh llama_eval.sh` to evaluate the original model. + +Note that this is using the 4-bit quantized Llama 3.1 8b model to reduce the memory footprint and improve the efficiency, as shown in the code nippet of llama_text2sql.py: + +```markdown + bnb_config = BitsAndBytesConfig( + load_in_4bit=True, + bnb_4bit_use_double_quant=True, + bnb_4bit_quant_type="nf4", + bnb_4bit_compute_dtype=torch.bfloat16, + ) + ### Creating a reasoning dataset from the TRAIN dataset (text2sql) jeffxtang@devgpu005:~/repos/DAMO-ConvAI/bird/llm$ python create_reasoning_dataset.py --input_json data/train/train.json --db_root_path data/train/train_databases @@ -116,12 +157,3 @@ which uses HF meta-llama/Llama-3.1-8B-Instruct and train_dataset_filtered.json a ### Filtering the reasoning dataset to only include examples where the predicted SQL matches the ground truth SQL Done: created a text2sql_cot_dataset_train_filtered dataset with 6400 examples of the predicted SQL in reasoning matching the ground truth SQL: (text2sql) jeffxtang@devgpu005:~/repos/DAMO-ConvAI/bird/llm/src$ nohup python reasoning_ground_diff.py --input_json ../data/train/train.json --db_root_path ../data/train/train_databases - - -## Fine-tuning - -## Evaluating the fine-tuned model - -(trl) jeffxtang@devgpu005:~/repos/DAMO-ConvAI/bird/llm$ python trl_sft_infer.py - -uses test_dataset_filtered.json diff --git a/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/trl_sft.py b/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/trl_sft.py index 0c74180db..e6c123692 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/trl_sft.py +++ b/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/trl_sft.py @@ -48,8 +48,8 @@ ) args = TrainingArguments( - output_dir="llama31-8b-text2sql-epochs-3", # directory to save and repository id - num_train_epochs=3, # number of training epochs + output_dir="llama31-8b-text2sql-epochs-20", # directory to save and repository id + num_train_epochs=20, # number of training epochs per_device_train_batch_size=3, # batch size per device during training gradient_accumulation_steps=2, # number of steps before performing a backward/update pass gradient_checkpointing=True, # use gradient checkpointing to save memory diff --git a/end-to-end-use-cases/coding/text2sql/tool/llama_eval.sh b/end-to-end-use-cases/coding/text2sql/tool/llama_eval.sh index 4f3382b3f..34597a428 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/llama_eval.sh +++ b/end-to-end-use-cases/coding/text2sql/tool/llama_eval.sh @@ -2,25 +2,25 @@ eval_path='./data/dev_20240627/dev.json' db_root_path='./data/dev_20240627/dev_databases/' ground_truth_path='./data/' -#YOUR_API_KEY='xxx' -#YOUR_API_KEY='yyy' - # Llama model on Hugging Face Hub # https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct -YOUR_API_KEY='huggingface' -model='meta-llama/Llama-3.1-8B-Instruct' +# YOUR_API_KEY='huggingface' +# model='meta-llama/Llama-3.1-8B-Instruct' # Fine-tuned Llama model locally -# YOUR_API_KEY='finetuned' -# model='fine_tuning/llama31-8b-text2sql-epochs-3' +#YOUR_API_KEY='finetuned' +#model='fine_tuning/llama31-8b-text2sql-epochs-3' +#model='fine_tuning/llama31-8b-text2sql-epochs-8' +YOUR_API_KEY='xxx' # Llama models on Together #model='meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo' #model='meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo' -#model='meta-llama/Llama-3.3-70B-Instruct-Turbo' +model='meta-llama/Llama-3.3-70B-Instruct-Turbo' #model='meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8' #model='meta-llama/Llama-4-Scout-17B-16E-Instruct' +#YOUR_API_KEY='yyy' # Llama models on Llama API #model='Llama-3.3-8B-Instruct' #model='Llama-3.3-70B-Instruct' @@ -31,9 +31,7 @@ model='meta-llama/Llama-3.1-8B-Instruct' #model="llama31-8b-text-sql-epochs-3" #model="llama31-8b-text-sql" -#data_output_path="./output/$model/run_500/no_ft/v3/" -#data_output_path="./output/$model/run_500/ft_epochs-25/v3/" -data_output_path="./output/$model/" +data_output_path="./output/$model/v2/" echo "Text2SQL using $model" python3 -u llama_text2sql.py --db_root_path ${db_root_path} --api_key ${YOUR_API_KEY} \ diff --git a/end-to-end-use-cases/coding/text2sql/tool/llama_text2sql.py b/end-to-end-use-cases/coding/text2sql/tool/llama_text2sql.py index e91e16f02..ffcb610ec 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/llama_text2sql.py +++ b/end-to-end-use-cases/coding/text2sql/tool/llama_text2sql.py @@ -13,6 +13,7 @@ import torch from datasets import Dataset, load_dataset +from langchain_together import ChatTogether from peft import AutoPeftModelForCausalLM from tqdm import tqdm from transformers import ( @@ -211,7 +212,6 @@ def huggingface_finetuned(api_key, model): ) tokenizer = AutoTokenizer.from_pretrained(model_id) - # TODO: uncomment to see if it makes a difference tokenizer.padding_side = "right" # to prevent warnings if tokenizer.pad_token is None: @@ -229,7 +229,6 @@ def huggingface_finetuned(api_key, model): model = AutoModelForCausalLM.from_pretrained( model_id, device_map="auto", - # attn_implementation="flash_attention_2", torch_dtype=torch.bfloat16, quantization_config=bnb_config, ) From 76a8caf6967e5468d9bf56ef1a368d861bf177db Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Wed, 25 Jun 2025 17:40:18 -0700 Subject: [PATCH 03/78] script to create reasoning dataset; llama_text2sql.py and requirements update --- .../fine_tuning/create_reasoning_dataset.py | 228 ++++++++++++++++++ .../coding/text2sql/tool/llama_text2sql.py | 10 +- .../coding/text2sql/tool/requirements.txt | 6 +- 3 files changed, 238 insertions(+), 6 deletions(-) create mode 100644 end-to-end-use-cases/coding/text2sql/tool/fine_tuning/create_reasoning_dataset.py diff --git a/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/create_reasoning_dataset.py b/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/create_reasoning_dataset.py new file mode 100644 index 000000000..ebb95b363 --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/create_reasoning_dataset.py @@ -0,0 +1,228 @@ +import argparse +import json +import os +import pdb +import pickle +import re +import sqlite3 +from typing import Dict, List, Tuple + +import sqlparse +from datasets import Dataset + +from langchain_together import ChatTogether +from llama_api_client import LlamaAPIClient +from tqdm import tqdm + + +if ( + os.environ.get("LLAMA_API_KEY", "") == "" + and os.environ.get("TOGETHER_API_KEY", "") == "" +): + print( + "Please set the environment variable LLAMA_API_KEY or TOGETHER_API_KEY to your API key." + ) + exit(1) + + +if os.environ.get("LLAMA_API_KEY", "") != "": # Llama model on Llama API + try: + client = LlamaAPIClient(api_key=os.environ["LLAMA_API_KEY"]) + + response = client.chat.completions.create( + model="Llama-3.3-70B-Instruct", + messages=[{"role": "user", "content": "125*125 is?"}], + temperature=0, + ) + answer = response.completion_message.content.text + except Exception as exception: + print(f"Invalid LLAMA_API_KEY {exception=}") + +if os.environ.get("TOGETHER_API_KEY", "") != "": # Llama model on together + llm = ChatTogether( + model="meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo", + temperature=0, + ) + try: + answer = llm.invoke("125*125 is?").content + except Exception as exception: + print(f"Invalid TOGETHER_API_KEY - {exception=}") + exit(1) + + +def llama(prompt, model="Llama-3.3-70B-Instruct"): + + if os.environ["LLAMA_API_KEY"] != "": + client = LlamaAPIClient(api_key=os.environ["LLAMA_API_KEY"]) + response = client.chat.completions.create( + model=model, messages=[{"role": "user", "content": prompt}], temperature=0 + ) + return response.completion_message.content.text + else: + llm = ChatTogether( + model="meta-llama/Llama-3.3-70B-Instruct-Turbo", + temperature=0, + ) + answer = llm.invoke(prompt).content + return answer + + +def new_directory(path): + if not os.path.exists(path): + os.makedirs(path) + + +def nice_look_table(column_names: list, values: list): + rows = [] + # Determine the maximum width of each column + widths = [ + max(len(str(value[i])) for value in values + [column_names]) + for i in range(len(column_names)) + ] + + # Print the column names + header = "".join( + f"{column.rjust(width)} " for column, width in zip(column_names, widths) + ) + # Print the values + for value in values: + row = "".join(f"{str(v).rjust(width)} " for v, width in zip(value, widths)) + rows.append(row) + rows = "\n".join(rows) + final_output = header + "\n" + rows + return final_output + + +def generate_schema_prompt(db_path, num_rows=None): + # extract create ddls + """ + :param root_place: + :param db_name: + :return: + """ + full_schema_prompt_list = [] + conn = sqlite3.connect(db_path) + # Create a cursor object + cursor = conn.cursor() + cursor.execute("SELECT name FROM sqlite_master WHERE type='table'") + tables = cursor.fetchall() + schemas = {} + for table in tables: + if table == "sqlite_sequence": + continue + cursor.execute( + "SELECT sql FROM sqlite_master WHERE type='table' AND name='{}';".format( + table[0] + ) + ) + create_prompt = cursor.fetchone()[0] + schemas[table[0]] = create_prompt + if num_rows: + cur_table = table[0] + if cur_table in ["order", "by", "group"]: + cur_table = "`{}`".format(cur_table) + + cursor.execute("SELECT * FROM {} LIMIT {}".format(cur_table, num_rows)) + column_names = [description[0] for description in cursor.description] + values = cursor.fetchall() + rows_prompt = nice_look_table(column_names=column_names, values=values) + verbose_prompt = "/* \n {} example rows: \n SELECT * FROM {} LIMIT {}; \n {} \n */".format( + num_rows, cur_table, num_rows, rows_prompt + ) + schemas[table[0]] = "{} \n {}".format(create_prompt, verbose_prompt) + + for k, v in schemas.items(): + full_schema_prompt_list.append(v) + + schema_prompt = "\n\n".join(full_schema_prompt_list) + + return schema_prompt + + +def create_cot_dataset(input_json, db_root_path): + cot_list = [] + diff = 0 + for i, item in enumerate(input_json): + print(f"processing #{i+1}") + + db_id = item["db_id"] + question = item["question"] + external_knowledge = item["evidence"] + gold_SQL = item["SQL"].strip() + db_path = db_root_path + "/" + item["db_id"] + "/" + item["db_id"] + ".sqlite" + # print(f"{db_path=}") + db_schema = generate_schema_prompt(db_path) + + prompt_to_generate_reasoning = """ + You are a text to SQL query translator. Based on the DB Schema and External Knowledge, given the Text Question Input and its Gold SQL Output below, generate the step-by-step reasoning to infer the Gold SQL Output from the Text Question Input. + + -- DB Schema: {db_schema} + -- External Knowledge: {external_knowledge} + -- Text Question Input: {question} + -- Gold SQL Output: {gold_SQL} + + Your response should be as follows:\n\n + Let me think through this step by step:\n\n1. First, I need to consider...\n2. Then...\n3. Next...\n...\n\nFinally, the SQL statement for the text question is: + ```sql ...```\n + + """ + + prompt_to_generate_reasoning = ( + prompt_to_generate_reasoning.replace("{db_schema}", db_schema) + .replace("{external_knowledge}", external_knowledge) + .replace("{question}", question) + .replace("{gold_SQL}", gold_SQL) + ) + reasoning = llama(prompt_to_generate_reasoning) + # print(f"\n======\n{prompt_to_generate_reasoning=}\n\n") + # print(f"\n======\n{reasoning=}\n\n") + + pattern = re.compile(r"```sql\n*(.*?)```", re.DOTALL) + matches = pattern.findall(reasoning) + if matches != []: + gene_SQL = matches[0].replace("\n", "").strip() + gene_SQL = re.sub(r"\s{2,}", " ", gene_SQL) + else: + gene_SQL = reasoning + + print(f"{diff=}\n{gold_SQL=}\n{gene_SQL=}") + if gold_SQL != gene_SQL: + diff += 1 + continue + + # use the reasoning generated above to generate an example for the reasoning dataset used for fine-tuning + prompt = f""" + -- DB Schema: {db_schema} + -- External Knowledge: {external_knowledge} + -- Text Question: {question} +""" + cot = { + "messages": [ + { + "role": "system", + "content": "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, generate the step-by-step reasoning and the final SQLite SQL select statement from the text question.", + }, + {"role": "user", "content": prompt}, + {"role": "assistant", "content": reasoning}, + ] + } + cot_list.append(cot) + + print(f"{diff=}, total: {len(input_json)}") + dataset_dict = {key: [d[key] for d in cot_list] for key in cot_list[0]} + hf_dataset = Dataset.from_dict(dataset_dict) + hf_dataset.save_to_disk(f"text2sql_cot_dataset") + + +if __name__ == "__main__": + args_parser = argparse.ArgumentParser() + args_parser.add_argument("--input_json", type=str, required=True) + args_parser.add_argument("--db_root_path", type=str, required=True) + args = args_parser.parse_args() + + input_json = json.load(open(args.input_json, "r")) + db_root_path = args.db_root_path + + create_cot_dataset(input_json, db_root_path) + +# python create_reasoning_dataset.py --input_json ../data/train/train.json --db_root_path ../data/train/train_databases diff --git a/end-to-end-use-cases/coding/text2sql/tool/llama_text2sql.py b/end-to-end-use-cases/coding/text2sql/tool/llama_text2sql.py index ffcb610ec..00295f665 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/llama_text2sql.py +++ b/end-to-end-use-cases/coding/text2sql/tool/llama_text2sql.py @@ -173,19 +173,25 @@ def generate_combined_prompts_one(db_path, question, knowledge=None): def cloud_llama(api_key, model, prompt, max_tokens, temperature, stop): + + SYSTEM_PROMPT = "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement." try: if model.startswith("meta-llama/"): llm = ChatTogether( model=model, temperature=0, ) - answer = llm.invoke(prompt).content + answer = llm.invoke(SYSTEM_PROMPT + "\n\n" + prompt).content else: client = LlamaAPIClient() + messages = [ + {"content": SYSTEM_PROMPT, "role": "system"}, + {"role": "user", "content": prompt}, + ] response = client.chat.completions.create( model=model, - messages=[{"role": "user", "content": prompt}], + messages=messages, temperature=0, ) answer = response.completion_message.content.text diff --git a/end-to-end-use-cases/coding/text2sql/tool/requirements.txt b/end-to-end-use-cases/coding/text2sql/tool/requirements.txt index 7a0b1496b..66fe9473d 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/requirements.txt +++ b/end-to-end-use-cases/coding/text2sql/tool/requirements.txt @@ -2,12 +2,10 @@ llama_api_client langchain-together sqlparse torch==2.4.1 -tensorboard +tensorboard liger-kernel==0.4.2 setuptools deepspeed==0.15.4 -# openai -# lm-eval[api]==0.4.5 transformers==4.46.3 datasets==3.6.0 accelerate==1.1.1 @@ -16,4 +14,4 @@ trl==0.12.1 peft==0.13.2 lighteval==0.6.2 hf-transfer==0.1.8 -func_timeout \ No newline at end of file +func_timeout From ab7df104120fc7835fe027fe65ee1007a83dbaff Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Wed, 25 Jun 2025 18:13:39 -0700 Subject: [PATCH 04/78] train loss png --- .../text2sql/tool/fine_tuning/train_loss.png | Bin 0 -> 148910 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 end-to-end-use-cases/coding/text2sql/tool/fine_tuning/train_loss.png diff --git a/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/train_loss.png b/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/train_loss.png new file mode 100644 index 0000000000000000000000000000000000000000..0c57364d19e95d952c14b536241854bb91466d2a GIT binary patch literal 148910 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 K0MEXI)B{Lvr%QA_Bp#TxNI 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 Date: Wed, 25 Jun 2025 18:16:09 -0700 Subject: [PATCH 05/78] README update --- .../coding/text2sql/tool/README.md | 35 ++++++------------- 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/tool/README.md b/end-to-end-use-cases/coding/text2sql/tool/README.md index 905b9a605..f0b67f95e 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/README.md +++ b/end-to-end-use-cases/coding/text2sql/tool/README.md @@ -108,52 +108,39 @@ Then run `python trl_sft.py`. After the fine-tuning completes, you'll see the fi After running `tensorboard --logdir ./llama31-8b-text2sql-fine_tuning` you can open `http://localhost:6006` to see the train loss chat etc: -```markdown -![train loss](train_loss.png) - +![](train_loss.png) ## Evaluating the fine-tuned model First, modify `llama_eval.sh` to use the fine-tuned model: - -```markdown +``` YOUR_API_KEY='finetuned' model='fine_tuning/llama31-8b-text2sql' - +``` Then run `sh llama_eval.sh` to evaluate the fine-tuned model. The accuracy on the first 500 examples of the BIRD DEV dataset is about 25.60%. This is a significant improvement over the original Llama 3.1 8B Instruct model, which has an accuracy of about 10.60% on the same examples - you can confirm this by comparing the fine-tuned model's accuracy above with the original model's accuracy by first modifying `llama_eval.sh` to use the original model: -```markdown +``` YOUR_API_KEY='huggingface' model='meta-llama/Llama-3.1-8B-Instruct' - +``` Then running `sh llama_eval.sh` to evaluate the original model. Note that this is using the 4-bit quantized Llama 3.1 8b model to reduce the memory footprint and improve the efficiency, as shown in the code nippet of llama_text2sql.py: -```markdown +``` bnb_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_use_double_quant=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype=torch.bfloat16, ) - +``` ### Creating a reasoning dataset from the TRAIN dataset -(text2sql) jeffxtang@devgpu005:~/repos/DAMO-ConvAI/bird/llm$ python create_reasoning_dataset.py --input_json data/train/train.json --db_root_path data/train/train_databases - -(trl) jeffxtang@devgpu005:~/repos/DAMO-ConvAI/bird/llm$ python convert_dataset.py -to use ./src/text2sql_cot_dataset_train_filtered (6400) generate train_dataset_filtered.json (4480) and test_dataset_filtered.json (1920) - -Now running: -(trl) jeffxtang@devgpu005:~/repos/DAMO-ConvAI/bird/llm$ CUDA_VISIBLE_DEVICES=1 nohup with-proxy python trl_sft.py -which uses HF meta-llama/Llama-3.1-8B-Instruct and train_dataset_filtered.json and GPU 25GB: -25707MiB / 97871MiB -1%|▏ | 66/5121 [02:20<2:58:39, 2.12s/it] - -### Filtering the reasoning dataset to only include examples where the predicted SQL matches the ground truth SQL -Done: created a text2sql_cot_dataset_train_filtered dataset with 6400 examples of the predicted SQL in reasoning matching the ground truth SQL: -(text2sql) jeffxtang@devgpu005:~/repos/DAMO-ConvAI/bird/llm/src$ nohup python reasoning_ground_diff.py --input_json ../data/train/train.json --db_root_path ../data/train/train_databases +In the fine_tuning folder, run: +``` +python create_reasoning_dataset.py --input_json data/train/train.json --db_root_path data/train/train_databases +``` From 2c514b11a985a1ab650f16bfd3e83fd9a27fb13c Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Wed, 25 Jun 2025 18:16:47 -0700 Subject: [PATCH 06/78] README update --- end-to-end-use-cases/coding/text2sql/tool/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/end-to-end-use-cases/coding/text2sql/tool/README.md b/end-to-end-use-cases/coding/text2sql/tool/README.md index f0b67f95e..8723ccf02 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/README.md +++ b/end-to-end-use-cases/coding/text2sql/tool/README.md @@ -108,7 +108,7 @@ Then run `python trl_sft.py`. After the fine-tuning completes, you'll see the fi After running `tensorboard --logdir ./llama31-8b-text2sql-fine_tuning` you can open `http://localhost:6006` to see the train loss chat etc: -![](train_loss.png) +![](fine_tuning/train_loss.png) ## Evaluating the fine-tuned model From 5a18b6b997430f364454685dc6bd8b553e5fc79a Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Wed, 25 Jun 2025 18:22:29 -0700 Subject: [PATCH 07/78] README cleanup --- .../coding/text2sql/tool/README.md | 47 +++++++------------ 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/tool/README.md b/end-to-end-use-cases/coding/text2sql/tool/README.md index 8723ccf02..5015b940d 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/README.md +++ b/end-to-end-use-cases/coding/text2sql/tool/README.md @@ -27,16 +27,16 @@ Llama-3.1-405B: Together: 55.80% - Together: 57.17% Llama 4 Scout: 43.94% - Llama API: 44.39% Llama 4 Maverick: 41.46% - Llama API: 44.00% -### Supported Models +## Supported Models -#### Together AI Models +### Together AI Models - meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo - meta-llama/Llama-3.3-70B-Instruct-Turbo - meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8 - meta-llama/Llama-4-Scout-17B-16E-Instruct - other Llama models hosted on Together AI -#### Llama API Models +### Llama API Models - Llama-3.3-8B-Instruct - Llama-3.3-70B-Instruct - Llama-4-Maverick-17B-128E-Instruct-FP8 @@ -53,31 +53,6 @@ Llama 4 Maverick: 41.46% - Llama API: 44.00% 4. **Accuracy Calculation**: Accuracy scores are calculated overall and broken down by difficulty levels (simple, moderate, challenging). -## Data Format - -The evaluation data should be in JSON format with the following structure: - -```json -[ - { - "question": "Natural language question", - "db_id": "database_name", - "evidence": "External knowledge (optional)", - "SQL": "Ground truth SQL query", - "difficulty": "simple|moderate|challenging" - }, - ... -] -``` - -## Output - -The evaluation produces: -- Generated SQL queries saved to the specified output directory -- Accuracy scores printed to the console, broken down by difficulty level - - - ## Preparing Fine-tuning Dataset ### Using the TRAIN to prepare for supervised fine-tuning @@ -100,7 +75,7 @@ This will create `train_text2sql_sft_dataset.json` and `test_text2sql_sft_datase {"messages":[{"content":"You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement.","role":"system"},{"content":"-- DB Schema: \n\n-- External Knowledge: \n\n-- Question: ","role":"user"},{"content":"","role":"assistant"}]} ``` -3. Supervised Fine-tuning +## Supervised Fine-tuning First, you need to login to HuggingFace (via running `huggingface-cli login` and enter your [HF token](https://huggingface.co/settings/tokens)) and have been granted access to the [Llama 3.1 8B Instruct](https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct) model. @@ -110,6 +85,7 @@ After running `tensorboard --logdir ./llama31-8b-text2sql-fine_tuning` you can o ![](fine_tuning/train_loss.png) + ## Evaluating the fine-tuned model First, modify `llama_eval.sh` to use the fine-tuned model: @@ -139,8 +115,21 @@ Note that this is using the 4-bit quantized Llama 3.1 8b model to reduce the mem ) ``` + ### Creating a reasoning dataset from the TRAIN dataset In the fine_tuning folder, run: ``` python create_reasoning_dataset.py --input_json data/train/train.json --db_root_path data/train/train_databases ``` +This will create `text2sql_cot_dataset` dataset in HuggingFace format, which is ready for fine-tuning with the reasoning prompt. Each line in the json file is in the conversation format ready for fine-tuning: + +``` + "messages": [ + { + "role": "system", + "content": "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, generate the step-by-step reasoning and the final SQLite SQL select statement from the text question.", + }, + {"role": "user", "content": prompt}, + {"role": "assistant", "content": reasoning}, + ] +``` From 0033fc9cf2962dda6465439d40b88390d08c80f9 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Thu, 26 Jun 2025 16:07:23 -0700 Subject: [PATCH 08/78] README update --- .../coding/text2sql/tool/README.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/tool/README.md b/end-to-end-use-cases/coding/text2sql/tool/README.md index 5015b940d..3f10de344 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/README.md +++ b/end-to-end-use-cases/coding/text2sql/tool/README.md @@ -22,10 +22,13 @@ After the script completes, you'll see the accuracy of the Llama model on the BI *Note:* To compare your evaluated accuracy of your selected Llama model with other results in the BIRD Dev leaderboard, click [here](https://bird-bench.github.io/). -Llama 3.3 70b: 54.69% - Llama API: 54.11%; Together: 54.63% -Llama-3.1-405B: Together: 55.80% - Together: 57.17% -Llama 4 Scout: 43.94% - Llama API: 44.39% -Llama 4 Maverick: 41.46% - Llama API: 44.00% +| Model | Llama API Accuracy | Together Accuracy | +|------------------------|--------------------|-------------------| +| Llama 3.1 8b | - | 35.66% | +| Llama 3.3 70b | 54.11% | 54.63% | +| Llama-3.1-405B | - | 55.80% | +| Llama 4 Scout | 44.39% | 43.94% | +| Llama 4 Maverick | 44.00% | 41.46% | ## Supported Models @@ -69,6 +72,7 @@ sh download_train_unzip.sh cd fine_tuning python create_sft_dataset.py --input_json ../data/train/train.json --db_root_path ../data/train/train_databases ``` + This will create `train_text2sql_sft_dataset.json` and `test_text2sql_sft_dataset.json` using the TRAIN set. Each line in the json files is in the conversation format ready for fine-tuning: ``` @@ -95,7 +99,7 @@ YOUR_API_KEY='finetuned' model='fine_tuning/llama31-8b-text2sql' ``` -Then run `sh llama_eval.sh` to evaluate the fine-tuned model. The accuracy on the first 500 examples of the BIRD DEV dataset is about 25.60%. This is a significant improvement over the original Llama 3.1 8B Instruct model, which has an accuracy of about 10.60% on the same examples - you can confirm this by comparing the fine-tuned model's accuracy above with the original model's accuracy by first modifying `llama_eval.sh` to use the original model: +Then run `sh llama_eval.sh` to evaluate the fine-tuned model. The accuracy on the BIRD DEV dataset is about 37.16%. This is a 165% improvement over the model before fine-tuning, which has an accuracy of about 14.02% on the same dataset - you can confirm this by comparing the fine-tuned model's accuracy above with the original model's accuracy by modifying `llama_eval.sh` to use the original model: ``` YOUR_API_KEY='huggingface' @@ -104,7 +108,7 @@ model='meta-llama/Llama-3.1-8B-Instruct' Then running `sh llama_eval.sh` to evaluate the original model. -Note that this is using the 4-bit quantized Llama 3.1 8b model to reduce the memory footprint and improve the efficiency, as shown in the code nippet of llama_text2sql.py: +*Note:* We are using the 4-bit quantized Llama 3.1 8b model to reduce the memory footprint and improve the efficiency (as shown in the code nippet of llama_text2sql.py below), hence the accuracy of the quantized version (14.02%) is quite lower than the accuracy of the original Llama 3.1 8b (35.66%). ``` bnb_config = BitsAndBytesConfig( From 399735749863d434ab6128723e246d67c9a738a6 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Thu, 26 Jun 2025 16:32:59 -0700 Subject: [PATCH 09/78] README update - overview and quick start --- .../coding/text2sql/tool/README.md | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/tool/README.md b/end-to-end-use-cases/coding/text2sql/tool/README.md index 3f10de344..6138692f8 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/README.md +++ b/end-to-end-use-cases/coding/text2sql/tool/README.md @@ -1,10 +1,24 @@ # Text2SQL Evaluation and Fine-Tuning Tools for Llama Models -This folder contains the scripts for evaluating Llama models on Text2SQL tasks, preparing supervised and reasoning datasets, fine-tuning Llama 3.1 8B with the datasets, and evaluating the fine-tuned model. The original dataset and scripts are from the BIRD-SQL [benchmark](https://bird-bench.github.io) and [repo](https://github.com/AlibabaResearch/DAMO-ConvAI/tree/main/bird), but we have significantly simplified and streamlined them for Llama models hosted via Meta's [Llama API](https://llama.developer.meta.com) or [Together.ai](https://together.ai), so you can quickly evaluate how well different Llama models perform Text2SQL tasks and how to fine-tune the models for better accuracy. +## Overview + +This folder contains the scripts for evaluating Llama (original and fine-tuned) models on Text2SQL tasks using the popular [BIRD](https://bird-bench.github.io) dataset, generating fine-tuning datasets, and fine-tuning Llama 3.1 8B with the datasets. + +We have significantly simplified the original eval scripts from the BIRD [repo](https://github.com/AlibabaResearch/DAMO-ConvAI/tree/main/bird) for Llama models hosted via Meta's [Llama API](https://llama.developer.meta.com) or [Together.ai](https://together.ai), so you can quickly evaluate in 1-2-3 steps how well different Llama models perform on the Text2SQL task. + +We have also provided end-to-end scripts for generating datasets and fine-tuning a quantized Llama 3.1 8B model to gain a 165% accuracy improvement over the original model. ## Quick Start on Evaluating Llama on Text2SQL -First, `cd llama-cookbook/getting-started/llama-tools/text2sql` and run `pip install -r requirements.txt` to install all the required packages. +First, run the commands below to create a new Conda environment and install all the required packages for Text2SQL evaluation and fine-tuning: + +``` +git clone https://github.com/meta-llama/llama-cookbook +cd llama-cookbook/end-to-end-use-cases/coding/text2sql/tool +conda create -n llama-text2sql python=3.10 +conda activate llama-text2sql +pip install -r requirements.txt +``` Then, follow the steps below to evaluate Llama 3 & 4 models on Text2SQL using the BIRD benchmark: @@ -22,6 +36,10 @@ After the script completes, you'll see the accuracy of the Llama model on the BI *Note:* To compare your evaluated accuracy of your selected Llama model with other results in the BIRD Dev leaderboard, click [here](https://bird-bench.github.io/). +### Evaluation Results + +Below are the results of the Llama models we have evaluated on the BIRD DEV dataset: + | Model | Llama API Accuracy | Together Accuracy | |------------------------|--------------------|-------------------| | Llama 3.1 8b | - | 35.66% | From 44aa896deb98f117f3fde1075a3986ee404a211c Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Thu, 26 Jun 2025 17:03:33 -0700 Subject: [PATCH 10/78] README update - next steps and creating reasoning dataset --- .../coding/text2sql/tool/README.md | 42 +++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/tool/README.md b/end-to-end-use-cases/coding/text2sql/tool/README.md index 6138692f8..c5905421f 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/README.md +++ b/end-to-end-use-cases/coding/text2sql/tool/README.md @@ -139,13 +139,24 @@ Then running `sh llama_eval.sh` to evaluate the original model. ### Creating a reasoning dataset from the TRAIN dataset -In the fine_tuning folder, run: + +The script `create_reasoning_dataset.py` is used to create a reasoning dataset from the TRAIN dataset by asking Llama 3.3 70B to generate the reasoning for each text question and its corresponding gold SQL. The intent is to use the reasoning dataset to fine-tune the Llama model to improve the accuracy of the generated SQL. + +To run the script, use the following commands: ``` -python create_reasoning_dataset.py --input_json data/train/train.json --db_root_path data/train/train_databases +cd fine_tuning +python create_reasoning_dataset.py --input_json ../data/train/train.json --db_root_path ../data/train/train_databases ``` -This will create `text2sql_cot_dataset` dataset in HuggingFace format, which is ready for fine-tuning with the reasoning prompt. Each line in the json file is in the conversation format ready for fine-tuning: + +This will create `text2sql_cot_dataset` dataset in the conversation format ready for fine-tuning. Each example in the dataset is generated from the code snippet below: ``` +prompt = f""" +-- DB Schema: {db_schema} +-- External Knowledge: {external_knowledge} +-- Text Question: {question} +""" +cot = { "messages": [ { "role": "system", @@ -154,4 +165,29 @@ This will create `text2sql_cot_dataset` dataset in HuggingFace format, which is {"role": "user", "content": prompt}, {"role": "assistant", "content": reasoning}, ] +} +``` + +The prompt for Llama 3.3 70B to generate the `reasoning` above is: ``` +You are a text to SQL query translator. Based on the DB Schema and External Knowledge, given the Text Question Input and its Gold SQL Output below, generate the step-by-step reasoning to infer the Gold SQL Output from the Text Question Input. + +-- DB Schema: {db_schema} +-- External Knowledge: {external_knowledge} +-- Text Question Input: {question} +-- Gold SQL Output: {gold_SQL} + +Your response should be as follows:\n\n +Let me think through this step by step:\n\n1. First, I need to consider...\n2. Then...\n3. Next...\n...\n\nFinally, the SQL statement for the text question is: +```sql ...```\n + +""" +``` + +## Next Steps +1. Fine-tune the model with the reasoning dataset and evaluate its accuracy. +2. Add a Colab notebook for fine-tuning and evaluation. +3. Try reinforcement fine-tuning to improve the accuracy further with reasoning. +4. Use torchtune for full and non-quantized fine-tuning of Llama 3.3 70b and Llama 4 models. +5. Introduce agent to try to improve the accuracy further. +6. Expand the tool to support other databases. From 46d32454256ae12a8f94100d107d2c76fd572e9e Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Fri, 27 Jun 2025 09:54:22 -0700 Subject: [PATCH 11/78] README and create_reasoning_dataset.py and trl_sft.py update --- .../coding/text2sql/tool/README.md | 41 ++++++++++--------- .../fine_tuning/create_reasoning_dataset.py | 23 +++++++++-- .../text2sql/tool/fine_tuning/trl_sft.py | 12 +++--- 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/tool/README.md b/end-to-end-use-cases/coding/text2sql/tool/README.md index c5905421f..1dffab4a6 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/README.md +++ b/end-to-end-use-cases/coding/text2sql/tool/README.md @@ -6,7 +6,20 @@ This folder contains the scripts for evaluating Llama (original and fine-tuned) We have significantly simplified the original eval scripts from the BIRD [repo](https://github.com/AlibabaResearch/DAMO-ConvAI/tree/main/bird) for Llama models hosted via Meta's [Llama API](https://llama.developer.meta.com) or [Together.ai](https://together.ai), so you can quickly evaluate in 1-2-3 steps how well different Llama models perform on the Text2SQL task. -We have also provided end-to-end scripts for generating datasets and fine-tuning a quantized Llama 3.1 8B model to gain a 165% accuracy improvement over the original model. +We have also provided end-to-end scripts for generating datasets and fine-tuning a quantized Llama 3.1 8B model to gain a **165% accuracy improvement** over the original model. + +## Llama Text2SQL Evaluation Results + +Below are the results of the Llama models we have evaluated on the BIRD DEV dataset: + +| Model | Llama API Accuracy | Together Accuracy | +|------------------------|--------------------|-------------------| +| Llama 3.1 8b | - | 35.66% | +| Llama 3.3 70b | 54.11% | 54.63% | +| Llama-3.1-405B | - | 55.80% | +| Llama 4 Scout | 44.39% | 43.94% | +| Llama 4 Maverick | 44.00% | 41.46% | + ## Quick Start on Evaluating Llama on Text2SQL @@ -36,17 +49,15 @@ After the script completes, you'll see the accuracy of the Llama model on the BI *Note:* To compare your evaluated accuracy of your selected Llama model with other results in the BIRD Dev leaderboard, click [here](https://bird-bench.github.io/). -### Evaluation Results +## Evaluation Process -Below are the results of the Llama models we have evaluated on the BIRD DEV dataset: +1. **SQL Generation**: `llama_text2sql.py` sends natural language questions to the specified Llama model and collects the generated SQL queries. -| Model | Llama API Accuracy | Together Accuracy | -|------------------------|--------------------|-------------------| -| Llama 3.1 8b | - | 35.66% | -| Llama 3.3 70b | 54.11% | 54.63% | -| Llama-3.1-405B | - | 55.80% | -| Llama 4 Scout | 44.39% | 43.94% | -| Llama 4 Maverick | 44.00% | 41.46% | +2. **SQL Execution**: `text2sql_eval.py` executes both the generated SQL and ground truth SQL against the corresponding databases, then continues with steps 3 and 4 below. + +3. **Result Comparison**: The results from executing the generated SQL are compared with the results from the ground truth SQL to determine correctness. + +4. **Accuracy Calculation**: Accuracy scores are calculated overall and broken down by difficulty levels (simple, moderate, challenging). ## Supported Models @@ -64,16 +75,6 @@ Below are the results of the Llama models we have evaluated on the BIRD DEV data - Llama-4-Scout-17B-16E-Instruct-FP8 - other Llama models hosted on Llama API -## Evaluation Process - -1. **SQL Generation**: `llama_text2sql.py` sends natural language questions to the specified Llama model and collects the generated SQL queries. - -2. **SQL Execution**: `text2sql_eval.py` executes both the generated SQL and ground truth SQL against the corresponding databases, then continues with steps 3 and 4 below. - -3. **Result Comparison**: The results from executing the generated SQL are compared with the results from the ground truth SQL to determine correctness. - -4. **Accuracy Calculation**: Accuracy scores are calculated overall and broken down by difficulty levels (simple, moderate, challenging). - ## Preparing Fine-tuning Dataset ### Using the TRAIN to prepare for supervised fine-tuning diff --git a/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/create_reasoning_dataset.py b/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/create_reasoning_dataset.py index ebb95b363..ebe47d984 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/create_reasoning_dataset.py +++ b/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/create_reasoning_dataset.py @@ -8,7 +8,7 @@ from typing import Dict, List, Tuple import sqlparse -from datasets import Dataset +from datasets import Dataset, load_from_disk from langchain_together import ChatTogether from llama_api_client import LlamaAPIClient @@ -139,6 +139,16 @@ def generate_schema_prompt(db_path, num_rows=None): return schema_prompt +def create_conversation(sample): + return { + "messages": [ + {"role": "system", "content": sample["messages"][0]["content"]}, + {"role": "user", "content": sample["messages"][1]["content"]}, + {"role": "assistant", "content": sample["messages"][2]["content"]}, + ] + } + + def create_cot_dataset(input_json, db_root_path): cot_list = [] diff = 0 @@ -174,8 +184,6 @@ def create_cot_dataset(input_json, db_root_path): .replace("{gold_SQL}", gold_SQL) ) reasoning = llama(prompt_to_generate_reasoning) - # print(f"\n======\n{prompt_to_generate_reasoning=}\n\n") - # print(f"\n======\n{reasoning=}\n\n") pattern = re.compile(r"```sql\n*(.*?)```", re.DOTALL) matches = pattern.findall(reasoning) @@ -213,6 +221,15 @@ def create_cot_dataset(input_json, db_root_path): hf_dataset = Dataset.from_dict(dataset_dict) hf_dataset.save_to_disk(f"text2sql_cot_dataset") + dataset = load_from_disk("text2sql_cot_dataset") + dataset = dataset.map( + create_conversation, remove_columns=dataset.features, batched=False + ) + dataset = dataset.train_test_split(test_size=0.3) + + dataset["train"].to_json("train_text2sql_cot_dataset.json", orient="records") + dataset["test"].to_json("test_text2sql_cot_dataset.json", orient="records") + if __name__ == "__main__": args_parser = argparse.ArgumentParser() diff --git a/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/trl_sft.py b/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/trl_sft.py index e6c123692..0a5729345 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/trl_sft.py +++ b/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/trl_sft.py @@ -11,9 +11,11 @@ ) from trl import setup_chat_format, SFTTrainer -dataset = load_dataset( - "json", data_files="train_text2sql_sft_dataset.json", split="train" -) +FT_DATASET = "train_text2sql_sft_dataset.json" +# uncomment to use the reasoning dataset created by "create_reasoning_dataset.py" +# FT_DATASET = "train_text2sql_cot_dataset.json" + +dataset = load_dataset("json", data_files=SFT_DATASET, split="train") model_id = "meta-llama/Llama-3.1-8B-Instruct" @@ -48,8 +50,8 @@ ) args = TrainingArguments( - output_dir="llama31-8b-text2sql-epochs-20", # directory to save and repository id - num_train_epochs=20, # number of training epochs + output_dir="llama31-8b-text2sql-fine-tuned", # directory to save and repository id + num_train_epochs=3, # number of training epochs per_device_train_batch_size=3, # batch size per device during training gradient_accumulation_steps=2, # number of steps before performing a backward/update pass gradient_checkpointing=True, # use gradient checkpointing to save memory From b89d945108bebbe1068766a603dead12c56c74f7 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Fri, 27 Jun 2025 14:40:23 -0700 Subject: [PATCH 12/78] readme and requirements updated based on PR feedback --- end-to-end-use-cases/coding/text2sql/tool/README.md | 2 ++ end-to-end-use-cases/coding/text2sql/tool/requirements.txt | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/tool/README.md b/end-to-end-use-cases/coding/text2sql/tool/README.md index 1dffab4a6..86c4aa493 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/README.md +++ b/end-to-end-use-cases/coding/text2sql/tool/README.md @@ -20,6 +20,8 @@ Below are the results of the Llama models we have evaluated on the BIRD DEV data | Llama 4 Scout | 44.39% | 43.94% | | Llama 4 Maverick | 44.00% | 41.46% | +Llama 3.1 8b quantized model: 14.02% (original) -> 37.16% (fine-tuned) + ## Quick Start on Evaluating Llama on Text2SQL diff --git a/end-to-end-use-cases/coding/text2sql/tool/requirements.txt b/end-to-end-use-cases/coding/text2sql/tool/requirements.txt index 66fe9473d..259fe8160 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/requirements.txt +++ b/end-to-end-use-cases/coding/text2sql/tool/requirements.txt @@ -1,5 +1,5 @@ -llama_api_client -langchain-together +llama_api_client==0.1.1 +langchain-together==0.3.0 sqlparse torch==2.4.1 tensorboard From 3731175e9913d0712d777b9226ad0865a4e8837d Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Fri, 27 Jun 2025 15:08:42 -0700 Subject: [PATCH 13/78] readme update based on PR feeedback --- .../coding/text2sql/tool/README.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/tool/README.md b/end-to-end-use-cases/coding/text2sql/tool/README.md index 86c4aa493..633ceef31 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/README.md +++ b/end-to-end-use-cases/coding/text2sql/tool/README.md @@ -2,9 +2,9 @@ ## Overview -This folder contains the scripts for evaluating Llama (original and fine-tuned) models on Text2SQL tasks using the popular [BIRD](https://bird-bench.github.io) dataset, generating fine-tuning datasets, and fine-tuning Llama 3.1 8B with the datasets. +This folder contains the scripts for evaluating Llama (original and fine-tuned) models on the Text2SQL task using the popular [BIRD](https://bird-bench.github.io) dataset, generating fine-tuning datasets, and fine-tuning Llama 3.1 8B with the datasets. -We have significantly simplified the original eval scripts from the BIRD [repo](https://github.com/AlibabaResearch/DAMO-ConvAI/tree/main/bird) for Llama models hosted via Meta's [Llama API](https://llama.developer.meta.com) or [Together.ai](https://together.ai), so you can quickly evaluate in 1-2-3 steps how well different Llama models perform on the Text2SQL task. +We have updated and significantly simplified the original eval scripts from the BIRD [repo](https://github.com/AlibabaResearch/DAMO-ConvAI/tree/main/bird) for Llama 3 & 4 models hosted via Meta's [Llama API](https://llama.developer.meta.com) or [Together.ai](https://together.ai), as well as the fine-tuned Llama 3.1 model, so you can quickly evaluate in 1-2-3 steps how well different Llama models perform on the Text2SQL task. We have also provided end-to-end scripts for generating datasets and fine-tuning a quantized Llama 3.1 8B model to gain a **165% accuracy improvement** over the original model. @@ -22,7 +22,6 @@ Below are the results of the Llama models we have evaluated on the BIRD DEV data Llama 3.1 8b quantized model: 14.02% (original) -> 37.16% (fine-tuned) - ## Quick Start on Evaluating Llama on Text2SQL First, run the commands below to create a new Conda environment and install all the required packages for Text2SQL evaluation and fine-tuning: @@ -57,7 +56,7 @@ After the script completes, you'll see the accuracy of the Llama model on the BI 2. **SQL Execution**: `text2sql_eval.py` executes both the generated SQL and ground truth SQL against the corresponding databases, then continues with steps 3 and 4 below. -3. **Result Comparison**: The results from executing the generated SQL are compared with the results from the ground truth SQL to determine correctness. +3. **Result Comparison**: The results from executing the generated SQL are compared [source code](text2sql_eval.py#L30) with the results from the ground truth SQL to determine correctness. 4. **Accuracy Calculation**: Accuracy scores are calculated overall and broken down by difficulty levels (simple, moderate, challenging). @@ -77,7 +76,9 @@ After the script completes, you'll see the accuracy of the Llama model on the BI - Llama-4-Scout-17B-16E-Instruct-FP8 - other Llama models hosted on Llama API -## Preparing Fine-tuning Dataset +## Fine-tuning with the BIRD TRAIN dataset (No Reasoning) + +We'll first use the BIRD TRAIN dataset to prepare for supervised fine-tuning with no reasoning info in the dataset. ### Using the TRAIN to prepare for supervised fine-tuning @@ -100,7 +101,7 @@ This will create `train_text2sql_sft_dataset.json` and `test_text2sql_sft_datase {"messages":[{"content":"You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement.","role":"system"},{"content":"-- DB Schema: \n\n-- External Knowledge: \n\n-- Question: ","role":"user"},{"content":"","role":"assistant"}]} ``` -## Supervised Fine-tuning +### Supervised Fine-tuning First, you need to login to HuggingFace (via running `huggingface-cli login` and enter your [HF token](https://huggingface.co/settings/tokens)) and have been granted access to the [Llama 3.1 8B Instruct](https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct) model. @@ -111,7 +112,7 @@ After running `tensorboard --logdir ./llama31-8b-text2sql-fine_tuning` you can o ![](fine_tuning/train_loss.png) -## Evaluating the fine-tuned model +### Evaluating the fine-tuned model First, modify `llama_eval.sh` to use the fine-tuned model: @@ -140,6 +141,9 @@ Then running `sh llama_eval.sh` to evaluate the original model. ) ``` +## Fine-tuning with the BIRD TRAIN dataset (With Reasoning) + +Next we'll use the BIRD TRAIN dataset to prepare for supervised fine-tuning with reasoning info in the dataset. The goal is to see if we can improve the accuracy of the fine-tuned model by adding the reasoning info in the dataset. ### Creating a reasoning dataset from the TRAIN dataset From 094ab0195f66d9281f5715a0647548e2d8144793 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Fri, 27 Jun 2025 15:18:49 -0700 Subject: [PATCH 14/78] readme --- end-to-end-use-cases/coding/text2sql/tool/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/end-to-end-use-cases/coding/text2sql/tool/README.md b/end-to-end-use-cases/coding/text2sql/tool/README.md index 633ceef31..5ad4588d8 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/README.md +++ b/end-to-end-use-cases/coding/text2sql/tool/README.md @@ -56,7 +56,7 @@ After the script completes, you'll see the accuracy of the Llama model on the BI 2. **SQL Execution**: `text2sql_eval.py` executes both the generated SQL and ground truth SQL against the corresponding databases, then continues with steps 3 and 4 below. -3. **Result Comparison**: The results from executing the generated SQL are compared [source code](text2sql_eval.py#L30) with the results from the ground truth SQL to determine correctness. +3. **Result Comparison**: The results from executing the generated SQL are compared ([source code](text2sql_eval.py#L30)) with the results from the ground truth SQL to determine correctness. 4. **Accuracy Calculation**: Accuracy scores are calculated overall and broken down by difficulty levels (simple, moderate, challenging). From 6d76ea0f7e2efc7093e5d2b59821a96bb46e9562 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Sat, 28 Jun 2025 10:53:24 -0700 Subject: [PATCH 15/78] updated create_reasoning_dataset, llama_text2sql.py and README for finetuned with reasoning eval --- .../coding/text2sql/tool/README.md | 44 ++++++++++++++----- .../coding/text2sql/tool/llama_eval.sh | 31 ++++++------- .../coding/text2sql/tool/llama_text2sql.py | 16 +++++-- 3 files changed, 58 insertions(+), 33 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/tool/README.md b/end-to-end-use-cases/coding/text2sql/tool/README.md index 5ad4588d8..0b6e2c91c 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/README.md +++ b/end-to-end-use-cases/coding/text2sql/tool/README.md @@ -6,7 +6,7 @@ This folder contains the scripts for evaluating Llama (original and fine-tuned) We have updated and significantly simplified the original eval scripts from the BIRD [repo](https://github.com/AlibabaResearch/DAMO-ConvAI/tree/main/bird) for Llama 3 & 4 models hosted via Meta's [Llama API](https://llama.developer.meta.com) or [Together.ai](https://together.ai), as well as the fine-tuned Llama 3.1 model, so you can quickly evaluate in 1-2-3 steps how well different Llama models perform on the Text2SQL task. -We have also provided end-to-end scripts for generating datasets and fine-tuning a quantized Llama 3.1 8B model to gain a **165% accuracy improvement** over the original model. +We have also provided end-to-end scripts for generating datasets (with and without reasoning steps) and fine-tuning the quantized Llama 3.1 8B model to gain a **165% (with no reasoning) and 209% (with reasoning) accuracy improvement** over the original model. ## Llama Text2SQL Evaluation Results @@ -20,7 +20,9 @@ Below are the results of the Llama models we have evaluated on the BIRD DEV data | Llama 4 Scout | 44.39% | 43.94% | | Llama 4 Maverick | 44.00% | 41.46% | -Llama 3.1 8b quantized model: 14.02% (original) -> 37.16% (fine-tuned) +Llama 3.1 8b quantized model: 14.02% (original) +Fine-tuned with no reasoning dataset: 37.16% +Fine-tuned with reasoning dataset: 43.37% ## Quick Start on Evaluating Llama on Text2SQL @@ -46,6 +48,8 @@ sh download_dev_unzip.sh 3. Run the evaluation script `sh llama_eval.sh`, which will use the BIRD DEV dataset (1534 examples in total) with external knowledge turned on to run the Llama model on each text question and compare the generated SQL with the gold SQL. +*Note:* If your API key or model name is incorrect, the script will exit with an authentication or model not supported error. + After the script completes, you'll see the accuracy of the Llama model on the BIRD DEV text2sql. For example, the total accuracy is about 54.24% with `YOUR_API_KEY` set to your Llama API key and `model='Llama-3.3-70B-Instruct'`, or about 35.07% with `YOUR_API_KEY` set to your Together API key and `model=meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo`. *Note:* To compare your evaluated accuracy of your selected Llama model with other results in the BIRD Dev leaderboard, click [here](https://bird-bench.github.io/). @@ -101,18 +105,18 @@ This will create `train_text2sql_sft_dataset.json` and `test_text2sql_sft_datase {"messages":[{"content":"You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement.","role":"system"},{"content":"-- DB Schema: \n\n-- External Knowledge: \n\n-- Question: ","role":"user"},{"content":"","role":"assistant"}]} ``` -### Supervised Fine-tuning +### Supervised Fine-tuning (No Reasoning) First, you need to login to HuggingFace (via running `huggingface-cli login` and enter your [HF token](https://huggingface.co/settings/tokens)) and have been granted access to the [Llama 3.1 8B Instruct](https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct) model. -Then run `python trl_sft.py`. After the fine-tuning completes, you'll see the fine-tuned model saved to `llama31-8b-text2sql-fine_tuning`. +Then run `python trl_sft.py`. After the fine-tuning completes, you'll see the fine-tuned model saved to `llama31-8b-text2sql-fine-tuned`, specified in `output_dir="llama31-8b-text2sql-fine-tuned"` of `TrainingArguments` in `trl_sft.py`. After running `tensorboard --logdir ./llama31-8b-text2sql-fine_tuning` you can open `http://localhost:6006` to see the train loss chat etc: ![](fine_tuning/train_loss.png) -### Evaluating the fine-tuned model +### Evaluating the fine-tuned model (No Reasoning) First, modify `llama_eval.sh` to use the fine-tuned model: @@ -155,7 +159,7 @@ cd fine_tuning python create_reasoning_dataset.py --input_json ../data/train/train.json --db_root_path ../data/train/train_databases ``` -This will create `text2sql_cot_dataset` dataset in the conversation format ready for fine-tuning. Each example in the dataset is generated from the code snippet below: +This will create a `text2sql_cot_dataset` dataset and `train_text2sql_cot_dataset.json` in the conversation format ready for fine-tuning. Each example in the dataset is generated from the code snippet below: ``` prompt = f""" @@ -191,10 +195,26 @@ Let me think through this step by step:\n\n1. First, I need to consider...\n2. T """ ``` +### Supervised Fine-tuning (With Reasoning) + +Uncomment the line `# FT_DATASET = "train_text2sql_cot_dataset.json"` in trl_sft.py to use the reasoning dataset for fine-tuning. Then run `python trl_sft.py`. After the fine-tuning completes, you'll see the fine-tuned model saved to `llama31-8b-text2sql-fine-tuned`, specified in `output_dir="llama31-8b-text2sql-fine-tuned"` of `TrainingArguments` in `trl_sft.py` - you may want to rename the `output_dir` folder to something else to avoid overwriting the previous fine-tuned model. + +### Evaluating the fine-tuned model (With Reasoning) + +First, modify `llama_eval.sh` to use the fine-tuned model, which should match the `output_dir` in `TrainingArguments` in `trl_sft.py`: + +``` +YOUR_API_KEY='finetuned' +model='fine_tuning/llama31-8b-text2sql-fine-tuned' +``` + +Then uncomment the line `SYSTEM_PROMPT` [here](https://github.com/meta-llama/llama-cookbook/blob/text2sql/end-to-end-use-cases/coding/text2sql/tool/llama_text2sql.py#L31) in `llama_text2sql.py` to use it with the reasoning dataset fine-tuned model. + +Now run `sh llama_eval.sh`, which will take longer because the reasoning is needed to generate the SQL. The accuracy this time is 43.37%, compared with 37.16% without reasoning. This is another 16% improvement over the model with fine-tuning without reasoning. + ## Next Steps -1. Fine-tune the model with the reasoning dataset and evaluate its accuracy. -2. Add a Colab notebook for fine-tuning and evaluation. -3. Try reinforcement fine-tuning to improve the accuracy further with reasoning. -4. Use torchtune for full and non-quantized fine-tuning of Llama 3.3 70b and Llama 4 models. -5. Introduce agent to try to improve the accuracy further. -6. Expand the tool to support other databases. +1. Add a Colab notebook for fine-tuning and evaluation. +2. Try reinforcement fine-tuning to improve the accuracy further with reasoning. +3. Use torchtune for full and non-quantized fine-tuning of Llama 3.3 70b and Llama 4 models. +4. Introduce agent to try to improve the accuracy further. +5. Expand the tool to support other databases. diff --git a/end-to-end-use-cases/coding/text2sql/tool/llama_eval.sh b/end-to-end-use-cases/coding/text2sql/tool/llama_eval.sh index 34597a428..3331d08e6 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/llama_eval.sh +++ b/end-to-end-use-cases/coding/text2sql/tool/llama_eval.sh @@ -2,36 +2,31 @@ eval_path='./data/dev_20240627/dev.json' db_root_path='./data/dev_20240627/dev_databases/' ground_truth_path='./data/' -# Llama model on Hugging Face Hub -# https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct -# YOUR_API_KEY='huggingface' -# model='meta-llama/Llama-3.1-8B-Instruct' - -# Fine-tuned Llama model locally -#YOUR_API_KEY='finetuned' -#model='fine_tuning/llama31-8b-text2sql-epochs-3' -#model='fine_tuning/llama31-8b-text2sql-epochs-8' - -YOUR_API_KEY='xxx' # Llama models on Together +#YOUR_API_KEY='YOUR_TOGETHER_API_KEY' #model='meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo' #model='meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo' -model='meta-llama/Llama-3.3-70B-Instruct-Turbo' +#model='meta-llama/Llama-3.3-70B-Instruct-Turbo' #model='meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8' #model='meta-llama/Llama-4-Scout-17B-16E-Instruct' -#YOUR_API_KEY='yyy' # Llama models on Llama API -#model='Llama-3.3-8B-Instruct' +YOUR_API_KEY='YOUR_LLAMA_API_KEY' +model='Llama-3.3-8B-Instruct' #model='Llama-3.3-70B-Instruct' #model='Llama-4-Maverick-17B-128E-Instruct-FP8' #model='Llama-4-Scout-17B-16E-Instruct-FP8' -#model="llama31-8b-text-sql-epochs-25" -#model="llama31-8b-text-sql-epochs-3" -#model="llama31-8b-text-sql" +# Llama model on Hugging Face Hub +# https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct +# YOUR_API_KEY='huggingface' +# model='meta-llama/Llama-3.1-8B-Instruct' + +# Fine-tuned Llama models locally +#YOUR_API_KEY='finetuned' +#model='fine_tuning/llama31-8b-text2sql-fine-tuned' -data_output_path="./output/$model/v2/" +data_output_path="./output/$model/" echo "Text2SQL using $model" python3 -u llama_text2sql.py --db_root_path ${db_root_path} --api_key ${YOUR_API_KEY} \ diff --git a/end-to-end-use-cases/coding/text2sql/tool/llama_text2sql.py b/end-to-end-use-cases/coding/text2sql/tool/llama_text2sql.py index 00295f665..b9c9f7d8b 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/llama_text2sql.py +++ b/end-to-end-use-cases/coding/text2sql/tool/llama_text2sql.py @@ -14,6 +14,7 @@ import torch from datasets import Dataset, load_dataset from langchain_together import ChatTogether +from llama_api_client import LlamaAPIClient from peft import AutoPeftModelForCausalLM from tqdm import tqdm from transformers import ( @@ -26,6 +27,8 @@ def local_llama(prompt, pipe): SYSTEM_PROMPT = "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement." + # UNCOMMENT TO USE THE FINE_TUNED MODEL WITH REASONING DATASET + # SYSTEM_PROMPT = "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, generate the step-by-step reasoning and the final SQLite SQL select statement from the text question." messages = [ {"content": SYSTEM_PROMPT, "role": "system"}, @@ -51,10 +54,17 @@ def local_llama(prompt, pipe): pad_token_id=pipe.tokenizer.pad_token_id, ) - generated_answer = outputs[0]["generated_text"][len(raw_prompt) :].strip() + answer = outputs[0]["generated_text"][len(raw_prompt) :].strip() - print(f"{generated_answer=}") - return generated_answer + pattern = re.compile(r"```sql\n*(.*?)```", re.DOTALL) + matches = pattern.findall(answer) + if matches != []: + result = matches[0] + else: + result = answer + + print(f"{result=}") + return result def new_directory(path): From cf54eb44d73a942208ae3a59083ade0c52ff47a3 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Sat, 28 Jun 2025 10:54:36 -0700 Subject: [PATCH 16/78] README format fix --- end-to-end-use-cases/coding/text2sql/tool/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/tool/README.md b/end-to-end-use-cases/coding/text2sql/tool/README.md index 0b6e2c91c..7fe77fe80 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/README.md +++ b/end-to-end-use-cases/coding/text2sql/tool/README.md @@ -20,9 +20,9 @@ Below are the results of the Llama models we have evaluated on the BIRD DEV data | Llama 4 Scout | 44.39% | 43.94% | | Llama 4 Maverick | 44.00% | 41.46% | -Llama 3.1 8b quantized model: 14.02% (original) -Fine-tuned with no reasoning dataset: 37.16% -Fine-tuned with reasoning dataset: 43.37% +- Llama 3.1 8b quantized model: 14.02% (original) +- Fine-tuned with no reasoning dataset: 37.16% +- Fine-tuned with reasoning dataset: 43.37% ## Quick Start on Evaluating Llama on Text2SQL From e182902fc052a68776f5056a72f8483ebb1d1d8f Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Sat, 28 Jun 2025 11:05:10 -0700 Subject: [PATCH 17/78] train loss cot; README --- .../coding/text2sql/tool/README.md | 3 +++ .../tool/fine_tuning/train_loss_cot.png | Bin 0 -> 104889 bytes 2 files changed, 3 insertions(+) create mode 100644 end-to-end-use-cases/coding/text2sql/tool/fine_tuning/train_loss_cot.png diff --git a/end-to-end-use-cases/coding/text2sql/tool/README.md b/end-to-end-use-cases/coding/text2sql/tool/README.md index 7fe77fe80..c4ba12422 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/README.md +++ b/end-to-end-use-cases/coding/text2sql/tool/README.md @@ -199,6 +199,9 @@ Let me think through this step by step:\n\n1. First, I need to consider...\n2. T Uncomment the line `# FT_DATASET = "train_text2sql_cot_dataset.json"` in trl_sft.py to use the reasoning dataset for fine-tuning. Then run `python trl_sft.py`. After the fine-tuning completes, you'll see the fine-tuned model saved to `llama31-8b-text2sql-fine-tuned`, specified in `output_dir="llama31-8b-text2sql-fine-tuned"` of `TrainingArguments` in `trl_sft.py` - you may want to rename the `output_dir` folder to something else to avoid overwriting the previous fine-tuned model. +The train loss chart will look like this: +![](fine_tuning/train_loss_cot.png) + ### Evaluating the fine-tuned model (With Reasoning) First, modify `llama_eval.sh` to use the fine-tuned model, which should match the `output_dir` in `TrainingArguments` in `trl_sft.py`: diff --git a/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/train_loss_cot.png b/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/train_loss_cot.png new file mode 100644 index 0000000000000000000000000000000000000000..3ffc7f871457bf1bad62d10132990ca0d79b6bc8 GIT binary patch literal 104889 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μuPT;+OpehmQjI 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

5%g_HU5vC@4a2HIhaU~hazEhxeu~Czuc{0hv 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
\n", + " \n", + " \n", + " [60/60 02:09, Epoch 0/1]\n", + "
\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
StepTraining Loss
11.124300
21.146600
31.080300
41.007300
51.294600
60.990800
70.945300
80.977200
90.709900
100.730600
110.742400
120.651700
130.610100
140.659700
150.582100
160.526100
170.701700
180.540800
190.580600
200.466500
210.432900
220.588300
230.392800
240.571500
250.473200
260.432700
270.460100
280.510300
290.329800
300.448200
310.444500
320.344200
330.439600
340.302700
350.403300
360.348200
370.363500
380.398100
390.518900
400.263000
410.286800
420.320400
430.324000
440.387200
450.230200
460.448800
470.196300
480.384200
490.337900
500.259800
510.262400
520.360300
530.151700
540.220300
550.297200
560.238500
570.292100
580.321500
590.257700
600.212100

" + ] + }, + "metadata": {} + } + ], + "source": [ + "trainer_stats = trainer.train()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "cellView": "form", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "pCqnaKmlO1U9", + "outputId": "26677bc3-d541-49ff-fc57-6db2b956e0f1" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "144.3049 seconds used for training.\n", + "2.41 minutes used for training.\n", + "Peak reserved memory = 30.502 GB.\n", + "Peak reserved memory for training = 0.0 GB.\n", + "Peak reserved memory % of max memory = 77.109 %.\n", + "Peak reserved memory for training % of max memory = 0.0 %.\n" + ] + } + ], + "source": [ + "# @title Show final memory and time stats\n", + "used_memory = round(torch.cuda.max_memory_reserved() / 1024 / 1024 / 1024, 3)\n", + "used_memory_for_lora = round(used_memory - start_gpu_memory, 3)\n", + "used_percentage = round(used_memory / max_memory * 100, 3)\n", + "lora_percentage = round(used_memory_for_lora / max_memory * 100, 3)\n", + "print(f\"{trainer_stats.metrics['train_runtime']} seconds used for training.\")\n", + "print(\n", + " f\"{round(trainer_stats.metrics['train_runtime']/60, 2)} minutes used for training.\"\n", + ")\n", + "print(f\"Peak reserved memory = {used_memory} GB.\")\n", + "print(f\"Peak reserved memory for training = {used_memory_for_lora} GB.\")\n", + "print(f\"Peak reserved memory % of max memory = {used_percentage} %.\")\n", + "print(f\"Peak reserved memory for training % of max memory = {lora_percentage} %.\")" + ] + }, + { + "cell_type": "markdown", + "source": [], + "metadata": { + "id": "PGU_6HO40Q2i" + } + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ekOmTR1hSNcr" + }, + "source": [ + "\n", + "### Inference\n", + "Let's run the model! You can change the instruction and input - leave the output blank!\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "kR3gIAX-SM2q", + "outputId": "08b36347-9bcc-40db-e9cc-f036668f0727" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "The following generation flags are not valid and may be ignored: ['cache_implementation']. Set `TRANSFORMERS_VERBOSITY=info` for more details.\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "['<|begin_of_text|>Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.\\n\\n### Instruction:\\nYou are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement.\\n\\n### Input:\\n-- DB Schema: CREATE TABLE \"lists\"\\n(\\n user_id INTEGER\\n references lists_users (user_id),\\n list_id INTEGER not null\\n primary key,\\n list_title TEXT,\\n list_movie_number INTEGER,\\n list_update_timestamp_utc TEXT,\\n list_creation_timestamp_utc TEXT,\\n list_followers INTEGER,\\n list_url TEXT,\\n list_comments INTEGER,\\n list_description TEXT,\\n list_cover_image_url TEXT,\\n list_first_image_url TEXT,\\n list_second_image_url TEXT,\\n list_third_image_url TEXT\\n)\\n\\nCREATE TABLE \"movies\"\\n(\\n movie_id INTEGER not null\\n primary key,\\n movie_title TEXT,\\n movie_release_year INTEGER,\\n movie_url TEXT,\\n movie_title_language TEXT,\\n movie_popularity INTEGER,\\n movie_image_url TEXT,\\n director_id TEXT,\\n director_name TEXT,\\n director_url TEXT\\n)\\n\\nCREATE TABLE \"ratings_users\"\\n(\\n user_id INTEGER\\n references lists_users (user_id),\\n rating_date_utc TEXT,\\n user_trialist INTEGER,\\n user_subscriber INTEGER,\\n user_avatar_image_url TEXT,\\n user_cover_image_url TEXT,\\n user_eligible_for_trial INTEGER,\\n user_has_payment_method INTEGER\\n)\\n\\nCREATE TABLE lists_users\\n(\\n user_id INTEGER not null,\\n list_id INTEGER not null,\\n list_update_date_utc TEXT,\\n list_creation_date_utc TEXT,\\n user_trialist INTEGER,\\n user_subscriber INTEGER,\\n user_avatar_image_url TEXT,\\n user_cover_image_url TEXT,\\n user_eligible_for_trial TEXT,\\n user_has_payment_method TEXT,\\n primary key (user_id, list_id),\\n foreign key (list_id) references lists(list_id),\\n foreign key (user_id) references lists(user_id)\\n)\\n\\nCREATE TABLE ratings\\n(\\n movie_id INTEGER,\\n rating_id INTEGER,\\n rating_url TEXT,\\n rating_score INTEGER,\\n rating_timestamp_utc TEXT,\\n critic TEXT,\\n critic_likes INTEGER,\\n critic_comments INTEGER,\\n user_id INTEGER,\\n user_trialist INTEGER,\\n user_subscriber INTEGER,\\n user_eligible_for_trial INTEGER,\\n user_has_payment_method INTEGER,\\n foreign key (movie_id) references movies(movie_id),\\n foreign key (user_id) references lists_users(user_id),\\n foreign key (rating_id) references ratings(rating_id),\\n foreign key (user_id) references ratings_users(user_id)\\n)\\n\\n-- External Knowledge: longest movie title refers to MAX(LENGTH(movie_title)); when it was released refers to movie_release_year;\\n\\n-- Question: What is the name of the longest movie title? When was it released?\\n\\n### Response:\\nSELECT T2.movie_title, T2.movie_release_year FROM lists AS T1 INNER JOIN movies AS T2 ON T1.list_id = T2.movie_id ORDER BY LENGTH(T2.movie_title) DESC LIMIT 1<|eot_id|>']" + ] + }, + "metadata": {}, + "execution_count": 21 + } + ], + "source": [ + "# alpaca_prompt = Copied from above\n", + "FastLanguageModel.for_inference(model) # Enable native 2x faster inference\n", + "inputs = tokenizer(\n", + "[\n", + " alpaca_prompt.format(\n", + " \"You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement.\", # instruction\n", + " \"-- DB Schema: CREATE TABLE \\\"lists\\\"\\n(\\n user_id INTEGER\\n references lists_users (user_id),\\n list_id INTEGER not null\\n primary key,\\n list_title TEXT,\\n list_movie_number INTEGER,\\n list_update_timestamp_utc TEXT,\\n list_creation_timestamp_utc TEXT,\\n list_followers INTEGER,\\n list_url TEXT,\\n list_comments INTEGER,\\n list_description TEXT,\\n list_cover_image_url TEXT,\\n list_first_image_url TEXT,\\n list_second_image_url TEXT,\\n list_third_image_url TEXT\\n)\\n\\nCREATE TABLE \\\"movies\\\"\\n(\\n movie_id INTEGER not null\\n primary key,\\n movie_title TEXT,\\n movie_release_year INTEGER,\\n movie_url TEXT,\\n movie_title_language TEXT,\\n movie_popularity INTEGER,\\n movie_image_url TEXT,\\n director_id TEXT,\\n director_name TEXT,\\n director_url TEXT\\n)\\n\\nCREATE TABLE \\\"ratings_users\\\"\\n(\\n user_id INTEGER\\n references lists_users (user_id),\\n rating_date_utc TEXT,\\n user_trialist INTEGER,\\n user_subscriber INTEGER,\\n user_avatar_image_url TEXT,\\n user_cover_image_url TEXT,\\n user_eligible_for_trial INTEGER,\\n user_has_payment_method INTEGER\\n)\\n\\nCREATE TABLE lists_users\\n(\\n user_id INTEGER not null ,\\n list_id INTEGER not null ,\\n list_update_date_utc TEXT,\\n list_creation_date_utc TEXT,\\n user_trialist INTEGER,\\n user_subscriber INTEGER,\\n user_avatar_image_url TEXT,\\n user_cover_image_url TEXT,\\n user_eligible_for_trial TEXT,\\n user_has_payment_method TEXT,\\n primary key (user_id, list_id),\\n foreign key (list_id) references lists(list_id),\\n foreign key (user_id) references lists(user_id)\\n)\\n\\nCREATE TABLE ratings\\n(\\n movie_id INTEGER,\\n rating_id INTEGER,\\n rating_url TEXT,\\n rating_score INTEGER,\\n rating_timestamp_utc TEXT,\\n critic TEXT,\\n critic_likes INTEGER,\\n critic_comments INTEGER,\\n user_id INTEGER,\\n user_trialist INTEGER,\\n user_subscriber INTEGER,\\n user_eligible_for_trial INTEGER,\\n user_has_payment_method INTEGER,\\n foreign key (movie_id) references movies(movie_id),\\n foreign key (user_id) references lists_users(user_id),\\n foreign key (rating_id) references ratings(rating_id),\\n foreign key (user_id) references ratings_users(user_id)\\n)\\n\\n-- External Knowledge: longest movie title refers to MAX(LENGTH(movie_title)); when it was released refers to movie_release_year;\\n\\n-- Question: What is the name of the longest movie title? When was it released?\", # input\n", + " \"\", # output - leave this blank for generation!\n", + " )\n", + "], return_tensors = \"pt\").to(\"cuda\")\n", + "\n", + "outputs = model.generate(**inputs, max_new_tokens = 1024, use_cache = False)\n", + "tokenizer.batch_decode(outputs)" + ] + }, + { + "cell_type": "code", + "source": [ + "# # alpaca_prompt = Copied from above\n", + "# FastLanguageModel.for_inference(model) # Enable native 2x faster inference\n", + "# inputs = tokenizer(\n", + "# [\n", + "# alpaca_prompt.format(\n", + "# \"You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement.\", # instruction\n", + "# \"-- DB Schema: CREATE TABLE \\\"lists\\\"\\n(\\n user_id INTEGER\\n references lists_users (user_id),\\n list_id INTEGER not null\\n primary key,\\n list_title TEXT,\\n list_movie_number INTEGER,\\n list_update_timestamp_utc TEXT,\\n list_creation_timestamp_utc TEXT,\\n list_followers INTEGER,\\n list_url TEXT,\\n list_comments INTEGER,\\n list_description TEXT,\\n list_cover_image_url TEXT,\\n list_first_image_url TEXT,\\n list_second_image_url TEXT,\\n list_third_image_url TEXT\\n)\\n\\nCREATE TABLE \\\"movies\\\"\\n(\\n movie_id INTEGER not null\\n primary key,\\n movie_title TEXT,\\n movie_release_year INTEGER,\\n movie_url TEXT,\\n movie_title_language TEXT,\\n movie_popularity INTEGER,\\n movie_image_url TEXT,\\n director_id TEXT,\\n director_name TEXT,\\n director_url TEXT\\n)\\n\\nCREATE TABLE \\\"ratings_users\\\"\\n(\\n user_id INTEGER\\n references lists_users (user_id),\\n rating_date_utc TEXT,\\n user_trialist INTEGER,\\n user_subscriber INTEGER,\\n user_avatar_image_url TEXT,\\n user_cover_image_url TEXT,\\n user_eligible_for_trial INTEGER,\\n user_has_payment_method INTEGER\\n)\\n\\nCREATE TABLE lists_users\\n(\\n user_id INTEGER not null ,\\n list_id INTEGER not null ,\\n list_update_date_utc TEXT,\\n list_creation_date_utc TEXT,\\n user_trialist INTEGER,\\n user_subscriber INTEGER,\\n user_avatar_image_url TEXT,\\n user_cover_image_url TEXT,\\n user_eligible_for_trial TEXT,\\n user_has_payment_method TEXT,\\n primary key (user_id, list_id),\\n foreign key (list_id) references lists(list_id),\\n foreign key (user_id) references lists(user_id)\\n)\\n\\nCREATE TABLE ratings\\n(\\n movie_id INTEGER,\\n rating_id INTEGER,\\n rating_url TEXT,\\n rating_score INTEGER,\\n rating_timestamp_utc TEXT,\\n critic TEXT,\\n critic_likes INTEGER,\\n critic_comments INTEGER,\\n user_id INTEGER,\\n user_trialist INTEGER,\\n user_subscriber INTEGER,\\n user_eligible_for_trial INTEGER,\\n user_has_payment_method INTEGER,\\n foreign key (movie_id) references movies(movie_id),\\n foreign key (user_id) references lists_users(user_id),\\n foreign key (rating_id) references ratings(rating_id),\\n foreign key (user_id) references ratings_users(user_id)\\n)\\n\\n-- External Knowledge: longest movie title refers to MAX(LENGTH(movie_title)); when it was released refers to movie_release_year;\\n\\n-- Question: What is the name of the longest movie title? When was it released?\", # input\n", + "# \"\", # output - leave this blank for generation!\n", + "# )\n", + "# ], return_tensors = \"pt\").to(\"cuda\")\n", + "\n", + "# outputs = model.generate(**inputs, max_new_tokens = 1024, use_cache = True)\n", + "# tokenizer.batch_decode(outputs)" + ], + "metadata": { + "id": "dusmu3Y-WPl_" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QQMjaNrjsU5_" + }, + "source": [ + "You can also use Hugging Face's `AutoModelForPeftCausalLM`. Only use this if you do not have `unsloth` installed. It can be hopelessly slow, since `4bit` model downloading is not supported, and Unsloth's **inference is 2x faster**." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "yFfaXG0WsQuE" + }, + "outputs": [], + "source": [ + "if False:\n", + " # I highly do NOT suggest - use Unsloth if possible\n", + " from peft import AutoPeftModelForCausalLM\n", + " from transformers import AutoTokenizer\n", + " model = AutoPeftModelForCausalLM.from_pretrained(\n", + " \"lora_model\", # YOUR MODEL YOU USED FOR TRAINING\n", + " load_in_4bit = load_in_4bit,\n", + " )\n", + " tokenizer = AutoTokenizer.from_pretrained(\"lora_model\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "upcOlWe7A1vc", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 130, + "referenced_widgets": [ + "b89abd16ac7645c2af3861be2a53e7a4", + "0a3dbf62929640f5b670bb9932ff9e85", + "774bc595ccdf4fcfbc078ae69e31cce2", + "a401420ba5a84c4e8e09d189ae31791f", + "d9338d0b5aa14d98a230f64a96dacfc6", + "da237a8e84234e9ab6eb73c8cc41dac5", + "6b730c841c28487596cb1358402f618b", + "954b8f5078384488b503919bb47b380e", + "2e589652d1b641b1bd49109f3a963a63", + "9db7e5022a1a4c82a4b218c4f0e58a7d", + "ec69d72c400d497cb43db1a2c4d3ffd0", + "9124002ea80946079b05669b8edf2e93", + "2418f4815f8e4db38821f04715509a87", + "8b024ae17b3d4f9d9458e0d24c4ba858", + "3aca95703e0b4da195020b22e03794d5", + "888e1a411dd84e68a9fb45319a384e53", + "2aa533d9f8154a2890442924f939b936", + "f7f0f1b891454fcb8271c2fd9afa5e39", + "032982a7372d47c09a039de0f89e7626", + "e909536897824b8492ed21651d7cdcc2", + "56f54ec10c5a411d97a8add4e37419e7", + "9ae2b77ef66949a8ac1a2c073adf654e", + "be77d2c16a8544ffae3c3224a88ceac7", + "18730cc628544463be32a527143908e7", + "783f0b6997c04133a92e75c8c1970555", + "317c60b6371b4f0b8903659a48915549", + "3299e112ee0e4b948383d0965e000665", + "123983553f524c86b2e34137c3e15a81", + "f8f4c7d3484040f5b7cc63dd507e7cac", + "bb9630f74a664507ac5fa5e7c3b28287", + "b80165d852f547f28d0ef91276586a4d", + "a46d09b6a9b649bd95b48d1ec9430a55", + "358661cd13c14e6eb64591b288f9f02f" + ] + }, + "outputId": "50f44657-a02d-4657-ce10-29436f4a4ad8" + }, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "README.md: 0%| | 0.00/587 [00:00 Date: Tue, 1 Jul 2025 09:19:45 -0700 Subject: [PATCH 20/78] README and requirements.txt update --- .../coding/text2sql/tool/README.md | 16 ++++++++++------ .../coding/text2sql/tool/requirements.txt | 8 ++++---- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/tool/README.md b/end-to-end-use-cases/coding/text2sql/tool/README.md index 98ef76d20..f6d419dbb 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/README.md +++ b/end-to-end-use-cases/coding/text2sql/tool/README.md @@ -2,13 +2,17 @@ ## Overview -This folder contains scripts for evaluating Llama (original and fine-tuned) models on the Text2SQL task using the popular [BIRD](https://bird-bench.github.io) dataset, and scripts for generating fine-tuning datasets and fine-tuning Llama 3.1 8B with the datasets. +This folder contains scripts to: +1. Evaluate Llama (original and fine-tuned) models on the Text2SQL task using the popular [BIRD](https://bird-bench.github.io) dataset; +2. Generate fine-tuning datasets (with and without reasoning steps)and fine-tuning Llama 3.1 8B with the datasets, gaining a **165% (with no reasoning) and 209% (with reasoning) accuracy improvement** over the original model. -We have updated and significantly simplified the original eval scripts from the BIRD [repo](https://github.com/AlibabaResearch/DAMO-ConvAI/tree/main/bird) for Llama 3 & 4 models hosted via Meta's [Llama API](https://llama.developer.meta.com) or [Together.ai](https://together.ai), as well as the fine-tuned Llama 3.1 model, so you can quickly evaluate in 1-2-3 steps how well different Llama models perform on the Text2SQL task. +Our end goal is to maximize the accuracy of Llama models on the Text2SQL task via fine-tuning, agent and other approaches. To do so we need to first evaluate the current state of the art Llama models on the task. In other words, "no eval, no success" AND "eval only is not success". Hence, we have created this tool to quickly evaluate Llama models on the Text2SQL task and, as a first step, to fine-tune Llama models to improve their accuracy on the task. + +## Llama Text2SQL Evaluation -We have also provided end-to-end scripts for generating datasets (with and without reasoning steps) and fine-tuning the quantized Llama 3.1 8B model to gain a **165% (with no reasoning) and 209% (with reasoning) accuracy improvement** over the original model. +We have updated and significantly simplified the original eval scripts from the BIRD [repo](https://github.com/AlibabaResearch/DAMO-ConvAI/tree/main/bird) for Llama 3 & 4 models hosted via Meta's [Llama API](https://llama.developer.meta.com) or [Together.ai](https://together.ai), as well as the fine-tuned Llama 3.1 model, so you can quickly evaluate in 1-2-3 steps how well different Llama models perform on the Text2SQL task. -## Llama Text2SQL Evaluation Results +### Evaluation Results Below are the results of the Llama models we have evaluated on the BIRD DEV dataset: @@ -24,7 +28,7 @@ Below are the results of the Llama models we have evaluated on the BIRD DEV data - Fine-tuned with no reasoning dataset: 37.16% - Fine-tuned with reasoning dataset: 43.37% -## Quick Start on Evaluating Llama on Text2SQL +### Quick Start on Evaluating Llama on Text2SQL First, run the commands below to create a new Conda environment and install all the required packages for Text2SQL evaluation and fine-tuning: @@ -54,7 +58,7 @@ After the script completes, you'll see the accuracy of the Llama model on the BI *Note:* To compare your evaluated accuracy of your selected Llama model with other results in the BIRD Dev leaderboard, click [here](https://bird-bench.github.io/). -## Evaluation Process +### Evaluation Process 1. **SQL Generation**: `llama_text2sql.py` sends natural language questions to the specified Llama model and collects the generated SQL queries. diff --git a/end-to-end-use-cases/coding/text2sql/tool/requirements.txt b/end-to-end-use-cases/coding/text2sql/tool/requirements.txt index 259fe8160..def1eccc3 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/requirements.txt +++ b/end-to-end-use-cases/coding/text2sql/tool/requirements.txt @@ -1,10 +1,10 @@ llama_api_client==0.1.1 langchain-together==0.3.0 -sqlparse +sqlparse==0.5.3 torch==2.4.1 -tensorboard +tensorboard==2.19.0 liger-kernel==0.4.2 -setuptools +setuptools==78.1.1 deepspeed==0.15.4 transformers==4.46.3 datasets==3.6.0 @@ -14,4 +14,4 @@ trl==0.12.1 peft==0.13.2 lighteval==0.6.2 hf-transfer==0.1.8 -func_timeout +func_timeout==4.3.5 From 5e8a7b03a3b9f8f03ddcb5fb561139a1be452da7 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Tue, 1 Jul 2025 09:23:52 -0700 Subject: [PATCH 21/78] remove needless words in README --- end-to-end-use-cases/coding/text2sql/tool/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/tool/README.md b/end-to-end-use-cases/coding/text2sql/tool/README.md index f6d419dbb..91ade764f 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/README.md +++ b/end-to-end-use-cases/coding/text2sql/tool/README.md @@ -52,11 +52,11 @@ sh download_dev_unzip.sh 3. Run the evaluation script `sh llama_eval.sh`, which will use the BIRD DEV dataset (1534 examples in total) with external knowledge turned on to run the Llama model on each text question and compare the generated SQL with the gold SQL. -*Note:* If your API key or model name is incorrect, the script will exit with an authentication or model not supported error. +If your API key or model name is incorrect, the script will exit with an authentication or model not supported error. After the script completes, you'll see the accuracy of the Llama model on the BIRD DEV text2sql. For example, the total accuracy is about 54.24% with `YOUR_API_KEY` set to your Llama API key and `model='Llama-3.3-70B-Instruct'`, or about 35.07% with `YOUR_API_KEY` set to your Together API key and `model=meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo`. -*Note:* To compare your evaluated accuracy of your selected Llama model with other results in the BIRD Dev leaderboard, click [here](https://bird-bench.github.io/). +To compare your evaluated accuracy of your selected Llama model with other results in the BIRD Dev leaderboard, click [here](https://bird-bench.github.io/). ### Evaluation Process From 71ca0aee8d0429515f6bfbeaee83bc0e767dc5bc Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Tue, 1 Jul 2025 09:26:39 -0700 Subject: [PATCH 22/78] README update --- end-to-end-use-cases/coding/text2sql/tool/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/tool/README.md b/end-to-end-use-cases/coding/text2sql/tool/README.md index 91ade764f..475a781f7 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/README.md +++ b/end-to-end-use-cases/coding/text2sql/tool/README.md @@ -68,16 +68,16 @@ To compare your evaluated accuracy of your selected Llama model with other resul 4. **Accuracy Calculation**: Accuracy scores are calculated overall and broken down by difficulty levels (simple, moderate, challenging). -## Supported Models +### Supported Models for Evaluation -### Together AI Models +Llama models supported on Together AI: - meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo - meta-llama/Llama-3.3-70B-Instruct-Turbo - meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8 - meta-llama/Llama-4-Scout-17B-16E-Instruct - other Llama models hosted on Together AI -### Llama API Models +Llama models supported on Llama API: - Llama-3.3-8B-Instruct - Llama-3.3-70B-Instruct - Llama-4-Maverick-17B-128E-Instruct-FP8 From b17f90b9669dd2f3036c23f36523651175f6d632 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Tue, 1 Jul 2025 15:15:19 -0700 Subject: [PATCH 23/78] README update --- end-to-end-use-cases/coding/text2sql/tool/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/tool/README.md b/end-to-end-use-cases/coding/text2sql/tool/README.md index 475a781f7..3dcaf03f0 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/README.md +++ b/end-to-end-use-cases/coding/text2sql/tool/README.md @@ -3,14 +3,14 @@ ## Overview This folder contains scripts to: -1. Evaluate Llama (original and fine-tuned) models on the Text2SQL task using the popular [BIRD](https://bird-bench.github.io) dataset; +1. Evaluate Llama (original and fine-tuned) models on the Text2SQL task using the popular [BIRD](https://bird-bench.github.io) dataset in **three simple steps**; 2. Generate fine-tuning datasets (with and without reasoning steps)and fine-tuning Llama 3.1 8B with the datasets, gaining a **165% (with no reasoning) and 209% (with reasoning) accuracy improvement** over the original model. Our end goal is to maximize the accuracy of Llama models on the Text2SQL task via fine-tuning, agent and other approaches. To do so we need to first evaluate the current state of the art Llama models on the task. In other words, "no eval, no success" AND "eval only is not success". Hence, we have created this tool to quickly evaluate Llama models on the Text2SQL task and, as a first step, to fine-tune Llama models to improve their accuracy on the task. ## Llama Text2SQL Evaluation -We have updated and significantly simplified the original eval scripts from the BIRD [repo](https://github.com/AlibabaResearch/DAMO-ConvAI/tree/main/bird) for Llama 3 & 4 models hosted via Meta's [Llama API](https://llama.developer.meta.com) or [Together.ai](https://together.ai), as well as the fine-tuned Llama 3.1 model, so you can quickly evaluate in 1-2-3 steps how well different Llama models perform on the Text2SQL task. +We have updated and significantly simplified the original eval scripts from the BIRD [repo](https://github.com/AlibabaResearch/DAMO-ConvAI/tree/main/bird) for Llama 3 & 4 models hosted via Meta's [Llama API](https://llama.developer.meta.com) or [Together.ai](https://together.ai), as well as the fine-tuned Llama 3.1 model. ### Evaluation Results From 6815255595d4a214f68e0682420c07d3b4985391 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Wed, 2 Jul 2025 09:31:47 -0700 Subject: [PATCH 24/78] folder struc refactoring --- .../text2sql/{tool => }/data/download_dev_unzip.sh | 0 .../{tool => }/data/download_train_unzip.sh | 0 .../coding/text2sql/{tool => eval}/README.md | 0 .../coding/text2sql/{tool => eval}/llama_eval.sh | 0 .../text2sql/{tool => eval}/llama_text2sql.py | 0 .../coding/text2sql/{tool => eval}/requirements.txt | 0 .../coding/text2sql/{tool => eval}/text2sql_eval.py | 0 .../create_reasoning_dataset.py | 0 .../create_sft_dataset.py | 0 ...ing_llama_3_1_8b_with_text2sql_sft_dataset.ipynb | 0 .../fine_tuning => fine-tuning}/train_loss.png | Bin .../fine_tuning => fine-tuning}/train_loss_cot.png | Bin .../{tool/fine_tuning => fine-tuning}/trl_sft.py | 0 13 files changed, 0 insertions(+), 0 deletions(-) rename end-to-end-use-cases/coding/text2sql/{tool => }/data/download_dev_unzip.sh (100%) rename end-to-end-use-cases/coding/text2sql/{tool => }/data/download_train_unzip.sh (100%) rename end-to-end-use-cases/coding/text2sql/{tool => eval}/README.md (100%) rename end-to-end-use-cases/coding/text2sql/{tool => eval}/llama_eval.sh (100%) rename end-to-end-use-cases/coding/text2sql/{tool => eval}/llama_text2sql.py (100%) rename end-to-end-use-cases/coding/text2sql/{tool => eval}/requirements.txt (100%) rename end-to-end-use-cases/coding/text2sql/{tool => eval}/text2sql_eval.py (100%) rename end-to-end-use-cases/coding/text2sql/{tool/fine_tuning => fine-tuning}/create_reasoning_dataset.py (100%) rename end-to-end-use-cases/coding/text2sql/{tool/fine_tuning => fine-tuning}/create_sft_dataset.py (100%) rename end-to-end-use-cases/coding/text2sql/{tool/fine_tuning => fine-tuning}/finetuning_llama_3_1_8b_with_text2sql_sft_dataset.ipynb (100%) rename end-to-end-use-cases/coding/text2sql/{tool/fine_tuning => fine-tuning}/train_loss.png (100%) rename end-to-end-use-cases/coding/text2sql/{tool/fine_tuning => fine-tuning}/train_loss_cot.png (100%) rename end-to-end-use-cases/coding/text2sql/{tool/fine_tuning => fine-tuning}/trl_sft.py (100%) diff --git a/end-to-end-use-cases/coding/text2sql/tool/data/download_dev_unzip.sh b/end-to-end-use-cases/coding/text2sql/data/download_dev_unzip.sh similarity index 100% rename from end-to-end-use-cases/coding/text2sql/tool/data/download_dev_unzip.sh rename to end-to-end-use-cases/coding/text2sql/data/download_dev_unzip.sh diff --git a/end-to-end-use-cases/coding/text2sql/tool/data/download_train_unzip.sh b/end-to-end-use-cases/coding/text2sql/data/download_train_unzip.sh similarity index 100% rename from end-to-end-use-cases/coding/text2sql/tool/data/download_train_unzip.sh rename to end-to-end-use-cases/coding/text2sql/data/download_train_unzip.sh diff --git a/end-to-end-use-cases/coding/text2sql/tool/README.md b/end-to-end-use-cases/coding/text2sql/eval/README.md similarity index 100% rename from end-to-end-use-cases/coding/text2sql/tool/README.md rename to end-to-end-use-cases/coding/text2sql/eval/README.md diff --git a/end-to-end-use-cases/coding/text2sql/tool/llama_eval.sh b/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh similarity index 100% rename from end-to-end-use-cases/coding/text2sql/tool/llama_eval.sh rename to end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh diff --git a/end-to-end-use-cases/coding/text2sql/tool/llama_text2sql.py b/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py similarity index 100% rename from end-to-end-use-cases/coding/text2sql/tool/llama_text2sql.py rename to end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py diff --git a/end-to-end-use-cases/coding/text2sql/tool/requirements.txt b/end-to-end-use-cases/coding/text2sql/eval/requirements.txt similarity index 100% rename from end-to-end-use-cases/coding/text2sql/tool/requirements.txt rename to end-to-end-use-cases/coding/text2sql/eval/requirements.txt diff --git a/end-to-end-use-cases/coding/text2sql/tool/text2sql_eval.py b/end-to-end-use-cases/coding/text2sql/eval/text2sql_eval.py similarity index 100% rename from end-to-end-use-cases/coding/text2sql/tool/text2sql_eval.py rename to end-to-end-use-cases/coding/text2sql/eval/text2sql_eval.py diff --git a/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/create_reasoning_dataset.py b/end-to-end-use-cases/coding/text2sql/fine-tuning/create_reasoning_dataset.py similarity index 100% rename from end-to-end-use-cases/coding/text2sql/tool/fine_tuning/create_reasoning_dataset.py rename to end-to-end-use-cases/coding/text2sql/fine-tuning/create_reasoning_dataset.py diff --git a/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/create_sft_dataset.py b/end-to-end-use-cases/coding/text2sql/fine-tuning/create_sft_dataset.py similarity index 100% rename from end-to-end-use-cases/coding/text2sql/tool/fine_tuning/create_sft_dataset.py rename to end-to-end-use-cases/coding/text2sql/fine-tuning/create_sft_dataset.py diff --git a/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/finetuning_llama_3_1_8b_with_text2sql_sft_dataset.ipynb b/end-to-end-use-cases/coding/text2sql/fine-tuning/finetuning_llama_3_1_8b_with_text2sql_sft_dataset.ipynb similarity index 100% rename from end-to-end-use-cases/coding/text2sql/tool/fine_tuning/finetuning_llama_3_1_8b_with_text2sql_sft_dataset.ipynb rename to end-to-end-use-cases/coding/text2sql/fine-tuning/finetuning_llama_3_1_8b_with_text2sql_sft_dataset.ipynb diff --git a/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/train_loss.png b/end-to-end-use-cases/coding/text2sql/fine-tuning/train_loss.png similarity index 100% rename from end-to-end-use-cases/coding/text2sql/tool/fine_tuning/train_loss.png rename to end-to-end-use-cases/coding/text2sql/fine-tuning/train_loss.png diff --git a/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/train_loss_cot.png b/end-to-end-use-cases/coding/text2sql/fine-tuning/train_loss_cot.png similarity index 100% rename from end-to-end-use-cases/coding/text2sql/tool/fine_tuning/train_loss_cot.png rename to end-to-end-use-cases/coding/text2sql/fine-tuning/train_loss_cot.png diff --git a/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/trl_sft.py b/end-to-end-use-cases/coding/text2sql/fine-tuning/trl_sft.py similarity index 100% rename from end-to-end-use-cases/coding/text2sql/tool/fine_tuning/trl_sft.py rename to end-to-end-use-cases/coding/text2sql/fine-tuning/trl_sft.py From 03ba7d59a86e8960bc826615f7d86d82cb3e6407 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Wed, 2 Jul 2025 09:40:36 -0700 Subject: [PATCH 25/78] quickstart folder --- .../coding/text2sql/{ => quickstart}/csv2db.py | 0 .../coding/text2sql/{ => quickstart}/nba.txt | 0 .../coding/text2sql/{ => quickstart}/nba_roster.db | Bin .../text2sql/{ => quickstart}/quickstart.ipynb | 0 .../text2sql/{ => quickstart}/requirements.txt | 0 .../coding/text2sql/{ => quickstart}/txt2csv.py | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename end-to-end-use-cases/coding/text2sql/{ => quickstart}/csv2db.py (100%) rename end-to-end-use-cases/coding/text2sql/{ => quickstart}/nba.txt (100%) rename end-to-end-use-cases/coding/text2sql/{ => quickstart}/nba_roster.db (100%) rename end-to-end-use-cases/coding/text2sql/{ => quickstart}/quickstart.ipynb (100%) rename end-to-end-use-cases/coding/text2sql/{ => quickstart}/requirements.txt (100%) rename end-to-end-use-cases/coding/text2sql/{ => quickstart}/txt2csv.py (100%) diff --git a/end-to-end-use-cases/coding/text2sql/csv2db.py b/end-to-end-use-cases/coding/text2sql/quickstart/csv2db.py similarity index 100% rename from end-to-end-use-cases/coding/text2sql/csv2db.py rename to end-to-end-use-cases/coding/text2sql/quickstart/csv2db.py diff --git a/end-to-end-use-cases/coding/text2sql/nba.txt b/end-to-end-use-cases/coding/text2sql/quickstart/nba.txt similarity index 100% rename from end-to-end-use-cases/coding/text2sql/nba.txt rename to end-to-end-use-cases/coding/text2sql/quickstart/nba.txt diff --git a/end-to-end-use-cases/coding/text2sql/nba_roster.db b/end-to-end-use-cases/coding/text2sql/quickstart/nba_roster.db similarity index 100% rename from end-to-end-use-cases/coding/text2sql/nba_roster.db rename to end-to-end-use-cases/coding/text2sql/quickstart/nba_roster.db diff --git a/end-to-end-use-cases/coding/text2sql/quickstart.ipynb b/end-to-end-use-cases/coding/text2sql/quickstart/quickstart.ipynb similarity index 100% rename from end-to-end-use-cases/coding/text2sql/quickstart.ipynb rename to end-to-end-use-cases/coding/text2sql/quickstart/quickstart.ipynb diff --git a/end-to-end-use-cases/coding/text2sql/requirements.txt b/end-to-end-use-cases/coding/text2sql/quickstart/requirements.txt similarity index 100% rename from end-to-end-use-cases/coding/text2sql/requirements.txt rename to end-to-end-use-cases/coding/text2sql/quickstart/requirements.txt diff --git a/end-to-end-use-cases/coding/text2sql/txt2csv.py b/end-to-end-use-cases/coding/text2sql/quickstart/txt2csv.py similarity index 100% rename from end-to-end-use-cases/coding/text2sql/txt2csv.py rename to end-to-end-use-cases/coding/text2sql/quickstart/txt2csv.py From 11a4a6442216518c46848dd0957a32c3860d4c2c Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Wed, 2 Jul 2025 09:44:35 -0700 Subject: [PATCH 26/78] quickstart readme and colab link --- .../coding/text2sql/quickstart/README.md | 13 + .../text2sql/quickstart/quickstart.ipynb | 643 +++++++++--------- 2 files changed, 335 insertions(+), 321 deletions(-) create mode 100644 end-to-end-use-cases/coding/text2sql/quickstart/README.md diff --git a/end-to-end-use-cases/coding/text2sql/quickstart/README.md b/end-to-end-use-cases/coding/text2sql/quickstart/README.md new file mode 100644 index 000000000..5379ae682 --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/quickstart/README.md @@ -0,0 +1,13 @@ +## Quickstart with Text2SQL + +The scripts and notebook in this folder let you get familiar with how to interact with a database using natural language inputs by asking Llama to convert natural language queries into SQL queries. + +For detailed instructions on setting up the environment, creating a database, and executing natural language queries using the Text2SQL interface, please refer to the [quickstart.ipynb](quickstart.ipynb) notebook. + +### Structure: + +- quickstart.ipynb: A Quick Demo of Text2SQL Using Llama 3.3. This Jupyter Notebook includes examples of how to use the interface to execute natural language queries on the sample data. It uses Llama 3.3 to answer questions about a SQLite database using LangChain and the Llama cloud provider Together.ai. +- nba.txt: A text file containing NBA roster information, which is used as sample data for demonstration purposes. +- txt2csv.py: A script that converts text data into a CSV format. This script is used to preprocess the input data before it is fed into csv2db.py. +- csv2db.py: A script that imports data from a CSV file into a SQLite database. This script is used to populate the database with sample data. +- nba_roster.db: A SQLite database file created from the nba.txt data, used to test the Text2SQL interface. diff --git a/end-to-end-use-cases/coding/text2sql/quickstart/quickstart.ipynb b/end-to-end-use-cases/coding/text2sql/quickstart/quickstart.ipynb index 39c7e75cd..3b04f9890 100644 --- a/end-to-end-use-cases/coding/text2sql/quickstart/quickstart.ipynb +++ b/end-to-end-use-cases/coding/text2sql/quickstart/quickstart.ipynb @@ -1,334 +1,335 @@ { - "cells": [ - { - "cell_type": "markdown", - "id": "e8cba0b6", - "metadata": {}, - "source": [ - "\"Open \n", - "\n", - "## Quick Demo of Text2SQL Using Llama 3.3\n", - "\n", - "This demo shows how to use Llama 3.3 to answer questions about a SQLite DB. \n", - "\n", - "We'll use LangChain and the Llama cloud provider [Together.ai](https://api.together.ai/), where you can easily get a free API key (or you can use any other Llama cloud provider or even Ollama running Llama locally)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "33fb3190-59fb-4edd-82dd-f20f6eab3e47", - "metadata": {}, - "outputs": [], - "source": [ - "!pip install --upgrade -r requirements.txt" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "fa4562d3", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "from langchain_together import ChatTogether\n", - "\n", - "os.environ['TOGETHER_API_KEY'] = 'your_api_key'\n", - "\n", - "llm = ChatTogether(\n", - " model=\"meta-llama/Llama-3.3-70B-Instruct-Turbo\",\n", - " temperature=0,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "6d421ae7", - "metadata": {}, - "source": [ - "To recreate the `nba_roster.db` file, run the two commands below:\n", - "- `python txt2csv.py` to convert the `nba.txt` file to `nba_roster.csv`. The `nba.txt` file was created by scraping the NBA roster info from the web.\n", - "- `python csv2db.py` to convert `nba_roster.csv` to `nba_roster.db`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "56f0360e-fca3-49a8-9a70-0416f84e15fc", - "metadata": {}, - "outputs": [], - "source": [ - "# uncomment if you don't want to create the db yourself\n", - "#! wget https://github.com/meta-llama/llama-recipes/raw/3649841b426999fdc61c30a9fc8721106bec769b/recipes/use_cases/coding/text2sql/nba_roster.db" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "3bb99f39-cd7a-4db6-91dd-02f3bf80347c", - "metadata": {}, - "outputs": [], - "source": [ - "from langchain_community.utilities import SQLDatabase\n", - "\n", - "# Note: to run in Colab, you need to upload the nba_roster.db file in the repo to the Colab folder first.\n", - "db = SQLDatabase.from_uri(\"sqlite:///nba_roster.db\", sample_rows_in_table_info=0)\n", - "\n", - "def get_schema():\n", - " return db.get_table_info()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "8d793ce7-324b-4861-926c-54973d7c9b43", - "metadata": {}, - "outputs": [ + "cells": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Based on the table schema below, write a SQL query that would answer the user's question; just return the SQL query and nothing else.\n", - "\n", - "Scheme:\n", - "\n", - "CREATE TABLE nba_roster (\n", - "\t\"Team\" TEXT, \n", - "\t\"NAME\" TEXT, \n", - "\t\"Jersey\" TEXT, \n", - "\t\"POS\" TEXT, \n", - "\t\"AGE\" INTEGER, \n", - "\t\"HT\" TEXT, \n", - "\t\"WT\" TEXT, \n", - "\t\"COLLEGE\" TEXT, \n", - "\t\"SALARY\" TEXT\n", - ")\n", - "\n", - "Question: What team is Stephen Curry on?\n", - "\n", - "SQL Query:\n" - ] - } - ], - "source": [ - "question = \"What team is Stephen Curry on?\"\n", - "prompt = f\"\"\"Based on the table schema below, write a SQL query that would answer the user's question; just return the SQL query and nothing else.\n", - "\n", - "Scheme:\n", - "{get_schema()}\n", - "\n", - "Question: {question}\n", - "\n", - "SQL Query:\"\"\"\n", - "\n", - "print(prompt)" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "70776558", - "metadata": {}, - "outputs": [ + "cell_type": "markdown", + "id": "e8cba0b6", + "metadata": {}, + "source": [ + "\"Open \n", + "\n", + "## Quick Demo of Text2SQL Using Llama 3.3\n", + "\n", + "This demo shows how to use Llama 3.3 to answer questions about a SQLite DB. \n", + "\n", + "We'll use LangChain and the Llama cloud provider [Together.ai](https://api.together.ai/), where you can easily get a free API key (or you can use any other Llama cloud provider or even Ollama running Llama locally)." + ] + }, { - "name": "stdout", - "output_type": "stream", - "text": [ - "SELECT Team FROM nba_roster WHERE NAME = 'Stephen Curry'\n" - ] - } - ], - "source": [ - "answer = llm.invoke(prompt).content\n", - "print(answer)" - ] - }, - { - "cell_type": "markdown", - "id": "afcf423a", - "metadata": {}, - "source": [ - "***Note:*** If you don't have the \"just return the SQL query and nothing else\" in the prompt above, you'll likely get more text other than the SQL query back in the answer, making some extra post-processing necessary before running the db query below." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "62472ce6-794b-4a61-b88c-a1e031e28e4e", - "metadata": {}, - "outputs": [ + "cell_type": "code", + "execution_count": null, + "id": "33fb3190-59fb-4edd-82dd-f20f6eab3e47", + "metadata": {}, + "outputs": [], + "source": [ + "!pip install --upgrade -r requirements.txt" + ] + }, { - "data": { - "text/plain": [ - "\"[('Golden State Warriors',)]\"" + "cell_type": "code", + "execution_count": 2, + "id": "fa4562d3", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "from langchain_together import ChatTogether\n", + "\n", + "os.environ['TOGETHER_API_KEY'] = 'your_api_key'\n", + "\n", + "llm = ChatTogether(\n", + " model=\"meta-llama/Llama-3.3-70B-Instruct-Turbo\",\n", + " temperature=0,\n", + ")" ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# note this is a dangerous operation and for demo purpose only; in production app you'll need to safe-guard any DB operation\n", - "result = db.run(answer)\n", - "result" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "39ed4bc3", - "metadata": {}, - "outputs": [ + }, { - "name": "stdout", - "output_type": "stream", - "text": [ - "I don't have enough information to determine whose salary you are referring to. Could you please provide more context or specify the person you are asking about?\n" - ] - } - ], - "source": [ - "# how about a follow up question\n", - "follow_up = \"What's his salary?\"\n", - "print(llm.invoke(follow_up).content)" - ] - }, - { - "cell_type": "markdown", - "id": "98b2c523", - "metadata": {}, - "source": [ - "Since we did not pass any context along with the follow-up to Llama, it doesn't know the answer. Let's try to fix it by adding context to the follow-up prompt." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "0c305278-29d2-4e88-9b3d-ad67c94ce0f2", - "metadata": {}, - "outputs": [ + "cell_type": "markdown", + "id": "6d421ae7", + "metadata": {}, + "source": [ + "To recreate the `nba_roster.db` file, run the two commands below:\n", + "- `python txt2csv.py` to convert the `nba.txt` file to `nba_roster.csv`. The `nba.txt` file was created by scraping the NBA roster info from the web.\n", + "- `python csv2db.py` to convert `nba_roster.csv` to `nba_roster.db`." + ] + }, { - "name": "stdout", - "output_type": "stream", - "text": [ - "Based on the table schema, question, SQL query, and SQL response below, write a new SQL response; be concise, just output the SQL response.\n", - "\n", - "Scheme:\n", - "\n", - "CREATE TABLE nba_roster (\n", - "\t\"Team\" TEXT, \n", - "\t\"NAME\" TEXT, \n", - "\t\"Jersey\" TEXT, \n", - "\t\"POS\" TEXT, \n", - "\t\"AGE\" INTEGER, \n", - "\t\"HT\" TEXT, \n", - "\t\"WT\" TEXT, \n", - "\t\"COLLEGE\" TEXT, \n", - "\t\"SALARY\" TEXT\n", - ")\n", - "\n", - "Question: What's his salary?\n", - "SQL Query: What team is Stephen Curry on?\n", - "SQL Result: [('Golden State Warriors',)]\n", - "\n", - "New SQL Response:\n", - "\n" - ] - } - ], - "source": [ - "prompt = f\"\"\"Based on the table schema, question, SQL query, and SQL response below, write a new SQL response; be concise, just output the SQL response.\n", - "\n", - "Scheme:\n", - "{get_schema()}\n", - "\n", - "Question: {follow_up}\n", - "SQL Query: {question}\n", - "SQL Result: {result}\n", - "\n", - "New SQL Response:\n", - "\"\"\"\n", - "print(prompt)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "03739b96-e607-4fa9-bc5c-df118198dc7f", - "metadata": {}, - "outputs": [ + "cell_type": "code", + "execution_count": null, + "id": "56f0360e-fca3-49a8-9a70-0416f84e15fc", + "metadata": {}, + "outputs": [], + "source": [ + "# uncomment if you don't want to create the db yourself\n", + "#! wget https://github.com/meta-llama/llama-recipes/raw/3649841b426999fdc61c30a9fc8721106bec769b/recipes/use_cases/coding/text2sql/nba_roster.db" + ] + }, { - "name": "stdout", - "output_type": "stream", - "text": [ - "SELECT SALARY FROM nba_roster WHERE NAME = \"Stephen Curry\"\n" - ] - } - ], - "source": [ - "new_answer = llm.invoke(prompt).content\n", - "print(new_answer)" - ] - }, - { - "cell_type": "markdown", - "id": "c782abb6-3b44-45be-8694-70fc29b82523", - "metadata": {}, - "source": [ - "Because we have \"be concise, just output the SQL response\", Llama 3 is able to just generate the SQL statement; otherwise output parsing will be needed." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "6ecfca53-be7e-4668-bad1-5ca7571817d7", - "metadata": {}, - "outputs": [ + "cell_type": "code", + "execution_count": 4, + "id": "3bb99f39-cd7a-4db6-91dd-02f3bf80347c", + "metadata": {}, + "outputs": [], + "source": [ + "from langchain_community.utilities import SQLDatabase\n", + "\n", + "# Note: to run in Colab, you need to upload the nba_roster.db file in the repo to the Colab folder first.\n", + "db = SQLDatabase.from_uri(\"sqlite:///nba_roster.db\", sample_rows_in_table_info=0)\n", + "\n", + "def get_schema():\n", + " return db.get_table_info()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "8d793ce7-324b-4861-926c-54973d7c9b43", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Based on the table schema below, write a SQL query that would answer the user's question; just return the SQL query and nothing else.\n", + "\n", + "Scheme:\n", + "\n", + "CREATE TABLE nba_roster (\n", + "\t\"Team\" TEXT, \n", + "\t\"NAME\" TEXT, \n", + "\t\"Jersey\" TEXT, \n", + "\t\"POS\" TEXT, \n", + "\t\"AGE\" INTEGER, \n", + "\t\"HT\" TEXT, \n", + "\t\"WT\" TEXT, \n", + "\t\"COLLEGE\" TEXT, \n", + "\t\"SALARY\" TEXT\n", + ")\n", + "\n", + "Question: What team is Stephen Curry on?\n", + "\n", + "SQL Query:\n" + ] + } + ], + "source": [ + "question = \"What team is Stephen Curry on?\"\n", + "prompt = f\"\"\"Based on the table schema below, write a SQL query that would answer the user's question; just return the SQL query and nothing else.\n", + "\n", + "Scheme:\n", + "{get_schema()}\n", + "\n", + "Question: {question}\n", + "\n", + "SQL Query:\"\"\"\n", + "\n", + "print(prompt)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "70776558", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "SELECT Team FROM nba_roster WHERE NAME = 'Stephen Curry'\n" + ] + } + ], + "source": [ + "answer = llm.invoke(prompt).content\n", + "print(answer)" + ] + }, + { + "cell_type": "markdown", + "id": "afcf423a", + "metadata": {}, + "source": [ + "***Note:*** If you don't have the \"just return the SQL query and nothing else\" in the prompt above, you'll likely get more text other than the SQL query back in the answer, making some extra post-processing necessary before running the db query below." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "62472ce6-794b-4a61-b88c-a1e031e28e4e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"[('Golden State Warriors',)]\"" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# note this is a dangerous operation and for demo purpose only; in production app you'll need to safe-guard any DB operation\n", + "result = db.run(answer)\n", + "result" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "39ed4bc3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "I don't have enough information to determine whose salary you are referring to. Could you please provide more context or specify the person you are asking about?\n" + ] + } + ], + "source": [ + "# how about a follow up question\n", + "follow_up = \"What's his salary?\"\n", + "print(llm.invoke(follow_up).content)" + ] + }, + { + "cell_type": "markdown", + "id": "98b2c523", + "metadata": {}, + "source": [ + "Since we did not pass any context along with the follow-up to Llama, it doesn't know the answer. Let's try to fix it by adding context to the follow-up prompt." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "0c305278-29d2-4e88-9b3d-ad67c94ce0f2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Based on the table schema, question, SQL query, and SQL response below, write a new SQL response; be concise, just output the SQL response.\n", + "\n", + "Scheme:\n", + "\n", + "CREATE TABLE nba_roster (\n", + "\t\"Team\" TEXT, \n", + "\t\"NAME\" TEXT, \n", + "\t\"Jersey\" TEXT, \n", + "\t\"POS\" TEXT, \n", + "\t\"AGE\" INTEGER, \n", + "\t\"HT\" TEXT, \n", + "\t\"WT\" TEXT, \n", + "\t\"COLLEGE\" TEXT, \n", + "\t\"SALARY\" TEXT\n", + ")\n", + "\n", + "Question: What's his salary?\n", + "SQL Query: What team is Stephen Curry on?\n", + "SQL Result: [('Golden State Warriors',)]\n", + "\n", + "New SQL Response:\n", + "\n" + ] + } + ], + "source": [ + "prompt = f\"\"\"Based on the table schema, question, SQL query, and SQL response below, write a new SQL response; be concise, just output the SQL response.\n", + "\n", + "Scheme:\n", + "{get_schema()}\n", + "\n", + "Question: {follow_up}\n", + "SQL Query: {question}\n", + "SQL Result: {result}\n", + "\n", + "New SQL Response:\n", + "\"\"\"\n", + "print(prompt)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "03739b96-e607-4fa9-bc5c-df118198dc7f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "SELECT SALARY FROM nba_roster WHERE NAME = \"Stephen Curry\"\n" + ] + } + ], + "source": [ + "new_answer = llm.invoke(prompt).content\n", + "print(new_answer)" + ] + }, + { + "cell_type": "markdown", + "id": "c782abb6-3b44-45be-8694-70fc29b82523", + "metadata": {}, + "source": [ + "Because we have \"be concise, just output the SQL response\", Llama 3 is able to just generate the SQL statement; otherwise output parsing will be needed." + ] + }, { - "data": { - "text/plain": [ - "\"[('$51,915,615',)]\"" + "cell_type": "code", + "execution_count": 11, + "id": "6ecfca53-be7e-4668-bad1-5ca7571817d7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"[('$51,915,615',)]\"" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "db.run(new_answer)" ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9d79bbb1-e91d-4b56-b6ef-98c94ff414d0", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "fileHeader": "", + "fileUid": "559664fd-826e-43fa-86b4-78edb9bbf80e", + "isAdHoc": false, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.14" } - ], - "source": [ - "db.run(new_answer)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9d79bbb1-e91d-4b56-b6ef-98c94ff414d0", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.14" } - }, - "nbformat": 4, - "nbformat_minor": 5 } From 99ead57fb6d72ae5d6627bfd681b8c3877b2c1d0 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Wed, 2 Jul 2025 10:26:09 -0700 Subject: [PATCH 27/78] 4 READMEs; requirements --- .../coding/text2sql/README.md | 30 ++-- .../coding/text2sql/eval/README.md | 167 +----------------- .../coding/text2sql/fine-tuning/README.md | 137 ++++++++++++++ .../text2sql/fine-tuning/requirements.txt | 17 ++ .../coding/text2sql/quickstart/README.md | 4 +- 5 files changed, 183 insertions(+), 172 deletions(-) create mode 100644 end-to-end-use-cases/coding/text2sql/fine-tuning/README.md create mode 100644 end-to-end-use-cases/coding/text2sql/fine-tuning/requirements.txt diff --git a/end-to-end-use-cases/coding/text2sql/README.md b/end-to-end-use-cases/coding/text2sql/README.md index eaaa91a9c..fd1e5f9dd 100644 --- a/end-to-end-use-cases/coding/text2sql/README.md +++ b/end-to-end-use-cases/coding/text2sql/README.md @@ -1,16 +1,24 @@ -## Text2SQL: Eval and Fine-tuning Tools and Quick Start Notebook +# Text2SQL: Evaluating and Fine-tuning Llama Models -This folder contains the `tool` subfolder, which has e2e scripts for evaluating Llama (original and fine-tuned) models on the Text2SQL task using the popular [BIRD](https://bird-bench.github.io) dataset, and e2e scripts for generating fine-tuning datasets and fine-tuning Llama 3.1 8B with the datasets. +This folder contains scripts to: -Before looking into the `tool` folder, you may start with the scripts and notebook in this folder to get familiar with how to interact with a database using natural language inputs bu asking Llama to convert natural language queries into SQL queries. +1. Evaluate Llama (original and fine-tuned) models on the Text2SQL task using the popular [BIRD](https://bird-bench.github.io) dataset in **3 simple steps**; -For detailed instructions on setting up the environment, creating a database, and executing natural language queries using the Text2SQL interface, please refer to the [quickstart.ipynb](quickstart.ipynb) notebook. +2. Generate fine-tuning datasets (both with and without CoT reasoning) and fine-tuning Llama 3.1 8B with the datasets, gaining a **165% (with no reasoning) and 209% (with reasoning) accuracy improvement** over the original model. -### Structure: +Our end goal is to maximize the accuracy of Llama models on the Text2SQL task. To do so we need to first evaluate the current state of the art Llama models on the task, then apply fine-tuning, agent and other approaches to evaluate and improve Llama's performance. -- tool: A folder containing scripts for evaluating and fine-tuning Llama models on the Text2SQL task. -- quickstart.ipynb: A Quick Demo of Text2SQL Using Llama 3.3. This Jupyter Notebook includes examples of how to use the interface to execute natural language queries on the sample data. It uses Llama 3.3 to answer questions about a SQLite database using LangChain and the Llama cloud provider Together.ai. -- nba.txt: A text file containing NBA roster information, which is used as sample data for demonstration purposes. -- txt2csv.py: A script that converts text data into a CSV format. This script is used to preprocess the input data before it is fed into csv2db.py. -- csv2db.py: A script that imports data from a CSV file into a SQLite database. This script is used to populate the database with sample data. -- nba_roster.db: A SQLite database file created from the nba.txt data, used to test the Text2SQL interface. +## Structure: + +- data: contains the scripts to download the BIRD TRAIN and DEV datasets; +- eval: contains the scripts to evaluate Llama models (original and fine-tuned) on the BIRD dataset; +- fine-tune: contains the scripts to generate non-CoT and CoT datasets based on the BIRD TRAIN set and to fine-tune Llama models using the datasets; +- quickstart: contains a notebook to ask Llama 3.3 to convert natural language queries into SQL queries. + +## Next Steps + +1. Try GRPO RFT to further improve the accuracy. +2. Fine-tune Llama 3.3 70b and Llama 4 models. +3. Use torchtune. +4. Try agentic workflow. +5. Expand the eval to support other enterprise databases. diff --git a/end-to-end-use-cases/coding/text2sql/eval/README.md b/end-to-end-use-cases/coding/text2sql/eval/README.md index 3dcaf03f0..188642ddc 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/README.md +++ b/end-to-end-use-cases/coding/text2sql/eval/README.md @@ -1,18 +1,8 @@ -# Text2SQL Evaluation and Fine-Tuning Tools for Llama Models +# Llama Text2SQL Evaluation -## Overview +We have updated and simplified the original eval scripts from the BIRD [repo](https://github.com/AlibabaResearch/DAMO-ConvAI/tree/main/bird) to 3 simple steps for Llama 3 & 4 models hosted via Meta's [Llama API](https://llama.developer.meta.com) or [Together.ai](https://together.ai), as well as the fine-tuned Llama 3.1 model. -This folder contains scripts to: -1. Evaluate Llama (original and fine-tuned) models on the Text2SQL task using the popular [BIRD](https://bird-bench.github.io) dataset in **three simple steps**; -2. Generate fine-tuning datasets (with and without reasoning steps)and fine-tuning Llama 3.1 8B with the datasets, gaining a **165% (with no reasoning) and 209% (with reasoning) accuracy improvement** over the original model. - -Our end goal is to maximize the accuracy of Llama models on the Text2SQL task via fine-tuning, agent and other approaches. To do so we need to first evaluate the current state of the art Llama models on the task. In other words, "no eval, no success" AND "eval only is not success". Hence, we have created this tool to quickly evaluate Llama models on the Text2SQL task and, as a first step, to fine-tune Llama models to improve their accuracy on the task. - -## Llama Text2SQL Evaluation - -We have updated and significantly simplified the original eval scripts from the BIRD [repo](https://github.com/AlibabaResearch/DAMO-ConvAI/tree/main/bird) for Llama 3 & 4 models hosted via Meta's [Llama API](https://llama.developer.meta.com) or [Together.ai](https://together.ai), as well as the fine-tuned Llama 3.1 model. - -### Evaluation Results +## Evaluation Results Below are the results of the Llama models we have evaluated on the BIRD DEV dataset: @@ -28,13 +18,13 @@ Below are the results of the Llama models we have evaluated on the BIRD DEV data - Fine-tuned with no reasoning dataset: 37.16% - Fine-tuned with reasoning dataset: 43.37% -### Quick Start on Evaluating Llama on Text2SQL +## Quick Start First, run the commands below to create a new Conda environment and install all the required packages for Text2SQL evaluation and fine-tuning: ``` git clone https://github.com/meta-llama/llama-cookbook -cd llama-cookbook/end-to-end-use-cases/coding/text2sql/tool +cd llama-cookbook/end-to-end-use-cases/coding/text2sql conda create -n llama-text2sql python=3.10 conda activate llama-text2sql pip install -r requirements.txt @@ -46,6 +36,7 @@ Then, follow the steps below to evaluate Llama 3 & 4 models on Text2SQL using th ``` cd data sh download_dev_unzip.sh +cd ../eval ``` 2. Open `llama_eval.sh` and set `YOUR_API_KEY` to your [Llama API](https://llama.developer.meta.com/) key or [Together](https://api.together.ai/) API key, then uncomment a line that starts with `model=` to specify the Llama model to use for the text2sql eval. @@ -58,7 +49,7 @@ After the script completes, you'll see the accuracy of the Llama model on the BI To compare your evaluated accuracy of your selected Llama model with other results in the BIRD Dev leaderboard, click [here](https://bird-bench.github.io/). -### Evaluation Process +## Evaluation Process 1. **SQL Generation**: `llama_text2sql.py` sends natural language questions to the specified Llama model and collects the generated SQL queries. @@ -68,7 +59,7 @@ To compare your evaluated accuracy of your selected Llama model with other resul 4. **Accuracy Calculation**: Accuracy scores are calculated overall and broken down by difficulty levels (simple, moderate, challenging). -### Supported Models for Evaluation +## Supported Models for Evaluation Llama models supported on Together AI: - meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo @@ -83,145 +74,3 @@ Llama models supported on Llama API: - Llama-4-Maverick-17B-128E-Instruct-FP8 - Llama-4-Scout-17B-16E-Instruct-FP8 - other Llama models hosted on Llama API - -## Fine-tuning with the BIRD TRAIN dataset (No Reasoning) - -We'll first use the BIRD TRAIN dataset to prepare for supervised fine-tuning with no reasoning info in the dataset. - -### Using the TRAIN to prepare for supervised fine-tuning - -1. Get the TRAIN dataset: -``` -cd data -sh download_train_unzip.sh -``` - -2. Create the dataset - -``` -cd fine_tuning -python create_sft_dataset.py --input_json ../data/train/train.json --db_root_path ../data/train/train_databases -``` - -This will create `train_text2sql_sft_dataset.json` and `test_text2sql_sft_dataset.json` using the TRAIN set. Each line in the json files is in the conversation format ready for fine-tuning: - -``` -{"messages":[{"content":"You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement.","role":"system"},{"content":"-- DB Schema: \n\n-- External Knowledge: \n\n-- Question: ","role":"user"},{"content":"","role":"assistant"}]} -``` - -### Supervised Fine-tuning (No Reasoning) - -First, you need to login to HuggingFace (via running `huggingface-cli login` and enter your [HF token](https://huggingface.co/settings/tokens)) and have been granted access to the [Llama 3.1 8B Instruct](https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct) model. - -Then run `python trl_sft.py`. After the fine-tuning completes, you'll see the fine-tuned model saved to `llama31-8b-text2sql-fine-tuned`, specified in `output_dir="llama31-8b-text2sql-fine-tuned"` of `TrainingArguments` in `trl_sft.py`. - -After running `tensorboard --logdir ./llama31-8b-text2sql-fine_tuning` you can open `http://localhost:6006` to see the train loss chat etc: - -![](fine_tuning/train_loss.png) - - -### Evaluating the fine-tuned model (No Reasoning) - -First, modify `llama_eval.sh` to use the fine-tuned model: - -``` -YOUR_API_KEY='finetuned' -model='fine_tuning/llama31-8b-text2sql' -``` - -Then run `sh llama_eval.sh` to evaluate the fine-tuned model. The accuracy on the BIRD DEV dataset is about 37.16%. This is a 165% improvement over the model before fine-tuning, which has an accuracy of about 14.02% on the same dataset - you can confirm this by comparing the fine-tuned model's accuracy above with the original model's accuracy by modifying `llama_eval.sh` to use the original model: - -``` -YOUR_API_KEY='huggingface' -model='meta-llama/Llama-3.1-8B-Instruct' -``` - -Then running `sh llama_eval.sh` to evaluate the original model. - -*Note:* We are using the 4-bit quantized Llama 3.1 8b model to reduce the memory footprint and improve the efficiency (as shown in the code nippet of llama_text2sql.py below), hence the accuracy of the quantized version (14.02%) is quite lower than the accuracy of the original Llama 3.1 8b (35.66%). - -``` - bnb_config = BitsAndBytesConfig( - load_in_4bit=True, - bnb_4bit_use_double_quant=True, - bnb_4bit_quant_type="nf4", - bnb_4bit_compute_dtype=torch.bfloat16, - ) -``` - -## Fine-tuning with the BIRD TRAIN dataset (With Reasoning) - -Next we'll use the BIRD TRAIN dataset to prepare for supervised fine-tuning with reasoning info in the dataset. The goal is to see if we can improve the accuracy of the fine-tuned model by adding the reasoning info in the dataset. - -### Creating a reasoning dataset from the TRAIN dataset - -The script `create_reasoning_dataset.py` is used to create a reasoning dataset from the TRAIN dataset by asking Llama 3.3 70B to generate the reasoning for each text question and its corresponding gold SQL. The intent is to use the reasoning dataset to fine-tune the Llama model to improve the accuracy of the generated SQL. - -To run the script, use the following commands: -``` -cd fine_tuning -python create_reasoning_dataset.py --input_json ../data/train/train.json --db_root_path ../data/train/train_databases -``` - -This will create a `text2sql_cot_dataset` dataset and `train_text2sql_cot_dataset.json` in the conversation format ready for fine-tuning. Each example in the dataset is generated from the code snippet below: - -``` -prompt = f""" --- DB Schema: {db_schema} --- External Knowledge: {external_knowledge} --- Text Question: {question} -""" -cot = { - "messages": [ - { - "role": "system", - "content": "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, generate the step-by-step reasoning and the final SQLite SQL select statement from the text question.", - }, - {"role": "user", "content": prompt}, - {"role": "assistant", "content": reasoning}, - ] -} -``` - -The prompt for Llama 3.3 70B to generate the `reasoning` above is: -``` -You are a text to SQL query translator. Based on the DB Schema and External Knowledge, given the Text Question Input and its Gold SQL Output below, generate the step-by-step reasoning to infer the Gold SQL Output from the Text Question Input. - --- DB Schema: {db_schema} --- External Knowledge: {external_knowledge} --- Text Question Input: {question} --- Gold SQL Output: {gold_SQL} - -Your response should be as follows:\n\n -Let me think through this step by step:\n\n1. First, I need to consider...\n2. Then...\n3. Next...\n...\n\nFinally, the SQL statement for the text question is: -```sql ...```\n - -""" -``` - -### Supervised Fine-tuning (With Reasoning) - -Uncomment the line `# FT_DATASET = "train_text2sql_cot_dataset.json"` in trl_sft.py to use the reasoning dataset for fine-tuning. Then run `python trl_sft.py`. After the fine-tuning completes, you'll see the fine-tuned model saved to `llama31-8b-text2sql-fine-tuned`, specified in `output_dir="llama31-8b-text2sql-fine-tuned"` of `TrainingArguments` in `trl_sft.py` - you may want to rename the `output_dir` folder to something else to avoid overwriting the previous fine-tuned model. - -The train loss chart will look like this: -![](fine_tuning/train_loss_cot.png) - -### Evaluating the fine-tuned model (With Reasoning) - -First, modify `llama_eval.sh` to use the fine-tuned model, which should match the `output_dir` in `TrainingArguments` in `trl_sft.py`: - -``` -YOUR_API_KEY='finetuned' -model='fine_tuning/llama31-8b-text2sql-fine-tuned' -``` - -Then uncomment the line `SYSTEM_PROMPT` [here](https://github.com/meta-llama/llama-cookbook/blob/text2sql/end-to-end-use-cases/coding/text2sql/tool/llama_text2sql.py#L31) in `llama_text2sql.py` to use it with the reasoning dataset fine-tuned model. - -Now run `sh llama_eval.sh`, which will take longer because the reasoning is needed to generate the SQL. The accuracy this time is 43.37%, compared with 37.16% without reasoning. This is another 16% improvement over the model with fine-tuning without reasoning. - -## Next Steps -1. Add a Colab notebook for fine-tuning and evaluation. -2. Try reinforcement fine-tuning to improve the accuracy further with reasoning. -3. Use torchtune for full and non-quantized fine-tuning of Llama 3.3 70b and Llama 4 models. -4. Introduce agent to try to improve the accuracy further. -5. Expand the tool to support other databases. diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md new file mode 100644 index 000000000..7873bb8b3 --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md @@ -0,0 +1,137 @@ +# Llama Text2SQL Fine-tuning + +This folder contains the scripts to generate datasets from the BIRD TRAIN set with and without CoT, and to supervised fine-tune (SFT), as the first step, the Llama 3.1 8B model: accuracy improvement of **165% on the fine-tuned model with no reasoning and 209% with reasoning** over the original model. + +## SFT with the BIRD TRAIN dataset (No Reasoning) + +We'll first use the BIRD TRAIN dataset to prepare for supervised fine-tuning with no reasoning info in the dataset. + +### Using the TRAIN to prepare for supervised fine-tuning + +1. Get the TRAIN dataset: +``` +cd data +sh download_train_unzip.sh +``` + +2. Create the dataset + +``` +cd ../fine_tuning +python create_sft_dataset.py --input_json ../data/train/train.json --db_root_path ../data/train/train_databases +``` + +This will create `train_text2sql_sft_dataset.json` and `test_text2sql_sft_dataset.json` using the TRAIN set. Each line in the json files is in the conversation format ready for fine-tuning: + +``` +{"messages":[{"content":"You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement.","role":"system"},{"content":"-- DB Schema: \n\n-- External Knowledge: \n\n-- Question: ","role":"user"},{"content":"","role":"assistant"}]} +``` + +### SFT (No Reasoning) + +First, you need to login to HuggingFace (via running `huggingface-cli login` and enter your [HF token](https://huggingface.co/settings/tokens)) and have been granted access to the [Llama 3.1 8B Instruct](https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct) model. + +Then run `python trl_sft.py`. After the fine-tuning completes, you'll see the fine-tuned model saved to `llama31-8b-text2sql-fine-tuned`, specified in `output_dir="llama31-8b-text2sql-fine-tuned"` of `TrainingArguments` in `trl_sft.py`. + +After running `tensorboard --logdir ./llama31-8b-text2sql-fine_tuning` you can open `http://localhost:6006` to see the train loss chat etc: + +![](fine_tuning/train_loss.png) + + +### Evaluating the fine-tuned model (No Reasoning) + +First, modify `llama_eval.sh` to use the fine-tuned model: + +``` +YOUR_API_KEY='finetuned' +model='fine_tuning/llama31-8b-text2sql' +``` + +Then run `sh llama_eval.sh` to evaluate the fine-tuned model. The accuracy on the BIRD DEV dataset is about 37.16%. This is a 165% improvement over the model before fine-tuning, which has an accuracy of about 14.02% on the same dataset - you can confirm this by comparing the fine-tuned model's accuracy above with the original model's accuracy by modifying `llama_eval.sh` to use the original model: + +``` +YOUR_API_KEY='huggingface' +model='meta-llama/Llama-3.1-8B-Instruct' +``` + +Then running `sh llama_eval.sh` to evaluate the original model. + +*Note:* We are using the 4-bit quantized Llama 3.1 8b model to reduce the memory footprint and improve the efficiency (as shown in the code nippet of llama_text2sql.py below), hence the accuracy of the quantized version (14.02%) is quite lower than the accuracy of the original Llama 3.1 8b (35.66%). + +``` + bnb_config = BitsAndBytesConfig( + load_in_4bit=True, + bnb_4bit_use_double_quant=True, + bnb_4bit_quant_type="nf4", + bnb_4bit_compute_dtype=torch.bfloat16, + ) +``` + +## SFT with the BIRD TRAIN dataset (With Reasoning) + +Next we'll use the BIRD TRAIN dataset to prepare for supervised fine-tuning with reasoning info in the dataset. The goal is to see if we can improve the accuracy of the fine-tuned model by adding the reasoning info in the dataset. + +### Creating a reasoning dataset from the TRAIN dataset + +The script `create_reasoning_dataset.py` is used to create a reasoning dataset from the TRAIN dataset by asking Llama 3.3 70B to generate the reasoning for each text question and its corresponding gold SQL. The intent is to use the reasoning dataset to fine-tune the Llama model to improve the accuracy of the generated SQL. + +To run the script, use the following commands: +``` +python create_reasoning_dataset.py --input_json ../data/train/train.json --db_root_path ../data/train/train_databases +``` + +This will create a `text2sql_cot_dataset` dataset and `train_text2sql_cot_dataset.json` in the conversation format ready for fine-tuning. Each example in the dataset is generated from the code snippet below: + +``` +prompt = f""" +-- DB Schema: {db_schema} +-- External Knowledge: {external_knowledge} +-- Text Question: {question} +""" +cot = { + "messages": [ + { + "role": "system", + "content": "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, generate the step-by-step reasoning and the final SQLite SQL select statement from the text question.", + }, + {"role": "user", "content": prompt}, + {"role": "assistant", "content": reasoning}, + ] +} +``` + +The prompt for Llama 3.3 70B to generate the `reasoning` above is: +``` +You are a text to SQL query translator. Based on the DB Schema and External Knowledge, given the Text Question Input and its Gold SQL Output below, generate the step-by-step reasoning to infer the Gold SQL Output from the Text Question Input. + +-- DB Schema: {db_schema} +-- External Knowledge: {external_knowledge} +-- Text Question Input: {question} +-- Gold SQL Output: {gold_SQL} + +Your response should be as follows:\n\n +Let me think through this step by step:\n\n1. First, I need to consider...\n2. Then...\n3. Next...\n...\n\nFinally, the SQL statement for the text question is: +```sql ...```\n + +""" +``` + +### SFT (With Reasoning) + +Uncomment the line `# FT_DATASET = "train_text2sql_cot_dataset.json"` in trl_sft.py to use the reasoning dataset for fine-tuning. Then run `python trl_sft.py`. After the fine-tuning completes, you'll see the fine-tuned model saved to `llama31-8b-text2sql-fine-tuned`, specified in `output_dir="llama31-8b-text2sql-fine-tuned"` of `TrainingArguments` in `trl_sft.py` - you may want to rename the `output_dir` folder to something else to avoid overwriting the previous fine-tuned model. + +The train loss chart will look like this: +![](fine_tuning/train_loss_cot.png) + +### Evaluating the fine-tuned model (With Reasoning) + +First, modify `llama_eval.sh` to use the fine-tuned model, which should match the `output_dir` in `TrainingArguments` in `trl_sft.py`: + +``` +YOUR_API_KEY='finetuned' +model='fine_tuning/llama31-8b-text2sql-fine-tuned' +``` + +Then uncomment the line `SYSTEM_PROMPT` [here](https://github.com/meta-llama/llama-cookbook/blob/text2sql/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py#L31) in `llama_text2sql.py` to use it with the reasoning dataset fine-tuned model. + +Now run `sh llama_eval.sh`, which will take longer because the reasoning is needed to generate the SQL. The accuracy this time is 43.37%, compared with 37.16% without reasoning. This is another 16% improvement over the model with fine-tuning without reasoning. diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/requirements.txt b/end-to-end-use-cases/coding/text2sql/fine-tuning/requirements.txt new file mode 100644 index 000000000..def1eccc3 --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/requirements.txt @@ -0,0 +1,17 @@ +llama_api_client==0.1.1 +langchain-together==0.3.0 +sqlparse==0.5.3 +torch==2.4.1 +tensorboard==2.19.0 +liger-kernel==0.4.2 +setuptools==78.1.1 +deepspeed==0.15.4 +transformers==4.46.3 +datasets==3.6.0 +accelerate==1.1.1 +bitsandbytes==0.44.1 +trl==0.12.1 +peft==0.13.2 +lighteval==0.6.2 +hf-transfer==0.1.8 +func_timeout==4.3.5 diff --git a/end-to-end-use-cases/coding/text2sql/quickstart/README.md b/end-to-end-use-cases/coding/text2sql/quickstart/README.md index 5379ae682..feb7db10a 100644 --- a/end-to-end-use-cases/coding/text2sql/quickstart/README.md +++ b/end-to-end-use-cases/coding/text2sql/quickstart/README.md @@ -1,10 +1,10 @@ -## Quickstart with Text2SQL +# Quickstart with Text2SQL The scripts and notebook in this folder let you get familiar with how to interact with a database using natural language inputs by asking Llama to convert natural language queries into SQL queries. For detailed instructions on setting up the environment, creating a database, and executing natural language queries using the Text2SQL interface, please refer to the [quickstart.ipynb](quickstart.ipynb) notebook. -### Structure: +## Structure: - quickstart.ipynb: A Quick Demo of Text2SQL Using Llama 3.3. This Jupyter Notebook includes examples of how to use the interface to execute natural language queries on the sample data. It uses Llama 3.3 to answer questions about a SQLite database using LangChain and the Llama cloud provider Together.ai. - nba.txt: A text file containing NBA roster information, which is used as sample data for demonstration purposes. From ee1fc974deba352ecae671f8e5dd7d2141859230 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Wed, 2 Jul 2025 10:27:55 -0700 Subject: [PATCH 28/78] png fix --- end-to-end-use-cases/coding/text2sql/fine-tuning/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md index 7873bb8b3..fe7dc58ca 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md @@ -35,7 +35,7 @@ Then run `python trl_sft.py`. After the fine-tuning completes, you'll see the fi After running `tensorboard --logdir ./llama31-8b-text2sql-fine_tuning` you can open `http://localhost:6006` to see the train loss chat etc: -![](fine_tuning/train_loss.png) +![](train_loss.png) ### Evaluating the fine-tuned model (No Reasoning) @@ -121,7 +121,7 @@ Let me think through this step by step:\n\n1. First, I need to consider...\n2. T Uncomment the line `# FT_DATASET = "train_text2sql_cot_dataset.json"` in trl_sft.py to use the reasoning dataset for fine-tuning. Then run `python trl_sft.py`. After the fine-tuning completes, you'll see the fine-tuned model saved to `llama31-8b-text2sql-fine-tuned`, specified in `output_dir="llama31-8b-text2sql-fine-tuned"` of `TrainingArguments` in `trl_sft.py` - you may want to rename the `output_dir` folder to something else to avoid overwriting the previous fine-tuned model. The train loss chart will look like this: -![](fine_tuning/train_loss_cot.png) +![](train_loss_cot.png) ### Evaluating the fine-tuned model (With Reasoning) From 9c294dfacf8490d0fd62dbbeafb269d12bc7fee7 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Wed, 2 Jul 2025 17:59:48 -0700 Subject: [PATCH 29/78] eval/llama_eval.sh data path --- end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh b/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh index 3331d08e6..95fc85782 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh +++ b/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh @@ -1,6 +1,6 @@ -eval_path='./data/dev_20240627/dev.json' -db_root_path='./data/dev_20240627/dev_databases/' -ground_truth_path='./data/' +eval_path='../data/dev_20240627/dev.json' +db_root_path='../data/dev_20240627/dev_databases/' +ground_truth_path='../data/' # Llama models on Together #YOUR_API_KEY='YOUR_TOGETHER_API_KEY' @@ -24,7 +24,7 @@ model='Llama-3.3-8B-Instruct' # Fine-tuned Llama models locally #YOUR_API_KEY='finetuned' -#model='fine_tuning/llama31-8b-text2sql-fine-tuned' +#model='../fine_tuning/llama31-8b-text2sql-fine-tuned' data_output_path="./output/$model/" From ef6bbb2b20e238109ceaae2485c792c69bad84ba Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Tue, 8 Jul 2025 09:08:03 -0700 Subject: [PATCH 30/78] main README and FT README update --- end-to-end-use-cases/coding/text2sql/README.md | 4 ++-- end-to-end-use-cases/coding/text2sql/fine-tuning/README.md | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/README.md b/end-to-end-use-cases/coding/text2sql/README.md index fd1e5f9dd..7d1517f9b 100644 --- a/end-to-end-use-cases/coding/text2sql/README.md +++ b/end-to-end-use-cases/coding/text2sql/README.md @@ -1,10 +1,10 @@ -# Text2SQL: Evaluating and Fine-tuning Llama Models +# Text2SQL: Evaluating and Fine-tuning Llama Models with CoT This folder contains scripts to: 1. Evaluate Llama (original and fine-tuned) models on the Text2SQL task using the popular [BIRD](https://bird-bench.github.io) dataset in **3 simple steps**; -2. Generate fine-tuning datasets (both with and without CoT reasoning) and fine-tuning Llama 3.1 8B with the datasets, gaining a **165% (with no reasoning) and 209% (with reasoning) accuracy improvement** over the original model. +2. Generate two fine-tuning datasets (with and without CoT) and fine-tuning Llama 3.1 8B with the datasets, gaining a **165% improvement on the fine-tuned model without CoT (accuracy 37.16%) and 209% with CoT (accuracy 43.37%)** over the original model (accuracy 14.02%). Our end goal is to maximize the accuracy of Llama models on the Text2SQL task. To do so we need to first evaluate the current state of the art Llama models on the task, then apply fine-tuning, agent and other approaches to evaluate and improve Llama's performance. diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md index fe7dc58ca..f10015d2e 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md @@ -1,6 +1,8 @@ -# Llama Text2SQL Fine-tuning +# Enhancing Text-to-SQL with CoT: A Fine-Tuning Approach with Llama -This folder contains the scripts to generate datasets from the BIRD TRAIN set with and without CoT, and to supervised fine-tune (SFT), as the first step, the Llama 3.1 8B model: accuracy improvement of **165% on the fine-tuned model with no reasoning and 209% with reasoning** over the original model. +This folder contains scripts to generate datasets from the BIRD TRAIN set with and, for comparison, without CoT (Chain-of-Thought) and scripts to supervised fine-tune (SFT), as the first step, the Llama 3.1 8B model. We observed a **165% improvement on the fine-tuned model without CoT (accuracy 37.16%) and 209% with CoT (accuracy 43.37%) ** over the original model (accuracy 14.02%). + +Note: In this document, we will use "CoT" and "reasoning" interchangeably, although generally, reasoning encompasses a broader concept than CoT. ## SFT with the BIRD TRAIN dataset (No Reasoning) From caf98ec76dd1a648d48916d3e095fbf93b205bf6 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Wed, 9 Jul 2025 17:05:25 -0700 Subject: [PATCH 31/78] unified script supporting 6 FT configs - quantized or not, peft/fft, cot or not (except q fft) --- .../coding/text2sql/fine-tuning/trl_sft.py | 237 ++++++++++++++---- 1 file changed, 187 insertions(+), 50 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/trl_sft.py b/end-to-end-use-cases/coding/text2sql/fine-tuning/trl_sft.py index 0a5729345..ff05f6d66 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/trl_sft.py +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/trl_sft.py @@ -1,85 +1,222 @@ -# Source: https://www.philschmid.de/fine-tune-llms-in-2024-with-trl +# Unified script supporting multiple fine-tuning configurations + +import argparse +import sys import torch from datasets import load_dataset -from peft import LoraConfig -from transformers import ( - AutoModelForCausalLM, - AutoTokenizer, - BitsAndBytesConfig, - TrainingArguments, +from transformers import AutoModelForCausalLM, AutoTokenizer + +# Parse command line arguments +parser = argparse.ArgumentParser( + description="Unified fine-tuning script for Llama 3.1 8B" +) +parser.add_argument( + "--quantized", + type=str, + choices=["true", "false"], + required=True, + help="Whether to use quantization (true/false)", +) +parser.add_argument( + "--peft", + type=str, + choices=["true", "false"], + required=True, + help="Whether to use PEFT (true/false)", +) +parser.add_argument( + "--cot", + type=str, + choices=["true", "false"], + required=True, + help="Whether to use Chain-of-Thought dataset (true/false)", ) -from trl import setup_chat_format, SFTTrainer +args = parser.parse_args() + +# Convert string arguments to boolean +use_quantized = args.quantized.lower() == "true" +use_peft = args.peft.lower() == "true" +use_cot = args.cot.lower() == "true" + +# Check for unsupported combination +if not use_peft and use_quantized: + print( + "ERROR: Full Fine-Tuning (peft=false) with Quantization (quantized=true) is NOT RECOMMENDED!" + ) + print("This combination can lead to:") + print("- Gradient precision loss due to quantization") + print("- Training instability") + print("- Suboptimal convergence") + print("\nRecommended combinations:") + print( + "1. --peft=true --quantized=true (PEFT + Quantized - Most memory efficient)" + ) + print("2. --peft=true --quantized=false (PEFT + Non-quantized - Good balance)") + print( + "3. --peft=false --quantized=false (FFT + Non-quantized - Maximum performance)" + ) + sys.exit(1) + +print(f"Configuration: PEFT={use_peft}, Quantized={use_quantized}, CoT={use_cot}") + +# Import additional modules based on configuration +if use_quantized: + from transformers import BitsAndBytesConfig +if use_peft: + from peft import LoraConfig + +from trl import setup_chat_format, SFTConfig, SFTTrainer -FT_DATASET = "train_text2sql_sft_dataset.json" -# uncomment to use the reasoning dataset created by "create_reasoning_dataset.py" -# FT_DATASET = "train_text2sql_cot_dataset.json" +# Dataset configuration based on CoT parameter +if use_cot: + FT_DATASET = "train_text2sql_cot_dataset.json" + print("Using Chain-of-Thought reasoning dataset") +else: + FT_DATASET = "train_text2sql_sft_dataset.json" + print("Using standard SFT dataset") -dataset = load_dataset("json", data_files=SFT_DATASET, split="train") +dataset = load_dataset("json", data_files=FT_DATASET, split="train") model_id = "meta-llama/Llama-3.1-8B-Instruct" -bnb_config = BitsAndBytesConfig( - load_in_4bit=True, - bnb_4bit_use_double_quant=True, - bnb_4bit_quant_type="nf4", - bnb_4bit_compute_dtype=torch.bfloat16, -) +# Configure quantization if needed +quantization_config = None +if use_quantized: + quantization_config = BitsAndBytesConfig( + load_in_4bit=True, + bnb_4bit_use_double_quant=True, + bnb_4bit_quant_type="nf4", + bnb_4bit_compute_dtype=torch.bfloat16, + ) +# Load model model = AutoModelForCausalLM.from_pretrained( model_id, device_map="auto", torch_dtype=torch.bfloat16, - quantization_config=bnb_config, + quantization_config=quantization_config, ) -tokenizer = AutoTokenizer.from_pretrained(model_id) +# Load tokenizer +tokenizer = AutoTokenizer.from_pretrained(model_id) tokenizer.padding_side = "right" if tokenizer.pad_token is None: tokenizer.add_special_tokens({"pad_token": "[PAD]"}) model.resize_token_embeddings(len(tokenizer)) -peft_config = LoraConfig( - lora_alpha=128, - lora_dropout=0.05, - r=256, - bias="none", - target_modules="all-linear", - task_type="CAUSAL_LM", -) +# Configure PEFT if needed +peft_config = None +if use_peft: + peft_config = LoraConfig( + lora_alpha=128, + lora_dropout=0.05, + r=256, + bias="none", + target_modules="all-linear", + task_type="CAUSAL_LM", + ) -args = TrainingArguments( - output_dir="llama31-8b-text2sql-fine-tuned", # directory to save and repository id - num_train_epochs=3, # number of training epochs - per_device_train_batch_size=3, # batch size per device during training - gradient_accumulation_steps=2, # number of steps before performing a backward/update pass - gradient_checkpointing=True, # use gradient checkpointing to save memory - optim="adamw_torch_fused", # use fused adamw optimizer - logging_steps=10, # log every 10 steps - save_strategy="epoch", # save checkpoint every epoch - learning_rate=2e-4, # learning rate, based on QLoRA paper - bf16=True, # use bfloat16 precision - tf32=True, # use tf32 precision - max_grad_norm=0.3, # max gradient norm based on QLoRA paper - warmup_ratio=0.03, # warmup ratio based on QLoRA paper - lr_scheduler_type="constant", # use constant learning rate scheduler - push_to_hub=True, # push model to hub - report_to="tensorboard", # report metrics to tensorboard -) +# Configure training arguments based on combination using newer TRL API +cot_suffix = "cot" if use_cot else "nocot" -max_seq_length = 4096 +if use_peft and use_quantized: + # PEFT + Quantized: Use SFTConfig (newer API) + print("Using PEFT + Quantized configuration") + args = SFTConfig( + output_dir=f"llama31-8b-text2sql-peft-quantized-{cot_suffix}", + num_train_epochs=3, + per_device_train_batch_size=3, + gradient_accumulation_steps=2, + gradient_checkpointing=True, + optim="adamw_torch_fused", + logging_steps=10, + save_strategy="epoch", + learning_rate=2e-4, + bf16=True, + tf32=True, + max_grad_norm=0.3, + warmup_ratio=0.03, + lr_scheduler_type="constant", + push_to_hub=True, + report_to="tensorboard", + max_seq_length=4096, + packing=True, + ) +elif use_peft and not use_quantized: + # PEFT + Non-quantized: Use SFTConfig (newer API) + print("Using PEFT + Non-quantized configuration") + args = SFTConfig( + output_dir=f"llama31-8b-text2sql-peft-nonquantized-{cot_suffix}", + num_train_epochs=3, + per_device_train_batch_size=2, # Slightly reduced for non-quantized + gradient_accumulation_steps=4, # Increased to maintain effective batch size + gradient_checkpointing=True, + optim="adamw_torch_fused", + logging_steps=10, + save_strategy="epoch", + learning_rate=2e-4, + bf16=True, + tf32=True, + max_grad_norm=0.3, + warmup_ratio=0.03, + lr_scheduler_type="constant", + push_to_hub=True, + report_to="tensorboard", + max_seq_length=4096, + packing=True, + ) + +else: # not use_peft and not use_quantized + # FFT + Non-quantized: Use SFTConfig (newer API) + print("Using Full Fine-Tuning + Non-quantized configuration") + args = SFTConfig( + output_dir=f"llama31-8b-text2sql-fft-nonquantized-{cot_suffix}", + num_train_epochs=1, # Reduced epochs for full fine-tuning + per_device_train_batch_size=1, # Reduced batch size for full model training + gradient_accumulation_steps=8, # Increased to maintain effective batch size + gradient_checkpointing=True, + optim="adamw_torch_fused", + logging_steps=10, + save_strategy="epoch", + learning_rate=5e-6, # Lower learning rate for full fine-tuning + bf16=True, + tf32=True, + max_grad_norm=1.0, # Standard gradient clipping for full fine-tuning + warmup_ratio=0.1, # Warmup ratio for full fine-tuning + lr_scheduler_type="cosine", # Cosine scheduler for full fine-tuning + push_to_hub=True, + report_to="tensorboard", + dataloader_pin_memory=False, # Disable pin memory to save GPU memory + remove_unused_columns=False, # Keep all columns + max_seq_length=4096, + packing=True, + ) + +# Create trainer with consistent newer API trainer = SFTTrainer( model=model, args=args, train_dataset=dataset, - max_seq_length=max_seq_length, - tokenizer=tokenizer, + processing_class=tokenizer, peft_config=peft_config, - packing=True, ) +# Print memory requirements estimate +print("\nEstimated GPU Memory Requirements:") +if use_peft and use_quantized: + print("- PEFT + Quantized: ~12-16 GB") +elif use_peft and not use_quantized: + print("- PEFT + Non-quantized: ~20-25 GB") +else: # FFT + Non-quantized + print("- Full Fine-Tuning + Non-quantized: ~70-90 GB") + +print("\nStarting training...") trainer.train() +print("Training completed. Saving model...") trainer.save_model() + +print("Model saved successfully!") From b02334a9ccd45452bb28477e8526d8c50b1dc57e Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Wed, 9 Jul 2025 19:02:36 -0700 Subject: [PATCH 32/78] updated fine-tuning README --- .../coding/text2sql/fine-tuning/README.md | 63 +++++++++++++------ 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md index f10015d2e..440453bc1 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md @@ -1,8 +1,12 @@ # Enhancing Text-to-SQL with CoT: A Fine-Tuning Approach with Llama -This folder contains scripts to generate datasets from the BIRD TRAIN set with and, for comparison, without CoT (Chain-of-Thought) and scripts to supervised fine-tune (SFT), as the first step, the Llama 3.1 8B model. We observed a **165% improvement on the fine-tuned model without CoT (accuracy 37.16%) and 209% with CoT (accuracy 43.37%) ** over the original model (accuracy 14.02%). +CoT stands for Chain of Thought and we will use "CoT" and "reasoning" interchangeably here, although generally, reasoning encompasses a broader concept than CoT. -Note: In this document, we will use "CoT" and "reasoning" interchangeably, although generally, reasoning encompasses a broader concept than CoT. +This folder contains scripts to: + +* generate a dataset from the BIRD TRAIN set (with no CoT info) for supervised fine-tuning (SFT); +* generate a dataset from the BIRD TRAIN set (with CoT info by Llama 3.3 70B) for SFT; +* SFT the Llama 3.1 8B model with the generated datasets with different fine-tuning combinations: with or without CoT, using quantization or not, full fine-tuning (FFT) or parameter-efficient fine-tuning (PEFT). ## SFT with the BIRD TRAIN dataset (No Reasoning) @@ -33,7 +37,24 @@ This will create `train_text2sql_sft_dataset.json` and `test_text2sql_sft_datase First, you need to login to HuggingFace (via running `huggingface-cli login` and enter your [HF token](https://huggingface.co/settings/tokens)) and have been granted access to the [Llama 3.1 8B Instruct](https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct) model. -Then run `python trl_sft.py`. After the fine-tuning completes, you'll see the fine-tuned model saved to `llama31-8b-text2sql-fine-tuned`, specified in `output_dir="llama31-8b-text2sql-fine-tuned"` of `TrainingArguments` in `trl_sft.py`. +Then run one of the commands below (`trl_sft.py` has three command line parameters: `--quantized`, `--peft`, and `--cot`, all with true or false values): + +``` +python trl_sft.py --quantized false --peft true --cot false +python trl_sft.py --quantized false --peft false --cot false +python trl_sft.py --quantized true --peft true --cot false +``` + +Note that we don't recommend using the quantized version with FFT (--peft false). + + +After the fine-tuning completes, you'll see the fine-tuned model saved in one of the following folders, as specified in `output_dir` of `SFTConfig` in `trl_sft.py`: + +``` +llama31-8b-text2sql-fft-nonquantized-nocot +lama31-8b-text2sql-peft-nonquantized-nocot +llama31-8b-text2sql-peft-quantized-nocot +``` After running `tensorboard --logdir ./llama31-8b-text2sql-fine_tuning` you can open `http://localhost:6006` to see the train loss chat etc: @@ -42,11 +63,11 @@ After running `tensorboard --logdir ./llama31-8b-text2sql-fine_tuning` you can o ### Evaluating the fine-tuned model (No Reasoning) -First, modify `llama_eval.sh` to use the fine-tuned model: +First, set the `model` value in `llama_eval.sh` to be one of the fine-tuned model folders above, e.g. ``` YOUR_API_KEY='finetuned' -model='fine_tuning/llama31-8b-text2sql' +model='fine_tuning/llama31-8b-text2sql-fft-nonquantized-nocot' ``` Then run `sh llama_eval.sh` to evaluate the fine-tuned model. The accuracy on the BIRD DEV dataset is about 37.16%. This is a 165% improvement over the model before fine-tuning, which has an accuracy of about 14.02% on the same dataset - you can confirm this by comparing the fine-tuned model's accuracy above with the original model's accuracy by modifying `llama_eval.sh` to use the original model: @@ -58,16 +79,6 @@ model='meta-llama/Llama-3.1-8B-Instruct' Then running `sh llama_eval.sh` to evaluate the original model. -*Note:* We are using the 4-bit quantized Llama 3.1 8b model to reduce the memory footprint and improve the efficiency (as shown in the code nippet of llama_text2sql.py below), hence the accuracy of the quantized version (14.02%) is quite lower than the accuracy of the original Llama 3.1 8b (35.66%). - -``` - bnb_config = BitsAndBytesConfig( - load_in_4bit=True, - bnb_4bit_use_double_quant=True, - bnb_4bit_quant_type="nf4", - bnb_4bit_compute_dtype=torch.bfloat16, - ) -``` ## SFT with the BIRD TRAIN dataset (With Reasoning) @@ -120,18 +131,34 @@ Let me think through this step by step:\n\n1. First, I need to consider...\n2. T ### SFT (With Reasoning) -Uncomment the line `# FT_DATASET = "train_text2sql_cot_dataset.json"` in trl_sft.py to use the reasoning dataset for fine-tuning. Then run `python trl_sft.py`. After the fine-tuning completes, you'll see the fine-tuned model saved to `llama31-8b-text2sql-fine-tuned`, specified in `output_dir="llama31-8b-text2sql-fine-tuned"` of `TrainingArguments` in `trl_sft.py` - you may want to rename the `output_dir` folder to something else to avoid overwriting the previous fine-tuned model. +Run one of the commands below: + +``` +python trl_sft.py --quantized false --peft true --cot true +python trl_sft.py --quantized false --peft false --cot true +python trl_sft.py --quantized true --peft true --cot true +``` + +Again we don't recommend using the quantized version with FFT. + +After the fine-tuning completes, you'll see the fine-tuned model saved in one of the following folders, as specified in `output_dir` of `SFTConfig` in `trl_sft.py`: + +``` +llama31-8b-text2sql-fft-nonquantized-cot +lama31-8b-text2sql-peft-nonquantized-cot +llama31-8b-text2sql-peft-quantized-cot +``` The train loss chart will look like this: ![](train_loss_cot.png) ### Evaluating the fine-tuned model (With Reasoning) -First, modify `llama_eval.sh` to use the fine-tuned model, which should match the `output_dir` in `TrainingArguments` in `trl_sft.py`: +First, set the `model` value in `llama_eval.sh` to be one of the fine-tuned model folders above, e.g. ``` YOUR_API_KEY='finetuned' -model='fine_tuning/llama31-8b-text2sql-fine-tuned' +model='fine_tuning/llama31-8b-text2sql-fft-nonquantized-cot' ``` Then uncomment the line `SYSTEM_PROMPT` [here](https://github.com/meta-llama/llama-cookbook/blob/text2sql/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py#L31) in `llama_text2sql.py` to use it with the reasoning dataset fine-tuned model. From f7c68c1003f29c684d9957a1e1c762b1e7588bde Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Thu, 10 Jul 2025 09:45:34 -0700 Subject: [PATCH 33/78] bug fix on loading PEFT and FFT model for eval --- .../coding/text2sql/eval/llama_text2sql.py | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py b/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py index b9c9f7d8b..2e6d2939c 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py +++ b/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py @@ -223,16 +223,33 @@ def cloud_llama(api_key, model, prompt, max_tokens, temperature, stop): def huggingface_finetuned(api_key, model): if api_key == "finetuned": model_id = model - model = AutoPeftModelForCausalLM.from_pretrained( - model_id, device_map="auto", torch_dtype=torch.float16 - ) - tokenizer = AutoTokenizer.from_pretrained(model_id) - tokenizer.padding_side = "right" # to prevent warnings + # Check if this is a PEFT model by looking for adapter_config.json + import os + + is_peft_model = os.path.exists(os.path.join(model_id, "adapter_config.json")) + + if is_peft_model: + # Use AutoPeftModelForCausalLM for PEFT fine-tuned models + print(f"Loading PEFT model from {model_id}") + model = AutoPeftModelForCausalLM.from_pretrained( + model_id, device_map="auto", torch_dtype=torch.float16 + ) + tokenizer = AutoTokenizer.from_pretrained(model_id) + else: + # Use AutoModelForCausalLM for FFT (Full Fine-Tuning) models + print(f"Loading FFT model from {model_id}") + model = AutoModelForCausalLM.from_pretrained( + model_id, device_map="auto", torch_dtype=torch.float16 + ) + tokenizer = AutoTokenizer.from_pretrained(model_id) - if tokenizer.pad_token is None: - tokenizer.add_special_tokens({"pad_token": "[PAD]"}) - model.resize_token_embeddings(len(tokenizer)) + # For FFT models, handle pad token if it was added during training + if tokenizer.pad_token is None: + tokenizer.add_special_tokens({"pad_token": "[PAD]"}) + model.resize_token_embeddings(len(tokenizer)) + + tokenizer.padding_side = "right" # to prevent warnings elif api_key == "huggingface": model_id = model @@ -246,7 +263,7 @@ def huggingface_finetuned(api_key, model): model_id, device_map="auto", torch_dtype=torch.bfloat16, - quantization_config=bnb_config, + quantization_config=bnb_config, # None ) tokenizer = AutoTokenizer.from_pretrained(model_id) From 4037737fa635d27b3ba613af128b80ebb17f9453 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Fri, 11 Jul 2025 10:16:23 -0700 Subject: [PATCH 34/78] READMEs update based on the new FT results etc --- .../coding/text2sql/README.md | 13 ++++++------ .../coding/text2sql/eval/README.md | 6 +++--- .../coding/text2sql/fine-tuning/README.md | 20 +++++++++++++++++-- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/README.md b/end-to-end-use-cases/coding/text2sql/README.md index 7d1517f9b..29310fa85 100644 --- a/end-to-end-use-cases/coding/text2sql/README.md +++ b/end-to-end-use-cases/coding/text2sql/README.md @@ -4,7 +4,7 @@ This folder contains scripts to: 1. Evaluate Llama (original and fine-tuned) models on the Text2SQL task using the popular [BIRD](https://bird-bench.github.io) dataset in **3 simple steps**; -2. Generate two fine-tuning datasets (with and without CoT) and fine-tuning Llama 3.1 8B with the datasets, gaining a **165% improvement on the fine-tuned model without CoT (accuracy 37.16%) and 209% with CoT (accuracy 43.37%)** over the original model (accuracy 14.02%). +2. Generate two supervised fine-tuning (SFT) datasets (with and without CoT) and fine-tuning Llama 3.1 8B with the datasets, using different SFT options: with or without CoT, using quantization or not, full fine-tuning (FFT) or parameter-efficient fine-tuning (PEFT). The non-quantized PEFT SFT has the most performance gains: from 39.47% of the original Llama 3.1 8B model to 43.35%. (Note: the results are based on only 3 epochs of SFT.) Our end goal is to maximize the accuracy of Llama models on the Text2SQL task. To do so we need to first evaluate the current state of the art Llama models on the task, then apply fine-tuning, agent and other approaches to evaluate and improve Llama's performance. @@ -17,8 +17,9 @@ Our end goal is to maximize the accuracy of Llama models on the Text2SQL task. T ## Next Steps -1. Try GRPO RFT to further improve the accuracy. -2. Fine-tune Llama 3.3 70b and Llama 4 models. -3. Use torchtune. -4. Try agentic workflow. -5. Expand the eval to support other enterprise databases. +1. Hyper-parameter tuning of the current SFT scripts. +2. Try GRPO RFT to further improve the accuracy. +3. Fine-tune Llama 3.3 70b and Llama 4 models. +4. Use torchtune. +5. Try agentic workflow. +6. Expand the eval to support other enterprise databases. diff --git a/end-to-end-use-cases/coding/text2sql/eval/README.md b/end-to-end-use-cases/coding/text2sql/eval/README.md index 188642ddc..41c91f8e4 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/README.md +++ b/end-to-end-use-cases/coding/text2sql/eval/README.md @@ -14,9 +14,9 @@ Below are the results of the Llama models we have evaluated on the BIRD DEV data | Llama 4 Scout | 44.39% | 43.94% | | Llama 4 Maverick | 44.00% | 41.46% | -- Llama 3.1 8b quantized model: 14.02% (original) -- Fine-tuned with no reasoning dataset: 37.16% -- Fine-tuned with reasoning dataset: 43.37% +- Llama 3.1 8b on Hugging Face: quantized 14.02%, non-quantized 39.47% +- Fine-tuned with no CoT dataset: 39.31% +- Fine-tuned with CoT dataset: 43.35% ## Quick Start diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md index 440453bc1..d3786b00f 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md @@ -1,13 +1,29 @@ # Enhancing Text-to-SQL with CoT: A Fine-Tuning Approach with Llama -CoT stands for Chain of Thought and we will use "CoT" and "reasoning" interchangeably here, although generally, reasoning encompasses a broader concept than CoT. - This folder contains scripts to: * generate a dataset from the BIRD TRAIN set (with no CoT info) for supervised fine-tuning (SFT); * generate a dataset from the BIRD TRAIN set (with CoT info by Llama 3.3 70B) for SFT; * SFT the Llama 3.1 8B model with the generated datasets with different fine-tuning combinations: with or without CoT, using quantization or not, full fine-tuning (FFT) or parameter-efficient fine-tuning (PEFT). +**Note:** CoT stands for Chain of Thought and we will use "CoT" and "reasoning" interchangeably here, although generally, reasoning encompasses a broader concept than CoT. + +## Eval Results of the Fine-tuned Models + +The eval results of SFT Llama 3.1 8B with different options are summarized in the table below: + +| Fine-tuning Combination | Accuracy | +|-----------------------------|----------| +| Non-Quantized, CoT, FFT | xx.xx% | +| Non-Quantized, CoT, PEFT | 43.35% | +| Quantized, CoT, PEFT | 42.89% | +| Non-Quantized, No CoT, PEFT | 39.31% | +| Quantized, No CoT, PEFT | 39.31% | +| Non-Quantized, No CoT, FFT | 33.70% | +| Quantized, CoT, FFT | N/A | +| Quantized, No CoT, FFT | N/A | + + ## SFT with the BIRD TRAIN dataset (No Reasoning) We'll first use the BIRD TRAIN dataset to prepare for supervised fine-tuning with no reasoning info in the dataset. From f07da727bceb94a2df836a6da11e01ed374dfb61 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Fri, 11 Jul 2025 11:26:22 -0700 Subject: [PATCH 35/78] finetuning README --- end-to-end-use-cases/coding/text2sql/fine-tuning/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md index d3786b00f..e15f2a827 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md @@ -14,11 +14,11 @@ The eval results of SFT Llama 3.1 8B with different options are summarized in th | Fine-tuning Combination | Accuracy | |-----------------------------|----------| -| Non-Quantized, CoT, FFT | xx.xx% | | Non-Quantized, CoT, PEFT | 43.35% | | Quantized, CoT, PEFT | 42.89% | | Non-Quantized, No CoT, PEFT | 39.31% | | Quantized, No CoT, PEFT | 39.31% | +| Non-Quantized, CoT, FFT | 38.46% | | Non-Quantized, No CoT, FFT | 33.70% | | Quantized, CoT, FFT | N/A | | Quantized, No CoT, FFT | N/A | From 57ffb7427b01870d6293e0aebf17688fd9e430e1 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Fri, 11 Jul 2025 11:28:43 -0700 Subject: [PATCH 36/78] finetuning README --- end-to-end-use-cases/coding/text2sql/fine-tuning/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md index e15f2a827..a0c7d654f 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md @@ -10,7 +10,7 @@ This folder contains scripts to: ## Eval Results of the Fine-tuned Models -The eval results of SFT Llama 3.1 8B with different options are summarized in the table below: +The eval results of SFT Llama 3.1 8B with different options (epochs is 3) are summarized in the table below: | Fine-tuning Combination | Accuracy | |-----------------------------|----------| @@ -23,7 +23,6 @@ The eval results of SFT Llama 3.1 8B with different options are summarized in th | Quantized, CoT, FFT | N/A | | Quantized, No CoT, FFT | N/A | - ## SFT with the BIRD TRAIN dataset (No Reasoning) We'll first use the BIRD TRAIN dataset to prepare for supervised fine-tuning with no reasoning info in the dataset. From a6f7d02c179cd9b8df5c375d7b0483cb968957f6 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Fri, 11 Jul 2025 16:57:16 -0700 Subject: [PATCH 37/78] train loss update --- .../text2sql/fine-tuning/train_loss.png | Bin 148910 -> 164421 bytes .../text2sql/fine-tuning/train_loss_cot.png | Bin 104889 -> 172379 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/train_loss.png b/end-to-end-use-cases/coding/text2sql/fine-tuning/train_loss.png index 0c57364d19e95d952c14b536241854bb91466d2a..a0fbadf0bd886ec667d2c44b7cd33f913e234ef3 100644 GIT binary patch literal 164421 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

hH9>gI*fij#(On|t3IQP8~QTA?H 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

tE_Y8J(tj9@Vr)Yw~I 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%0DWOIRU(KZjesmmQaA!HMw2jkbn z#2r%T{95e8j0rtF{zDDOQ&BL=C?nqPQ``DQ+qI(REl<4;Swu;(}jed7AN<>`6rf|31C%L~*RKU$T@0!BFxV6O8Zb z13fL8Wx4MR_d7gErpSB(b*YQuSo&OR6O`)L%?I?>Pp{S$w!WI}sL}68t+fe63pOyw z{ATGoYrMVRYvYh-1IPa$`iM*Q-4642oHcmO@JrTr!h4N|sm6lZf^DIJDypdv*%%e+ z&C=uj^@DCJPl#5wG%Hqiyb(yO{WXbs_cRKVNny;i3ONxi+sbRDthqHvAUpy~8PkgkSn_{&4TDGp-$MT%zTTMyq6wJ&L zSN|wk3pH)dU+Ig7o%USpCCrrnHZfyC%pCq%o+&>y?$zuY>2Wmw@(X&`5@yi#SXN&v z*<>i;i(81JWwXV8+poqMaB!R*$e1O0b_8ts)2+UF2OGTL65yzK?6`|Kl9V1t7|;4L zZfpb?xi~I-u5se}`}fUmt@qAs$O-hJ5v=wc36)vDJabX{^L^OO&T11G3zBP17rroF zuNBkQy1r0A7P;*Ww&5kv9l@tj?P<7MP_!1wi!d+MVdHT{Mb`(@VGoz?Pr~e6=f6up zzGO4}QB2y#U@#%$Js!zEyMm?q73W-`-p)=H!-4vV$Y#zr-oq_tVJ{Gi{Fl!jl`cQP z;lf)V!rIE6mZ!xZE{uqa_SJ-khhv$adu!EqdeQ33TzN?)li%i64kaKYvSKuKX}79N zqulCCTv5*voe>r45+$#_HaY9uf!tFLZLg;^8e2Ab^`OmaW9?`Wnh(7c4N(7g&}=sSJ-@pQEIZ3wh9S(nX$DZs+HqUP43@@&9oYb z|2u|%EQgif?mvAJa3wbV?U?k!&^#IZk2n7r{(l-52xV8A;r-M`4tclIem07tiOR$I z^cUK|e_eH(8&giixVQOolZlCGeIfXH?#{ir8!7JPm^A+X%pN4hUE&A?Fhl|R}O4Wrp z&@{5Kk>%jvAhNZ!bshqLwEQsP%fCCUj8fj81N&a4rlzj$>^KH0TOG`UwX3f2c-hSC z?1byv-(acJ&r+{o4{-l4wEr_ey9~ut>*?(5Y!?=b#fKt|Hda?(Hng>Ijf{){ssH|H z5xy|^_`kYDQYeBzw9U=Uhv4<=^S*@D%AVxwtgNh)mc|EE_)V{2-v7O}VzY5=h6o`=4#~-zbGWx_ukt)}cQ|@^62}sL1gFbd&!z^q+<`70DIx Y(Bl*Q7LZ+x;O5X$*H^1}V*U320Jmivvj6}9 literal 148910 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 K0MEXI)B{Lvr%QA_Bp#TxNI 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

;mh1PKiEyV@2>LnOxiYZAy?O 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%0D;V>wbZyRQQ(zit#>ssPm@9NUp67(JINY^TtTP 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μuPT;+OpehmQjI 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

5%g_HU5vC@4a2HIhaU~hazEhxeu~Czuc{0hv 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
\n", - " \n", - " \n", - " [60/60 02:09, Epoch 0/1]\n", - "
\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
StepTraining Loss
11.124300
21.146600
31.080300
41.007300
51.294600
60.990800
70.945300
80.977200
90.709900
100.730600
110.742400
120.651700
130.610100
140.659700
150.582100
160.526100
170.701700
180.540800
190.580600
200.466500
210.432900
220.588300
230.392800
240.571500
250.473200
260.432700
270.460100
280.510300
290.329800
300.448200
310.444500
320.344200
330.439600
340.302700
350.403300
360.348200
370.363500
380.398100
390.518900
400.263000
410.286800
420.320400
430.324000
440.387200
450.230200
460.448800
470.196300
480.384200
490.337900
500.259800
510.262400
520.360300
530.151700
540.220300
550.297200
560.238500
570.292100
580.321500
590.257700
600.212100

" - ] - }, - "metadata": {} - } - ], - "source": [ - "trainer_stats = trainer.train()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "pCqnaKmlO1U9", - "outputId": "26677bc3-d541-49ff-fc57-6db2b956e0f1" - }, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "144.3049 seconds used for training.\n", - "2.41 minutes used for training.\n", - "Peak reserved memory = 30.502 GB.\n", - "Peak reserved memory for training = 0.0 GB.\n", - "Peak reserved memory % of max memory = 77.109 %.\n", - "Peak reserved memory for training % of max memory = 0.0 %.\n" - ] - } - ], - "source": [ - "# @title Show final memory and time stats\n", - "used_memory = round(torch.cuda.max_memory_reserved() / 1024 / 1024 / 1024, 3)\n", - "used_memory_for_lora = round(used_memory - start_gpu_memory, 3)\n", - "used_percentage = round(used_memory / max_memory * 100, 3)\n", - "lora_percentage = round(used_memory_for_lora / max_memory * 100, 3)\n", - "print(f\"{trainer_stats.metrics['train_runtime']} seconds used for training.\")\n", - "print(\n", - " f\"{round(trainer_stats.metrics['train_runtime']/60, 2)} minutes used for training.\"\n", - ")\n", - "print(f\"Peak reserved memory = {used_memory} GB.\")\n", - "print(f\"Peak reserved memory for training = {used_memory_for_lora} GB.\")\n", - "print(f\"Peak reserved memory % of max memory = {used_percentage} %.\")\n", - "print(f\"Peak reserved memory for training % of max memory = {lora_percentage} %.\")" - ] - }, - { - "cell_type": "markdown", - "source": [], - "metadata": { - "id": "PGU_6HO40Q2i" - } - }, - { - "cell_type": "markdown", - "metadata": { - "id": "ekOmTR1hSNcr" - }, - "source": [ - "\n", - "### Inference\n", - "Let's run the model! You can change the instruction and input - leave the output blank!\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "kR3gIAX-SM2q", - "outputId": "08b36347-9bcc-40db-e9cc-f036668f0727" - }, - "outputs": [ - { - "output_type": "stream", - "name": "stderr", - "text": [ - "The following generation flags are not valid and may be ignored: ['cache_implementation']. Set `TRANSFORMERS_VERBOSITY=info` for more details.\n" - ] - }, - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "['<|begin_of_text|>Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.\\n\\n### Instruction:\\nYou are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement.\\n\\n### Input:\\n-- DB Schema: CREATE TABLE \"lists\"\\n(\\n user_id INTEGER\\n references lists_users (user_id),\\n list_id INTEGER not null\\n primary key,\\n list_title TEXT,\\n list_movie_number INTEGER,\\n list_update_timestamp_utc TEXT,\\n list_creation_timestamp_utc TEXT,\\n list_followers INTEGER,\\n list_url TEXT,\\n list_comments INTEGER,\\n list_description TEXT,\\n list_cover_image_url TEXT,\\n list_first_image_url TEXT,\\n list_second_image_url TEXT,\\n list_third_image_url TEXT\\n)\\n\\nCREATE TABLE \"movies\"\\n(\\n movie_id INTEGER not null\\n primary key,\\n movie_title TEXT,\\n movie_release_year INTEGER,\\n movie_url TEXT,\\n movie_title_language TEXT,\\n movie_popularity INTEGER,\\n movie_image_url TEXT,\\n director_id TEXT,\\n director_name TEXT,\\n director_url TEXT\\n)\\n\\nCREATE TABLE \"ratings_users\"\\n(\\n user_id INTEGER\\n references lists_users (user_id),\\n rating_date_utc TEXT,\\n user_trialist INTEGER,\\n user_subscriber INTEGER,\\n user_avatar_image_url TEXT,\\n user_cover_image_url TEXT,\\n user_eligible_for_trial INTEGER,\\n user_has_payment_method INTEGER\\n)\\n\\nCREATE TABLE lists_users\\n(\\n user_id INTEGER not null,\\n list_id INTEGER not null,\\n list_update_date_utc TEXT,\\n list_creation_date_utc TEXT,\\n user_trialist INTEGER,\\n user_subscriber INTEGER,\\n user_avatar_image_url TEXT,\\n user_cover_image_url TEXT,\\n user_eligible_for_trial TEXT,\\n user_has_payment_method TEXT,\\n primary key (user_id, list_id),\\n foreign key (list_id) references lists(list_id),\\n foreign key (user_id) references lists(user_id)\\n)\\n\\nCREATE TABLE ratings\\n(\\n movie_id INTEGER,\\n rating_id INTEGER,\\n rating_url TEXT,\\n rating_score INTEGER,\\n rating_timestamp_utc TEXT,\\n critic TEXT,\\n critic_likes INTEGER,\\n critic_comments INTEGER,\\n user_id INTEGER,\\n user_trialist INTEGER,\\n user_subscriber INTEGER,\\n user_eligible_for_trial INTEGER,\\n user_has_payment_method INTEGER,\\n foreign key (movie_id) references movies(movie_id),\\n foreign key (user_id) references lists_users(user_id),\\n foreign key (rating_id) references ratings(rating_id),\\n foreign key (user_id) references ratings_users(user_id)\\n)\\n\\n-- External Knowledge: longest movie title refers to MAX(LENGTH(movie_title)); when it was released refers to movie_release_year;\\n\\n-- Question: What is the name of the longest movie title? When was it released?\\n\\n### Response:\\nSELECT T2.movie_title, T2.movie_release_year FROM lists AS T1 INNER JOIN movies AS T2 ON T1.list_id = T2.movie_id ORDER BY LENGTH(T2.movie_title) DESC LIMIT 1<|eot_id|>']" - ] - }, - "metadata": {}, - "execution_count": 21 - } - ], - "source": [ - "# alpaca_prompt = Copied from above\n", - "FastLanguageModel.for_inference(model) # Enable native 2x faster inference\n", - "inputs = tokenizer(\n", - "[\n", - " alpaca_prompt.format(\n", - " \"You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement.\", # instruction\n", - " \"-- DB Schema: CREATE TABLE \\\"lists\\\"\\n(\\n user_id INTEGER\\n references lists_users (user_id),\\n list_id INTEGER not null\\n primary key,\\n list_title TEXT,\\n list_movie_number INTEGER,\\n list_update_timestamp_utc TEXT,\\n list_creation_timestamp_utc TEXT,\\n list_followers INTEGER,\\n list_url TEXT,\\n list_comments INTEGER,\\n list_description TEXT,\\n list_cover_image_url TEXT,\\n list_first_image_url TEXT,\\n list_second_image_url TEXT,\\n list_third_image_url TEXT\\n)\\n\\nCREATE TABLE \\\"movies\\\"\\n(\\n movie_id INTEGER not null\\n primary key,\\n movie_title TEXT,\\n movie_release_year INTEGER,\\n movie_url TEXT,\\n movie_title_language TEXT,\\n movie_popularity INTEGER,\\n movie_image_url TEXT,\\n director_id TEXT,\\n director_name TEXT,\\n director_url TEXT\\n)\\n\\nCREATE TABLE \\\"ratings_users\\\"\\n(\\n user_id INTEGER\\n references lists_users (user_id),\\n rating_date_utc TEXT,\\n user_trialist INTEGER,\\n user_subscriber INTEGER,\\n user_avatar_image_url TEXT,\\n user_cover_image_url TEXT,\\n user_eligible_for_trial INTEGER,\\n user_has_payment_method INTEGER\\n)\\n\\nCREATE TABLE lists_users\\n(\\n user_id INTEGER not null ,\\n list_id INTEGER not null ,\\n list_update_date_utc TEXT,\\n list_creation_date_utc TEXT,\\n user_trialist INTEGER,\\n user_subscriber INTEGER,\\n user_avatar_image_url TEXT,\\n user_cover_image_url TEXT,\\n user_eligible_for_trial TEXT,\\n user_has_payment_method TEXT,\\n primary key (user_id, list_id),\\n foreign key (list_id) references lists(list_id),\\n foreign key (user_id) references lists(user_id)\\n)\\n\\nCREATE TABLE ratings\\n(\\n movie_id INTEGER,\\n rating_id INTEGER,\\n rating_url TEXT,\\n rating_score INTEGER,\\n rating_timestamp_utc TEXT,\\n critic TEXT,\\n critic_likes INTEGER,\\n critic_comments INTEGER,\\n user_id INTEGER,\\n user_trialist INTEGER,\\n user_subscriber INTEGER,\\n user_eligible_for_trial INTEGER,\\n user_has_payment_method INTEGER,\\n foreign key (movie_id) references movies(movie_id),\\n foreign key (user_id) references lists_users(user_id),\\n foreign key (rating_id) references ratings(rating_id),\\n foreign key (user_id) references ratings_users(user_id)\\n)\\n\\n-- External Knowledge: longest movie title refers to MAX(LENGTH(movie_title)); when it was released refers to movie_release_year;\\n\\n-- Question: What is the name of the longest movie title? When was it released?\", # input\n", - " \"\", # output - leave this blank for generation!\n", - " )\n", - "], return_tensors = \"pt\").to(\"cuda\")\n", - "\n", - "outputs = model.generate(**inputs, max_new_tokens = 1024, use_cache = False)\n", - "tokenizer.batch_decode(outputs)" - ] - }, - { - "cell_type": "code", - "source": [ - "# # alpaca_prompt = Copied from above\n", - "# FastLanguageModel.for_inference(model) # Enable native 2x faster inference\n", - "# inputs = tokenizer(\n", - "# [\n", - "# alpaca_prompt.format(\n", - "# \"You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement.\", # instruction\n", - "# \"-- DB Schema: CREATE TABLE \\\"lists\\\"\\n(\\n user_id INTEGER\\n references lists_users (user_id),\\n list_id INTEGER not null\\n primary key,\\n list_title TEXT,\\n list_movie_number INTEGER,\\n list_update_timestamp_utc TEXT,\\n list_creation_timestamp_utc TEXT,\\n list_followers INTEGER,\\n list_url TEXT,\\n list_comments INTEGER,\\n list_description TEXT,\\n list_cover_image_url TEXT,\\n list_first_image_url TEXT,\\n list_second_image_url TEXT,\\n list_third_image_url TEXT\\n)\\n\\nCREATE TABLE \\\"movies\\\"\\n(\\n movie_id INTEGER not null\\n primary key,\\n movie_title TEXT,\\n movie_release_year INTEGER,\\n movie_url TEXT,\\n movie_title_language TEXT,\\n movie_popularity INTEGER,\\n movie_image_url TEXT,\\n director_id TEXT,\\n director_name TEXT,\\n director_url TEXT\\n)\\n\\nCREATE TABLE \\\"ratings_users\\\"\\n(\\n user_id INTEGER\\n references lists_users (user_id),\\n rating_date_utc TEXT,\\n user_trialist INTEGER,\\n user_subscriber INTEGER,\\n user_avatar_image_url TEXT,\\n user_cover_image_url TEXT,\\n user_eligible_for_trial INTEGER,\\n user_has_payment_method INTEGER\\n)\\n\\nCREATE TABLE lists_users\\n(\\n user_id INTEGER not null ,\\n list_id INTEGER not null ,\\n list_update_date_utc TEXT,\\n list_creation_date_utc TEXT,\\n user_trialist INTEGER,\\n user_subscriber INTEGER,\\n user_avatar_image_url TEXT,\\n user_cover_image_url TEXT,\\n user_eligible_for_trial TEXT,\\n user_has_payment_method TEXT,\\n primary key (user_id, list_id),\\n foreign key (list_id) references lists(list_id),\\n foreign key (user_id) references lists(user_id)\\n)\\n\\nCREATE TABLE ratings\\n(\\n movie_id INTEGER,\\n rating_id INTEGER,\\n rating_url TEXT,\\n rating_score INTEGER,\\n rating_timestamp_utc TEXT,\\n critic TEXT,\\n critic_likes INTEGER,\\n critic_comments INTEGER,\\n user_id INTEGER,\\n user_trialist INTEGER,\\n user_subscriber INTEGER,\\n user_eligible_for_trial INTEGER,\\n user_has_payment_method INTEGER,\\n foreign key (movie_id) references movies(movie_id),\\n foreign key (user_id) references lists_users(user_id),\\n foreign key (rating_id) references ratings(rating_id),\\n foreign key (user_id) references ratings_users(user_id)\\n)\\n\\n-- External Knowledge: longest movie title refers to MAX(LENGTH(movie_title)); when it was released refers to movie_release_year;\\n\\n-- Question: What is the name of the longest movie title? When was it released?\", # input\n", - "# \"\", # output - leave this blank for generation!\n", - "# )\n", - "# ], return_tensors = \"pt\").to(\"cuda\")\n", - "\n", - "# outputs = model.generate(**inputs, max_new_tokens = 1024, use_cache = True)\n", - "# tokenizer.batch_decode(outputs)" - ], - "metadata": { - "id": "dusmu3Y-WPl_" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "QQMjaNrjsU5_" - }, - "source": [ - "You can also use Hugging Face's `AutoModelForPeftCausalLM`. Only use this if you do not have `unsloth` installed. It can be hopelessly slow, since `4bit` model downloading is not supported, and Unsloth's **inference is 2x faster**." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "yFfaXG0WsQuE" - }, - "outputs": [], - "source": [ - "if False:\n", - " # I highly do NOT suggest - use Unsloth if possible\n", - " from peft import AutoPeftModelForCausalLM\n", - " from transformers import AutoTokenizer\n", - " model = AutoPeftModelForCausalLM.from_pretrained(\n", - " \"lora_model\", # YOUR MODEL YOU USED FOR TRAINING\n", - " load_in_4bit = load_in_4bit,\n", - " )\n", - " tokenizer = AutoTokenizer.from_pretrained(\"lora_model\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "upcOlWe7A1vc", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 130, - "referenced_widgets": [ - "b89abd16ac7645c2af3861be2a53e7a4", - "0a3dbf62929640f5b670bb9932ff9e85", - "774bc595ccdf4fcfbc078ae69e31cce2", - "a401420ba5a84c4e8e09d189ae31791f", - "d9338d0b5aa14d98a230f64a96dacfc6", - "da237a8e84234e9ab6eb73c8cc41dac5", - "6b730c841c28487596cb1358402f618b", - "954b8f5078384488b503919bb47b380e", - "2e589652d1b641b1bd49109f3a963a63", - "9db7e5022a1a4c82a4b218c4f0e58a7d", - "ec69d72c400d497cb43db1a2c4d3ffd0", - "9124002ea80946079b05669b8edf2e93", - "2418f4815f8e4db38821f04715509a87", - "8b024ae17b3d4f9d9458e0d24c4ba858", - "3aca95703e0b4da195020b22e03794d5", - "888e1a411dd84e68a9fb45319a384e53", - "2aa533d9f8154a2890442924f939b936", - "f7f0f1b891454fcb8271c2fd9afa5e39", - "032982a7372d47c09a039de0f89e7626", - "e909536897824b8492ed21651d7cdcc2", - "56f54ec10c5a411d97a8add4e37419e7", - "9ae2b77ef66949a8ac1a2c073adf654e", - "be77d2c16a8544ffae3c3224a88ceac7", - "18730cc628544463be32a527143908e7", - "783f0b6997c04133a92e75c8c1970555", - "317c60b6371b4f0b8903659a48915549", - "3299e112ee0e4b948383d0965e000665", - "123983553f524c86b2e34137c3e15a81", - "f8f4c7d3484040f5b7cc63dd507e7cac", - "bb9630f74a664507ac5fa5e7c3b28287", - "b80165d852f547f28d0ef91276586a4d", - "a46d09b6a9b649bd95b48d1ec9430a55", - "358661cd13c14e6eb64591b288f9f02f" - ] - }, - "outputId": "50f44657-a02d-4657-ce10-29436f4a4ad8" - }, - "outputs": [ - { - "output_type": "display_data", - "data": { - "text/plain": [ - "README.md: 0%| | 0.00/587 [00:00 Date: Sat, 12 Jul 2025 09:49:31 -0700 Subject: [PATCH 45/78] fine-tuning README update with latest result --- .../coding/text2sql/fine-tuning/README.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md index 3e1a8ff4d..e1a8fc7d9 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md @@ -10,19 +10,25 @@ This folder contains scripts to: ## Eval Results of the Fine-tuned Models -The eval results of SFT Llama 3.1 8B with different options (epochs is 3) are summarized in the table below: +The eval results of SFT Llama 3.1 8B with different options (epochs is 3) are summarized below: | Fine-tuning Combination | Accuracy | |-----------------------------|----------| | Non-Quantized, CoT, PEFT | 43.35% | | Quantized, CoT, PEFT | 42.89% | +| Non-Quantized, CoT, FFT | 42.44% | | Non-Quantized, No CoT, PEFT | 39.31% | | Quantized, No CoT, PEFT | 39.31% | -| Non-Quantized, CoT, FFT | 38.46% | -| Non-Quantized, No CoT, FFT | 33.70% | +| Non-Quantized, No CoT, FFT | 36.31% | | Quantized, CoT, FFT | N/A | | Quantized, No CoT, FFT | N/A | +The table above shows that: + +1. The CoT FFT/PEFT model (with or without quantization) outperforms the no CoT FFT/PEFT model (with or without quantization) by 3.5% to 6.1%. + +2. The non-quantized PEFT model (CoT or not) is slightly better than the non-quantized FFT model. + ## SFT with the BIRD TRAIN dataset (No Reasoning) We'll first use the BIRD TRAIN dataset to prepare for supervised fine-tuning with no reasoning info in the dataset. From 2cdfbf059395fe41e6714338eb3c191702e5dc77 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Mon, 14 Jul 2025 14:57:16 -0700 Subject: [PATCH 46/78] READMEs update --- .../coding/text2sql/eval/README.md | 4 ++-- .../coding/text2sql/fine-tuning/README.md | 24 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/eval/README.md b/end-to-end-use-cases/coding/text2sql/eval/README.md index 41c91f8e4..fa70ab38b 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/README.md +++ b/end-to-end-use-cases/coding/text2sql/eval/README.md @@ -15,8 +15,8 @@ Below are the results of the Llama models we have evaluated on the BIRD DEV data | Llama 4 Maverick | 44.00% | 41.46% | - Llama 3.1 8b on Hugging Face: quantized 14.02%, non-quantized 39.47% -- Fine-tuned with no CoT dataset: 39.31% -- Fine-tuned with CoT dataset: 43.35% +- Non-quantized FFT with no CoT dataset: 36.31% +- Non-quantized FFT with CoT dataset: 43.87% ## Quick Start diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md index e1a8fc7d9..2b6183823 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md @@ -10,18 +10,18 @@ This folder contains scripts to: ## Eval Results of the Fine-tuned Models -The eval results of SFT Llama 3.1 8B with different options (epochs is 3) are summarized below: - -| Fine-tuning Combination | Accuracy | -|-----------------------------|----------| -| Non-Quantized, CoT, PEFT | 43.35% | -| Quantized, CoT, PEFT | 42.89% | -| Non-Quantized, CoT, FFT | 42.44% | -| Non-Quantized, No CoT, PEFT | 39.31% | -| Quantized, No CoT, PEFT | 39.31% | -| Non-Quantized, No CoT, FFT | 36.31% | -| Quantized, CoT, FFT | N/A | -| Quantized, No CoT, FFT | N/A | +The eval results of SFT Llama 3.1 8B with different options (epochs is 3, with an additional 10 for the two FFT models) are summarized below: + +| Fine-tuning Combination | Accuracy | +|-----------------------------|-------------------------------| +| Non-Quantized, CoT, PEFT | 43.35% | +| Quantized, CoT, PEFT | 42.89% | +| Non-Quantized, CoT, FFT | 42.44% (43.87% for 10 epochs) | +| Non-Quantized, No CoT, PEFT | 39.31% | +| Quantized, No CoT, PEFT | 39.31% | +| Non-Quantized, No CoT, FFT | 36.31% (38.27% for 10 epochs) | +| Quantized, CoT, FFT | N/A | +| Quantized, No CoT, FFT | N/A | The table above shows that: From 4bb7faa35c7779d296b7db1e0d9c2b02be0d20dc Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Mon, 14 Jul 2025 14:58:04 -0700 Subject: [PATCH 47/78] READMEs update --- .../coding/text2sql/README.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/README.md b/end-to-end-use-cases/coding/text2sql/README.md index 29310fa85..12811f2b6 100644 --- a/end-to-end-use-cases/coding/text2sql/README.md +++ b/end-to-end-use-cases/coding/text2sql/README.md @@ -2,24 +2,23 @@ This folder contains scripts to: -1. Evaluate Llama (original and fine-tuned) models on the Text2SQL task using the popular [BIRD](https://bird-bench.github.io) dataset in **3 simple steps**; +1. Evaluate Llama (original and fine-tuned) models on the Text2SQL task using the popular [BIRD](https://bird-bench.github.io) dataset. -2. Generate two supervised fine-tuning (SFT) datasets (with and without CoT) and fine-tuning Llama 3.1 8B with the datasets, using different SFT options: with or without CoT, using quantization or not, full fine-tuning (FFT) or parameter-efficient fine-tuning (PEFT). The non-quantized PEFT SFT has the most performance gains: from 39.47% of the original Llama 3.1 8B model to 43.35%. (Note: the results are based on only 3 epochs of SFT.) +2. Generate two supervised fine-tuning (SFT) datasets (with and without CoT) and fine-tuning Llama 3.1 8B with the datasets, using different SFT options: with or without CoT, using quantization or not, full fine-tuning (FFT) or parameter-efficient fine-tuning (PEFT). The non-quantized PEFT CoT SFT has the most performance gains: from 39.47% of the original Llama 3.1 8B model to 43.35%. (Note: the results are based on 3 epochs of SFT.) Our end goal is to maximize the accuracy of Llama models on the Text2SQL task. To do so we need to first evaluate the current state of the art Llama models on the task, then apply fine-tuning, agent and other approaches to evaluate and improve Llama's performance. ## Structure: -- data: contains the scripts to download the BIRD TRAIN and DEV datasets; -- eval: contains the scripts to evaluate Llama models (original and fine-tuned) on the BIRD dataset; -- fine-tune: contains the scripts to generate non-CoT and CoT datasets based on the BIRD TRAIN set and to fine-tune Llama models using the datasets; +- data: contains scripts to download the BIRD TRAIN and DEV datasets; +- eval: contains scripts to evaluate Llama models (original and fine-tuned) on the BIRD dataset; +- fine-tune: contains scripts to generate non-CoT and CoT datasets based on the BIRD TRAIN set and to supervised fine-tune Llama models using the datasets, with different SFT options (quantization or not, full fine-tuning or parameter-efficient fine-tuning); - quickstart: contains a notebook to ask Llama 3.3 to convert natural language queries into SQL queries. ## Next Steps 1. Hyper-parameter tuning of the current SFT scripts. -2. Try GRPO RFT to further improve the accuracy. -3. Fine-tune Llama 3.3 70b and Llama 4 models. -4. Use torchtune. -5. Try agentic workflow. -6. Expand the eval to support other enterprise databases. +2. Try GRPO reinforcement learning to further improve the accuracy. +3. Fine-tune Llama 3.3 70B and Llama 4 models. +4. Try agentic workflow. +5. Expand the eval to support other enterprise databases. From 2bd662c67d76529f3430cfed1a4d5eb363c36b09 Mon Sep 17 00:00:00 2001 From: Amir Youssefi <328194+ghd3v@users.noreply.github.com> Date: Thu, 17 Jul 2025 23:20:12 -0700 Subject: [PATCH 48/78] adding vllm eval files and updating requirements.txt --- .../coding/text2sql/eval/llama_eval_vllm.sh | 24 ++ .../text2sql/eval/llama_text2sql_vllm.py | 289 ++++++++++++++++++ .../coding/text2sql/eval/requirements.txt | 2 + 3 files changed, 315 insertions(+) create mode 100644 end-to-end-use-cases/coding/text2sql/eval/llama_eval_vllm.sh create mode 100644 end-to-end-use-cases/coding/text2sql/eval/llama_text2sql_vllm.py diff --git a/end-to-end-use-cases/coding/text2sql/eval/llama_eval_vllm.sh b/end-to-end-use-cases/coding/text2sql/eval/llama_eval_vllm.sh new file mode 100644 index 000000000..532ee6235 --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/eval/llama_eval_vllm.sh @@ -0,0 +1,24 @@ +eval_path='../data/dev_20240627/dev.json' +db_root_path='../data/dev_20240627/dev_databases/' +ground_truth_path='../data/' + +model='meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo' +data_output_path="./output/$model/" + +echo "Text2SQL using $model" +python3 -u llama_text2sql_vllm.py --db_root_path ${db_root_path} \ +--model ${model} --eval_path ${eval_path} --data_output_path ${data_output_path} + +# Check if llama_text2sql.py exited successfully +if [ $? -eq 0 ]; then + echo "llama_text2sql.py completed successfully. Proceeding with evaluation..." + python3 -u text2sql_eval.py --db_root_path ${db_root_path} --predicted_sql_path ${data_output_path} \ + --ground_truth_path ${ground_truth_path} \ + --diff_json_path ${eval_path} + + echo "Done evaluating $model." + +else + echo "Error: llama_text2sql.py failed with exit code $?. Skipping evaluation." + exit 1 +fi diff --git a/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql_vllm.py b/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql_vllm.py new file mode 100644 index 000000000..e7936a061 --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql_vllm.py @@ -0,0 +1,289 @@ +import argparse +import json +import os +import re +import sqlite3 +from typing import Dict, List, Tuple + +from tqdm import tqdm + +from vllm import LLM, EngineArgs, SamplingParams + +DEFAULT_MAX_TOKENS=10240 +SYSTEM_PROMPT = "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement." +# UNCOMMENT TO USE THE FINE_TUNED MODEL WITH REASONING DATASET +# SYSTEM_PROMPT = "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, generate the step-by-step reasoning and the final SQLite SQL select statement from the text question." + + +def inference(llm, sampling_params, user_prompt): + messages = [ + {"content": SYSTEM_PROMPT, "role": "system"}, + {"role": "user", "content": user_prompt}, + ] + + print(f"{messages=}") + + response = llm.chat(messages, sampling_params, use_tqdm=False) + print(f"{response=}") + response_text = response[0].outputs[0].text + pattern = re.compile(r"```sql\n*(.*?)```", re.DOTALL) + matches = pattern.findall(response_text) + if matches != []: + result = matches[0] + else: + result = response_text + print(f"{result=}") + return result + + +def new_directory(path): + if not os.path.exists(path): + os.makedirs(path) + + +def get_db_schemas(bench_root: str, db_name: str) -> Dict[str, str]: + """ + Read an sqlite file, and return the CREATE commands for each of the tables in the database. + """ + asdf = "database" if bench_root == "spider" else "databases" + with sqlite3.connect( + f"file:{bench_root}/{asdf}/{db_name}/{db_name}.sqlite?mode=ro", uri=True + ) as conn: + # conn.text_factory = bytes + cursor = conn.cursor() + cursor.execute("SELECT name FROM sqlite_master WHERE type='table';") + tables = cursor.fetchall() + schemas = {} + for table in tables: + cursor.execute( + "SELECT sql FROM sqlite_master WHERE type='table' AND name='{}';".format( + table[0] + ) + ) + schemas[table[0]] = cursor.fetchone()[0] + + return schemas + + +def nice_look_table(column_names: list, values: list): + rows = [] + # Determine the maximum width of each column + widths = [ + max(len(str(value[i])) for value in values + [column_names]) + for i in range(len(column_names)) + ] + + # Print the column names + header = "".join( + f"{column.rjust(width)} " for column, width in zip(column_names, widths) + ) + # print(header) + # Print the values + for value in values: + row = "".join(f"{str(v).rjust(width)} " for v, width in zip(value, widths)) + rows.append(row) + rows = "\n".join(rows) + final_output = header + "\n" + rows + return final_output + + +def generate_schema_prompt(db_path, num_rows=None): + # extract create ddls + """ + :param root_place: + :param db_name: + :return: + """ + full_schema_prompt_list = [] + conn = sqlite3.connect(db_path) + # Create a cursor object + cursor = conn.cursor() + cursor.execute("SELECT name FROM sqlite_master WHERE type='table'") + tables = cursor.fetchall() + schemas = {} + for table in tables: + if table == "sqlite_sequence": + continue + cursor.execute( + "SELECT sql FROM sqlite_master WHERE type='table' AND name='{}';".format( + table[0] + ) + ) + create_prompt = cursor.fetchone()[0] + schemas[table[0]] = create_prompt + if num_rows: + cur_table = table[0] + if cur_table in ["order", "by", "group"]: + cur_table = "`{}`".format(cur_table) + + cursor.execute("SELECT * FROM {} LIMIT {}".format(cur_table, num_rows)) + column_names = [description[0] for description in cursor.description] + values = cursor.fetchall() + rows_prompt = nice_look_table(column_names=column_names, values=values) + verbose_prompt = "/* \n {} example rows: \n SELECT * FROM {} LIMIT {}; \n {} \n */".format( + num_rows, cur_table, num_rows, rows_prompt + ) + schemas[table[0]] = "{} \n {}".format(create_prompt, verbose_prompt) + + for k, v in schemas.items(): + full_schema_prompt_list.append(v) + + schema_prompt = "-- DB Schema: " + "\n\n".join(full_schema_prompt_list) + + return schema_prompt + + +def generate_comment_prompt(question, knowledge=None): + knowledge_prompt = "-- External Knowledge: {}".format(knowledge) + question_prompt = "-- Question: {}".format(question) + + result_prompt = knowledge_prompt + "\n\n" + question_prompt + + return result_prompt + + +def generate_combined_prompts_one(db_path, question, knowledge=None): + schema_prompt = generate_schema_prompt(db_path, num_rows=None) + comment_prompt = generate_comment_prompt(question, knowledge) + + combined_prompts = schema_prompt + "\n\n" + comment_prompt + + return combined_prompts + + + +def collect_response_from_llama( + llm, sampling_params, db_path_list, question_list, knowledge_list=None +): + response_list = [] + + for i, question in tqdm(enumerate(question_list)): + print( + "--------------------- processing question #{}---------------------".format( + i + 1 + ) + ) + print("the question is: {}".format(question)) + + if knowledge_list: + cur_prompt = generate_combined_prompts_one( + db_path=db_path_list[i], question=question, knowledge=knowledge_list[i] + ) + else: + cur_prompt = generate_combined_prompts_one( + db_path=db_path_list[i], question=question + ) + + plain_result = inference(llm, sampling_params, cur_prompt) + if type(plain_result) == str: + sql = plain_result + else: + sql = "SELECT" + plain_result["choices"][0]["text"] + + # responses_dict[i] = sql + db_id = db_path_list[i].split("/")[-1].split(".sqlite")[0] + sql = ( + sql + "\t----- bird -----\t" + db_id + ) # to avoid unpredicted \t appearing in codex results + response_list.append(sql) + + return response_list + + +def question_package(data_json, knowledge=False): + question_list = [] + for data in data_json: + question_list.append(data["question"]) + + return question_list + + +def knowledge_package(data_json, knowledge=False): + knowledge_list = [] + for data in data_json: + knowledge_list.append(data["evidence"]) + + return knowledge_list + + +def decouple_question_schema(datasets, db_root_path): + question_list = [] + db_path_list = [] + knowledge_list = [] + for i, data in enumerate(datasets): + question_list.append(data["question"]) + cur_db_path = db_root_path + data["db_id"] + "/" + data["db_id"] + ".sqlite" + db_path_list.append(cur_db_path) + knowledge_list.append(data["evidence"]) + + return question_list, db_path_list, knowledge_list + + +def generate_sql_file(sql_lst, output_path=None): + result = {} + for i, sql in enumerate(sql_lst): + result[i] = sql + + if output_path: + directory_path = os.path.dirname(output_path) + new_directory(directory_path) + json.dump(result, open(output_path, "w"), indent=4) + + return result + + +if __name__ == "__main__": + args_parser = argparse.ArgumentParser() + args_parser.add_argument("--eval_path", type=str, default="") + args_parser.add_argument("--mode", type=str, default="dev") + args_parser.add_argument("--test_path", type=str, default="") + args_parser.add_argument("--use_knowledge", type=str, default="True") + args_parser.add_argument("--db_root_path", type=str, default="") + args_parser.add_argument("--model", type=str, default="meta-llama/Llama-3.1-8B-Instruct") + args_parser.add_argument("--data_output_path", type=str) + args_parser.add_argument("--max_tokens", type=int, default=DEFAULT_MAX_TOKENS) + args_parser.add_argument("--temperature", type=float, default=0.0) + args_parser.add_argument("--top_k", type=int, default=50) + args_parser.add_argument("--top_p", type=float, default=0.1) + args = args_parser.parse_args() + + eval_data = json.load(open(args.eval_path, "r")) + # '''for debug''' + # eval_data = eval_data[:3] + # '''for debug''' + + question_list, db_path_list, knowledge_list = decouple_question_schema( + datasets=eval_data, db_root_path=args.db_root_path + ) + assert len(question_list) == len(db_path_list) == len(knowledge_list) + + llm = LLM(model=args.model, download_dir="/opt/hpcaas/.mounts/fs-06ad2f76a5ad0b18f/shared/amiryo/.cache/vllm") + sampling_params = llm.get_default_sampling_params() + sampling_params.max_tokens = args.max_tokens + sampling_params.temperature = args.temperature + sampling_params.top_p = args.top_p + sampling_params.top_k = args.top_k + + + if args.use_knowledge == "True": + responses = collect_response_from_llama( + llm=llm, + sampling_params=sampling_params, + db_path_list=db_path_list, + question_list=question_list, + knowledge_list=knowledge_list, + ) + else: + responses = collect_response_from_llama( + llm=llm, + sampling_params=sampling_params, + db_path_list=db_path_list, + question_list=question_list, + knowledge_list=None, + ) + + output_name = args.data_output_path + "predict_" + args.mode + ".json" + + generate_sql_file(sql_lst=responses, output_path=output_name) + + print("successfully collect results from {}".format(args.model)) diff --git a/end-to-end-use-cases/coding/text2sql/eval/requirements.txt b/end-to-end-use-cases/coding/text2sql/eval/requirements.txt index def1eccc3..90e8f9c4f 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/requirements.txt +++ b/end-to-end-use-cases/coding/text2sql/eval/requirements.txt @@ -15,3 +15,5 @@ peft==0.13.2 lighteval==0.6.2 hf-transfer==0.1.8 func_timeout==4.3.5 +vllm==0.9.2 +flashinfer-python==0.2.7.post1 From b574c6dc78497cb0807fa664613d41d9a1b9cdf8 Mon Sep 17 00:00:00 2001 From: Amir <328194+ghd3v@users.noreply.github.com> Date: Mon, 21 Jul 2025 18:11:57 -0700 Subject: [PATCH 49/78] Updated README.md --- .../coding/text2sql/README.md | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/README.md b/end-to-end-use-cases/coding/text2sql/README.md index 12811f2b6..e6e7078e2 100644 --- a/end-to-end-use-cases/coding/text2sql/README.md +++ b/end-to-end-use-cases/coding/text2sql/README.md @@ -1,19 +1,27 @@ -# Text2SQL: Evaluating and Fine-tuning Llama Models with CoT +# Improving Llama Text2SQL performance with CoT Fine-tuning -This folder contains scripts to: +This recipe is step by step guide to improve Llama performance on Text2SQL measured with the popular [BIRD](https://bird-bench.github.io) benchmark. We generate synthetic Chain of Thought(CoT) dataset and fine-tune Llama models on it. -1. Evaluate Llama (original and fine-tuned) models on the Text2SQL task using the popular [BIRD](https://bird-bench.github.io) dataset. +Results: [graph_placeholder] -2. Generate two supervised fine-tuning (SFT) datasets (with and without CoT) and fine-tuning Llama 3.1 8B with the datasets, using different SFT options: with or without CoT, using quantization or not, full fine-tuning (FFT) or parameter-efficient fine-tuning (PEFT). The non-quantized PEFT CoT SFT has the most performance gains: from 39.47% of the original Llama 3.1 8B model to 43.35%. (Note: the results are based on 3 epochs of SFT.) +We followed following steps: -Our end goal is to maximize the accuracy of Llama models on the Text2SQL task. To do so we need to first evaluate the current state of the art Llama models on the task, then apply fine-tuning, agent and other approaches to evaluate and improve Llama's performance. +1. Pre-processing the BIRD TRAIN datset by converting SQL statements into conversation format + +2. We use the conversations from step 1, add CoT to these existing conversations using Llama-3.3-70B + +3. Fine-tuning Llama-3.1-8B on the dataset from step 2 + +4. We provide scripts to simplify running the [BIRD](https://bird-bench.github.io) benchmark on the fine-tuned models and compare it with out of the model. ## Structure: -- data: contains scripts to download the BIRD TRAIN and DEV datasets; -- eval: contains scripts to evaluate Llama models (original and fine-tuned) on the BIRD dataset; -- fine-tune: contains scripts to generate non-CoT and CoT datasets based on the BIRD TRAIN set and to supervised fine-tune Llama models using the datasets, with different SFT options (quantization or not, full fine-tuning or parameter-efficient fine-tuning); -- quickstart: contains a notebook to ask Llama 3.3 to convert natural language queries into SQL queries. +- quickstart folder: contains a notebook to ask Llama 3.3 to convert natural language queries into SQL queries. +- data folder: contains scripts to download the BIRD TRAIN and DEV datasets; +- fine-tune folder: contains scripts to generate non-CoT and CoT datasets based on the BIRD TRAIN set and to supervised fine-tune Llama models using the datasets, with different SFT options (quantization or not, full fine-tuning or parameter-efficient fine-tuning); +- eval folder: contains scripts to evaluate Llama models (original and fine-tuned) on the BIRD dataset; + +We also experimented with supervised fine-tuning (SFT) without CoT which resulted in slightly lower accuracy. ## Next Steps From 58ea6cb1153367d391717210ff7d3384c5f2367c Mon Sep 17 00:00:00 2001 From: Amir <328194+ghd3v@users.noreply.github.com> Date: Mon, 21 Jul 2025 18:15:52 -0700 Subject: [PATCH 50/78] Update README.md --- .../coding/text2sql/eval/README.md | 39 +++++-------------- 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/eval/README.md b/end-to-end-use-cases/coding/text2sql/eval/README.md index fa70ab38b..80ac09373 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/README.md +++ b/end-to-end-use-cases/coding/text2sql/eval/README.md @@ -6,17 +6,14 @@ We have updated and simplified the original eval scripts from the BIRD [repo](ht Below are the results of the Llama models we have evaluated on the BIRD DEV dataset: -| Model | Llama API Accuracy | Together Accuracy | -|------------------------|--------------------|-------------------| -| Llama 3.1 8b | - | 35.66% | -| Llama 3.3 70b | 54.11% | 54.63% | -| Llama-3.1-405B | - | 55.80% | -| Llama 4 Scout | 44.39% | 43.94% | -| Llama 4 Maverick | 44.00% | 41.46% | - -- Llama 3.1 8b on Hugging Face: quantized 14.02%, non-quantized 39.47% -- Non-quantized FFT with no CoT dataset: 36.31% -- Non-quantized FFT with CoT dataset: 43.87% +| Model | Llama API Accuracy | +|------------------------|--------------------| +| Llama 3.1 8b | 39.47% (*) | +| Llama 3.3 70b | 54.11% | +| Llama 4 Scout | 44.39% | +| Llama 4 Maverick | 44.00% | + +- Since Llama API does not have Llama 3.1 8b model, we use Hugging Face weights to run locally. ## Quick Start @@ -39,13 +36,13 @@ sh download_dev_unzip.sh cd ../eval ``` -2. Open `llama_eval.sh` and set `YOUR_API_KEY` to your [Llama API](https://llama.developer.meta.com/) key or [Together](https://api.together.ai/) API key, then uncomment a line that starts with `model=` to specify the Llama model to use for the text2sql eval. +2. Open `llama_eval.sh` and set `YOUR_API_KEY` to your [Llama API](https://llama.developer.meta.com/) key then uncomment a line that starts with `model=` to specify the Llama model to use for the text2sql eval. 3. Run the evaluation script `sh llama_eval.sh`, which will use the BIRD DEV dataset (1534 examples in total) with external knowledge turned on to run the Llama model on each text question and compare the generated SQL with the gold SQL. If your API key or model name is incorrect, the script will exit with an authentication or model not supported error. -After the script completes, you'll see the accuracy of the Llama model on the BIRD DEV text2sql. For example, the total accuracy is about 54.24% with `YOUR_API_KEY` set to your Llama API key and `model='Llama-3.3-70B-Instruct'`, or about 35.07% with `YOUR_API_KEY` set to your Together API key and `model=meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo`. +After the script completes, you'll see the accuracy of the Llama model on the BIRD DEV text2sql. For example, the total accuracy is about 54.24% with `YOUR_API_KEY` set to your Llama API key and `model='Llama-3.3-70B-Instruct'` To compare your evaluated accuracy of your selected Llama model with other results in the BIRD Dev leaderboard, click [here](https://bird-bench.github.io/). @@ -58,19 +55,3 @@ To compare your evaluated accuracy of your selected Llama model with other resul 3. **Result Comparison**: The results from executing the generated SQL are compared ([source code](text2sql_eval.py#L30)) with the results from the ground truth SQL to determine correctness. 4. **Accuracy Calculation**: Accuracy scores are calculated overall and broken down by difficulty levels (simple, moderate, challenging). - -## Supported Models for Evaluation - -Llama models supported on Together AI: -- meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo -- meta-llama/Llama-3.3-70B-Instruct-Turbo -- meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8 -- meta-llama/Llama-4-Scout-17B-16E-Instruct -- other Llama models hosted on Together AI - -Llama models supported on Llama API: -- Llama-3.3-8B-Instruct -- Llama-3.3-70B-Instruct -- Llama-4-Maverick-17B-128E-Instruct-FP8 -- Llama-4-Scout-17B-16E-Instruct-FP8 -- other Llama models hosted on Llama API From 33ac1abc9fbdebab3975d56102d7469c46e06827 Mon Sep 17 00:00:00 2001 From: Amir <328194+ghd3v@users.noreply.github.com> Date: Mon, 21 Jul 2025 18:27:18 -0700 Subject: [PATCH 51/78] Update README.md --- .../coding/text2sql/fine-tuning/README.md | 102 ++---------------- 1 file changed, 9 insertions(+), 93 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md index 2b6183823..f19e7c36d 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md @@ -14,96 +14,17 @@ The eval results of SFT Llama 3.1 8B with different options (epochs is 3, with a | Fine-tuning Combination | Accuracy | |-----------------------------|-------------------------------| -| Non-Quantized, CoT, PEFT | 43.35% | -| Quantized, CoT, PEFT | 42.89% | -| Non-Quantized, CoT, FFT | 42.44% (43.87% for 10 epochs) | -| Non-Quantized, No CoT, PEFT | 39.31% | -| Quantized, No CoT, PEFT | 39.31% | -| Non-Quantized, No CoT, FFT | 36.31% (38.27% for 10 epochs) | -| Quantized, CoT, FFT | N/A | -| Quantized, No CoT, FFT | N/A | +| baseline | 39.47% | +| CoT, PEFT | 43.35% | +| CoT, FFT | 42.44% (3 epochs) | +| CoT, FFT | 43.87% (10 epochs) | -The table above shows that: -1. The CoT FFT/PEFT model (with or without quantization) outperforms the no CoT FFT/PEFT model (with or without quantization) by 3.5% to 6.1%. +Using Quantization+PEFT on CoT dataset only dropped the accuracy from 43.35% to 42.89%. -2. The non-quantized PEFT model (CoT or not) is slightly better than the non-quantized FFT model. +## Creating dataset -## SFT with the BIRD TRAIN dataset (No Reasoning) - -We'll first use the BIRD TRAIN dataset to prepare for supervised fine-tuning with no reasoning info in the dataset. - -### Using the TRAIN to prepare for supervised fine-tuning - -1. Get the TRAIN dataset: -``` -cd data -sh download_train_unzip.sh -``` - -2. Create the dataset - -``` -cd ../fine_tuning -python create_sft_dataset.py --input_json ../data/train/train.json --db_root_path ../data/train/train_databases -``` - -This will create `train_text2sql_sft_dataset.json` and `test_text2sql_sft_dataset.json` using the TRAIN set. Each line in the json files is in the conversation format ready for fine-tuning: - -``` -{"messages":[{"content":"You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement.","role":"system"},{"content":"-- DB Schema: \n\n-- External Knowledge: \n\n-- Question: ","role":"user"},{"content":"","role":"assistant"}]} -``` - -### SFT (No Reasoning) - -First, you need to login to HuggingFace (via running `huggingface-cli login` and enter your [HF token](https://huggingface.co/settings/tokens)) and have been granted access to the [Llama 3.1 8B Instruct](https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct) model. - -Then run one of the commands below (`trl_sft.py` has three command line parameters: `--quantized`, `--peft`, and `--cot`, all with true or false values): - -``` -python trl_sft.py --quantized false --peft true --cot false -python trl_sft.py --quantized false --peft false --cot false -python trl_sft.py --quantized true --peft true --cot false -``` - -Note that we don't recommend using the quantized version with FFT (--peft false). - - -After the fine-tuning completes, you'll see the fine-tuned model saved in one of the following folders, as specified in `output_dir` of `SFTConfig` in `trl_sft.py`: - -``` -llama31-8b-text2sql-fft-nonquantized-nocot -lama31-8b-text2sql-peft-nonquantized-nocot -llama31-8b-text2sql-peft-quantized-nocot -``` - -After running `tensorboard --logdir ./llama31-8b-text2sql-fine_tuning` you can open `http://localhost:6006` to see the train loss chart like this: - -![](train_loss.png) - - -### Evaluating the fine-tuned model (No Reasoning) - -First, set the `model` value in `llama_eval.sh` to be one of the fine-tuned model folders above, e.g. - -``` -YOUR_API_KEY='finetuned' -model='fine_tuning/llama31-8b-text2sql-fft-nonquantized-nocot' -``` - -Then run `sh llama_eval.sh` to evaluate the fine-tuned model. The accuracy on the BIRD DEV dataset is about 37.16%. This is a 165% improvement over the model before fine-tuning, which has an accuracy of about 14.02% on the same dataset - you can confirm this by comparing the fine-tuned model's accuracy above with the original model's accuracy by modifying `llama_eval.sh` to use the original model: - -``` -YOUR_API_KEY='huggingface' -model='meta-llama/Llama-3.1-8B-Instruct' -``` - -Then running `sh llama_eval.sh` to evaluate the original model. - - -## SFT with the BIRD TRAIN dataset (With Reasoning) - -Next we'll use the BIRD TRAIN dataset to prepare for supervised fine-tuning with reasoning info in the dataset. The goal is to see if we can improve the accuracy of the fine-tuned model by adding the reasoning info in the dataset. +We use the BIRD TRAIN dataset to prepare for supervised fine-tuning with reasoning info in the dataset. The goal is to see if we can improve the accuracy of the fine-tuned model by adding the reasoning info in the dataset. ### Creating a reasoning dataset from the TRAIN dataset @@ -150,24 +71,19 @@ Let me think through this step by step:\n\n1. First, I need to consider...\n2. T """ ``` -### SFT (With Reasoning) +### Running fine-tuning Run one of the commands below: ``` python trl_sft.py --quantized false --peft true --cot true -python trl_sft.py --quantized false --peft false --cot true -python trl_sft.py --quantized true --peft true --cot true ``` -Again we don't recommend using the quantized version with FFT. - After the fine-tuning completes, you'll see the fine-tuned model saved in one of the following folders, as specified in `output_dir` of `SFTConfig` in `trl_sft.py`: ``` llama31-8b-text2sql-fft-nonquantized-cot -lama31-8b-text2sql-peft-nonquantized-cot -llama31-8b-text2sql-peft-quantized-cot +llama31-8b-text2sql-peft-nonquantized-cot ``` The train loss chart should look like this: From e10ddda64ac86f23deff87b6e20ecede1d1fc324 Mon Sep 17 00:00:00 2001 From: Amir Youssefi <328194+ghd3v@users.noreply.github.com> Date: Tue, 22 Jul 2025 17:09:28 -0700 Subject: [PATCH 52/78] some refactoring and cleaning --- .../coding/text2sql/eval/llama_text2sql.py | 14 +++----------- .../coding/text2sql/eval/text2sql_eval.py | 10 ++++------ .../fine-tuning/create_reasoning_dataset.py | 11 ++--------- .../text2sql/fine-tuning/create_sft_dataset.py | 8 +------- 4 files changed, 10 insertions(+), 33 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py b/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py index aaa7fdae7..a5b8a852d 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py +++ b/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py @@ -1,18 +1,11 @@ import argparse -import fnmatch import json import os -import pdb -import pickle import re import sqlite3 -from typing import Dict, List, Tuple - -import pandas as pd -import sqlparse +from typing import Dict import torch -from datasets import Dataset, load_dataset from langchain_together import ChatTogether from llama_api_client import LlamaAPIClient from peft import AutoPeftModelForCausalLM @@ -284,7 +277,6 @@ def collect_response_from_llama( :param question_list: [] :return: dict of responses """ - responses_dict = {} response_list = [] if api_key in ["huggingface", "finetuned"]: @@ -318,7 +310,7 @@ def collect_response_from_llama( temperature=0, stop=["--", "\n\n", ";", "#"], ) - if type(plain_result) == str: + if isinstance(plain_result, str): sql = plain_result else: sql = "SELECT" + plain_result["choices"][0]["text"] @@ -387,7 +379,7 @@ def generate_sql_file(sql_lst, output_path=None): args_parser.add_argument("--data_output_path", type=str) args = args_parser.parse_args() - if not args.api_key in ["huggingface", "finetuned"]: + if args.api_key not in ["huggingface", "finetuned"]: if args.model.startswith("meta-llama/"): # Llama model on together os.environ["TOGETHER_API_KEY"] = args.api_key diff --git a/end-to-end-use-cases/coding/text2sql/eval/text2sql_eval.py b/end-to-end-use-cases/coding/text2sql/eval/text2sql_eval.py index 2b582d9af..0aecc9d62 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/text2sql_eval.py +++ b/end-to-end-use-cases/coding/text2sql/eval/text2sql_eval.py @@ -1,11 +1,10 @@ import argparse import json import multiprocessing as mp -import re import sqlite3 import sys -from func_timeout import func_timeout, FunctionTimedOut +from func_timeout import FunctionTimedOut, func_timeout def load_json(dir): @@ -45,10 +44,10 @@ def execute_model(predicted_sql, ground_truth, db_place, idx, meta_time_out): except KeyboardInterrupt: sys.exit(0) except FunctionTimedOut: - result = [(f"timeout",)] + result = [("timeout",)] res = 0 except Exception as e: - result = [(f"error",)] # possibly len(query) > 512 or not executable + result = [("error",)] # possibly len(query) > 512 or not executable res = 0 result = {"sql_idx": idx, "res": res} return result @@ -60,7 +59,7 @@ def package_sqls(sql_path, db_root_path, mode="gpt", data_mode="dev"): if mode == "gpt": sql_data = json.load(open(sql_path + "predict_" + data_mode + ".json", "r")) for idx, sql_str in sql_data.items(): - if type(sql_str) == str: + if isinstance(sql_str, str): sql, db_name = sql_str.split("\t----- bird -----\t") else: sql, db_name = " ", "financial" @@ -83,7 +82,6 @@ def package_sqls(sql_path, db_root_path, mode="gpt", data_mode="dev"): def run_sqls_parallel(sqls, db_places, num_cpus=1, meta_time_out=30.0): pool = mp.Pool(processes=num_cpus) for i, sql_pair in enumerate(sqls): - predicted_sql, ground_truth = sql_pair pool.apply_async( execute_model, diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/create_reasoning_dataset.py b/end-to-end-use-cases/coding/text2sql/fine-tuning/create_reasoning_dataset.py index ebe47d984..33724afee 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/create_reasoning_dataset.py +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/create_reasoning_dataset.py @@ -1,19 +1,12 @@ import argparse import json import os -import pdb -import pickle import re import sqlite3 -from typing import Dict, List, Tuple -import sqlparse from datasets import Dataset, load_from_disk - from langchain_together import ChatTogether from llama_api_client import LlamaAPIClient -from tqdm import tqdm - if ( os.environ.get("LLAMA_API_KEY", "") == "" @@ -159,7 +152,7 @@ def create_cot_dataset(input_json, db_root_path): question = item["question"] external_knowledge = item["evidence"] gold_SQL = item["SQL"].strip() - db_path = db_root_path + "/" + item["db_id"] + "/" + item["db_id"] + ".sqlite" + db_path = db_root_path + "/" + db_id + "/" + db_id + ".sqlite" # print(f"{db_path=}") db_schema = generate_schema_prompt(db_path) @@ -219,7 +212,7 @@ def create_cot_dataset(input_json, db_root_path): print(f"{diff=}, total: {len(input_json)}") dataset_dict = {key: [d[key] for d in cot_list] for key in cot_list[0]} hf_dataset = Dataset.from_dict(dataset_dict) - hf_dataset.save_to_disk(f"text2sql_cot_dataset") + hf_dataset.save_to_disk("text2sql_cot_dataset") dataset = load_from_disk("text2sql_cot_dataset") dataset = dataset.map( diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/create_sft_dataset.py b/end-to-end-use-cases/coding/text2sql/fine-tuning/create_sft_dataset.py index d0664016a..b2597af87 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/create_sft_dataset.py +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/create_sft_dataset.py @@ -1,15 +1,9 @@ import argparse import json import os -import pdb -import pickle -import re import sqlite3 -from typing import Dict, List, Tuple -import sqlparse from datasets import Dataset - from tqdm import tqdm @@ -124,7 +118,7 @@ def create_sft_dataset(input_json, db_root_path): question = item["question"] external_knowledge = item["evidence"] SQL = item["SQL"] - db_path = db_root_path + "/" + item["db_id"] + "/" + item["db_id"] + ".sqlite" + db_path = db_root_path + "/" + db_id + "/" + db_id + ".sqlite" print(f"{db_path=}") prompt = generate_combined_prompts_one( db_path, From 5baa1e3fd77286a6853211db77014464aa38680f Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Tue, 22 Jul 2025 17:44:25 -0700 Subject: [PATCH 53/78] vllm enabled eval for HF and fine-tuned models; code cleanup and refactoring for text2sql_eval; minimum eval packages for eval requirements; merge peft script to make vllm happy --- .../coding/text2sql/eval/llama_eval.sh | 15 +- .../coding/text2sql/eval/llama_text2sql.py | 197 +++++------------- .../coding/text2sql/eval/requirements.txt | 23 +- .../coding/text2sql/eval/text2sql_eval.py | 9 +- 4 files changed, 67 insertions(+), 177 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh b/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh index 95fc85782..bbd99e65c 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh +++ b/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh @@ -2,14 +2,6 @@ eval_path='../data/dev_20240627/dev.json' db_root_path='../data/dev_20240627/dev_databases/' ground_truth_path='../data/' -# Llama models on Together -#YOUR_API_KEY='YOUR_TOGETHER_API_KEY' -#model='meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo' -#model='meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo' -#model='meta-llama/Llama-3.3-70B-Instruct-Turbo' -#model='meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8' -#model='meta-llama/Llama-4-Scout-17B-16E-Instruct' - # Llama models on Llama API YOUR_API_KEY='YOUR_LLAMA_API_KEY' model='Llama-3.3-8B-Instruct' @@ -17,14 +9,13 @@ model='Llama-3.3-8B-Instruct' #model='Llama-4-Maverick-17B-128E-Instruct-FP8' #model='Llama-4-Scout-17B-16E-Instruct-FP8' -# Llama model on Hugging Face Hub -# https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct +# Llama model on Hugging Face Hub https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct # YOUR_API_KEY='huggingface' # model='meta-llama/Llama-3.1-8B-Instruct' # Fine-tuned Llama models locally -#YOUR_API_KEY='finetuned' -#model='../fine_tuning/llama31-8b-text2sql-fine-tuned' +# YOUR_API_KEY='finetuned' +# model='../fine-tuning/final_test/llama31-8b-text2sql-peft-quantized-cot_merged' data_output_path="./output/$model/" diff --git a/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py b/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py index a5b8a852d..f1b1ffbf0 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py +++ b/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py @@ -5,21 +5,13 @@ import sqlite3 from typing import Dict -import torch -from langchain_together import ChatTogether from llama_api_client import LlamaAPIClient -from peft import AutoPeftModelForCausalLM -from tqdm import tqdm -from transformers import ( - AutoModelForCausalLM, - AutoTokenizer, - BitsAndBytesConfig, - pipeline, -) - -MAX_NEW_TOKENS=10240 # If API has max tokens (vs max new tokens), we calculate it - -def local_llama(prompt, pipe): + +MAX_NEW_TOKENS = 10240 # If API has max tokens (vs max new tokens), we calculate it +TIMEOUT = 60 # Timeout in seconds for each API call + + +def local_llama(client, prompt, model): SYSTEM_PROMPT = "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement." # UNCOMMENT TO USE THE FINE_TUNED MODEL WITH REASONING DATASET # SYSTEM_PROMPT = "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, generate the step-by-step reasoning and the final SQLite SQL select statement from the text question." @@ -28,27 +20,13 @@ def local_llama(prompt, pipe): {"content": SYSTEM_PROMPT, "role": "system"}, {"role": "user", "content": prompt}, ] - - raw_prompt = pipe.tokenizer.apply_chat_template( - messages, - tokenize=False, - add_generation_prompt=True, - ) - - print(f"local_llama: {raw_prompt=}") - - outputs = pipe( - raw_prompt, - max_new_tokens=MAX_NEW_TOKENS, - do_sample=False, - temperature=0.0, - top_k=50, - top_p=0.1, - eos_token_id=pipe.tokenizer.eos_token_id, - pad_token_id=pipe.tokenizer.pad_token_id, + print(f"local_llama: {model=}") + chat_response = client.chat.completions.create( + model=model, + messages=messages, + timeout=TIMEOUT, ) - - answer = outputs[0]["generated_text"][len(raw_prompt) :].strip() + answer = chat_response.choices[0].message.content.strip() pattern = re.compile(r"```sql\n*(.*?)```", re.DOTALL) matches = pattern.findall(answer) @@ -98,12 +76,9 @@ def nice_look_table(column_names: list, values: list): for i in range(len(column_names)) ] - # Print the column names header = "".join( f"{column.rjust(width)} " for column, width in zip(column_names, widths) ) - # print(header) - # Print the values for value in values: row = "".join(f"{str(v).rjust(width)} " for v, width in zip(value, widths)) rows.append(row) @@ -176,33 +151,22 @@ def generate_combined_prompts_one(db_path, question, knowledge=None): return combined_prompts -def cloud_llama(api_key, model, prompt, max_tokens, temperature, stop): +def cloud_llama(client, api_key, model, prompt, max_tokens, temperature, stop): SYSTEM_PROMPT = "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement." try: - if model.startswith("meta-llama/"): - final_prompt = SYSTEM_PROMPT + "\n\n" + prompt - final_max_tokens = len(final_prompt) + MAX_NEW_TOKENS - llm = ChatTogether( - model=model, - temperature=0, - max_tokens=final_max_tokens, - ) - answer = llm.invoke(final_prompt).content - else: - client = LlamaAPIClient() - messages = [ - {"content": SYSTEM_PROMPT, "role": "system"}, - {"role": "user", "content": prompt}, - ] - final_max_tokens = len(messages) + MAX_NEW_TOKENS - response = client.chat.completions.create( - model=model, - messages=messages, - temperature=0, - max_completion_tokens=final_max_tokens, - ) - answer = response.completion_message.content.text + messages = [ + {"content": SYSTEM_PROMPT, "role": "system"}, + {"role": "user", "content": prompt}, + ] + final_max_tokens = len(messages) + MAX_NEW_TOKENS + response = client.chat.completions.create( + model=model, + messages=messages, + temperature=0, + max_completion_tokens=final_max_tokens, + ) + answer = response.completion_message.content.text pattern = re.compile(r"```sql\n*(.*?)```", re.DOTALL) matches = pattern.findall(answer) @@ -218,57 +182,6 @@ def cloud_llama(api_key, model, prompt, max_tokens, temperature, stop): return result -def huggingface_finetuned(api_key, model): - if api_key == "finetuned": - model_id = model - - # Check if this is a PEFT model by looking for adapter_config.json - import os - - is_peft_model = os.path.exists(os.path.join(model_id, "adapter_config.json")) - - if is_peft_model: - # Use AutoPeftModelForCausalLM for PEFT fine-tuned models - print(f"Loading PEFT model from {model_id}") - model = AutoPeftModelForCausalLM.from_pretrained( - model_id, device_map="auto", torch_dtype=torch.float16 - ) - tokenizer = AutoTokenizer.from_pretrained(model_id) - else: - # Use AutoModelForCausalLM for FFT (Full Fine-Tuning) models - print(f"Loading FFT model from {model_id}") - model = AutoModelForCausalLM.from_pretrained( - model_id, device_map="auto", torch_dtype=torch.float16 - ) - tokenizer = AutoTokenizer.from_pretrained(model_id) - - # For FFT models, handle pad token if it was added during training - if tokenizer.pad_token is None: - tokenizer.add_special_tokens({"pad_token": "[PAD]"}) - model.resize_token_embeddings(len(tokenizer)) - - tokenizer.padding_side = "right" # to prevent warnings - - elif api_key == "huggingface": - model_id = model - bnb_config = BitsAndBytesConfig( - load_in_4bit=True, - bnb_4bit_use_double_quant=True, - bnb_4bit_quant_type="nf4", - bnb_4bit_compute_dtype=torch.bfloat16, - ) - model = AutoModelForCausalLM.from_pretrained( - model_id, - device_map="auto", - torch_dtype=torch.bfloat16, - quantization_config=bnb_config, # None - ) - tokenizer = AutoTokenizer.from_pretrained(model_id) - - pipe = pipeline("text-generation", model=model, tokenizer=tokenizer) - return pipe - - def collect_response_from_llama( db_path_list, question_list, api_key, model, knowledge_list=None ): @@ -280,9 +193,19 @@ def collect_response_from_llama( response_list = [] if api_key in ["huggingface", "finetuned"]: - pipe = huggingface_finetuned(api_key=api_key, model=model) + from openai import OpenAI + + openai_api_key = "EMPTY" + openai_api_base = "http://localhost:8000/v1" - for i, question in tqdm(enumerate(question_list)): + client = OpenAI( + api_key=openai_api_key, + base_url=openai_api_base, + ) + else: + client = LlamaAPIClient() + + for i, question in enumerate(question_list): print( "--------------------- processing question #{}---------------------".format( i + 1 @@ -300,9 +223,11 @@ def collect_response_from_llama( ) if api_key in ["huggingface", "finetuned"]: - plain_result = local_llama(prompt=cur_prompt, pipe=pipe) + plain_result = local_llama(client=client, prompt=cur_prompt, model=model) else: + plain_result = cloud_llama( + client=client, api_key=api_key, model=model, prompt=cur_prompt, @@ -310,7 +235,7 @@ def collect_response_from_llama( temperature=0, stop=["--", "\n\n", ";", "#"], ) - if isinstance(plain_result, str): + if type(plain_result) == str: sql = plain_result else: sql = "SELECT" + plain_result["choices"][0]["text"] @@ -379,37 +304,23 @@ def generate_sql_file(sql_lst, output_path=None): args_parser.add_argument("--data_output_path", type=str) args = args_parser.parse_args() - if args.api_key not in ["huggingface", "finetuned"]: - if args.model.startswith("meta-llama/"): # Llama model on together + if not args.api_key in ["huggingface", "finetuned"]: + os.environ["LLAMA_API_KEY"] = args.api_key + + try: + client = LlamaAPIClient() - os.environ["TOGETHER_API_KEY"] = args.api_key - llm = ChatTogether( + response = client.chat.completions.create( model=args.model, + messages=[{"role": "user", "content": "125*125 is?"}], temperature=0, ) - try: - response = llm.invoke("125*125 is?").content - print(f"{response=}") - except Exception as exception: - print(f"{exception=}") - exit(1) - else: # Llama model on Llama API - os.environ["LLAMA_API_KEY"] = args.api_key - - try: - client = LlamaAPIClient() - - response = client.chat.completions.create( - model=args.model, - messages=[{"role": "user", "content": "125*125 is?"}], - temperature=0, - ) - answer = response.completion_message.content.text + answer = response.completion_message.content.text - print(f"{answer=}") - except Exception as exception: - print(f"{exception=}") - exit(1) + print(f"{answer=}") + except Exception as exception: + print(f"{exception=}") + exit(1) eval_data = json.load(open(args.eval_path, "r")) # '''for debug''' @@ -422,7 +333,7 @@ def generate_sql_file(sql_lst, output_path=None): assert len(question_list) == len(db_path_list) == len(knowledge_list) if args.use_knowledge == "True": - responses = collect_response_from_llama( + responses = collect_response_from_llama( # collect_batch_response_from_llama db_path_list=db_path_list, question_list=question_list, api_key=args.api_key, diff --git a/end-to-end-use-cases/coding/text2sql/eval/requirements.txt b/end-to-end-use-cases/coding/text2sql/eval/requirements.txt index 90e8f9c4f..0006a4776 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/requirements.txt +++ b/end-to-end-use-cases/coding/text2sql/eval/requirements.txt @@ -1,19 +1,6 @@ -llama_api_client==0.1.1 -langchain-together==0.3.0 -sqlparse==0.5.3 -torch==2.4.1 -tensorboard==2.19.0 -liger-kernel==0.4.2 -setuptools==78.1.1 -deepspeed==0.15.4 -transformers==4.46.3 -datasets==3.6.0 -accelerate==1.1.1 -bitsandbytes==0.44.1 -trl==0.12.1 -peft==0.13.2 -lighteval==0.6.2 -hf-transfer==0.1.8 +llama_api_client==0.1.2 func_timeout==4.3.5 -vllm==0.9.2 -flashinfer-python==0.2.7.post1 + +# uncomment to run vllm for eval with Llama 3.1 8B on HF and its fine-tuned models +# vllm==0.9.2 +# openai==1.90.0 diff --git a/end-to-end-use-cases/coding/text2sql/eval/text2sql_eval.py b/end-to-end-use-cases/coding/text2sql/eval/text2sql_eval.py index 0aecc9d62..7a1374d99 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/text2sql_eval.py +++ b/end-to-end-use-cases/coding/text2sql/eval/text2sql_eval.py @@ -4,7 +4,7 @@ import sqlite3 import sys -from func_timeout import FunctionTimedOut, func_timeout +from func_timeout import func_timeout, FunctionTimedOut def load_json(dir): @@ -44,10 +44,10 @@ def execute_model(predicted_sql, ground_truth, db_place, idx, meta_time_out): except KeyboardInterrupt: sys.exit(0) except FunctionTimedOut: - result = [("timeout",)] + result = [(f"timeout",)] res = 0 except Exception as e: - result = [("error",)] # possibly len(query) > 512 or not executable + result = [(f"{e}",)] # possibly len(query) > 512 or not executable res = 0 result = {"sql_idx": idx, "res": res} return result @@ -59,7 +59,7 @@ def package_sqls(sql_path, db_root_path, mode="gpt", data_mode="dev"): if mode == "gpt": sql_data = json.load(open(sql_path + "predict_" + data_mode + ".json", "r")) for idx, sql_str in sql_data.items(): - if isinstance(sql_str, str): + if type(sql_str) == str: sql, db_name = sql_str.split("\t----- bird -----\t") else: sql, db_name = " ", "financial" @@ -82,6 +82,7 @@ def package_sqls(sql_path, db_root_path, mode="gpt", data_mode="dev"): def run_sqls_parallel(sqls, db_places, num_cpus=1, meta_time_out=30.0): pool = mp.Pool(processes=num_cpus) for i, sql_pair in enumerate(sqls): + predicted_sql, ground_truth = sql_pair pool.apply_async( execute_model, From f894d26f29978ff4ebcd739ba1c74a36c8e15182 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Tue, 22 Jul 2025 17:45:21 -0700 Subject: [PATCH 54/78] vllm enabled eval for HF and fine-tuned models; code cleanup and refactoring for text2sql_eval; minimum eval packages for eval requirements; merge peft script to make vllm happy --- .../coding/text2sql/fine-tuning/merge_peft.py | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 end-to-end-use-cases/coding/text2sql/fine-tuning/merge_peft.py diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/merge_peft.py b/end-to-end-use-cases/coding/text2sql/fine-tuning/merge_peft.py new file mode 100644 index 000000000..5764bf0e3 --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/merge_peft.py @@ -0,0 +1,45 @@ +import torch +from peft import PeftModel +from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig + +peft_model_path = "../fine-tuning/final_test/llama31-8b-text2sql-peft-nonquantized-cot" +output_dir = ( + "../fine-tuning/final_test/llama31-8b-text2sql-peft-nonquantized-cot_merged" +) +# === Load Base Model and Tokenizer === +print("Loading base model and tokenizer...") +base_model_id = "meta-llama/Llama-3.1-8B-Instruct" +tokenizer = AutoTokenizer.from_pretrained(base_model_id) + +# Configure quantization if needed +quantization_config = None +use_quantized = False +if use_quantized: + quantization_config = BitsAndBytesConfig( + load_in_4bit=True, + bnb_4bit_use_double_quant=True, + bnb_4bit_quant_type="nf4", + bnb_4bit_compute_dtype=torch.bfloat16, + ) + +# Load model +base_model = AutoModelForCausalLM.from_pretrained( + base_model_id, + device_map="auto", + torch_dtype=torch.bfloat16, + quantization_config=quantization_config, +) +base_model.resize_token_embeddings(128257) + +# === Load PEFT Adapter and Merge === +print("Loading PEFT adapter and merging...") +# peft_config = PeftConfig.from_pretrained(peft_model_path) +model = PeftModel.from_pretrained(base_model, peft_model_path) +model = model.merge_and_unload() # This merges the adapter weights into the base model + +# === Save the Merged Model === +print(f"Saving merged model to {output_dir} ...") +model.save_pretrained(output_dir) +tokenizer.save_pretrained(output_dir) + +print("Done! The merged model is ready for vLLM serving.") From ad485095aee956c1116b0fed50b7a72c271d7929 Mon Sep 17 00:00:00 2001 From: Amir Youssefi <328194+ghd3v@users.noreply.github.com> Date: Tue, 22 Jul 2025 17:46:47 -0700 Subject: [PATCH 55/78] trl import --- end-to-end-use-cases/coding/text2sql/fine-tuning/trl_sft.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/trl_sft.py b/end-to-end-use-cases/coding/text2sql/fine-tuning/trl_sft.py index ff05f6d66..81ddf64c2 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/trl_sft.py +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/trl_sft.py @@ -6,6 +6,7 @@ import torch from datasets import load_dataset from transformers import AutoModelForCausalLM, AutoTokenizer +from trl import SFTConfig, SFTTrainer # Parse command line arguments parser = argparse.ArgumentParser( @@ -66,8 +67,6 @@ if use_peft: from peft import LoraConfig -from trl import setup_chat_format, SFTConfig, SFTTrainer - # Dataset configuration based on CoT parameter if use_cot: FT_DATASET = "train_text2sql_cot_dataset.json" From e059899812e01379dce94403595170a52db4cf9d Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Tue, 22 Jul 2025 19:00:29 -0700 Subject: [PATCH 56/78] Update the eval section using vllm for fine-tuning README.md --- .../coding/text2sql/fine-tuning/README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md index f19e7c36d..71985354d 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md @@ -89,15 +89,17 @@ llama31-8b-text2sql-peft-nonquantized-cot The train loss chart should look like this: ![](train_loss_cot.png) -### Evaluating the fine-tuned model (With Reasoning) +### Evaluating the fine-tuned model -First, set the `model` value in `llama_eval.sh` to be one of the fine-tuned model folders above, e.g. +1. Set the `model` value in `llama_eval.sh` to be one of the fine-tuned model folders above, e.g. ``` YOUR_API_KEY='finetuned' model='fine_tuning/llama31-8b-text2sql-fft-nonquantized-cot' ``` -Then uncomment the line `SYSTEM_PROMPT` [here](https://github.com/meta-llama/llama-cookbook/blob/text2sql/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py#L31) in `llama_text2sql.py` to use it with the reasoning dataset fine-tuned model. +2. Uncomment the line `SYSTEM_PROMPT` [here](https://github.com/meta-llama/llama-cookbook/blob/text2sql/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py#L31) in `llama_text2sql.py` to use it with the reasoning dataset fine-tuned model. -Now run `sh llama_eval.sh`, which will take longer because the reasoning is needed to generate the SQL. The accuracy this time is 43.37%, compared with 37.16% without reasoning. This is another 16% improvement over the model with fine-tuning without reasoning. +3. Start the vllm server by running `vllm serve fine_tuning/llama31-8b-text2sql-fft-nonquantized-cot --tensor-parallel-size 1 --max-num-batched-tokens 8192 --max-num-seqs 64`. If you have multiple GPUs you can run something like `CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 vllm serve fine_tuning/llama31-8b-text2sql-fft-nonquantized-cot --tensor-parallel-size 8 --max-num-batched-tokens 8192 --max-num-seqs 64` to speed up the eval. + +4. Run `sh llama_eval.sh`. From f80e7bf5e9a714d816d5a78b3142678d0358a008 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Tue, 22 Jul 2025 19:03:40 -0700 Subject: [PATCH 57/78] Update fine-tuning README.md --- .../coding/text2sql/fine-tuning/README.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md index 71985354d..f7a766b00 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md @@ -98,8 +98,16 @@ YOUR_API_KEY='finetuned' model='fine_tuning/llama31-8b-text2sql-fft-nonquantized-cot' ``` -2. Uncomment the line `SYSTEM_PROMPT` [here](https://github.com/meta-llama/llama-cookbook/blob/text2sql/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py#L31) in `llama_text2sql.py` to use it with the reasoning dataset fine-tuned model. +2. Uncomment the line `SYSTEM_PROMPT` [here](https://github.com/meta-llama/llama-cookbook/blob/text2sql/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py#L17) in `llama_text2sql.py` to use it with the reasoning dataset fine-tuned model. -3. Start the vllm server by running `vllm serve fine_tuning/llama31-8b-text2sql-fft-nonquantized-cot --tensor-parallel-size 1 --max-num-batched-tokens 8192 --max-num-seqs 64`. If you have multiple GPUs you can run something like `CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 vllm serve fine_tuning/llama31-8b-text2sql-fft-nonquantized-cot --tensor-parallel-size 8 --max-num-batched-tokens 8192 --max-num-seqs 64` to speed up the eval. +3. Start the vllm server by running +``` +vllm serve fine_tuning/llama31-8b-text2sql-fft-nonquantized-cot --tensor-parallel-size 1 --max-num-batched-tokens 8192 --max-num-seqs 64 +``` +If you have multiple GPUs you can run something like +``` +CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 vllm serve fine_tuning/llama31-8b-text2sql-fft-nonquantized-cot --tensor-parallel-size 8 --max-num-batched-tokens 8192 --max-num-seqs 64 +``` + to speed up the eval. -4. Run `sh llama_eval.sh`. +6. Run `sh llama_eval.sh`. From b6307351597e1cccc913bce70e2d3f406dd003e5 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Tue, 22 Jul 2025 19:07:22 -0700 Subject: [PATCH 58/78] Update fine-tuning README.md --- end-to-end-use-cases/coding/text2sql/fine-tuning/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md index f7a766b00..cbd66379e 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md @@ -110,4 +110,6 @@ CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 vllm serve fine_tuning/llama31-8b-text2sql- ``` to speed up the eval. -6. Run `sh llama_eval.sh`. +4. Run `sh llama_eval.sh`. + +**Note:** If your fine-tuned model is PEFT based, you may need to run `python merge_peft.py` after modifying its `peft_model_path` and `output_dir` and set the merged folder path after `vllm serve`. From 1ac67d99504da70ebff3c9003cfabdad63cd2f0f Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Tue, 22 Jul 2025 19:20:43 -0700 Subject: [PATCH 59/78] Update eval README.md for vllm based HF model --- .../coding/text2sql/eval/README.md | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/eval/README.md b/end-to-end-use-cases/coding/text2sql/eval/README.md index 80ac09373..13adea4d5 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/README.md +++ b/end-to-end-use-cases/coding/text2sql/eval/README.md @@ -13,9 +13,9 @@ Below are the results of the Llama models we have evaluated on the BIRD DEV data | Llama 4 Scout | 44.39% | | Llama 4 Maverick | 44.00% | -- Since Llama API does not have Llama 3.1 8b model, we use Hugging Face weights to run locally. +- Since Llama API does not have Llama 3.1 8b model, we use Hugging Face weights and vllm to run locally. -## Quick Start +## Quick Start with Llama Models via Llama API First, run the commands below to create a new Conda environment and install all the required packages for Text2SQL evaluation and fine-tuning: @@ -46,12 +46,39 @@ After the script completes, you'll see the accuracy of the Llama model on the BI To compare your evaluated accuracy of your selected Llama model with other results in the BIRD Dev leaderboard, click [here](https://bird-bench.github.io/). +## Evaluation with Llama Models on Hugging Face or Fine-tuned + +We use vllm OpenAI compatible server to run Llama 3.1 8B on Hugging Face (steps below) or its fine-tuned models (steps [here](../fine-tuning/#evaluating-the-fine-tuned-model) for eval: + +1. Uncomment the last two lines in requirements.txt then run `pip install -r requirements.txt`: +``` +# vllm==0.9.2 +# openai==1.90.0 +``` + +2. Uncomment in `llama_eval.sh`: +``` +YOUR_API_KEY='huggingface' +model='meta-llama/Llama-3.1-8B-Instruct' +``` + +3. Start the vllm server: +``` +vllm serve meta-llama/Llama-3.1-8B-Instruct --tensor-parallel-size 1 --max-num-batched-tokens 8192 --max-num-seqs 64 +``` +or if you have multiple GPUs, do something like: +``` +CUDA_VISIBLE_DEVICES=0,1,2,3 vllm serve meta-llama/Llama-3.1-8B-Instruct --tensor-parallel-size 4 --max-num-batched-tokens 8192 --max-num-seqs 64 +``` + +4. Run `sh llama_eval.sh`. + ## Evaluation Process 1. **SQL Generation**: `llama_text2sql.py` sends natural language questions to the specified Llama model and collects the generated SQL queries. 2. **SQL Execution**: `text2sql_eval.py` executes both the generated SQL and ground truth SQL against the corresponding databases, then continues with steps 3 and 4 below. -3. **Result Comparison**: The results from executing the generated SQL are compared ([source code](text2sql_eval.py#L30)) with the results from the ground truth SQL to determine correctness. +3. **Result Comparison**: The results from executing the generated SQL are compared ([source code](text2sql_eval.py#L29)) with the results from the ground truth SQL to determine correctness. 4. **Accuracy Calculation**: Accuracy scores are calculated overall and broken down by difficulty levels (simple, moderate, challenging). From 1b802d30bfbd4a313d11312eb6523ba3952c2324 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Tue, 22 Jul 2025 19:24:05 -0700 Subject: [PATCH 60/78] Update FT README.md --- end-to-end-use-cases/coding/text2sql/fine-tuning/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md index cbd66379e..fcf146505 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md @@ -76,7 +76,9 @@ Let me think through this step by step:\n\n1. First, I need to consider...\n2. T Run one of the commands below: ``` +python trl_sft.py --quantized false --peft false --cot true python trl_sft.py --quantized false --peft true --cot true +python trl_sft.py --quantized true --peft true --cot true ``` After the fine-tuning completes, you'll see the fine-tuned model saved in one of the following folders, as specified in `output_dir` of `SFTConfig` in `trl_sft.py`: @@ -84,6 +86,7 @@ After the fine-tuning completes, you'll see the fine-tuned model saved in one of ``` llama31-8b-text2sql-fft-nonquantized-cot llama31-8b-text2sql-peft-nonquantized-cot +llama31-8b-text2sql-peft-quantized-cot ``` The train loss chart should look like this: From df598c474dd0845d4c6eddce475bf392aee8edcd Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Tue, 22 Jul 2025 19:26:18 -0700 Subject: [PATCH 61/78] Update eval README.md --- end-to-end-use-cases/coding/text2sql/eval/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/eval/README.md b/end-to-end-use-cases/coding/text2sql/eval/README.md index 13adea4d5..d03c3140f 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/README.md +++ b/end-to-end-use-cases/coding/text2sql/eval/README.md @@ -1,6 +1,6 @@ # Llama Text2SQL Evaluation -We have updated and simplified the original eval scripts from the BIRD [repo](https://github.com/AlibabaResearch/DAMO-ConvAI/tree/main/bird) to 3 simple steps for Llama 3 & 4 models hosted via Meta's [Llama API](https://llama.developer.meta.com) or [Together.ai](https://together.ai), as well as the fine-tuned Llama 3.1 model. +We have updated and simplified the original eval scripts from the BIRD [repo](https://github.com/AlibabaResearch/DAMO-ConvAI/tree/main/bird) to 3 simple steps for Llama 3 & 4 models hosted via Meta's [Llama API](https://llama.developer.meta.com), as well as the Llama 3.1 on Hugging Face and its fine-tuned models. ## Evaluation Results @@ -71,7 +71,7 @@ or if you have multiple GPUs, do something like: CUDA_VISIBLE_DEVICES=0,1,2,3 vllm serve meta-llama/Llama-3.1-8B-Instruct --tensor-parallel-size 4 --max-num-batched-tokens 8192 --max-num-seqs 64 ``` -4. Run `sh llama_eval.sh`. +then run `sh llama_eval.sh`. ## Evaluation Process From cb8b0bd40e72f12ccd0998aa06c225b7be5e80ca Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Tue, 22 Jul 2025 19:26:59 -0700 Subject: [PATCH 62/78] Update eval README.md --- end-to-end-use-cases/coding/text2sql/eval/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/end-to-end-use-cases/coding/text2sql/eval/README.md b/end-to-end-use-cases/coding/text2sql/eval/README.md index d03c3140f..e5e4be9b9 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/README.md +++ b/end-to-end-use-cases/coding/text2sql/eval/README.md @@ -1,6 +1,6 @@ # Llama Text2SQL Evaluation -We have updated and simplified the original eval scripts from the BIRD [repo](https://github.com/AlibabaResearch/DAMO-ConvAI/tree/main/bird) to 3 simple steps for Llama 3 & 4 models hosted via Meta's [Llama API](https://llama.developer.meta.com), as well as the Llama 3.1 on Hugging Face and its fine-tuned models. +We have updated and simplified the original eval scripts from the BIRD [repo](https://github.com/AlibabaResearch/DAMO-ConvAI/tree/main/bird) to 3 simple steps for Llama 3 & 4 models hosted via Meta's [Llama API](https://llama.developer.meta.com), as well as Llama 3.1 8B on Hugging Face and its fine-tuned models. ## Evaluation Results From 77d3544c81cf68d0000f58bce743b81affaabeca Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Thu, 24 Jul 2025 11:24:13 -0700 Subject: [PATCH 63/78] batch processing and vllm llama call in parallel; clean progress showing in 2-step eval --- .../coding/text2sql/eval/llama_eval.sh | 25 +- .../coding/text2sql/eval/llama_text2sql.py | 236 ++++++++++++++++-- .../coding/text2sql/eval/text2sql_eval.py | 83 ++++-- 3 files changed, 298 insertions(+), 46 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh b/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh index bbd99e65c..0a4130f1f 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh +++ b/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh @@ -1,10 +1,13 @@ +# Set to "true" to enable debug mode with detailed prints +DEBUG_MODE="false" + eval_path='../data/dev_20240627/dev.json' db_root_path='../data/dev_20240627/dev_databases/' ground_truth_path='../data/' # Llama models on Llama API -YOUR_API_KEY='YOUR_LLAMA_API_KEY' -model='Llama-3.3-8B-Instruct' +# YOUR_API_KEY='YOUR_LLAMA_API_KEY' +# model='Llama-3.3-8B-Instruct' #model='Llama-3.3-70B-Instruct' #model='Llama-4-Maverick-17B-128E-Instruct-FP8' #model='Llama-4-Scout-17B-16E-Instruct-FP8' @@ -14,8 +17,8 @@ model='Llama-3.3-8B-Instruct' # model='meta-llama/Llama-3.1-8B-Instruct' # Fine-tuned Llama models locally -# YOUR_API_KEY='finetuned' -# model='../fine-tuning/final_test/llama31-8b-text2sql-peft-quantized-cot_merged' +YOUR_API_KEY='finetuned' +model='../fine-tuning/llama31-8b-text2sql-fft-nonquantized-cot-epochs-3' data_output_path="./output/$model/" @@ -26,9 +29,17 @@ python3 -u llama_text2sql.py --db_root_path ${db_root_path} --api_key ${YOUR_API # Check if llama_text2sql.py exited successfully if [ $? -eq 0 ]; then echo "llama_text2sql.py completed successfully. Proceeding with evaluation..." - python3 -u text2sql_eval.py --db_root_path ${db_root_path} --predicted_sql_path ${data_output_path} \ - --ground_truth_path ${ground_truth_path} \ - --diff_json_path ${eval_path} + + # Add --debug flag if DEBUG_MODE is true + if [ "$DEBUG_MODE" = "true" ]; then + python3 -u text2sql_eval.py --db_root_path ${db_root_path} --predicted_sql_path ${data_output_path} \ + --ground_truth_path ${ground_truth_path} \ + --diff_json_path ${eval_path} --debug + else + python3 -u text2sql_eval.py --db_root_path ${db_root_path} --predicted_sql_path ${data_output_path} \ + --ground_truth_path ${ground_truth_path} \ + --diff_json_path ${eval_path} + fi echo "Done evaluating $model." diff --git a/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py b/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py index f1b1ffbf0..4b0d73bba 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py +++ b/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py @@ -1,4 +1,5 @@ import argparse +import concurrent.futures import json import os import re @@ -6,6 +7,7 @@ from typing import Dict from llama_api_client import LlamaAPIClient +from tqdm import tqdm MAX_NEW_TOKENS = 10240 # If API has max tokens (vs max new tokens), we calculate it TIMEOUT = 60 # Timeout in seconds for each API call @@ -25,20 +27,98 @@ def local_llama(client, prompt, model): model=model, messages=messages, timeout=TIMEOUT, + temperature=0, ) answer = chat_response.choices[0].message.content.strip() pattern = re.compile(r"```sql\n*(.*?)```", re.DOTALL) matches = pattern.findall(answer) - if matches != []: - result = matches[0] - else: + if not matches: result = answer + else: + result = matches[0] print(f"{result=}") return result +def batch_local_llama(client, prompts, model, max_workers=8): + """ + Process multiple prompts in parallel using the vllm server. + + Args: + client: OpenAI client + prompts: List of prompts to process + model: Model name + max_workers: Maximum number of parallel workers + + Returns: + List of results in the same order as prompts + """ + SYSTEM_PROMPT = ( + "You are a text to SQL query translator. Using the SQLite DB Schema " + "and the External Knowledge, translate the following text question " + "into a SQLite SQL select statement." + ) + + def process_single_prompt(prompt): + messages = [ + {"content": SYSTEM_PROMPT, "role": "system"}, + {"role": "user", "content": prompt}, + ] + try: + chat_response = client.chat.completions.create( + model=model, + messages=messages, + timeout=TIMEOUT, + temperature=0, + ) + answer = chat_response.choices[0].message.content.strip() + + pattern = re.compile(r"```sql\n*(.*?)```", re.DOTALL) + matches = pattern.findall(answer) + if not matches: + result = answer + else: + result = matches[0] + + return result + except Exception as e: + print(f"Error processing prompt: {e}") + return f"error:{e}" + + print( + f"batch_local_llama: Processing {len(prompts)} prompts with {model=} " + f"using {max_workers} workers" + ) + results = [] + + with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: + # Submit all tasks and create a map of futures to their indices + future_to_index = { + executor.submit(process_single_prompt, prompt): i + for i, prompt in enumerate(prompts) + } + + # Initialize results list with None values + results = [None] * len(prompts) + + # Process completed futures as they complete + for future in tqdm( + concurrent.futures.as_completed(future_to_index), + total=len(prompts), + desc="Processing prompts", + ): + index = future_to_index[future] + try: + results[index] = future.result() + except Exception as e: + print(f"Error processing prompt at index {index}: {e}") + results[index] = f"error:{e}" + + return results + + def new_directory(path): if not os.path.exists(path): os.makedirs(path) @@ -235,7 +315,7 @@ def collect_response_from_llama( temperature=0, stop=["--", "\n\n", ";", "#"], ) - if type(plain_result) == str: + if isinstance(plain_result, str): sql = plain_result else: sql = "SELECT" + plain_result["choices"][0]["text"] @@ -250,6 +330,89 @@ def collect_response_from_llama( return response_list +def batch_collect_response_from_llama( + db_path_list, question_list, api_key, model, knowledge_list=None, batch_size=8 +): + """ + Process multiple questions in parallel using the vllm server. + + Args: + db_path_list: List of database paths + question_list: List of questions + api_key: API key + model: Model name + knowledge_list: List of knowledge strings (optional) + batch_size: Number of parallel requests + + Returns: + List of SQL responses + """ + if api_key in ["huggingface", "finetuned"]: + from openai import OpenAI + + openai_api_key = "EMPTY" + openai_api_base = "http://localhost:8000/v1" + + client = OpenAI( + api_key=openai_api_key, + base_url=openai_api_base, + ) + else: + client = LlamaAPIClient() + + # Generate all prompts first + prompts = [] + for i, question in enumerate(question_list): + if knowledge_list: + cur_prompt = generate_combined_prompts_one( + db_path=db_path_list[i], question=question, knowledge=knowledge_list[i] + ) + else: + cur_prompt = generate_combined_prompts_one( + db_path=db_path_list[i], question=question + ) + prompts.append(cur_prompt) + + print(f"Generated {len(prompts)} prompts for batch processing") + + # Process prompts in parallel + if api_key in ["huggingface", "finetuned"]: + results = batch_local_llama( + client=client, prompts=prompts, model=model, max_workers=batch_size + ) + else: + # For cloud API, we could implement a batch version of cloud_llama if needed + # For now, just process sequentially + results = [] + for prompt in prompts: + plain_result = cloud_llama( + client=client, + api_key=api_key, + model=model, + prompt=prompt, + max_tokens=10240, + temperature=0, + stop=["--", "\n\n", ";", "#"], + ) + results.append(plain_result) + + # Format results + response_list = [] + for i, result in enumerate(results): + if isinstance(result, str): + sql = result + else: + sql = "SELECT" + result["choices"][0]["text"] + + db_id = db_path_list[i].split("/")[-1].split(".sqlite")[0] + sql = ( + sql + "\t----- bird -----\t" + db_id + ) # to avoid unpredicted \t appearing in codex results + response_list.append(sql) + + return response_list + + def question_package(data_json, knowledge=False): question_list = [] for data in data_json: @@ -302,9 +465,18 @@ def generate_sql_file(sql_lst, output_path=None): args_parser.add_argument("--api_key", type=str, required=True) args_parser.add_argument("--model", type=str, required=True) args_parser.add_argument("--data_output_path", type=str) + args_parser.add_argument( + "--batch_size", + type=int, + default=8, + help="Number of parallel requests for batch processing", + ) + args_parser.add_argument( + "--use_batch", type=str, default="True", help="Whether to use batch processing" + ) args = args_parser.parse_args() - if not args.api_key in ["huggingface", "finetuned"]: + if args.api_key not in ["huggingface", "finetuned"]: os.environ["LLAMA_API_KEY"] = args.api_key try: @@ -332,22 +504,46 @@ def generate_sql_file(sql_lst, output_path=None): ) assert len(question_list) == len(db_path_list) == len(knowledge_list) - if args.use_knowledge == "True": - responses = collect_response_from_llama( # collect_batch_response_from_llama - db_path_list=db_path_list, - question_list=question_list, - api_key=args.api_key, - model=args.model, - knowledge_list=knowledge_list, - ) + use_batch = args.use_batch.lower() == "true" + + if use_batch: + print(f"Using batch processing with batch_size={args.batch_size}") + if args.use_knowledge == "True": + responses = batch_collect_response_from_llama( + db_path_list=db_path_list, + question_list=question_list, + api_key=args.api_key, + model=args.model, + knowledge_list=knowledge_list, + batch_size=args.batch_size, + ) + else: + responses = batch_collect_response_from_llama( + db_path_list=db_path_list, + question_list=question_list, + api_key=args.api_key, + model=args.model, + knowledge_list=None, + batch_size=args.batch_size, + ) else: - responses = collect_response_from_llama( - db_path_list=db_path_list, - question_list=question_list, - api_key=args.api_key, - model=args.model, - knowledge_list=None, - ) + print("Using sequential processing") + if args.use_knowledge == "True": + responses = collect_response_from_llama( + db_path_list=db_path_list, + question_list=question_list, + api_key=args.api_key, + model=args.model, + knowledge_list=knowledge_list, + ) + else: + responses = collect_response_from_llama( + db_path_list=db_path_list, + question_list=question_list, + api_key=args.api_key, + model=args.model, + knowledge_list=None, + ) output_name = args.data_output_path + "predict_" + args.mode + ".json" diff --git a/end-to-end-use-cases/coding/text2sql/eval/text2sql_eval.py b/end-to-end-use-cases/coding/text2sql/eval/text2sql_eval.py index 7a1374d99..22c30f314 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/text2sql_eval.py +++ b/end-to-end-use-cases/coding/text2sql/eval/text2sql_eval.py @@ -5,6 +5,7 @@ import sys from func_timeout import func_timeout, FunctionTimedOut +from tqdm import tqdm def load_json(dir): @@ -17,7 +18,7 @@ def result_callback(result): exec_result.append(result) -def execute_sql(predicted_sql, ground_truth, db_path): +def execute_sql(predicted_sql, ground_truth, db_path, debug=False): conn = sqlite3.connect(db_path) # Connect to the database cursor = conn.cursor() @@ -28,7 +29,7 @@ def execute_sql(predicted_sql, ground_truth, db_path): res = 0 if set(predicted_res) == set(ground_truth_res): res = 1 - else: + elif debug: print( f"\n\n==== INCORRECT SQL GENERATED ====\n{predicted_sql=}\n{predicted_res=}\n{ground_truth=}\n{ground_truth_res=}\n======\n\n" ) @@ -36,10 +37,14 @@ def execute_sql(predicted_sql, ground_truth, db_path): return res -def execute_model(predicted_sql, ground_truth, db_place, idx, meta_time_out): +def execute_model( + predicted_sql, ground_truth, db_place, idx, meta_time_out, debug=False +): try: res = func_timeout( - meta_time_out, execute_sql, args=(predicted_sql, ground_truth, db_place) + meta_time_out, + execute_sql, + args=(predicted_sql, ground_truth, db_place, debug), ) except KeyboardInterrupt: sys.exit(0) @@ -79,19 +84,35 @@ def package_sqls(sql_path, db_root_path, mode="gpt", data_mode="dev"): return clean_sqls, db_path_list -def run_sqls_parallel(sqls, db_places, num_cpus=1, meta_time_out=30.0): +def run_sqls_parallel(sqls, db_places, num_cpus=1, meta_time_out=30.0, debug=False): pool = mp.Pool(processes=num_cpus) - for i, sql_pair in enumerate(sqls): + # Create a progress bar if not in debug mode + if not debug: + pbar = tqdm(total=len(sqls), desc="Evaluating SQL queries") + + for i, sql_pair in enumerate(sqls): predicted_sql, ground_truth = sql_pair pool.apply_async( execute_model, - args=(predicted_sql, ground_truth, db_places[i], i, meta_time_out), - callback=result_callback, + args=(predicted_sql, ground_truth, db_places[i], i, meta_time_out, debug), + callback=lambda result: result_callback_with_progress( + result, not debug, pbar + ), ) pool.close() pool.join() + # Close the progress bar if not in debug mode + if not debug: + pbar.close() + + +def result_callback_with_progress(result, use_progress, pbar=None): + exec_result.append(result) + if use_progress and pbar: + pbar.update(1) + def sort_results(list_of_dicts): return sorted(list_of_dicts, key=lambda x: x["sql_idx"]) @@ -137,14 +158,19 @@ def compute_acc_by_diff(exec_results, diff_json_path): ) -def print_data(score_lists, count_lists): +def print_data(score_lists, count_lists, debug=False): levels = ["simple", "moderate", "challenging", "total"] - print("{:20} {:20} {:20} {:20} {:20}".format("", *levels)) - print("{:20} {:<20} {:<20} {:<20} {:<20}".format("count", *count_lists)) - print( - "====================================== ACCURACY =====================================" - ) + if debug: + print("{:20} {:20} {:20} {:20} {:20}".format("", *levels)) + print("{:20} {:<20} {:<20} {:<20} {:<20}".format("count", *count_lists)) + print( + "====================================== ACCURACY =====================================" + ) + else: + print("\nEvaluation Results:") + print("-" * 40) + print( "{:20} {:<20.2f} {:<20.2f} {:<20.2f} {:<20.2f}".format("accuracy", *score_lists) ) @@ -164,9 +190,19 @@ def print_data(score_lists, count_lists): args_parser.add_argument("--mode_predict", type=str, default="gpt") args_parser.add_argument("--difficulty", type=str, default="simple") args_parser.add_argument("--diff_json_path", type=str, default="") + args_parser.add_argument( + "--debug", action="store_true", help="Enable debug mode with detailed prints" + ) args = args_parser.parse_args() exec_result = [] + if args.debug: + print("Debug mode enabled - showing detailed output") + + # Show loading progress if not in debug mode + if not args.debug: + print("Loading SQL queries and database paths...") + pred_queries, db_paths = package_sqls( args.predicted_sql_path, args.db_root_path, @@ -179,20 +215,29 @@ def print_data(score_lists, count_lists): ) query_pairs = list(zip(pred_queries, gt_queries)) + + if args.debug: + print(f"Executing {len(query_pairs)} SQL query pairs...") + run_sqls_parallel( query_pairs, db_places=db_paths, num_cpus=args.num_cpus, meta_time_out=args.meta_time_out, + debug=args.debug, ) exec_result = sort_results(exec_result) - print("Evaluating statistics...") + if args.debug: + print("Evaluating statistics...") + simple_acc, moderate_acc, challenging_acc, acc, count_lists = compute_acc_by_diff( exec_result, args.diff_json_path ) score_lists = [simple_acc, moderate_acc, challenging_acc, acc] - print_data(score_lists, count_lists) - print( - "===========================================================================================" - ) + print_data(score_lists, count_lists, debug=args.debug) + + if args.debug: + print( + "===========================================================================================" + ) From 12a6dfa2acc52b63d407293ed85b1ce314ec20f4 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Thu, 24 Jul 2025 16:44:15 -0700 Subject: [PATCH 64/78] code cleanup and refactoring; cloud llama response generation in tqdm progress --- .../coding/text2sql/eval/llama_text2sql.py | 276 ++++++------------ .../coding/text2sql/eval/requirements.txt | 1 + 2 files changed, 93 insertions(+), 184 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py b/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py index 4b0d73bba..20d5c71f5 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py +++ b/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py @@ -13,36 +13,7 @@ TIMEOUT = 60 # Timeout in seconds for each API call -def local_llama(client, prompt, model): - SYSTEM_PROMPT = "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement." - # UNCOMMENT TO USE THE FINE_TUNED MODEL WITH REASONING DATASET - # SYSTEM_PROMPT = "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, generate the step-by-step reasoning and the final SQLite SQL select statement from the text question." - - messages = [ - {"content": SYSTEM_PROMPT, "role": "system"}, - {"role": "user", "content": prompt}, - ] - print(f"local_llama: {model=}") - chat_response = client.chat.completions.create( - model=model, - messages=messages, - timeout=TIMEOUT, - temperature=0, - ) - answer = chat_response.choices[0].message.content.strip() - - pattern = re.compile(r"```sql\n*(.*?)```", re.DOTALL) - matches = pattern.findall(answer) - if not matches: - result = answer - else: - result = matches[0] - - print(f"{result=}") - return result - - -def batch_local_llama(client, prompts, model, max_workers=8): +def local_llama(client, api_key, prompts, model, max_workers=8): """ Process multiple prompts in parallel using the vllm server. @@ -55,10 +26,19 @@ def batch_local_llama(client, prompts, model, max_workers=8): Returns: List of results in the same order as prompts """ + SYSTEM_PROMPT = ( - "You are a text to SQL query translator. Using the SQLite DB Schema " - "and the External Knowledge, translate the following text question " - "into a SQLite SQL select statement." + ( + "You are a text to SQL query translator. Using the SQLite DB Schema " + "and the External Knowledge, translate the following text question " + "into a SQLite SQL select statement." + ) + if api_key == "huggingface" + else ( + "You are a text to SQL query translator. Using the SQLite DB Schema " + "and the External Knowledge, generate the step-by-step reasoning and " + "then the final SQLite SQL select statement from the text question." + ) ) def process_single_prompt(prompt): @@ -88,7 +68,7 @@ def process_single_prompt(prompt): return f"error:{e}" print( - f"batch_local_llama: Processing {len(prompts)} prompts with {model=} " + f"local_llama: Processing {len(prompts)} prompts with {model=} " f"using {max_workers} workers" ) results = [] @@ -231,103 +211,61 @@ def generate_combined_prompts_one(db_path, question, knowledge=None): return combined_prompts -def cloud_llama(client, api_key, model, prompt, max_tokens, temperature, stop): - - SYSTEM_PROMPT = "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement." - try: - messages = [ - {"content": SYSTEM_PROMPT, "role": "system"}, - {"role": "user", "content": prompt}, - ] - final_max_tokens = len(messages) + MAX_NEW_TOKENS - response = client.chat.completions.create( - model=model, - messages=messages, - temperature=0, - max_completion_tokens=final_max_tokens, - ) - answer = response.completion_message.content.text - - pattern = re.compile(r"```sql\n*(.*?)```", re.DOTALL) - matches = pattern.findall(answer) - if matches != []: - result = matches[0] - else: - result = answer - - print(result) - except Exception as e: - result = "error:{}".format(e) - print(f"{result=}") - return result - - -def collect_response_from_llama( - db_path_list, question_list, api_key, model, knowledge_list=None -): +def cloud_llama(client, api_key, model, prompts): """ - :param db_path: str - :param question_list: [] - :return: dict of responses - """ - response_list = [] - - if api_key in ["huggingface", "finetuned"]: - from openai import OpenAI + Process multiple prompts sequentially using the cloud API, showing progress with tqdm. - openai_api_key = "EMPTY" - openai_api_base = "http://localhost:8000/v1" + Args: + client: LlamaAPIClient + api_key: API key + model: Model name + prompts: List of prompts to process (or a single prompt as string) - client = OpenAI( - api_key=openai_api_key, - base_url=openai_api_base, - ) - else: - client = LlamaAPIClient() + Returns: + List of results if prompts is a list, or a single result if prompts is a string + """ + SYSTEM_PROMPT = "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement." - for i, question in enumerate(question_list): - print( - "--------------------- processing question #{}---------------------".format( - i + 1 - ) - ) - print("the question is: {}".format(question)) + # Handle the case where a single prompt is passed + single_prompt = False + if isinstance(prompts, str): + prompts = [prompts] + single_prompt = True - if knowledge_list: - cur_prompt = generate_combined_prompts_one( - db_path=db_path_list[i], question=question, knowledge=knowledge_list[i] - ) - else: - cur_prompt = generate_combined_prompts_one( - db_path=db_path_list[i], question=question - ) - - if api_key in ["huggingface", "finetuned"]: - plain_result = local_llama(client=client, prompt=cur_prompt, model=model) - else: + results = [] - plain_result = cloud_llama( - client=client, - api_key=api_key, + # Process each prompt sequentially with tqdm progress bar + for prompt in tqdm(prompts, desc="Processing prompts", unit="prompt"): + try: + messages = [ + {"content": SYSTEM_PROMPT, "role": "system"}, + {"role": "user", "content": prompt}, + ] + final_max_tokens = len(messages) + MAX_NEW_TOKENS + response = client.chat.completions.create( model=model, - prompt=cur_prompt, - max_tokens=10240, + messages=messages, temperature=0, - stop=["--", "\n\n", ";", "#"], + max_completion_tokens=final_max_tokens, ) - if isinstance(plain_result, str): - sql = plain_result - else: - sql = "SELECT" + plain_result["choices"][0]["text"] + answer = response.completion_message.content.text - # responses_dict[i] = sql - db_id = db_path_list[i].split("/")[-1].split(".sqlite")[0] - sql = ( - sql + "\t----- bird -----\t" + db_id - ) # to avoid unpredicted \t appearing in codex results - response_list.append(sql) + pattern = re.compile(r"```sql\n*(.*?)```", re.DOTALL) + matches = pattern.findall(answer) + if matches != []: + result = matches[0] + else: + result = answer + except Exception as e: + result = "error:{}".format(e) + print(f"{result=}") - return response_list + results.append(result) + + # Return a single result if input was a single prompt + if single_prompt: + return results[0] + return results def batch_collect_response_from_llama( @@ -376,25 +314,24 @@ def batch_collect_response_from_llama( print(f"Generated {len(prompts)} prompts for batch processing") # Process prompts in parallel - if api_key in ["huggingface", "finetuned"]: - results = batch_local_llama( - client=client, prompts=prompts, model=model, max_workers=batch_size + if api_key in [ + "huggingface", + "finetuned", + ]: # running vllm on multiple GPUs to see best performance + results = local_llama( + client=client, + api_key=api_key, + prompts=prompts, + model=model, + max_workers=batch_size, ) else: - # For cloud API, we could implement a batch version of cloud_llama if needed - # For now, just process sequentially - results = [] - for prompt in prompts: - plain_result = cloud_llama( - client=client, - api_key=api_key, - model=model, - prompt=prompt, - max_tokens=10240, - temperature=0, - stop=["--", "\n\n", ";", "#"], - ) - results.append(plain_result) + results = cloud_llama( + client=client, + api_key=api_key, + model=model, + prompts=prompts, + ) # Format results response_list = [] @@ -471,9 +408,6 @@ def generate_sql_file(sql_lst, output_path=None): default=8, help="Number of parallel requests for batch processing", ) - args_parser.add_argument( - "--use_batch", type=str, default="True", help="Whether to use batch processing" - ) args = args_parser.parse_args() if args.api_key not in ["huggingface", "finetuned"]: @@ -488,62 +422,36 @@ def generate_sql_file(sql_lst, output_path=None): temperature=0, ) answer = response.completion_message.content.text - - print(f"{answer=}") except Exception as exception: print(f"{exception=}") exit(1) eval_data = json.load(open(args.eval_path, "r")) - # '''for debug''' - # eval_data = eval_data[:3] - # '''for debug''' question_list, db_path_list, knowledge_list = decouple_question_schema( datasets=eval_data, db_root_path=args.db_root_path ) assert len(question_list) == len(db_path_list) == len(knowledge_list) - use_batch = args.use_batch.lower() == "true" - - if use_batch: - print(f"Using batch processing with batch_size={args.batch_size}") - if args.use_knowledge == "True": - responses = batch_collect_response_from_llama( - db_path_list=db_path_list, - question_list=question_list, - api_key=args.api_key, - model=args.model, - knowledge_list=knowledge_list, - batch_size=args.batch_size, - ) - else: - responses = batch_collect_response_from_llama( - db_path_list=db_path_list, - question_list=question_list, - api_key=args.api_key, - model=args.model, - knowledge_list=None, - batch_size=args.batch_size, - ) + print(f"Using batch processing with batch_size={args.batch_size}") + if args.use_knowledge == "True": + responses = batch_collect_response_from_llama( + db_path_list=db_path_list, + question_list=question_list, + api_key=args.api_key, + model=args.model, + knowledge_list=knowledge_list, + batch_size=args.batch_size, + ) else: - print("Using sequential processing") - if args.use_knowledge == "True": - responses = collect_response_from_llama( - db_path_list=db_path_list, - question_list=question_list, - api_key=args.api_key, - model=args.model, - knowledge_list=knowledge_list, - ) - else: - responses = collect_response_from_llama( - db_path_list=db_path_list, - question_list=question_list, - api_key=args.api_key, - model=args.model, - knowledge_list=None, - ) + responses = batch_collect_response_from_llama( + db_path_list=db_path_list, + question_list=question_list, + api_key=args.api_key, + model=args.model, + knowledge_list=None, + batch_size=args.batch_size, + ) output_name = args.data_output_path + "predict_" + args.mode + ".json" diff --git a/end-to-end-use-cases/coding/text2sql/eval/requirements.txt b/end-to-end-use-cases/coding/text2sql/eval/requirements.txt index 0006a4776..cb22a1b7a 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/requirements.txt +++ b/end-to-end-use-cases/coding/text2sql/eval/requirements.txt @@ -1,5 +1,6 @@ llama_api_client==0.1.2 func_timeout==4.3.5 +tqdm==4.67.1 # uncomment to run vllm for eval with Llama 3.1 8B on HF and its fine-tuned models # vllm==0.9.2 From 799dee681377e9c95a9e2f28adc0fce4c3225532 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Thu, 24 Jul 2025 17:52:02 -0700 Subject: [PATCH 65/78] some cleanup and typo fix --- end-to-end-use-cases/coding/text2sql/eval/README.md | 13 +++++++------ .../coding/text2sql/eval/llama_eval.sh | 9 +++++---- .../coding/text2sql/eval/llama_text2sql.py | 12 +++++------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/eval/README.md b/end-to-end-use-cases/coding/text2sql/eval/README.md index e5e4be9b9..beab59193 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/README.md +++ b/end-to-end-use-cases/coding/text2sql/eval/README.md @@ -20,10 +20,11 @@ Below are the results of the Llama models we have evaluated on the BIRD DEV data First, run the commands below to create a new Conda environment and install all the required packages for Text2SQL evaluation and fine-tuning: ``` -git clone https://github.com/meta-llama/llama-cookbook -cd llama-cookbook/end-to-end-use-cases/coding/text2sql conda create -n llama-text2sql python=3.10 conda activate llama-text2sql +git clone https://github.com/meta-llama/llama-cookbook +git checkout text2sql # to be removed after the PR merge +cd llama-cookbook/end-to-end-use-cases/coding/text2sql/eval pip install -r requirements.txt ``` @@ -31,7 +32,7 @@ Then, follow the steps below to evaluate Llama 3 & 4 models on Text2SQL using th 1. Get the DEV dataset: ``` -cd data +cd ../data sh download_dev_unzip.sh cd ../eval ``` @@ -46,7 +47,7 @@ After the script completes, you'll see the accuracy of the Llama model on the BI To compare your evaluated accuracy of your selected Llama model with other results in the BIRD Dev leaderboard, click [here](https://bird-bench.github.io/). -## Evaluation with Llama Models on Hugging Face or Fine-tuned +## Evaluation with Llama Models on Hugging Face or Fine-tuned We use vllm OpenAI compatible server to run Llama 3.1 8B on Hugging Face (steps below) or its fine-tuned models (steps [here](../fine-tuning/#evaluating-the-fine-tuned-model) for eval: @@ -63,7 +64,7 @@ model='meta-llama/Llama-3.1-8B-Instruct' ``` 3. Start the vllm server: -``` +``` vllm serve meta-llama/Llama-3.1-8B-Instruct --tensor-parallel-size 1 --max-num-batched-tokens 8192 --max-num-seqs 64 ``` or if you have multiple GPUs, do something like: @@ -72,7 +73,7 @@ CUDA_VISIBLE_DEVICES=0,1,2,3 vllm serve meta-llama/Llama-3.1-8B-Instruct --tenso ``` then run `sh llama_eval.sh`. - + ## Evaluation Process 1. **SQL Generation**: `llama_text2sql.py` sends natural language questions to the specified Llama model and collects the generated SQL queries. diff --git a/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh b/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh index 0a4130f1f..7c5e1f6ba 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh +++ b/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh @@ -6,8 +6,8 @@ db_root_path='../data/dev_20240627/dev_databases/' ground_truth_path='../data/' # Llama models on Llama API -# YOUR_API_KEY='YOUR_LLAMA_API_KEY' -# model='Llama-3.3-8B-Instruct' +YOUR_API_KEY='YOUR_LLAMA_API_KEY' +model='Llama-3.3-8B-Instruct' #model='Llama-3.3-70B-Instruct' #model='Llama-4-Maverick-17B-128E-Instruct-FP8' #model='Llama-4-Scout-17B-16E-Instruct-FP8' @@ -17,12 +17,13 @@ ground_truth_path='../data/' # model='meta-llama/Llama-3.1-8B-Instruct' # Fine-tuned Llama models locally -YOUR_API_KEY='finetuned' -model='../fine-tuning/llama31-8b-text2sql-fft-nonquantized-cot-epochs-3' +# YOUR_API_KEY='finetuned' +# model='../fine-tuning/llama31-8b-text2sql-fft-nonquantized-cot-epochs-3' data_output_path="./output/$model/" echo "Text2SQL using $model" + python3 -u llama_text2sql.py --db_root_path ${db_root_path} --api_key ${YOUR_API_KEY} \ --model ${model} --eval_path ${eval_path} --data_output_path ${data_output_path} diff --git a/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py b/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py index 20d5c71f5..a20d4e5d9 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py +++ b/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py @@ -311,13 +311,13 @@ def batch_collect_response_from_llama( ) prompts.append(cur_prompt) - print(f"Generated {len(prompts)} prompts for batch processing") + print(f"Generated {len(prompts)} prompts for Llama processing") - # Process prompts in parallel if api_key in [ "huggingface", "finetuned", - ]: # running vllm on multiple GPUs to see best performance + ]: + # Process prompts in parallel; running vllm on multiple GPUs for best eval performance results = local_llama( client=client, api_key=api_key, @@ -414,14 +414,13 @@ def generate_sql_file(sql_lst, output_path=None): os.environ["LLAMA_API_KEY"] = args.api_key try: + # test if the Llama API key is valid client = LlamaAPIClient() - - response = client.chat.completions.create( + client.chat.completions.create( model=args.model, messages=[{"role": "user", "content": "125*125 is?"}], temperature=0, ) - answer = response.completion_message.content.text except Exception as exception: print(f"{exception=}") exit(1) @@ -433,7 +432,6 @@ def generate_sql_file(sql_lst, output_path=None): ) assert len(question_list) == len(db_path_list) == len(knowledge_list) - print(f"Using batch processing with batch_size={args.batch_size}") if args.use_knowledge == "True": responses = batch_collect_response_from_llama( db_path_list=db_path_list, From 6501cf4566f64ae8cb80726b67dc759b90d30ee7 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Fri, 25 Jul 2025 07:57:43 -0700 Subject: [PATCH 66/78] FT readme update; removed old vllm py and sh files --- .../coding/text2sql/eval/llama_eval_vllm.sh | 24 -- .../text2sql/eval/llama_text2sql_vllm.py | 289 ------------------ .../coding/text2sql/fine-tuning/README.md | 8 +- 3 files changed, 3 insertions(+), 318 deletions(-) delete mode 100644 end-to-end-use-cases/coding/text2sql/eval/llama_eval_vllm.sh delete mode 100644 end-to-end-use-cases/coding/text2sql/eval/llama_text2sql_vllm.py diff --git a/end-to-end-use-cases/coding/text2sql/eval/llama_eval_vllm.sh b/end-to-end-use-cases/coding/text2sql/eval/llama_eval_vllm.sh deleted file mode 100644 index 532ee6235..000000000 --- a/end-to-end-use-cases/coding/text2sql/eval/llama_eval_vllm.sh +++ /dev/null @@ -1,24 +0,0 @@ -eval_path='../data/dev_20240627/dev.json' -db_root_path='../data/dev_20240627/dev_databases/' -ground_truth_path='../data/' - -model='meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo' -data_output_path="./output/$model/" - -echo "Text2SQL using $model" -python3 -u llama_text2sql_vllm.py --db_root_path ${db_root_path} \ ---model ${model} --eval_path ${eval_path} --data_output_path ${data_output_path} - -# Check if llama_text2sql.py exited successfully -if [ $? -eq 0 ]; then - echo "llama_text2sql.py completed successfully. Proceeding with evaluation..." - python3 -u text2sql_eval.py --db_root_path ${db_root_path} --predicted_sql_path ${data_output_path} \ - --ground_truth_path ${ground_truth_path} \ - --diff_json_path ${eval_path} - - echo "Done evaluating $model." - -else - echo "Error: llama_text2sql.py failed with exit code $?. Skipping evaluation." - exit 1 -fi diff --git a/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql_vllm.py b/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql_vllm.py deleted file mode 100644 index e7936a061..000000000 --- a/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql_vllm.py +++ /dev/null @@ -1,289 +0,0 @@ -import argparse -import json -import os -import re -import sqlite3 -from typing import Dict, List, Tuple - -from tqdm import tqdm - -from vllm import LLM, EngineArgs, SamplingParams - -DEFAULT_MAX_TOKENS=10240 -SYSTEM_PROMPT = "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement." -# UNCOMMENT TO USE THE FINE_TUNED MODEL WITH REASONING DATASET -# SYSTEM_PROMPT = "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, generate the step-by-step reasoning and the final SQLite SQL select statement from the text question." - - -def inference(llm, sampling_params, user_prompt): - messages = [ - {"content": SYSTEM_PROMPT, "role": "system"}, - {"role": "user", "content": user_prompt}, - ] - - print(f"{messages=}") - - response = llm.chat(messages, sampling_params, use_tqdm=False) - print(f"{response=}") - response_text = response[0].outputs[0].text - pattern = re.compile(r"```sql\n*(.*?)```", re.DOTALL) - matches = pattern.findall(response_text) - if matches != []: - result = matches[0] - else: - result = response_text - print(f"{result=}") - return result - - -def new_directory(path): - if not os.path.exists(path): - os.makedirs(path) - - -def get_db_schemas(bench_root: str, db_name: str) -> Dict[str, str]: - """ - Read an sqlite file, and return the CREATE commands for each of the tables in the database. - """ - asdf = "database" if bench_root == "spider" else "databases" - with sqlite3.connect( - f"file:{bench_root}/{asdf}/{db_name}/{db_name}.sqlite?mode=ro", uri=True - ) as conn: - # conn.text_factory = bytes - cursor = conn.cursor() - cursor.execute("SELECT name FROM sqlite_master WHERE type='table';") - tables = cursor.fetchall() - schemas = {} - for table in tables: - cursor.execute( - "SELECT sql FROM sqlite_master WHERE type='table' AND name='{}';".format( - table[0] - ) - ) - schemas[table[0]] = cursor.fetchone()[0] - - return schemas - - -def nice_look_table(column_names: list, values: list): - rows = [] - # Determine the maximum width of each column - widths = [ - max(len(str(value[i])) for value in values + [column_names]) - for i in range(len(column_names)) - ] - - # Print the column names - header = "".join( - f"{column.rjust(width)} " for column, width in zip(column_names, widths) - ) - # print(header) - # Print the values - for value in values: - row = "".join(f"{str(v).rjust(width)} " for v, width in zip(value, widths)) - rows.append(row) - rows = "\n".join(rows) - final_output = header + "\n" + rows - return final_output - - -def generate_schema_prompt(db_path, num_rows=None): - # extract create ddls - """ - :param root_place: - :param db_name: - :return: - """ - full_schema_prompt_list = [] - conn = sqlite3.connect(db_path) - # Create a cursor object - cursor = conn.cursor() - cursor.execute("SELECT name FROM sqlite_master WHERE type='table'") - tables = cursor.fetchall() - schemas = {} - for table in tables: - if table == "sqlite_sequence": - continue - cursor.execute( - "SELECT sql FROM sqlite_master WHERE type='table' AND name='{}';".format( - table[0] - ) - ) - create_prompt = cursor.fetchone()[0] - schemas[table[0]] = create_prompt - if num_rows: - cur_table = table[0] - if cur_table in ["order", "by", "group"]: - cur_table = "`{}`".format(cur_table) - - cursor.execute("SELECT * FROM {} LIMIT {}".format(cur_table, num_rows)) - column_names = [description[0] for description in cursor.description] - values = cursor.fetchall() - rows_prompt = nice_look_table(column_names=column_names, values=values) - verbose_prompt = "/* \n {} example rows: \n SELECT * FROM {} LIMIT {}; \n {} \n */".format( - num_rows, cur_table, num_rows, rows_prompt - ) - schemas[table[0]] = "{} \n {}".format(create_prompt, verbose_prompt) - - for k, v in schemas.items(): - full_schema_prompt_list.append(v) - - schema_prompt = "-- DB Schema: " + "\n\n".join(full_schema_prompt_list) - - return schema_prompt - - -def generate_comment_prompt(question, knowledge=None): - knowledge_prompt = "-- External Knowledge: {}".format(knowledge) - question_prompt = "-- Question: {}".format(question) - - result_prompt = knowledge_prompt + "\n\n" + question_prompt - - return result_prompt - - -def generate_combined_prompts_one(db_path, question, knowledge=None): - schema_prompt = generate_schema_prompt(db_path, num_rows=None) - comment_prompt = generate_comment_prompt(question, knowledge) - - combined_prompts = schema_prompt + "\n\n" + comment_prompt - - return combined_prompts - - - -def collect_response_from_llama( - llm, sampling_params, db_path_list, question_list, knowledge_list=None -): - response_list = [] - - for i, question in tqdm(enumerate(question_list)): - print( - "--------------------- processing question #{}---------------------".format( - i + 1 - ) - ) - print("the question is: {}".format(question)) - - if knowledge_list: - cur_prompt = generate_combined_prompts_one( - db_path=db_path_list[i], question=question, knowledge=knowledge_list[i] - ) - else: - cur_prompt = generate_combined_prompts_one( - db_path=db_path_list[i], question=question - ) - - plain_result = inference(llm, sampling_params, cur_prompt) - if type(plain_result) == str: - sql = plain_result - else: - sql = "SELECT" + plain_result["choices"][0]["text"] - - # responses_dict[i] = sql - db_id = db_path_list[i].split("/")[-1].split(".sqlite")[0] - sql = ( - sql + "\t----- bird -----\t" + db_id - ) # to avoid unpredicted \t appearing in codex results - response_list.append(sql) - - return response_list - - -def question_package(data_json, knowledge=False): - question_list = [] - for data in data_json: - question_list.append(data["question"]) - - return question_list - - -def knowledge_package(data_json, knowledge=False): - knowledge_list = [] - for data in data_json: - knowledge_list.append(data["evidence"]) - - return knowledge_list - - -def decouple_question_schema(datasets, db_root_path): - question_list = [] - db_path_list = [] - knowledge_list = [] - for i, data in enumerate(datasets): - question_list.append(data["question"]) - cur_db_path = db_root_path + data["db_id"] + "/" + data["db_id"] + ".sqlite" - db_path_list.append(cur_db_path) - knowledge_list.append(data["evidence"]) - - return question_list, db_path_list, knowledge_list - - -def generate_sql_file(sql_lst, output_path=None): - result = {} - for i, sql in enumerate(sql_lst): - result[i] = sql - - if output_path: - directory_path = os.path.dirname(output_path) - new_directory(directory_path) - json.dump(result, open(output_path, "w"), indent=4) - - return result - - -if __name__ == "__main__": - args_parser = argparse.ArgumentParser() - args_parser.add_argument("--eval_path", type=str, default="") - args_parser.add_argument("--mode", type=str, default="dev") - args_parser.add_argument("--test_path", type=str, default="") - args_parser.add_argument("--use_knowledge", type=str, default="True") - args_parser.add_argument("--db_root_path", type=str, default="") - args_parser.add_argument("--model", type=str, default="meta-llama/Llama-3.1-8B-Instruct") - args_parser.add_argument("--data_output_path", type=str) - args_parser.add_argument("--max_tokens", type=int, default=DEFAULT_MAX_TOKENS) - args_parser.add_argument("--temperature", type=float, default=0.0) - args_parser.add_argument("--top_k", type=int, default=50) - args_parser.add_argument("--top_p", type=float, default=0.1) - args = args_parser.parse_args() - - eval_data = json.load(open(args.eval_path, "r")) - # '''for debug''' - # eval_data = eval_data[:3] - # '''for debug''' - - question_list, db_path_list, knowledge_list = decouple_question_schema( - datasets=eval_data, db_root_path=args.db_root_path - ) - assert len(question_list) == len(db_path_list) == len(knowledge_list) - - llm = LLM(model=args.model, download_dir="/opt/hpcaas/.mounts/fs-06ad2f76a5ad0b18f/shared/amiryo/.cache/vllm") - sampling_params = llm.get_default_sampling_params() - sampling_params.max_tokens = args.max_tokens - sampling_params.temperature = args.temperature - sampling_params.top_p = args.top_p - sampling_params.top_k = args.top_k - - - if args.use_knowledge == "True": - responses = collect_response_from_llama( - llm=llm, - sampling_params=sampling_params, - db_path_list=db_path_list, - question_list=question_list, - knowledge_list=knowledge_list, - ) - else: - responses = collect_response_from_llama( - llm=llm, - sampling_params=sampling_params, - db_path_list=db_path_list, - question_list=question_list, - knowledge_list=None, - ) - - output_name = args.data_output_path + "predict_" + args.mode + ".json" - - generate_sql_file(sql_lst=responses, output_path=output_name) - - print("successfully collect results from {}".format(args.model)) diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md index fcf146505..51bf444f5 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md @@ -101,18 +101,16 @@ YOUR_API_KEY='finetuned' model='fine_tuning/llama31-8b-text2sql-fft-nonquantized-cot' ``` -2. Uncomment the line `SYSTEM_PROMPT` [here](https://github.com/meta-llama/llama-cookbook/blob/text2sql/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py#L17) in `llama_text2sql.py` to use it with the reasoning dataset fine-tuned model. - -3. Start the vllm server by running +2. Start the vllm server by running ``` vllm serve fine_tuning/llama31-8b-text2sql-fft-nonquantized-cot --tensor-parallel-size 1 --max-num-batched-tokens 8192 --max-num-seqs 64 ``` -If you have multiple GPUs you can run something like +If you have multiple GPUs you can run something like ``` CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 vllm serve fine_tuning/llama31-8b-text2sql-fft-nonquantized-cot --tensor-parallel-size 8 --max-num-batched-tokens 8192 --max-num-seqs 64 ``` to speed up the eval. -4. Run `sh llama_eval.sh`. +3. Run `sh llama_eval.sh`. **Note:** If your fine-tuned model is PEFT based, you may need to run `python merge_peft.py` after modifying its `peft_model_path` and `output_dir` and set the merged folder path after `vllm serve`. From 82bb0087b8d4370aab1531f4528d048afbd7d275 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Mon, 28 Jul 2025 16:17:30 -0700 Subject: [PATCH 67/78] 3 READMEs update; fine-tuning requirements update with vllm etc --- .../coding/text2sql/README.md | 21 ++-- .../coding/text2sql/eval/README.md | 12 +- .../coding/text2sql/fine-tuning/README.md | 112 +++++++++++++----- .../text2sql/fine-tuning/requirements.txt | 28 +++-- 4 files changed, 117 insertions(+), 56 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/README.md b/end-to-end-use-cases/coding/text2sql/README.md index e6e7078e2..5351ab91b 100644 --- a/end-to-end-use-cases/coding/text2sql/README.md +++ b/end-to-end-use-cases/coding/text2sql/README.md @@ -1,20 +1,25 @@ # Improving Llama Text2SQL performance with CoT Fine-tuning -This recipe is step by step guide to improve Llama performance on Text2SQL measured with the popular [BIRD](https://bird-bench.github.io) benchmark. We generate synthetic Chain of Thought(CoT) dataset and fine-tune Llama models on it. +This recipe is step by step guide to improve Llama performance on Text2SQL measured with the popular [BIRD](https://bird-bench.github.io) benchmark. We generate a synthetic Chain of Thought(CoT) dataset and fine-tune Llama models on it. -Results: [graph_placeholder] +Results: +|-----------------------------|-------------------------------| +| baseline | 39.47% | +| CoT, PEFT | 43.35% | +| CoT, FFT | 42.44% (3 epochs) | +| CoT, FFT | 43.87% (10 epochs) | -We followed following steps: +The complete steps are: -1. Pre-processing the BIRD TRAIN datset by converting SQL statements into conversation format +1. Pre-processing the BIRD TRAIN datset by converting SQL statements into the conversation format. -2. We use the conversations from step 1, add CoT to these existing conversations using Llama-3.3-70B +2. We use the conversations from step 1, add CoT to these existing conversations using Llama-3.3-70B. -3. Fine-tuning Llama-3.1-8B on the dataset from step 2 +3. Fine-tuning Llama-3.1-8B on the dataset from step 2. -4. We provide scripts to simplify running the [BIRD](https://bird-bench.github.io) benchmark on the fine-tuned models and compare it with out of the model. +4. We provide scripts to simplify running the [BIRD](https://bird-bench.github.io) eval benchmark on the fine-tuned models and compare it with out of the model. -## Structure: +## Folder Structure - quickstart folder: contains a notebook to ask Llama 3.3 to convert natural language queries into SQL queries. - data folder: contains scripts to download the BIRD TRAIN and DEV datasets; diff --git a/end-to-end-use-cases/coding/text2sql/eval/README.md b/end-to-end-use-cases/coding/text2sql/eval/README.md index beab59193..2ed752afd 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/README.md +++ b/end-to-end-use-cases/coding/text2sql/eval/README.md @@ -17,7 +17,9 @@ Below are the results of the Llama models we have evaluated on the BIRD DEV data ## Quick Start with Llama Models via Llama API -First, run the commands below to create a new Conda environment and install all the required packages for Text2SQL evaluation and fine-tuning: +Follow the steps below to evaluate Llama 3 & 4 models on Text2SQL using the BIRD benchmark: + +1. Run the commands below to create a new Conda environment and install all the required packages for Text2SQL evaluation: ``` conda create -n llama-text2sql python=3.10 @@ -28,18 +30,16 @@ cd llama-cookbook/end-to-end-use-cases/coding/text2sql/eval pip install -r requirements.txt ``` -Then, follow the steps below to evaluate Llama 3 & 4 models on Text2SQL using the BIRD benchmark: - -1. Get the DEV dataset: +2. Get the DEV dataset: ``` cd ../data sh download_dev_unzip.sh cd ../eval ``` -2. Open `llama_eval.sh` and set `YOUR_API_KEY` to your [Llama API](https://llama.developer.meta.com/) key then uncomment a line that starts with `model=` to specify the Llama model to use for the text2sql eval. +3. Open `llama_eval.sh` and set `YOUR_API_KEY` to your [Llama API](https://llama.developer.meta.com/) key then uncomment a line that starts with `model=` to specify the Llama model to use for the text2sql eval. -3. Run the evaluation script `sh llama_eval.sh`, which will use the BIRD DEV dataset (1534 examples in total) with external knowledge turned on to run the Llama model on each text question and compare the generated SQL with the gold SQL. +4. Run the evaluation script `sh llama_eval.sh`, which will use the BIRD DEV dataset (1534 examples in total) with external knowledge turned on to run the Llama model on each text question and compare the generated SQL with the gold SQL. If your API key or model name is incorrect, the script will exit with an authentication or model not supported error. diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md index 51bf444f5..59db70ded 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md @@ -4,7 +4,7 @@ This folder contains scripts to: * generate a dataset from the BIRD TRAIN set (with no CoT info) for supervised fine-tuning (SFT); * generate a dataset from the BIRD TRAIN set (with CoT info by Llama 3.3 70B) for SFT; -* SFT the Llama 3.1 8B model with the generated datasets with different fine-tuning combinations: with or without CoT, using quantization or not, full fine-tuning (FFT) or parameter-efficient fine-tuning (PEFT). +* SFT the Llama 3.1 8B model with the generated datasets with different fine-tuning combinations: with or without CoT, using quantization or not, full fine-tuning (FFT) or parameter-efficient fine-tuning (PEFT). **Note:** CoT stands for Chain of Thought and we will use "CoT" and "reasoning" interchangeably here, although generally, reasoning encompasses a broader concept than CoT. @@ -22,15 +22,92 @@ The eval results of SFT Llama 3.1 8B with different options (epochs is 3, with a Using Quantization+PEFT on CoT dataset only dropped the accuracy from 43.35% to 42.89%. -## Creating dataset +## Quick Start with Fine-tuning Llama 3.1 8B -We use the BIRD TRAIN dataset to prepare for supervised fine-tuning with reasoning info in the dataset. The goal is to see if we can improve the accuracy of the fine-tuned model by adding the reasoning info in the dataset. +1. If you have already run the eval folder's Quick Start Step 1's commands [here](../eval/README.md#quick-start-with-llama-models-via-llama-api) to "create a new Conda environment and install all the required packages for Text2SQL evaluation", just run: + +``` +cd llama-cookbook/end-to-end-use-cases/coding/text2sql/fine-tuning +pip install -r requirements.txt +``` + +Otherwise, run the commands below to create a new Conda environment and install all the required packages for Text2SQL evaluation and fine-tuning: + +``` +conda create -n llama-text2sql python=3.10 +conda activate llama-text2sql +git clone https://github.com/meta-llama/llama-cookbook +git checkout text2sql # to be removed after the PR merge +cd llama-cookbook/end-to-end-use-cases/coding/text2sql/fine-tuning +pip install -r requirements.txt +``` + +2. Get the TRAIN dataset: + +``` +cd ../data +sh download_train_unzip.sh +cd ../fine-tuning +``` + +3. Create a CoT reasoning dataset from the TRAIN dataset: + +``` +python create_reasoning_dataset.py --input_json ../data/train/train.json --db_root_path ../data/train/train_databases +``` + +See the section "About Creating the CoT Dataset" below for more details. + +4. Run one of the commands below to fine-tune the Llama 3.1 8B model with the generated dataset (about 50-70GB GPU memory required): + +``` +python trl_sft.py --quantized false --peft false --cot true +python trl_sft.py --quantized false --peft true --cot true +python trl_sft.py --quantized true --peft true --cot true +``` + +See the section "About fine-tuning" below for more details. + +## Evaluating the fine-tuned model + +1. Set the `model` value in `llama_eval.sh` to be one of the fine-tuned model folders above, e.g. + +``` +YOUR_API_KEY='finetuned' +model='fine_tuning/llama31-8b-text2sql-fft-nonquantized-cot' +``` + +2. Start the vllm server by running +``` +vllm serve fine_tuning/llama31-8b-text2sql-fft-nonquantized-cot --tensor-parallel-size 1 --max-num-batched-tokens 8192 --max-num-seqs 64 +``` +If you have multiple GPUs you can run something like + +``` +CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 vllm serve fine_tuning/llama31-8b-text2sql-fft-nonquantized-cot --tensor-parallel-size 8 --max-num-batched-tokens 8192 --max-num-seqs 64 +``` + +to speed up the eval. -### Creating a reasoning dataset from the TRAIN dataset +3. If you haven't downloaded the DEV dataset, download it and unzip it first: + +``` +cd ../data +sh download_dev_unzip.sh +cd ../eval +``` + +Then run `sh llama_eval.sh`. + +**Note:** If your fine-tuned model is PEFT based, you may need to run `python merge_peft.py` after modifying its `peft_model_path` and `output_dir` and set the merged folder path after `vllm serve`. + +## About Creating the CoT Dataset + +We use the BIRD TRAIN dataset to prepare for supervised fine-tuning with reasoning info in the dataset. The goal is to see if we can improve the accuracy of the fine-tuned model by adding the reasoning info in the dataset. The script `create_reasoning_dataset.py` is used to create a reasoning dataset from the TRAIN dataset by asking Llama 3.3 70B to generate the reasoning for each text question and its corresponding gold SQL. The intent is to use the reasoning dataset to fine-tune the Llama model to improve the accuracy of the generated SQL. -To run the script, use the following commands: +To run the script, use the following command: ``` python create_reasoning_dataset.py --input_json ../data/train/train.json --db_root_path ../data/train/train_databases ``` @@ -71,7 +148,7 @@ Let me think through this step by step:\n\n1. First, I need to consider...\n2. T """ ``` -### Running fine-tuning +## About fine-tuning Run one of the commands below: @@ -91,26 +168,3 @@ llama31-8b-text2sql-peft-quantized-cot The train loss chart should look like this: ![](train_loss_cot.png) - -### Evaluating the fine-tuned model - -1. Set the `model` value in `llama_eval.sh` to be one of the fine-tuned model folders above, e.g. - -``` -YOUR_API_KEY='finetuned' -model='fine_tuning/llama31-8b-text2sql-fft-nonquantized-cot' -``` - -2. Start the vllm server by running -``` -vllm serve fine_tuning/llama31-8b-text2sql-fft-nonquantized-cot --tensor-parallel-size 1 --max-num-batched-tokens 8192 --max-num-seqs 64 -``` -If you have multiple GPUs you can run something like -``` -CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 vllm serve fine_tuning/llama31-8b-text2sql-fft-nonquantized-cot --tensor-parallel-size 8 --max-num-batched-tokens 8192 --max-num-seqs 64 -``` - to speed up the eval. - -3. Run `sh llama_eval.sh`. - -**Note:** If your fine-tuned model is PEFT based, you may need to run `python merge_peft.py` after modifying its `peft_model_path` and `output_dir` and set the merged folder path after `vllm serve`. diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/requirements.txt b/end-to-end-use-cases/coding/text2sql/fine-tuning/requirements.txt index def1eccc3..d08af229b 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/requirements.txt +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/requirements.txt @@ -1,17 +1,19 @@ -llama_api_client==0.1.1 +llama_api_client==0.1.2 +func_timeout==4.3.5 +tqdm==4.67.1 +vllm==0.9.2 +openai==1.90.0 langchain-together==0.3.0 sqlparse==0.5.3 -torch==2.4.1 tensorboard==2.19.0 -liger-kernel==0.4.2 +liger_kernel==0.6.1 setuptools==78.1.1 -deepspeed==0.15.4 -transformers==4.46.3 -datasets==3.6.0 -accelerate==1.1.1 -bitsandbytes==0.44.1 -trl==0.12.1 -peft==0.13.2 -lighteval==0.6.2 -hf-transfer==0.1.8 -func_timeout==4.3.5 +deepspeed==0.17.3 +transformers==4.54.0 +datasets==4.0.0 +accelerate==1.9.0 +bitsandbytes==0.46.1 +trl==0.19.1 +peft==0.16.0 +lighteval==0.10.0 +hf_transfer==0.1.9 From 27a23afdd3b8271177c2074e8d0432c6fe9d604d Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Mon, 28 Jul 2025 16:28:23 -0700 Subject: [PATCH 68/78] main README --- end-to-end-use-cases/coding/text2sql/README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/README.md b/end-to-end-use-cases/coding/text2sql/README.md index 5351ab91b..25da0a741 100644 --- a/end-to-end-use-cases/coding/text2sql/README.md +++ b/end-to-end-use-cases/coding/text2sql/README.md @@ -3,6 +3,8 @@ This recipe is step by step guide to improve Llama performance on Text2SQL measured with the popular [BIRD](https://bird-bench.github.io) benchmark. We generate a synthetic Chain of Thought(CoT) dataset and fine-tune Llama models on it. Results: + +| Fine-tuning Combination | Accuracy | |-----------------------------|-------------------------------| | baseline | 39.47% | | CoT, PEFT | 43.35% | @@ -11,20 +13,20 @@ Results: The complete steps are: -1. Pre-processing the BIRD TRAIN datset by converting SQL statements into the conversation format. +1. Pre-processing the [BIRD](https://bird-bench.github.io) TRAIN datset by converting text, schema, external knowledge, and SQL statements into the conversation format. -2. We use the conversations from step 1, add CoT to these existing conversations using Llama-3.3-70B. +2. Using Llama-3.3-70B to add CoT to the conversation format dataset. -3. Fine-tuning Llama-3.1-8B on the dataset from step 2. +3. Fine-tuning Llama-3.1-8B on the CoT dataset from step 2. -4. We provide scripts to simplify running the [BIRD](https://bird-bench.github.io) eval benchmark on the fine-tuned models and compare it with out of the model. +4. Running the BIRD DEV eval benchmark on the fine-tuned models and compare it with out of the model. ## Folder Structure - quickstart folder: contains a notebook to ask Llama 3.3 to convert natural language queries into SQL queries. - data folder: contains scripts to download the BIRD TRAIN and DEV datasets; -- fine-tune folder: contains scripts to generate non-CoT and CoT datasets based on the BIRD TRAIN set and to supervised fine-tune Llama models using the datasets, with different SFT options (quantization or not, full fine-tuning or parameter-efficient fine-tuning); -- eval folder: contains scripts to evaluate Llama models (original and fine-tuned) on the BIRD dataset; +- fine-tune folder: contains scripts to generate CoT dataset based on the BIRD TRAIN set and to supervised fine-tune Llama models using the dataset, with different SFT options (quantization or not, full fine-tuning or parameter-efficient fine-tuning); +- eval folder: contains scripts to evaluate Llama models (original and fine-tuned) on the BIRD dataset. We also experimented with supervised fine-tuning (SFT) without CoT which resulted in slightly lower accuracy. From e38abf12025e28d8063296666f0ff41f99968f5a Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Fri, 1 Aug 2025 08:49:13 -0700 Subject: [PATCH 69/78] Update eval README.md --- end-to-end-use-cases/coding/text2sql/eval/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/eval/README.md b/end-to-end-use-cases/coding/text2sql/eval/README.md index 2ed752afd..be213ceb6 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/README.md +++ b/end-to-end-use-cases/coding/text2sql/eval/README.md @@ -67,9 +67,9 @@ model='meta-llama/Llama-3.1-8B-Instruct' ``` vllm serve meta-llama/Llama-3.1-8B-Instruct --tensor-parallel-size 1 --max-num-batched-tokens 8192 --max-num-seqs 64 ``` -or if you have multiple GPUs, do something like: +or if you want to speed up the inference and eval and have multiple GPUs, you can set `--tensor-parallel-size` to the number of your available GPUs, e.g.: ``` -CUDA_VISIBLE_DEVICES=0,1,2,3 vllm serve meta-llama/Llama-3.1-8B-Instruct --tensor-parallel-size 4 --max-num-batched-tokens 8192 --max-num-seqs 64 +vllm serve meta-llama/Llama-3.1-8B-Instruct --tensor-parallel-size 8 --max-num-batched-tokens 8192 --max-num-seqs 64 ``` then run `sh llama_eval.sh`. From fc8054603552b918ff8f0da9fc7eea184ed17f97 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Fri, 1 Aug 2025 08:50:32 -0700 Subject: [PATCH 70/78] Update FT EADME.md --- end-to-end-use-cases/coding/text2sql/fine-tuning/README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md index 59db70ded..6a1033c87 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md @@ -81,14 +81,12 @@ model='fine_tuning/llama31-8b-text2sql-fft-nonquantized-cot' ``` vllm serve fine_tuning/llama31-8b-text2sql-fft-nonquantized-cot --tensor-parallel-size 1 --max-num-batched-tokens 8192 --max-num-seqs 64 ``` -If you have multiple GPUs you can run something like +or if you want to speed up the inference and eval and have multiple GPUs, you can set `--tensor-parallel-size` to the number of your available GPUs, e.g.: ``` -CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 vllm serve fine_tuning/llama31-8b-text2sql-fft-nonquantized-cot --tensor-parallel-size 8 --max-num-batched-tokens 8192 --max-num-seqs 64 +vllm serve fine_tuning/llama31-8b-text2sql-fft-nonquantized-cot --tensor-parallel-size 8 --max-num-batched-tokens 8192 --max-num-seqs 64 ``` -to speed up the eval. - 3. If you haven't downloaded the DEV dataset, download it and unzip it first: ``` From be4817c94b0d8c917dfecc1faabf888ec06719fc Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Tue, 12 Aug 2025 18:32:59 -0700 Subject: [PATCH 71/78] Update FT README.md with llama 3.3 70b on multiple gpus --- .../coding/text2sql/fine-tuning/README.md | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md index 6a1033c87..a6d02796a 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md @@ -166,3 +166,54 @@ llama31-8b-text2sql-peft-quantized-cot The train loss chart should look like this: ![](train_loss_cot.png) + + +## Fine-tuning with Llama 3.3 70B + +If you have 8xH100 GPUs, you can use [torchtune](https://github.com/pytorch/torchtune) to fine-tune Llama 3.3 70B and then evaluate the fine-tuned model. Note that "active development on torchtune" has been stopped ([detail](https://github.com/pytorch/torchtune/issues/2883)), but "Torchtune will continue to receive critical bug fixes and security patches during 2025", so here we just show torchtune as a method to fine-tune the larger Llama 3.3 70B on multiple GPUs. + +``` +pip install torch torchvision torchao +pip install torchtune +tune download meta-llama/Llama-3.3-70B-Instruct --ignore-patterns "original/consolidated*" --output-dir /tmp/Llama-3.3-70B-Instruct +git clone https://github.com/pytorch/torchtune +cd torchtune/tree/main/recipes/configs +``` + +Modify `llama3_3/70B_lora.yaml` as follows: + +``` +output_dir: /tmp/torchtune/llama3_3_70B/lora + +# Dataset and Sampler +dataset: + _component_: torchtune.datasets.chat_dataset + source: json + conversation_column: messages + conversation_style: openai + data_files: train_text2sql_cot_dataset_array.json + #split: train +seed: null +shuffle: True + +# Validation +run_val_every_n_steps: null # Change to an integer to enable validation every N steps +dataset_val: + _component_: torchtune.datasets.chat_dataset + source: json + conversation_column: messages + conversation_style: openai + data_files: test_text2sql_cot_dataset_array.json + #split: validation +batch_size_val: ${batch_size} +``` + +Then run: + +``` +tune run --nproc_per_node 8 lora_finetune_distributed --config llama3_3/70B_lora +``` + +After the fine-tuning is done, cd to `text2sql/fine-tuning` folder, set `peft_model_path` as `/tmp/torchtune/llama3_3_70B/lora` and `output_dir` as `llama3_3_70B/lora`, then run `vllm serve llama3_3_70B/lora --tensor-parallel-size 8 --max-num-batched-tokens 8192 --max-num-seqs 64`. + +Finally, in the `eval/llama_eval.sh`, set `model='llama3_3_70B/lora'`, and run `sh llama_eval.sh`. The accuracy of the fine-tuned Llama 3.3 70B should be around 57.24%, compared with the original 54.11% for off-the-shelf Llama 3.3 70B as shown in the [eval README](../eval#evaluation-results). From af3ea4fe64626768a3c8232c560f2ed43e12e687 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Fri, 22 Aug 2025 10:41:15 -0700 Subject: [PATCH 72/78] script to save dev set in pandas csv format --- .../text2sql/eval/create_bird_eval_dataset.py | 159 ++++++++++++++++++ .../coding/text2sql/eval/llama_eval.sh | 50 ------ 2 files changed, 159 insertions(+), 50 deletions(-) create mode 100644 end-to-end-use-cases/coding/text2sql/eval/create_bird_eval_dataset.py delete mode 100644 end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh diff --git a/end-to-end-use-cases/coding/text2sql/eval/create_bird_eval_dataset.py b/end-to-end-use-cases/coding/text2sql/eval/create_bird_eval_dataset.py new file mode 100644 index 000000000..0807ea40c --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/eval/create_bird_eval_dataset.py @@ -0,0 +1,159 @@ +import argparse +import json +import os +import sqlite3 + +import pandas as pd + +# from datasets import Dataset +from tqdm import tqdm + + +def new_directory(path): + if not os.path.exists(path): + os.makedirs(path) + + +def nice_look_table(column_names: list, values: list): + rows = [] + # Determine the maximum width of each column + widths = [ + max(len(str(value[i])) for value in values + [column_names]) + for i in range(len(column_names)) + ] + + # Print the column names + header = "".join( + f"{column.rjust(width)} " for column, width in zip(column_names, widths) + ) + # print(header) + # Print the values + for value in values: + row = "".join(f"{str(v).rjust(width)} " for v, width in zip(value, widths)) + rows.append(row) + rows = "\n".join(rows) + final_output = header + "\n" + rows + return final_output + + +def generate_schema_prompt(db_path, num_rows=None): + # extract create ddls + """ + :param root_place: + :param db_name: + :return: + """ + full_schema_prompt_list = [] + conn = sqlite3.connect(db_path) + # Create a cursor object + cursor = conn.cursor() + cursor.execute("SELECT name FROM sqlite_master WHERE type='table'") + tables = cursor.fetchall() + schemas = {} + for table in tables: + if table == "sqlite_sequence": + continue + cursor.execute( + "SELECT sql FROM sqlite_master WHERE type='table' AND name='{}';".format( + table[0] + ) + ) + create_prompt = cursor.fetchone()[0] + schemas[table[0]] = create_prompt + if num_rows: + cur_table = table[0] + if cur_table in ["order", "by", "group"]: + cur_table = "`{}`".format(cur_table) + + cursor.execute("SELECT * FROM {} LIMIT {}".format(cur_table, num_rows)) + column_names = [description[0] for description in cursor.description] + values = cursor.fetchall() + rows_prompt = nice_look_table(column_names=column_names, values=values) + verbose_prompt = "/* \n {} example rows: \n SELECT * FROM {} LIMIT {}; \n {} \n */".format( + num_rows, cur_table, num_rows, rows_prompt + ) + schemas[table[0]] = "{} \n {}".format(create_prompt, verbose_prompt) + + for k, v in schemas.items(): + full_schema_prompt_list.append(v) + + schema_prompt = "-- DB Schema: " + "\n\n".join(full_schema_prompt_list) + + return schema_prompt + + +def generate_comment_prompt(question, knowledge=None): + knowledge_prompt = "-- External Knowledge: {}".format(knowledge) + question_prompt = "-- Question: {}".format(question) + + result_prompt = knowledge_prompt + "\n\n" + question_prompt + + return result_prompt + + +def generate_combined_prompts_one(db_path, question, knowledge=None): + schema_prompt = generate_schema_prompt(db_path, num_rows=None) + comment_prompt = generate_comment_prompt(question, knowledge) + + combined_prompts = schema_prompt + "\n\n" + comment_prompt + + return combined_prompts + + +def create_conversation(sample): + return { + "messages": [ + {"role": "system", "content": sample["messages"][0]["content"]}, + {"role": "user", "content": sample["messages"][1]["content"]}, + {"role": "assistant", "content": sample["messages"][2]["content"]}, + ] + } + + +def create_bird_eval_dataset(input_json, db_root_path): + SYSTEM_PROMPT = ( + "You are a text to SQL query translator. Using the SQLite DB Schema and the " + "External Knowledge, translate the following text question into a SQLite SQL " + "select statement." + ) + data = [] + + for i, item in tqdm(enumerate(input_json)): + print(f"processing #{i+1}") + db_id = item["db_id"] + question = item["question"] + external_knowledge = item["evidence"] + SQL = item["SQL"] + db_path = db_root_path + "/" + db_id + "/" + db_id + ".sqlite" + print(f"{db_path=}") + prompt = generate_combined_prompts_one( + db_path, + question, + knowledge=external_knowledge, + ) + + data.append( + { + "prompt": SYSTEM_PROMPT + "\n\n" + prompt, + "gold_sql": SQL, + "db_id": db_id, + } + ) + + df = pd.DataFrame(data) + df.to_csv("bird_dev_set_eval.csv", index=False) + print(f"Dataset saved as bird_dev_set_eval.csv with {len(df)} rows") + + +if __name__ == "__main__": + args_parser = argparse.ArgumentParser() + args_parser.add_argument("--input_json", type=str, required=True) + args_parser.add_argument("--db_root_path", type=str, required=True) + args = args_parser.parse_args() + + input_json = json.load(open(args.input_json, "r")) + db_root_path = args.db_root_path + + create_bird_eval_dataset(input_json, db_root_path) + +# python3 create_bird_eval_dataset.py --input_json ../data/dev_20240627/dev.json --db_root_path ../data/dev_20240627/dev_databases diff --git a/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh b/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh deleted file mode 100644 index 7c5e1f6ba..000000000 --- a/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh +++ /dev/null @@ -1,50 +0,0 @@ -# Set to "true" to enable debug mode with detailed prints -DEBUG_MODE="false" - -eval_path='../data/dev_20240627/dev.json' -db_root_path='../data/dev_20240627/dev_databases/' -ground_truth_path='../data/' - -# Llama models on Llama API -YOUR_API_KEY='YOUR_LLAMA_API_KEY' -model='Llama-3.3-8B-Instruct' -#model='Llama-3.3-70B-Instruct' -#model='Llama-4-Maverick-17B-128E-Instruct-FP8' -#model='Llama-4-Scout-17B-16E-Instruct-FP8' - -# Llama model on Hugging Face Hub https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct -# YOUR_API_KEY='huggingface' -# model='meta-llama/Llama-3.1-8B-Instruct' - -# Fine-tuned Llama models locally -# YOUR_API_KEY='finetuned' -# model='../fine-tuning/llama31-8b-text2sql-fft-nonquantized-cot-epochs-3' - -data_output_path="./output/$model/" - -echo "Text2SQL using $model" - -python3 -u llama_text2sql.py --db_root_path ${db_root_path} --api_key ${YOUR_API_KEY} \ ---model ${model} --eval_path ${eval_path} --data_output_path ${data_output_path} - -# Check if llama_text2sql.py exited successfully -if [ $? -eq 0 ]; then - echo "llama_text2sql.py completed successfully. Proceeding with evaluation..." - - # Add --debug flag if DEBUG_MODE is true - if [ "$DEBUG_MODE" = "true" ]; then - python3 -u text2sql_eval.py --db_root_path ${db_root_path} --predicted_sql_path ${data_output_path} \ - --ground_truth_path ${ground_truth_path} \ - --diff_json_path ${eval_path} --debug - else - python3 -u text2sql_eval.py --db_root_path ${db_root_path} --predicted_sql_path ${data_output_path} \ - --ground_truth_path ${ground_truth_path} \ - --diff_json_path ${eval_path} - fi - - echo "Done evaluating $model." - -else - echo "Error: llama_text2sql.py failed with exit code $?. Skipping evaluation." - exit 1 -fi From 0c7b3482eb41975a1bfbeb85f7020cda9f905323 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Fri, 22 Aug 2025 10:56:15 -0700 Subject: [PATCH 73/78] restored llama_eval.sh --- .../coding/text2sql/eval/llama_eval.sh | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh diff --git a/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh b/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh new file mode 100644 index 000000000..0a4130f1f --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/eval/llama_eval.sh @@ -0,0 +1,49 @@ +# Set to "true" to enable debug mode with detailed prints +DEBUG_MODE="false" + +eval_path='../data/dev_20240627/dev.json' +db_root_path='../data/dev_20240627/dev_databases/' +ground_truth_path='../data/' + +# Llama models on Llama API +# YOUR_API_KEY='YOUR_LLAMA_API_KEY' +# model='Llama-3.3-8B-Instruct' +#model='Llama-3.3-70B-Instruct' +#model='Llama-4-Maverick-17B-128E-Instruct-FP8' +#model='Llama-4-Scout-17B-16E-Instruct-FP8' + +# Llama model on Hugging Face Hub https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct +# YOUR_API_KEY='huggingface' +# model='meta-llama/Llama-3.1-8B-Instruct' + +# Fine-tuned Llama models locally +YOUR_API_KEY='finetuned' +model='../fine-tuning/llama31-8b-text2sql-fft-nonquantized-cot-epochs-3' + +data_output_path="./output/$model/" + +echo "Text2SQL using $model" +python3 -u llama_text2sql.py --db_root_path ${db_root_path} --api_key ${YOUR_API_KEY} \ +--model ${model} --eval_path ${eval_path} --data_output_path ${data_output_path} + +# Check if llama_text2sql.py exited successfully +if [ $? -eq 0 ]; then + echo "llama_text2sql.py completed successfully. Proceeding with evaluation..." + + # Add --debug flag if DEBUG_MODE is true + if [ "$DEBUG_MODE" = "true" ]; then + python3 -u text2sql_eval.py --db_root_path ${db_root_path} --predicted_sql_path ${data_output_path} \ + --ground_truth_path ${ground_truth_path} \ + --diff_json_path ${eval_path} --debug + else + python3 -u text2sql_eval.py --db_root_path ${db_root_path} --predicted_sql_path ${data_output_path} \ + --ground_truth_path ${ground_truth_path} \ + --diff_json_path ${eval_path} + fi + + echo "Done evaluating $model." + +else + echo "Error: llama_text2sql.py failed with exit code $?. Skipping evaluation." + exit 1 +fi From 54e49bca09f76aa2eedb7bbf58422bfed935574a Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Fri, 22 Aug 2025 10:59:33 -0700 Subject: [PATCH 74/78] added steps to run create_bird_eval_dataset.py --- .../coding/text2sql/eval/create_bird_eval_dataset.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/end-to-end-use-cases/coding/text2sql/eval/create_bird_eval_dataset.py b/end-to-end-use-cases/coding/text2sql/eval/create_bird_eval_dataset.py index 0807ea40c..892ed4620 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/create_bird_eval_dataset.py +++ b/end-to-end-use-cases/coding/text2sql/eval/create_bird_eval_dataset.py @@ -156,4 +156,6 @@ def create_bird_eval_dataset(input_json, db_root_path): create_bird_eval_dataset(input_json, db_root_path) +# follow steps 1 and 2 here https://github.com/meta-llama/llama-cookbook/tree/text2sql/end-to-end-use-cases/coding/text2sql/eval#quick-start-with-llama-models-via-llama-api +# then run: # python3 create_bird_eval_dataset.py --input_json ../data/dev_20240627/dev.json --db_root_path ../data/dev_20240627/dev_databases From c88e10fab69dacf01da00570916ab0a8e0ab488c Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Mon, 6 Oct 2025 17:17:24 -0700 Subject: [PATCH 75/78] grpo llama 3.2 3b with 3 reward functions --- .../fine-tuning/grpo/deepspeed_zero3.yaml | 22 + .../grpo/grpo-llama323b-text2sql.yaml | 72 +++ .../fine-tuning/grpo/grpo_text2sql.py | 537 ++++++++++++++++++ .../fine-tuning/grpo/requirements.txt | 13 + 4 files changed, 644 insertions(+) create mode 100644 end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/deepspeed_zero3.yaml create mode 100644 end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo-llama323b-text2sql.yaml create mode 100644 end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo_text2sql.py create mode 100644 end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/requirements.txt diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/deepspeed_zero3.yaml b/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/deepspeed_zero3.yaml new file mode 100644 index 000000000..b5a1201f8 --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/deepspeed_zero3.yaml @@ -0,0 +1,22 @@ +compute_environment: LOCAL_MACHINE +debug: false +deepspeed_config: + deepspeed_multinode_launcher: standard + offload_optimizer_device: none + offload_param_device: none + zero3_init_flag: true + zero3_save_16bit_model: true + zero_stage: 3 +distributed_type: DEEPSPEED +downcast_bf16: 'no' +machine_rank: 0 +main_training_function: main +mixed_precision: bf16 +num_machines: 1 +num_processes: 8 +rdzv_backend: static +same_network: true +tpu_env: [] +tpu_use_cluster: false +tpu_use_sudo: false +use_cpu: false diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo-llama323b-text2sql.yaml b/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo-llama323b-text2sql.yaml new file mode 100644 index 000000000..b5f27a49b --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo-llama323b-text2sql.yaml @@ -0,0 +1,72 @@ +# Model arguments +model_name_or_path: meta-llama/Llama-3.2-3B-Instruct +model_revision: main +torch_dtype: bfloat16 +attn_implementation: flash_attention_2 +bf16: true +tf32: true +output_dir: runs/llama-3.2-3b-grpo-text2sql-alltrain-lr5-ng8 + +# Lora Arguments +# No LoRA is used here + +# Training arguments +max_steps: 500 # 1000 #500 +per_device_train_batch_size: 1 +gradient_accumulation_steps: 8 +gradient_checkpointing: true +gradient_checkpointing_kwargs: + use_reentrant: false +learning_rate: 5.0e-7 # 1.0e-6 # 5.0e-7 # 1.0e-6 as in the deepseek math paper 5-e7 from https://hijkzzz.notion.site/unraveling-rlhf-and-its-variants-engineering-insights#147d9a33ecc9806090f3d5c749d31f05 +lr_scheduler_type: cosine +warmup_ratio: 0.03 +# GRPO specific parameters +beta: 0.001 # 0.04 as in the deepseek math paper 0.001 from https://hijkzzz.notion.site/unraveling-rlhf-and-its-variants-engineering-insights#147d9a33ecc9806090f3d5c749d31f05 +max_prompt_length: 512 # 256 +max_completion_length: 1024 +num_generations: 8 # 6 # 8 +use_vllm: true + +# Reward function weights +# Order: [format_reward_func, execution_reward_func, ensemble_n_gram_reward_func] +reward_weights: [1.0, 3.0, 1.0] +# **Recommended Weight Strategy** +# Current Setting: `[1.0, 3.0, 1.0]`** +# * **Format reward (1.0)**: Standard weight since format correctness is binary but essential +# * **Execution reward (3.0)**: **Highest weight** - SQL execution correctness is most important for text2sql +# * **N-gram similarity (1.0)**: Standard weight for syntactic similarity + +# **Alternative Weight Strategies** +# **Conservative approach: `[2.0, 4.0, 1.0]`** +# * Emphasizes both format and execution correctness +# * Lower weight on similarity metrics +# **Balanced approach: `[1.5, 2.0, 1.5]`** +# * More balanced across all three metrics +# * Good for early training stages +# **Similarity-focused: `[1.0, 2.0, 2.0]`** +# * Higher weight on N-gram similarity +# * Useful if execution often fails initially + + +vllm_device: "cuda:0" # use vLLM for generation and DeepSpeed for distributed training. +# Set the num_processes to the number of GPUs you have - +# the last one will be used with vLLM for Generation. +# if you have 6 GPUs, set vllm_device to "cuda:5" (or 5?) and +# num_processes to 5 (or 6? in which case, 6th GPU will be used +# for both generation and training + +vllm_gpu_memory_utilization: 0.5 + +# Logging arguments +logging_strategy: steps +logging_steps: 2 +report_to: +- tensorboard +save_strategy: "steps" +save_steps: 50 +seed: 42 + +# Hugging Face Hub +push_to_hub: false + # hub_model_id: llama-3-1-8b-math-orca-qlora-10k-ep1 # if not defined same as output_dir +hub_strategy: every_save diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo_text2sql.py b/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo_text2sql.py new file mode 100644 index 000000000..96bdaedd6 --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo_text2sql.py @@ -0,0 +1,537 @@ +import json +import logging + +import os +import random +import re +import sqlite3 +import sys +from dataclasses import dataclass +from datetime import datetime +from typing import List + +from datasets import Dataset +from func_timeout import func_timeout, FunctionTimedOut +from tqdm import tqdm +from transformers import AutoTokenizer +from transformers.trainer_utils import get_last_checkpoint +from trl import get_peft_config, GRPOConfig, GRPOTrainer, ModelConfig, TrlParser + +os.environ["HF_HUB_ENABLE_HF_TRANSFER"] = "1" +TRAIN_JSON = "../../data/train/train.json" +DB_ROOT_PATH = "../../data/train/train_databases/" +LOG_REWARD_FILE_NAME = "text2sql_grpo_rewards5.log" +COMPLETION_SAMPLE_TXT_FILE_NAME = "completion_samples5.txt" + + +def load_json(dir): + with open(dir, "r") as j: + contents = json.loads(j.read()) + return contents + + +def execute_sql(predicted_sql, ground_truth_dbid): + ground_truth, db_name = ground_truth_dbid.split("\t----- bird -----\t") + + # print(f"\n==== execute_sql ====\n{predicted_sql=}\n{ground_truth=}") + + db_path = DB_ROOT_PATH + db_name + "/" + db_name + ".sqlite" + conn = sqlite3.connect(db_path) + # Connect to the database + cursor = conn.cursor() + cursor.execute(predicted_sql) + predicted_res = cursor.fetchall() + cursor.execute(ground_truth) + ground_truth_res = cursor.fetchall() + res = 0 + + if set(predicted_res) == set(ground_truth_res): + res = 1 + print("execution result same") + else: + print("execution result different") + conn.close() + + return res + + +@dataclass +class ScriptArguments: + tokenizer_name_or_path: str = None + + +######################## +# Setup logging +######################## +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) +logger.setLevel(logging.INFO) +handler = logging.StreamHandler() +handler.setFormatter( + logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") +) +logger.addHandler(handler) + +######################## +# Helper functions +######################## + + +def log_reward(reason, completion, gt): + import os + + os.makedirs("logs", exist_ok=True) + log_file = os.path.join("logs", LOG_REWARD_FILE_NAME) + with open(log_file, "a") as f: + f.write("\n\n==============\n") + f.write(f">>>{reason=}\n>>>{completion=}\n>>>{gt=}\n") + + +def extract_answer(text): + """ + Extracts the final SQL statement answer from the raw text. + """ + try: + match = re.search(r"#### (\-?[\d\.,$]+)", text) + if match: + matched_string = match.group(1) + + # Remove any characters that would cause a ValueError, + # such as dollar signs ($) and commas (,) + cleaned_string = re.sub(r"[$,]", "", matched_string) + + return float(cleaned_string) + + match = re.search( + r"(?:The final answer is|The answer is):?\s*(\-?[\d\.,$]+)", + text, + re.IGNORECASE, + ) + if match: + matched_string = match.group(1) + cleaned_string = re.sub(r"[$,]", "", matched_string) + return float(cleaned_string) + + except (ValueError, AttributeError): + print(f"Error extracting answer from text: {match.group(1)}") + pass + return None + + +def format_reward_func(completions, answer, **kwargs): + """ + Format: ...... + Args: + completions (list[str]): Generated outputs + answer (list[str]): Expected answers + + Returns: + list[float]: Reward scores + """ + rewards = [] + + for completion, gt in zip(completions, answer): + + try: + if random.random() < 0.1: # 1% chance to write samples into a file + os.makedirs("completion_samples", exist_ok=True) + log_file = os.path.join( + "completion_samples", COMPLETION_SAMPLE_TXT_FILE_NAME + ) + with open(log_file, "a") as f: + f.write(f"\n\n==============\n") + f.write(completion) + + # Check if the format is correct + regex = r"([^<]*(?:<(?!/?think>)[^<]*)*)<\/think>\s*([\s\S]*?)<\/answer>$" + + match = re.search(regex, completion, re.DOTALL) + # if the format is not correct, reward is 0 + if match is None or len(match.groups()) != 2: + rewards.append(0.0) + log_reward("format_reward 0", completion, gt) + else: + rewards.append(1.0) + log_reward("format_reward 1", completion, gt) + except Exception as e: + rewards.append(0.0) + log_reward(f"format_reward 0 - exception {e=}", completion, gt) + return rewards + + +def execution_reward_func(completions, answer, **kwargs): + """ + Evaluates completions based on SQL statement execution result + + Args: + completions (list[str]): Generated outputs + answer (list[str]): Ground truth answers (from content with "role":"assistant" in train_text2sql_sft_dataset.json) + + Returns: + list[float]: Reward scores + """ + rewards = [] + for completion, gt in zip(completions, answer): + try: + # gt = extract_answer(gt) + match = re.search(r"(.*?)<\/answer>", completion) + if match is None: + rewards.append(0.0) + log_reward("execution_reward 0 - no answer tag found", completion, gt) + continue + # Extract the "answer" part from the completion + predicted_sql = match.group(1).strip() + + reason = "execution result different" + # execute the sql_generated and gt and compare the results + try: + res = func_timeout( + 30.0, + execute_sql, + args=(predicted_sql, gt), + ) + except KeyboardInterrupt: + sys.exit(0) + except FunctionTimedOut: + print("FunctionTimedOut") + reason = "execution timeout" + res = 0 + except Exception as e: + print("Exception", e) + reason = f"execution exception {e}" + res = 0 + + if res == 1: + # reason = "execution result same" + rewards.append(1.0) + log_reward("execution_reward 1", completion, gt) + else: + rewards.append(0.0) + log_reward( + f"execution_reward 0 {reason=}, {predicted_sql=}", + completion, + gt, + ) + + except Exception as e: + # If evaluation fails, reward is 0 + rewards.append(0.0) + log_reward(f"execution_reward 0 - exception {e=}", completion, gt) + + return rewards + + +def get_ngrams(tokens: List[str], n: int) -> set: + """Generates a set of n-grams from a list of tokens.""" + # Ensure there are enough tokens to create at least one n-gram + if len(tokens) < n: + return set() + return {tuple(tokens[i : i + n]) for i in range(len(tokens) - n + 1)} + + +def n_gram_jaccard_similarity(candidate_query: str, gold_query: str, n: int) -> float: + """Calculates the n-gram Jaccard similarity for a single n.""" + # Tokenize the SQL queries. Using .lower() for case-insensitivity. + candidate_tokens = candidate_query.lower().split() + gold_tokens = gold_query.lower().split() + + # Get the n-grams for both sets of tokens. + candidate_ngrams = get_ngrams(candidate_tokens, n) + gold_ngrams = get_ngrams(gold_tokens, n) + + # Handle the edge case where one or both sets are empty. + if not candidate_ngrams and not gold_ngrams: + return 1.0 + if not candidate_ngrams or not gold_ngrams: + return 0.0 + + # Calculate Jaccard similarity. + intersection = len(candidate_ngrams.intersection(gold_ngrams)) + union = len(candidate_ngrams.union(gold_ngrams)) + + return intersection / union + + +def ensemble_n_gram_reward_func(completions, answer, **kwargs): + """ + Calculates the averaged ensemble n-gram Jaccard similarity reward. + This function computes the Jaccard similarity for n=1, 2, and 3 + and returns the average score for each sample. + + Args: + completions (list[str]): Generated outputs + answer (list[str]): Ground truth answers (from content with "role":"assistant" in train_text2sql_sft_dataset.json) + + Returns: + list[float]: Reward scores + """ + + rewards = [] + + for completion, gt in zip(completions, answer): + try: + match = re.search(r"(.*?)<\/answer>", completion) + if match is None: + rewards.append(0.0) + log_reward("n_gram_reward 0 - no answer tag found", completion, gt) + continue + # Extract the "answer" part from the completion + predicted_sql = match.group(1).strip() + + # Calculate Jaccard similarity for n=1, 2, and 3 + jaccard_1 = n_gram_jaccard_similarity(predicted_sql, gt, n=1) + jaccard_2 = n_gram_jaccard_similarity(predicted_sql, gt, n=2) + jaccard_3 = n_gram_jaccard_similarity(predicted_sql, gt, n=3) + + # Average the scores to get the final ensemble reward + average_jaccard = (jaccard_1 + jaccard_2 + jaccard_3) / 3.0 + rewards.append(average_jaccard) + except Exception as e: + rewards.append(0.0) + log_reward(f"n_gram_reward 0 - exception {e=}", completion, gt) + + return rewards + + +def get_checkpoint(training_args: GRPOConfig): + last_checkpoint = None + if os.path.isdir(training_args.output_dir): + last_checkpoint = get_last_checkpoint(training_args.output_dir) + return last_checkpoint + + +def generate_schema_prompt(db_path, num_rows=None): + # extract create ddls + """ + :param root_place: + :param db_name: + :return: + """ + full_schema_prompt_list = [] + conn = sqlite3.connect(db_path) + # Create a cursor object + cursor = conn.cursor() + cursor.execute("SELECT name FROM sqlite_master WHERE type='table'") + tables = cursor.fetchall() + schemas = {} + for table in tables: + if table == "sqlite_sequence": + continue + cursor.execute( + "SELECT sql FROM sqlite_master WHERE type='table' AND name='{}';".format( + table[0] + ) + ) + create_prompt = cursor.fetchone()[0] + schemas[table[0]] = create_prompt + if num_rows: + cur_table = table[0] + if cur_table in ["order", "by", "group"]: + cur_table = "`{}`".format(cur_table) + + cursor.execute("SELECT * FROM {} LIMIT {}".format(cur_table, num_rows)) + column_names = [description[0] for description in cursor.description] + values = cursor.fetchall() + rows_prompt = nice_look_table(column_names=column_names, values=values) + verbose_prompt = "/* \n {} example rows: \n SELECT * FROM {} LIMIT {}; \n {} \n */".format( + num_rows, cur_table, num_rows, rows_prompt + ) + schemas[table[0]] = "{} \n {}".format(create_prompt, verbose_prompt) + + for k, v in schemas.items(): + full_schema_prompt_list.append(v) + + schema_prompt = "-- DB Schema: " + "\n\n".join(full_schema_prompt_list) + + return schema_prompt + + +def generate_comment_prompt(question, knowledge=None): + knowledge_prompt = "-- External Knowledge: {}".format(knowledge) + question_prompt = "-- Question: {}".format(question) + + result_prompt = knowledge_prompt + "\n\n" + question_prompt + + return result_prompt + + +def generate_combined_prompts_one(db_path, question, knowledge=None): + schema_prompt = generate_schema_prompt(db_path, num_rows=None) + comment_prompt = generate_comment_prompt(question, knowledge) + + combined_prompts = schema_prompt + "\n\n" + comment_prompt + + return combined_prompts + + +def grpo_function( + model_args: ModelConfig, script_args: ScriptArguments, training_args: GRPOConfig +): + + logger.info(f"Model parameters {model_args}") + logger.info(f"Training/evaluation parameters {training_args}") + + tokenizer = AutoTokenizer.from_pretrained( + ( + script_args.tokenizer_name_or_path + if script_args.tokenizer_name_or_path + else model_args.model_name_or_path + ), + revision=model_args.model_revision, + trust_remote_code=model_args.trust_remote_code, + ) + if tokenizer.pad_token is None: + tokenizer.pad_token = tokenizer.eos_token + + ds = [] + SYSTEM_PROMPT = "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement." + + input_json = json.load(open(TRAIN_JSON, "r")) + + for i, item in tqdm(enumerate(input_json)): + print(f"processing #{i+1}") + db_id = item["db_id"] + question = item["question"] + external_knowledge = item["evidence"] + SQL = item["SQL"] + db_path = DB_ROOT_PATH + "/" + db_id + "/" + db_id + ".sqlite" + prompt = generate_combined_prompts_one( + db_path, + question, + knowledge=external_knowledge, + ) + + example = { + "messages": [ + {"role": "system", "content": SYSTEM_PROMPT}, + {"role": "user", "content": prompt}, + {"role": "assistant", "content": SQL + "\t----- bird -----\t" + db_id}, + ] + } + + ds.append(example) + + dataset_dict = {key: [d[key] for d in ds] for key in ds[0]} + dataset = Dataset.from_dict(dataset_dict) + + def generate_r1_prompt(system_prompt, user_prompt, ground_truth): + r1_prefix = [ + { + "role": "system", + "content": """You are great at reasoning and translating natural language question to SQLite SQL query. Given DB Schema, External Knowledge, and Question, your task is to first generate step-by-step reasoning, then apply the resoning to generate the SQLite select statement as the accurate translation of the Question. Enclose the step-by-step reasoning within the tags, and the final SQL statement within the tags, i.e. reasoning steps final SQL .""", + }, + {"role": "user", "content": user_prompt}, + ] + + return { + "prompt": tokenizer.apply_chat_template( + r1_prefix, tokenize=False, continue_final_message=True + ), + "answer": ground_truth, + } + + # convert our dataset to the r1 prompt + dataset = dataset.map( + lambda x: generate_r1_prompt( + x["messages"][0]["content"], + x["messages"][1]["content"], + x["messages"][2]["content"], + ), + remove_columns=dataset.column_names, # Remove original columns to avoid conflicts with apply_chat_template + ) + + # split the dataset into train and test + train_test_split = dataset.train_test_split(test_size=0.3) + + train_dataset = train_test_split["train"] + eval_dataset = train_test_split["test"] + print("len(train_dataset)", len(train_dataset)) + print(train_dataset[0]) + print("len(eval_dataset)", len(eval_dataset)) + print(eval_dataset[0]) + + ######################### + # Instantiate DPO trainer + ######################### + + trainer = GRPOTrainer( + model=model_args.model_name_or_path, + reward_funcs=[ + format_reward_func, + execution_reward_func, + ensemble_n_gram_reward_func, + ], + args=training_args, + train_dataset=train_dataset, + eval_dataset=eval_dataset, + peft_config=get_peft_config(model_args), + ) + + trainer.tokenizer = tokenizer + + ############### + # Training loop + ############### + # Check for last checkpoint + last_checkpoint = get_checkpoint(training_args) + # JT: by default training_args.resume_from_checkpoint is None + if last_checkpoint is not None and training_args.resume_from_checkpoint is None: + logger.info(f"Checkpoint detected, resuming training at {last_checkpoint}.") + + # Train the model + logger.info( + f'*** Starting training {datetime.now().strftime("%Y-%m-%d %H:%M:%S")} for {training_args.num_train_epochs} epochs***' + ) + train_result = trainer.train(resume_from_checkpoint=last_checkpoint) + # Log and save metrics + metrics = train_result.metrics + metrics["train_samples"] = len(train_dataset) + trainer.log_metrics("train", metrics) + trainer.save_metrics("train", metrics) + trainer.save_state() + + logger.info("*** Training complete ***") + + ################################## + # Save model and create model card + ################################## + + logger.info("*** Save model ***") + trainer.model.config.use_cache = True + trainer.save_model(training_args.output_dir) + logger.info(f"Model saved to {training_args.output_dir}") + training_args.distributed_state.wait_for_everyone() # wait for all processes to load + + tokenizer.save_pretrained(training_args.output_dir) + logger.info(f"Tokenizer saved to {training_args.output_dir}") + + # Save everything else on main process + # if trainer.accelerator.is_main_process: + # trainer.create_model_card({"tags": ["rl", "grpo", "tutorial", "philschmid"]}) + # push to hub if needed + # if training_args.push_to_hub is True: + # logger.info("Pushing to hub...") + # trainer.push_to_hub() + + logger.info("*** Training complete! ***") + + +def main(): + parser = TrlParser((ModelConfig, ScriptArguments, GRPOConfig)) + model_args, script_args, training_args = parser.parse_args_and_config() + # print("model_args", model_args) + # print("script_args", script_args) + # print("training_args", training_args) + # exit() + + # Run the main training loop + grpo_function(model_args, script_args, training_args) + + +if __name__ == "__main__": + main() + +# two ways to run this script: +# with-proxy accelerate launch --num_processes 8 --config_file deepspeed_zero3.yaml grpo_text2sql.py --config grpo-llama323b-text2sql.yaml + +# with-proxy nohup accelerate launch --num_processes 4 --config_file deepspeed_zero3.yaml grpo_text2sql.py --config grpo-llama323b-text2sql.yaml & diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/requirements.txt b/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/requirements.txt new file mode 100644 index 000000000..8951d7b54 --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/requirements.txt @@ -0,0 +1,13 @@ +torch==2.5.1 +tensorboard==2.19.0 +setuptools==70.3.0 +flash-attn==2.7.4.post1 +transformers==4.48.1 +datasets==3.1.0 +accelerate==1.3.0 +hf-transfer==0.1.9 +deepspeed==0.15.4 +trl==0.14.0 +peft==0.15.2 +vllm==0.7.0 +func_timeout==4.3.5 From 57c05170ebfd3cb0f7fa2fb10545bd8232fcb4c8 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Tue, 7 Oct 2025 19:06:11 -0700 Subject: [PATCH 76/78] added llm as a judge reward func --- .../grpo/grpo-llama323b-text2sql.yaml | 6 +- .../fine-tuning/grpo/grpo_text2sql.py | 143 +++++++++++++++++- .../fine-tuning/grpo/requirements.txt | 1 + 3 files changed, 142 insertions(+), 8 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo-llama323b-text2sql.yaml b/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo-llama323b-text2sql.yaml index b5f27a49b..d1db9de28 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo-llama323b-text2sql.yaml +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo-llama323b-text2sql.yaml @@ -5,13 +5,13 @@ torch_dtype: bfloat16 attn_implementation: flash_attention_2 bf16: true tf32: true -output_dir: runs/llama-3.2-3b-grpo-text2sql-alltrain-lr5-ng8 +output_dir: runs/llama-3.2-3b-grpo-text2sql-3rewards-6gpu # Lora Arguments # No LoRA is used here # Training arguments -max_steps: 500 # 1000 #500 +max_steps: 750 # 1000 #500 per_device_train_batch_size: 1 gradient_accumulation_steps: 8 gradient_checkpointing: true @@ -46,7 +46,7 @@ reward_weights: [1.0, 3.0, 1.0] # **Similarity-focused: `[1.0, 2.0, 2.0]`** # * Higher weight on N-gram similarity # * Useful if execution often fails initially - +# final_reward = format_reward*1.0 + execution_reward*3.0 + ngram_reward*1.0 vllm_device: "cuda:0" # use vLLM for generation and DeepSpeed for distributed training. # Set the num_processes to the number of GPUs you have - diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo_text2sql.py b/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo_text2sql.py index 96bdaedd6..0623835b9 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo_text2sql.py +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo_text2sql.py @@ -12,6 +12,7 @@ from datasets import Dataset from func_timeout import func_timeout, FunctionTimedOut +from together import Together from tqdm import tqdm from transformers import AutoTokenizer from transformers.trainer_utils import get_last_checkpoint @@ -267,8 +268,16 @@ def ensemble_n_gram_reward_func(completions, answer, **kwargs): """ rewards = [] - - for completion, gt in zip(completions, answer): + questions = kwargs.get("question") + evidences = kwargs.get("evidence") + + for completion, gt, question, evidence in zip( + completions, answer, questions, evidences + ): + # print(f">>>>>ensemble_n_gram_reward_func: {gt=}") + # print(f">>>>>ensemble_n_gram_reward_func: {completion=}") + # print(f">>>>>ensemble_n_gram_reward_func: {question=}") + # print(f">>>>>ensemble_n_gram_reward_func: {evidence=}") try: match = re.search(r"(.*?)<\/answer>", completion) if match is None: @@ -285,6 +294,7 @@ def ensemble_n_gram_reward_func(completions, answer, **kwargs): # Average the scores to get the final ensemble reward average_jaccard = (jaccard_1 + jaccard_2 + jaccard_3) / 3.0 + print(f"{average_jaccard=}") rewards.append(average_jaccard) except Exception as e: rewards.append(0.0) @@ -293,6 +303,118 @@ def ensemble_n_gram_reward_func(completions, answer, **kwargs): return rewards +def llm_as_a_judge_reward_func(completions, answer, **kwargs): + """ + Use Llama 3.3 70b as a judge to evaluate the quality of the generated SQL statements by comparing them to the ground truth answers. + + Args: + completions (list[str]): Generated outputs + answer (list[str]): Ground truth answers (from content with "role":"assistant" in train_text2sql_sft_dataset.json) + + Returns: + list[float]: Reward scores + """ + + rewards = [] + + client = Together() + PROMPT_TEMPLATE = """ +You are an experienced database expert. Your task is to evaluate a generated SQL query by comparing it +to the ground truth (gold) query and then assign a score between 0.0 and 2.0. A higher score indicates +the predicted query is more correct, while a score of 0.0 means it is completely incorrect. + +Follow these evaluation rules strictly: + +1. SELECT Clause: +• Only select columns that are mentioned in the user’s question. +• Do not include unnecessary columns or values. + +2. Aggregation (MAX/MIN): +• Always perform JOINs before applying MAX() or MIN(). + +3. ORDER BY with Distinct Values: +• Use a GROUP BY before an ORDER BY ASC|DESC to ensure +distinct values. + +4. Handling NULLs: +• If a column may contain NULL values (indicated by "None" in value examples +or explicitly mentioned), include a JOIN or a WHERE IS NOT NULL +clause. + +5. FROM/JOIN Clauses: +• Only include the tables essential for answering the question. + +6. Strictly Follow Hints: +• Adhere to all hints provided with the question. + +7. Thorough Question Analysis: +• Ensure all conditions and requirements mentioned in the question are ad- +dressed. + +8. DISTINCT Keyword: +• Use SELECT DISTINCTwhen the question requires unique values (e.g., IDs, URLs) +or when column statistics (Value Statics) indicate its necessity. + +9. Column Selection: +• Carefully analyze column descriptions and hints to choose the correct column +when similar columns exist across tables. + +10. String Concatenation: +• Do not use any string concatenation methods (e.g., || ’ ’ ||) in the SELECT +clause. + +11. JOIN Preference: +• Prefer using INNER JOINover nested SELECT statements. + +12. Date Processing: +• Use STRFTIME()for any date manipulations (e.g., STRFTIME(’%Y’, SOMETIME)to +extract the year). + +You are provided with the following inputs: +• Question: {QUESTION} +• Hint: {HINT} +• Gold Query: {GOLD_QUERY} +• Predicted Query: {PREDICTED_QUERY} + +Based on the above, return a single numeric score between 0.0 and 2.0 that reflects how +correct the predicted query is compared to the gold query. Respond with only the score and +no additional explanation. +""" + + questions = kwargs.get("question") + evidences = kwargs.get("evidence") + for completion, gt, question, evidence in zip( + completions, answer, questions, evidences + ): + try: + match = re.search(r"(.*?)<\/answer>", completion) + if match is None: + rewards.append(0.0) + log_reward( + "llm_as_a_judge_reward_func 0 - no answer tag found", completion, gt + ) + continue + # Extract the "answer" part from the completion + predicted_sql = match.group(1).strip() + prompt = PROMPT_TEMPLATE.format( + QUESTION=question, + HINT=evidence, + GOLD_QUERY=gt, + PREDICTED_QUERY=predicted_sql, + ) + response = client.chat.completions.create( + model="meta-llama/Llama-3.3-70B-Instruct-Turbo", + messages=[{"role": "user", "content": prompt}], + temperature=0, + ) + rewards.append(float(response.choices[0].message.content)) + except Exception as e: + rewards.append(0.0) + log_reward(f"llm_as_a_judge_reward_func 0 - exception {e=}", completion, gt) + + return rewards + + def get_checkpoint(training_args: GRPOConfig): last_checkpoint = None if os.path.isdir(training_args.output_dir): @@ -332,7 +454,10 @@ def generate_schema_prompt(db_path, num_rows=None): cursor.execute("SELECT * FROM {} LIMIT {}".format(cur_table, num_rows)) column_names = [description[0] for description in cursor.description] values = cursor.fetchall() - rows_prompt = nice_look_table(column_names=column_names, values=values) + # Format the rows as a simple table representation + rows_prompt = "\n".join( + "\t".join(str(val) for val in row) for row in values + ) verbose_prompt = "/* \n {} example rows: \n SELECT * FROM {} LIMIT {}; \n {} \n */".format( num_rows, cur_table, num_rows, rows_prompt ) @@ -406,7 +531,9 @@ def grpo_function( {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": prompt}, {"role": "assistant", "content": SQL + "\t----- bird -----\t" + db_id}, - ] + ], + "question": question, + "evidence": external_knowledge, } ds.append(example) @@ -414,7 +541,9 @@ def grpo_function( dataset_dict = {key: [d[key] for d in ds] for key in ds[0]} dataset = Dataset.from_dict(dataset_dict) - def generate_r1_prompt(system_prompt, user_prompt, ground_truth): + def generate_r1_prompt( + system_prompt, user_prompt, ground_truth, question, evidence + ): r1_prefix = [ { "role": "system", @@ -428,6 +557,8 @@ def generate_r1_prompt(system_prompt, user_prompt, ground_truth): r1_prefix, tokenize=False, continue_final_message=True ), "answer": ground_truth, + "question": question, + "evidence": evidence, } # convert our dataset to the r1 prompt @@ -436,6 +567,8 @@ def generate_r1_prompt(system_prompt, user_prompt, ground_truth): x["messages"][0]["content"], x["messages"][1]["content"], x["messages"][2]["content"], + x["question"], + x["evidence"], ), remove_columns=dataset.column_names, # Remove original columns to avoid conflicts with apply_chat_template ) diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/requirements.txt b/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/requirements.txt index 8951d7b54..91127851d 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/requirements.txt +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/requirements.txt @@ -11,3 +11,4 @@ trl==0.14.0 peft==0.15.2 vllm==0.7.0 func_timeout==4.3.5 +together==1.5.26 From 7edf3d8df086dd4cb2311f3d90cba6de9c443896 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Wed, 8 Oct 2025 18:19:16 -0700 Subject: [PATCH 77/78] llm as a judge running now --- .../grpo/grpo-llama323b-text2sql.yaml | 4 +-- .../fine-tuning/grpo/grpo_text2sql.py | 26 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo-llama323b-text2sql.yaml b/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo-llama323b-text2sql.yaml index d1db9de28..e8eace639 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo-llama323b-text2sql.yaml +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo-llama323b-text2sql.yaml @@ -5,7 +5,7 @@ torch_dtype: bfloat16 attn_implementation: flash_attention_2 bf16: true tf32: true -output_dir: runs/llama-3.2-3b-grpo-text2sql-3rewards-6gpu +output_dir: runs/llama-3.2-3b-grpo-text2sql-4rewards-6gpu # Lora Arguments # No LoRA is used here @@ -29,7 +29,7 @@ use_vllm: true # Reward function weights # Order: [format_reward_func, execution_reward_func, ensemble_n_gram_reward_func] -reward_weights: [1.0, 3.0, 1.0] +reward_weights: [1.0, 3.0, 1.0, 1.0] # **Recommended Weight Strategy** # Current Setting: `[1.0, 3.0, 1.0]`** # * **Format reward (1.0)**: Standard weight since format correctness is binary but essential diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo_text2sql.py b/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo_text2sql.py index 0623835b9..b78fa7e05 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo_text2sql.py +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo_text2sql.py @@ -274,10 +274,6 @@ def ensemble_n_gram_reward_func(completions, answer, **kwargs): for completion, gt, question, evidence in zip( completions, answer, questions, evidences ): - # print(f">>>>>ensemble_n_gram_reward_func: {gt=}") - # print(f">>>>>ensemble_n_gram_reward_func: {completion=}") - # print(f">>>>>ensemble_n_gram_reward_func: {question=}") - # print(f">>>>>ensemble_n_gram_reward_func: {evidence=}") try: match = re.search(r"(.*?)<\/answer>", completion) if match is None: @@ -407,7 +403,9 @@ def llm_as_a_judge_reward_func(completions, answer, **kwargs): messages=[{"role": "user", "content": prompt}], temperature=0, ) - rewards.append(float(response.choices[0].message.content)) + reward = float(response.choices[0].message.content) + print(f"llm_as_a_judge_reward_func>>> {reward=}") + rewards.append(reward) except Exception as e: rewards.append(0.0) log_reward(f"llm_as_a_judge_reward_func 0 - exception {e=}", completion, gt) @@ -593,6 +591,7 @@ def generate_r1_prompt( format_reward_func, execution_reward_func, ensemble_n_gram_reward_func, + llm_as_a_judge_reward_func, ], args=training_args, train_dataset=train_dataset, @@ -607,7 +606,7 @@ def generate_r1_prompt( ############### # Check for last checkpoint last_checkpoint = get_checkpoint(training_args) - # JT: by default training_args.resume_from_checkpoint is None + # by default training_args.resume_from_checkpoint is None if last_checkpoint is not None and training_args.resume_from_checkpoint is None: logger.info(f"Checkpoint detected, resuming training at {last_checkpoint}.") @@ -652,10 +651,6 @@ def generate_r1_prompt( def main(): parser = TrlParser((ModelConfig, ScriptArguments, GRPOConfig)) model_args, script_args, training_args = parser.parse_args_and_config() - # print("model_args", model_args) - # print("script_args", script_args) - # print("training_args", training_args) - # exit() # Run the main training loop grpo_function(model_args, script_args, training_args) @@ -664,7 +659,12 @@ def main(): if __name__ == "__main__": main() -# two ways to run this script: -# with-proxy accelerate launch --num_processes 8 --config_file deepspeed_zero3.yaml grpo_text2sql.py --config grpo-llama323b-text2sql.yaml +# before running this script, make sure you set the following environment variable +# so the reward of using LLM as a judge can be calculated: +# export TOGETHER_API_KEY= -# with-proxy nohup accelerate launch --num_processes 4 --config_file deepspeed_zero3.yaml grpo_text2sql.py --config grpo-llama323b-text2sql.yaml & +# two ways to run this script, assuming you have 6 GPUs to use for the training + +# with-proxy accelerate launch --num_processes 6 --gpu_ids 2,3,4,5,6,7 --config_file deepspeed_zero3.yaml grpo_text2sql.py --config grpo-llama323b-text2sql.yaml + +# with-proxy nohup accelerate launch --num_processes 6 --gpu_ids 2,3,4,5,6,7 --config_file deepspeed_zero3.yaml grpo_text2sql.py --config grpo-llama323b-text2sql.yaml & From 8989e699371acb3a32b6367144cc1e2b34ae3862 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Fri, 10 Oct 2025 11:09:09 -0700 Subject: [PATCH 78/78] README for grpo --- .../text2sql/fine-tuning/grpo/README.md | 41 +++++++++++++++++++ .../fine-tuning/grpo/grpo_text2sql.py | 10 ----- 2 files changed, 41 insertions(+), 10 deletions(-) create mode 100644 end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/README.md diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/README.md b/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/README.md new file mode 100644 index 000000000..d0a7fd7cf --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/README.md @@ -0,0 +1,41 @@ +# GRPO Fine-tuning for Text2SQL + +This folder contains scripts to reinforcemen fine-tuning Llama models for the Text2SQL task using GRPO. + +## Quick start + +1. Download the BIRD train and dev datasets, if you haven't already: + +``` +git clone https://github.com/meta-llama/llama-cookbook +git checkout text2sql +cd llama-cookbook/end-to-end-use-cases/coding/text2sql/data +sh download_dev_unzip.sh +sh download_train_unzip.sh +``` + +2. (Optional) Set the following environment variable, so the reward of using LLM as a judge (via Llama 3.3 70b hosted on Together.ai) can be calculated: + +``` +pip install together +export TOGETHER_API_KEY= +``` + +If you don't want to use the using LLM as a judge reward, you can comment out this [line](https://github.com/meta-llama/llama-cookbook/blob/text2sql/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo_text2sql.py#L594) when calling GRPOTrainer and change the reward weights [here](https://github.com/meta-llama/llama-cookbook/blob/text2sql/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo-llama323b-text2sql.yaml#L32) to [1.0, 3.0, 1.0] + +3. Install the required libraries in a conda or virtual environment: + +``` +cd ../fine-tuning/grpo +pip install -r requirements.txt +``` + +4. Run the training script, assuming you have 6 GPUs to use for the training (if not, modify the `--num_processes` and `--gpu_ids`): + +``` +accelerate launch --num_processes 6 --gpu_ids 2,3,4,5,6,7 --config_file deepspeed_zero3.yaml grpo_text2sql.py --config grpo-llama323b-text2sql.yaml +``` + +You can modify the grpo-llama323b-text2sql.yaml file and tune `num_generations`, `learning_rate`, `reward_weights` and other parameters. + +5. To evaluate a saved checkpoint, follow the steps [here](https://github.com/meta-llama/llama-cookbook/tree/text2sql/end-to-end-use-cases/coding/text2sql/eval#evaluation-with-llama-models-on-hugging-face-or-fine-tuned). diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo_text2sql.py b/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo_text2sql.py index b78fa7e05..f09f8ec9c 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo_text2sql.py +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/grpo/grpo_text2sql.py @@ -658,13 +658,3 @@ def main(): if __name__ == "__main__": main() - -# before running this script, make sure you set the following environment variable -# so the reward of using LLM as a judge can be calculated: -# export TOGETHER_API_KEY= - -# two ways to run this script, assuming you have 6 GPUs to use for the training - -# with-proxy accelerate launch --num_processes 6 --gpu_ids 2,3,4,5,6,7 --config_file deepspeed_zero3.yaml grpo_text2sql.py --config grpo-llama323b-text2sql.yaml - -# with-proxy nohup accelerate launch --num_processes 6 --gpu_ids 2,3,4,5,6,7 --config_file deepspeed_zero3.yaml grpo_text2sql.py --config grpo-llama323b-text2sql.yaml &

l>(pOyKkLU8|S5jUQKm&kVd@S zk z0+J&?2IT>zmX6cJI9NWC00h+xiMdwweF=MG#f)52ef&Np292Lr_=sBor=^-%B=yx` zx898B%I&wQEj(TQto3aacc$ldcZ@(VuXm9-#%UMFEsDSZMzyR;SjvA;8`-ne3BGlic9V;9xauj!;Fko_6`V;Ce zI)7}REZ1Vjl&DzxpVwegI~*SSyk9Q)E_U`$zpk=jl)u<@qgfYyrd#hPruuEyD6nwA zrI}^mu;EWNY*_mXyJ{oJj5a-^z%pKw&IT&XgHS%m{&#IAs{qu=-NxWx%FQ>H$Ik8w zN%!|vItRu1>c{ZA)n+}EkEx5f1W49_7^uP+@f{>8qQy_%2cJIf%AuQDa4`Evui!#N zoCc1SS$>H69ydmI%mQ-MQC>(YE6ENomN{&#oX^H)WbW7ZMmAB*^s|ul223lq zX2!@yQl2l?uJjWy)3L#{$U~AXGjb;}k9nMX*RWL-E_R_yVeS3>Qhx*@s|qu10%tXI znJ@oo;IiKuLB4|9O8-;wzklP+l`}Qgrt4{vCd@(d2u_(F@KIKR=nO#QqC8S zoYuVdS=S^+B**d#m*Bs}6b=|P5Q&CqeG3J6JC`}8tr`P;v$9kMUgtc!Yxx?mMnl6Z z&)=!we>cDT_B9{sHLs#7)TgU}LpOMK@`svYAk_)CQYCDmsrX0K{aE%5H#u(6#OdTa zZkf?vAidDH!!N5p9B@hRRAOQaqwmyY^8VV-IMAiW`GfHpIpZ+Q%j1VEZfC*{I-g@R zc$tNn35kPlzQ){zFu6e6AflRlAm zwabq=#)LG;gW>=S)YV0X7tQ^u1X8iVM?~ZyCPaf#Z{{TrOx3bxu-|CSZDt{q2_K8R z+A0yxuN2#98%I7MKC)#xh=MMi} z+TnxS1hqCa>ag6b6WVrTCYb9xMT?0|yN^q|D%%du2l1J?=1!64)g$9z15F<=k43D(UV%EUC zY-BQ;=V6~J%`V+~JRhp|J;HfDeRUT1xTw|#gkKlx2hu|Ke47A z3jxABamji?;%5#*X;)WEU+k}c*%jKYQ(tL5-bv{U^j4Ik6dW=&XyDY|Qqd-QvE3S~ zu^u>RpS5L&rUPyR_LG905p}>c-6<#)o`|N$>+Y0(-%4kN2frW8*BS3V?o(hAW(R)E1o0 zxMnGqUq~#+&nuj$8oXIo63Rmhw#Q74|Jb)Gei6@k400#KkA?UZqnk1eO8BJgrhw_$ zT4P!~*MdRAp3O1oPk>M^KNcmi$G}ut5*p*XKQrTRE;t`G{IW^pJ*EykY%8_RPs34Q56P>)1a}Sps z)m?vyy&O+HRCl;T;bD})_<0C=%;S4Ckdq$cGuiE>Ncqn)L) zf0ybohC+kHwI*R&)ScU|kmsJ73fXx+80DL>jG{QwA`9!)Yy(;*kw780cEgO)`E6Br zS^JKeKhd%yU&zaFPbI&E^yECyVEVltPga>PdjF{W+?;+%S94jbaZEeMvMx6#j+7iY zX?n`8ZwhJ6B`=al5F|!&d(p4dey8U>ae9ERD^>_5B`0#S=vbvjf^-c5VYtRJCt!u~a zU0-|B4Tfy~7j9;Oo!^39c$^aB25ipVp)k%=>_x0uv~Da;;*Lt`&nuj4Kj!|>j3Z$g zzLxnx2Ke0zInIFfHuRTS$r8;c7cM`>B>IPg&#oT1b_uQlA{YZ*_zw0bRqH+Pb0yL! z73Fc`i4W6l-PX21;umTx=Zh9g?z*S4vj;r@^pc~`L)hk-4|^U`+5m%RiYQT-M=BlU zB0=7=@Ai2}lgq=a>GqsWeo`*ue+LJ9n#^NS&BgLMWOjm}4R1>!tP{>G;sqZg^ zFUt4UVplV#iPRfc6>U86$PV33IolLntvhcqn;U&(7&l!Y zg+)nKoih)_6MBKpsi4)vNh%7xuYDZTt)eR&W83Gbw~&{Q&)nfckwV9GZ)y57) z1a9&rbD;KUltwg4QatV(ZoQ1dXA3$M7ZI{arQ^mdCJc!?8RcZ~>962FWq(N*^qGoH z2i-L95j;n~R9kK)$+_<;$dM@H-<$f(c-#RqN)=xPrbW#9cD zKRa&9uHC%ynb)XuHS~gpiJW?oL}G^X`xvKThSf&0o_juE9`ew?{`wqxNhwqpe=X#@ zHC&Y@TmhpyCj6c<*Fi5PbB+YSwEZp<>ncCoH>jj`0yEN6*^m+nwB~4NKW9}K)L@MM z1vn#$%TGOSiuGjKx_3PUB~o{UfqGGP7miTBtr6Ds^AdUrQok3XmB!BEBae0+;<23J=FG{JFqwqbP}sew z7AZJ5o6RLIx#yhCW{=s!eUUtt18JY4k144iFx&)swY&-4Ryi9Mnb;ck9%A!L=sF$Y z-R59Y@qddb-D_|pHah{T49QP6@9*K=f)sDkrDalTiK0L{b!y=BDHEg*n6T-b=l1Y5X~_qj%-$}c>q-4=UQvM5yYRie!!snMXHoFXnP_2^lOI&{=2 zPf}-it;&v1FT6lgBnU(kC&D;NxJ&7A@SXHjcN$z&&n`)<*kJExF2r8Vs4-C{9|nbH z%YCs&+{9I5J#52TW*tv5CX)yK8!pDJ`V+liY1@i;~uwuaf;^S@%l1ur@V&GtX(Vu$#)Gxij#ro%(}n1g`vtle5@5M zq7Q%8eNJbV%m9z@{glDP7hV;t7trv$$buJUn-vKtf2$lBI$R_vVp7fl3oCifELMto zvJWMlD|0pl9MHYAD_Jx~pA^}iXm9-}*?en&RE7_{^BL5$q2I@azEMVi%J}}gdTsm3 zno9pirxOSU_9wh?%tY_XGsBxZl2<$}k4C;_9%m>BYK;$roB@VUI1b1=-PZJ_w~q*leo**m^iB%C4;DXQyOD-ffp!Mzy(rWX;=ws1c>PHEGMk zpr_5A^$WhgmsyL7mWoPC))ZNSU@`N4y^(>C=4+wjBBrX#L(j?c`_mp|SF67*%x;_w zA*@}fv%TWmn>CL=^CAV2KWFTVr$T?U&nMOOH1bJk$xv6uAIlo@&6*UK4$FWSh=}LX z^u#EI@KsA>&C-lMT&*t5EMcf&0BM|b2d_xO!7&MrLZklI5?TLzN$W6q+5tNhK4v22 zInJK=Ny|r<&-3{H>@>sD*%q?trT6R&GA0RvzrcQ(I2lw%NBCGY(PU18(V=*g2$rt4V_MY^Rm7_t_=T=kI3Jkg zq*^gOkikx8>Nw74(XqWBo{AD!2Q<+H+{r))zNi&}kx~M!Xg-U6S0IT7;c4YiTKDI2 z#$WfPko9RAzbo7uWU)Niq|vGiUbPX#;}(Rlkc3GIIFQZ(8NH`{3~+4kO2+5K+qJ2= zi>l3mi~0?gJR8+IR1;|a*Lrej*R29A1I2;3^V*_~eQ)t@gn|RbP9EqS;!&~g2wUoG{hEM+yuZmP;g1T~Mo{$iZVtH!35}|@UZ>zNdpR=E< z54h33C;1Y!oC4U&-g(qJ`$kF2Zo|+BCLfh~{WtEnvJ|<`&<&ymsbW@9`n;l_b$Vwo z3Kkq7cl&$cO=wN7(xS*J&&^yVPPA=~?)`1;bo8U3g#Ym zn}j?q@Z8q7WsleVk=>m+fTEix>LnY3DrpA8wul~T?6ll=#49Fl`O0il09noKoY zw50QZ3bIHSj+)gNukd}86)m0(SElV*Et}`g&*wECKojX>VxSZ zLo6W!3-T$~*@~0A47=J7w&Of?D_pad9Rx+fC73Y78z`$+4ZukO)^AKwKesvj5ON`; z6g$4%D<9Tcd1bNmi&<^F@IE%F)2WtWww|OsKKFKGkB59b05*~)sScH1$0Qha zyj;dMw&&Rt*cf>?CjY!rWBJt6Lf(y?|N6xF3)mQxo}S*AnvIM#PzXp(IwrGzo|HU) zs!bsCLDcXMuK2BHJ-PLK*jB-o=%{8{($46xl2}iPk5ul~n)bnnBv=Y=CoV^iqOWH; zr&orcvh^vf*Up}{|1z0Z%3O=;xSr}QG*sT2*xTS^R#FT+Qk;*7@|*t(kK~(@M&VeS zjpP1C9iDmh_We4vt_qJjmY)ALs^oo#gM+Xp7=QO67F8S4m7I?KQe>a_r9nf$n|6$Z z)*#mp=fhDzt?p7M4>^h|Dcb^H#!$$wb3bh*S(DBl>_;KDGl%ELt835*rysVs+&E(+ zG)W`T!Xae+O;6fDoiAUM)4FOnDb5+kUe7=^p?LPSidLJ1QnO)Oz>nx^#Me{PG^h@b z_I~C`062iySjXfS<9!{~9jLK<0(C-ZHI?}gu}sjJESUQ9R@8TN_68s}C1u?wCh;IB z8h?I^sfSUmb86eqkTUx#O~Xiod$kc~JViTp91!r58nN+g%(S&6+HhoM zx6XruQB+&J*;P%^< z4Hg^6R%pGA5PV9FcNzWumKCJ>mf~2Tqlr|HZCjnhoQ#I`aT~mVS7__!O%or*_Fa z)a+4B1VxrnU!QLwLQ*2qvzoIl)XnWcOU)#_Sj;WZ%70-+$>j=yG@;P&I4Co@6Ok8S^ZHVI{mdpyC;*Fo)?1*IS z8P?ug9f7nZOs={?lMigAM zg097_T>k-O)P&m>UKA+tH|P4Wd2lKsEri6J>2Yzi8i`nf_+=|bMJY_%sRvv41i&@S zDaBLOMher$XtiGDtstvIv_?V687rG{>G=XdFt1~P<%D2ej_t&J1=f2$#uiN{tMNb+ zD$c~c{r77cuvXRl0KaAX;pk>gD9EA4D_ATiduk9V4*k zx@v^!J)l2u+-RD|^reCB1a9F_e;$3%$>THtIq0=3S5memGvgy}QCQs@eAm5NGb z{mIMpoFnY#{FUm&jPXwokzj31{OAzfjaHB(F2pti&7OhL3-|=Za-2)-7gJI%JAM;6 z|0+KTbIr}iacleZ7ZG{*jkkI;qHeLvV#fpLC?wYn3t&a$UFk_dLO`}cbMytunKR>? zAcK{SaU^b6jx^#{s6Ss>gRqW+rqgZw7cN;x7dPLg&$|!W7=yTR-WA7(d6G>b6}U%S zn}p;b4%tyRCKp(U=(9T0dCrs9$?INF1Lo-^XK!h8Z@UKWQGXYq2Sa|Lyg>&esdA~4 zotvA?>p|tfx;+E0pIXr;=+PuUCsL*1dwz4khf%<9^Pq1uh6fLBoQRc%7+z(us$4A> zAhIo_zbS@4sF!{B*H7Wbf8|o>rwto?L|Eg!vqIiJGm~8@)?@@GGx9CO*+yt-!}1> z;3vxS7v9%R#F3n{ai0MQui;0_G=<{J-nYKjvi!;YIrF)YJMjUrRm8wqi57`H({d3b z@F#iE_G1ef-Y3(OlYg8hUOkuzsVHp{=VgDifv)=KSEOA=CCe2jFP%a@oF1zh)3+h} z*tD(xn-*^Mi$au%Tugi}mp>6=XC$@rvf<4PH`(wTPBPaN4l+)Co_mwB`rP-4sk7hO za42weWsQ!9fC*^G8a}MEltZj%r0e}$e93i5vePqa?^|>0AXgF)^_5_~*`{J}i#ya-_OIJygxwekgZ4KGTjC^EY zaOQSn{Sg0^hS6!hJnQ@A&UEfzecG#?#&;h~MGr1^i&;>4e=O8RtM6&}($(*paJbjP z)JJyXey13LjC1u-1vwk{)u9?OA9Vv+Cb9=Ijo7iNJXdk6$XQnsh-S)ljX*JDYFZ_Q z%xl#vVoT+#GhAzQ32@-A%!-1qnFH{v7oveDJ;q-DbJmY1KgrX8l61(tNmeFLokCN6 zuHknI4uce|;EjgC;+dax%DcP<%$@3t_K_mwRqoP+#q%?0=?*6&B3>slMXQo&hLTB{ z9v?F^8=2-+1CyG;c^R^9=wS<*bodd&V04?GS$bVOq@grnIE34S)PC!b`PbxO zNw@2(9>mguvrj-kz$zcM_!Ty~EsxI^@u+t*RjMZqN^VVc>BWiI{{E3rTr_QU+|R#& zOd`m6P~TgFQL!hj&@4}b(9@`0bCv%g#@Wx%=FRvI^2n~FweJ?k2zt89ij!NYZu>W_ zHywiQ+BRk3lhygr55EPB5r#y|UODz9?S|SeGxM7LGC4t0_{H1(X!#{`{8?EMKV?@J z{4Dho?vG^TgT))OR5EL%9u~UbuR(YESt-uzAm4tR_%xA@i9|{f9nBY1RE^qJkj?|G zRH)MN4VfM{!L#y9-)&JyQGVYz(9R_Xo)7I18mwRB z%2%=79QEd(g*{uoe=+R5ERqP!oIm)}P}aPR`i;n3ay}9%IEw&XS`Yrc`hCjRdRsr$ z-+gjFN;U|2MRNbXMNV$TsLG=aVpAQ*ZKKt;jNEGaQ$;P1_BR$5LmpU$p{Lt7Ns{A( zHv&p4CSuYk%hwW_)NhbuKD^J|J)H0j$Uo`6DV(SzQpFOlJDU#W?b8md;p^OwE#$a+ zsnTHaa5Eld@oxhJb!PH(RxDMBW49DSqSGDfO(e8TDP6?KZ&N78D2@a^N*Jebby+iI z^TGe%p4^7U-jmv<@~z>D;XK+o8|wdkVvxz5LVb$=(cz8rd0o4NbQfCpXooM3TZNV0 z(-colOkQ|~BOu8Jf(!^^k;%`C&~dk0$WR(nB(OrrSMB{lhpS}|jL3z%Qf72`I#a^F`8uEoa`qSgG(6MqxbR_s8tyYj^h*2t-($;EzUP-7>>PK%ciPK zKJf?vC2qeV!ntRzYmrW*w@pE4Ggw0rmYrcQxi&ORbzW%CQw#J2!M{a!WoPnqniRvn z=sB@>N9QIA$ofHWk3sS|c$kIHMbV(k2^6smezq+@QZqKP__OUrgIhK9`D9(F9&a)DPC4>?mq zYk8`YLw$|)t9FZl1{#btk+WA(JCiIhg!V%7qK5gxOJ`s4hwD3k7!H-1@Y@z0ULQ3w z(2r>zaGgN3yXfYzA49%X8z18I^Rq85dYOLvrP|1leCHkr=Gx=kxcP0zI&^r~>+}s1(r;I}qJ8(d|L@ZOUeWyjYVgQ|o~hGt0~1w8wLPzQ1xG zW7ycvm1_x1PcWesyc?+;!OwnD42{%`J>1~<`$f>J=4Bk59z*0RC7s z0`vH0l5S0vlhTL17aJ07mV5IheK0@*5hi?N>(lR@&DU!m2x!Kqi9IN5Z)f19}nRm%k(X zU)-RqLbwyHQrA1a7)Tc%L)%@%P1Yn{usCfQv#J)jhnbYOFH}{u)l>y!cxl~ao0mA} z9n7MJ+R$&YJg!2ha%+JwvUPkSp-3Q*Dc=#0#C#FIN8xjR@D($CR1kT-pJG0bDX?i@<#K?2VGS{_(e0+BRyCO}{tjw5o*8&V6sz zxCjM4Tib5CAPq&d8E;k>t)OrwFPLC#Y;YBDN0 zDoZPh^Gzqngw`6CQMOYOAV@STlUJHSs5)J~bGPI7CzMS8!kNa3=NKHI)kqu-0OypK zy29mxALHc$^mDTN>Nbr(PBc4_dr(uR;T0+@@#}b2&^Dx)K+@F~jUR)9#cma=H4EqJmPcp_8e9P4tR zt)d@2sTIFnnfx+5g>?9x2G^K-1xVPv*klJId$wt%fHZf|MhDea^K!q-<~BMb<7)Xx zUyV{w+?;Ajr02=97TlMuW3Nn=kjY3#MX-iSE{IC;Ff3&?0y83O7jxxrL(trbANq^# z)9WdL^!xu{&iFA9YqOMH8_Wkv)rF^~nAI?j{X}Uv!+!XIj_QG^oYec+gkJW}+b2#* zjJDgINWyGoO>5_$t$$vHRX@fz?eauY5SI&E9aT*XvIy00}3q zom2r>GxkX_^WjjVmr_BeEbl8K?D`d%|!EYvd1k5@V64PzEtlG8U^&87V z-6@@#Av#ONPaLi<%j@i)+?I42Ecizpsx{G^WdiaRCun`LPQWR>{b^pw)^^CZ=b#oj za&ah(#UVKNs_pGQNNMa9^7RNXVp*T$)>p1s5x=i>NZ;V`vX-xQ0c3-gNPv*%9%?UySkh)R8N8|0~zZmUie_Y2m zvtl_9;D{XM^$J_EpqQj-yC?`3l?A#$M zQL_mc0WNr0_YIo~RqyUQ#SUkmdFdYgvt3)8)XWEZH!IpQ$)8-->oJ^XO|L34oZzq{ zKUm_U8yJ^x%BQFmP=;c%&+8+0)DTtATe*a^u}Y^b3)Clu3vsr~1eSxvd_=UVGE_5E zgJsW3V+y=8|D=JOdB`UOvvnmlxk9fKAbj{y{fFO`P>|?_zHcDz>+AAuN?xtBi!Kyr!v``sdSnPZ z3OllgT~~0mikO+55B$bg9p3Y5^0Y6r9z+`&kaKNV#2RtncDJ(mn|2~&Zd&Jh!%<#} zPh4BU@o&s3KDsn03Hr(qsxL^irSkQYz7}}FJ!Rw8GeJWbG(j)oQax^1r}24)GCFdJ zn!52zHT@s=l8svE&o?9%Z}1-8AT5}+%3>&VU-!=JI|mF_N%WQ-=$%2G!}jtAp(H6w9%RGF4-l_yjFNDv2k^RP%{ z{8c1gWM25n!L`?KgRD|lV86*4#V~7=WCkpigQHeQHgqutbZ8CgBAgg<&}$ukfhsM# z2|ByjO8MLz*={R%D6lUjf}fmrfP~|$Zo^=9EYWqW>ognhFd0(w@(vEoP^r@_I@m({ z2JKiq0+lv+&-YTxv=2xEaFZIP7KiO6)YKA{>jlWxshI7$fB&Ga(10s9G0pAvSjw>a za3)@YtSLSUUuYc(JnXZO?zqDjF_V4%Fiuc~BaQ!-)1;~Twb>QMFQJt8T_K3-kg*Bm z>A}3%+~$xb^QZ+QjU~0y2f*U)UZ4!DCdg z=!~=_$ZE+qIul0^6F;G6c*f9Ku5B^I>NOX(sDR!T3!mJ&*q#|m-oN6!cvf2LF`QTJ zQBzWtxHcpQA$C$wd@X$`5ivToYhL){JBG{RCU+-X0B6sr22hV+THI4HbPB&3prJ>b zMt9oPmEro$E$u|(%9B6zeb~DfUvkWadDNcKbN(fCo7F%0mCLKV6tcm@?kpM+B$Irp zAX%yfC*7hiZ6=J*wMuoe1N8cL2p&8PNp2r!@}x?+Wb_C;+P3ZJtQJ^+{gQpWT)qfJ zq_drqy`;(b-KXWPA3?*K)5`qIchl?)jAI&*b# zM?xe@*BQ>Ya{o3NauDr}*6j`CsPc%dE9w>P<2z@uro>(K(7t2Uh&4TydSvcC@Pp^n z!1d;_PtLq(W`5@va;{04UfN6tPhn9b{T=hVFNO_~9Ssk*ND{ivr8b9?XEv7-p{F8x_Bc1^OCXA*2OP^m)&tutg)N68YZ^o~x zlIuBiHl^B-5D3uSP$+pVV(lF1CuwQNT+ zh7He)C}tkVc3R}~z4&1_mW1SDdQ-gu=IU*W3m)RdM88Y%%N7Kmk^bscWR2-Ix5CNb zi;mn__gP}OhP(B;SVf@gjlQt`o!VPtyKHisR9zyUwYwxe$Sm+aUqMwjE!=#uE1Zx* z;Sf`A0FHHXUI26(3$0AID4C7psy=Qr>m1XlsKw?0G4$oPCO~ExmYfP6yd#{iIM2|4 zZ9s8s^pJq1FJ7<#K3G@Z7pby_VYEb#jZy2Qy^@ZnAxYfvUw!rXlUtJIAXm0vi;R#g zKozE7#~&OdaUNN$>o+#L$sy`_l@kacV|+zs$=V&1x6sVmPU`?j+x{C7AsD|>bkqA7 zODr7A7!i`^Qp3?_MR(@nyTam#C>Ue`B((KaoExEyOZ#+;IY`qc$e6l3r~we1?wwH^ zoB~NeM$h1?oD?@8h{QNJpGQksS~n^KVkVXs2>2Y-%46XFREoNQyH3}Ijf5zyA(w(_ ztbiV4BD5zJXxd$Ppq%o&yEL1c3kPrpC$ZMD8Hd7(eDMW_|>GZ;4A7B*YUnP(@F zN)i$DIqT=`c7vIIrj)2n+^(jn>n+wKke>)Ms0DZ)+7)^l4(!JjStzSd3qTRq+kqjs zGhbXa;)F5t$+7qC4tE;}8{0=@TV8rWq@{Eb<;|w_M?XLY*+XoOmBd;h-f;5tf?G-}ZLqhRf(lYaLw?mz1{Q%~-YL%NsB{;ezs?U9m+%+ zUm>@oiUDgSgld3BkFx95qx@+Keu3KzBr|YyA3{?g9TzyvPa0r*Uh%(_;T++!HBP zkp+XA=pvi4b9=Z`4H?m0T80&YYujhS8bfn~D4@G>7;A;Gmw4RU7Qahc_K9rr`M}s* zqDzqGAfy}k+dSt8Lc@0=F$2q2wcM2`K7h*rOGZ3~I08wmL=~BY3jpaRfqeu+Ch1hN zi2A$I|77sUf<#&fh2etZ(G^3#XsAr&keilR$s}7CRJGP*sHw_qWybh@l6`~yb~xBQ zjZ7&wLHN+;TpcV<9$GzWW)+!ZEg^fL7^FhsR9dKEi08%&)~5>PEWE1&Yht5i{`zNNSj{%=f86e-NQ+*ly1T`J{ zVahLP>bCV61t@b}xmr>8qy#bzGlKCJ$dq}T=E1aye6B_a3JkpAO|N?Jqk^hKz))r`SctG~p6hs&6l+X5R{IcA0GE8TRTynnQ61)P5awP#hk) z;1z4TLE2B5E%>L)f@8rV)1Yk8W|=}5%@#^|*(YA~5x#AU(OKawk%4Bh$h+na?i5sG zzvqB5Y*YGod4XXs^vR@NYHz@sG-l}gp%zM0b0Dflx74OJ~K5Q9yhltQ6M!z(!^F=UGu!p zop5y;*m=2Zr!VLnV8^_=l92>}#@Z~*J=me*h=H6GjO#fBCK;QWu1pT>UpfW6Oe*Gb zb?#qEA=p-^{z@)JhkA|(QSQQbjcU24jLp->57xY=Kfx2jk!%=8NRg1z&TVL+$IhRr zJg16Nx>X>UY^j=wH>W_NtG!S-{B&!}yV`(oU%;wH9I1XQ#R6z+I_XGUd2hZk|AZsP zu(Y*~^WDn9G`Qb0$QwVDHC!wyo?BPfW!ua_hlrZ0C_~O{sOr;8y@N+#tx`6&q&^Bz zK~Pn8a9^YtPR`(9TET8bh^tX)@x1FtYgW?Yd!{#Gf90AX(VXwA_Kydh)sfWdmqA- zmSkCJWk9pdP?{@2oAZZ|3Fnzjj-!Cds6}~Ye?=Bo7H2>q$q|-X30>uAwgP=D$Jr`_ z^40s_JI(Vh1E+g0U+u0 zX2kHSzh0*F^&p{>QHWl-(o$UeB5UXC+svDNtE-vnw$UJjuM>m5_U+qVi3ZC&;f-W; z-3FC-F5gA+nSEgXm6}~gvRA)Ou^RH;ihqVkMu$O~6AdWkF}@F~#_Z&>SB$Oi!@hmlnBrm20rCsu6lGkef|A|qW27mf?7fj=_NOPE1= z6Rx9I3OBpr41301ran-Up1}nKeo2h7-LT}vc3hL#9foXnN}_tP&2c=?!%ik?JCtnR z)M8^c%#-L$Ac$K@E)VN91@(qj-648cCg_lz&RwJ;dfkKBR|g3O4K(Ro@6mN0EqFnqm0 zjEdAns&Ybbn1j7j?uq{&n|XYFZAgm3mi&5Lvw=a&)XM_BT+`x%GgY4!`3L2wIYWfj^PBon?S}W zESH_39YYLIg2Xk^*Bb{+$OK%Zfn8z5ycrB}%+81@QaqgYfE@z|nzXcBcYIc7{65Pb zmew67L!^w|BoD`3QlDo>%_Ti|bJ(J>s%$rI=TP%Q#M2?*d-sSnbTw3;G0@qF zw+3%*>OX889C1_N2-wieVuq)Y7xFQEgWgnLyLrRe6$Xd(OdGkplIB-~A!Ir7q1?~m z9N>P+BSwO&OK+CO0;Zjw`S(B!xp@e_wsW`Bbe(u6ro4;mHiW$u>MN?GkZ&%!X+*%f zN=;=AYhJ)Gu)!3d_q&kuUFcz>z+y~YvZ6I%PtV}A0;mrGnBU^fX@(s#0?)~Pt~S{c z^00;N+IF#KY%4e7Y)X?ag-GhI$FKg@ctv(0``uc~X5W5v8>>=9Cs}SwnZv9?`pg4M z0>--`(|^z@krQMmma?PmoTLm0#Sh^!=^ay&v+et)`r9^Zi>>K60mxCCz%B81wCoaO z%c(fPGWWrgN($6ibtyc4@U?yD#ER7+Wn1p&O$oz(m-2BNY}$0APr!KwTYT#-B6J^0 zM^C@6ASMzzp2?B(2YwiV+gZ1sNPnC_r^j;_0?n)~RFp*0rz_ZbZ`{7O0?%{5!0= z6nyHN(zk;4cVW^>XGI}HQ#I=35QfDNR+QyLBJ7A(0j*8GKE{7*9Wc?m!_z4n7o5QW zamF4O{q9#UgvRWRdNZGVU1^hb%RoEbSf=eMN;%n}|0)5w77|*wT%IZpumu$TnNfrL z$TjUn1@sRVfciqfA(`D)gi+;1837ZKcJ7lVO2DwkFGok_pZllN=T6rZ4YN%*9W$Y1 zIIUr#>j6q70g=$)t7maN^m6jISVNzgWctB~jhM^jqD+I}-<%gFyma1{>Y1a9>0$}@z_28g?z~f*gAVZQ?51rgQOlo)isbp;Z&ZKZrMZNJf%i3@V z3{&Z1pE6xp2Pv{vflGuuTW8VC+y$`5mjS*<I>01W}8TRp?*bn!_RL%oA_ ztQ3wHQ7EOb^*G~Bt#Sm50m@l<{_t0PfNhnNJiOTw`q!iioe_}U-EHNDVv z^jdcGPhJkZt#V2vcXgJsZlbnMps=;E(!Jp zftgf^D~^-X9K7Udndp}`-E=q!Djdc{2VrzoxRqRwHA&WFruSL#72Q25ZP}ygmQ*N`Lj{api z;J+LIsg-&=zTx@z+5bFr-pBb-dPMM)|KY!$%>Q2o{QH0qAo`vuasbG0eU<$$pF8R( z|KAb+oGCttx%iFK**ehjS#{m=4zut#v8GM%|GCk>E^?SwWAC=P=BZt^_Obp^s(dE~ zel&-Lq;_tJTrPE&2_OC^3(kq$r~WSc^!7CLw#3dg{1y4L?j6_nxhg-YB89s242;o+r}794n2_;0O!x|^q4?wTn|E^|K$e$_B&dP@ZQ zyRHgEQJ!_o;I6uaJE2UW0sIG?tEhoJ7uFraFHS0$H9j*U8 z@b2mcAmz+xW!|zR^Y_ozv3)P3ci(>(VdVdJjQvleNMhcqmUbMx?T5Mw{O`H@$B7ow ze*&Mhr=#tEdGxQDvtYpctZL7|41D(=e7+mu&`J4`Afj{QODgFeL)!{}1-c^t%86 From 7a4ae9f66c08366051fd79c97b5351f4d36e6c03 Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Fri, 11 Jul 2025 17:00:39 -0700 Subject: [PATCH 38/78] ft readme typo fix --- end-to-end-use-cases/coding/text2sql/fine-tuning/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md index a0c7d654f..3e1a8ff4d 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/README.md @@ -71,7 +71,7 @@ lama31-8b-text2sql-peft-nonquantized-nocot llama31-8b-text2sql-peft-quantized-nocot ``` -After running `tensorboard --logdir ./llama31-8b-text2sql-fine_tuning` you can open `http://localhost:6006` to see the train loss chat etc: +After running `tensorboard --logdir ./llama31-8b-text2sql-fine_tuning` you can open `http://localhost:6006` to see the train loss chart like this: ![](train_loss.png) @@ -164,7 +164,7 @@ lama31-8b-text2sql-peft-nonquantized-cot llama31-8b-text2sql-peft-quantized-cot ``` -The train loss chart will look like this: +The train loss chart should look like this: ![](train_loss_cot.png) ### Evaluating the fine-tuned model (With Reasoning) From 9ac5dd12fb26b01770d0cdefa47cb2a071e76e5c Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Fri, 11 Jul 2025 17:07:06 -0700 Subject: [PATCH 39/78] make max_tokens same - 10240 --- end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py b/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py index 2e6d2939c..e0addccfc 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py +++ b/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py @@ -309,7 +309,7 @@ def collect_response_from_llama( api_key=api_key, model=model, prompt=cur_prompt, - max_tokens=4096, + max_tokens=10240, temperature=0, stop=["--", "\n\n", ";", "#"], ) From 6b924095073e1155a52feed8418da29903ab9d5c Mon Sep 17 00:00:00 2001 From: Amir Youssefi <328194+ghd3v@users.noreply.github.com> Date: Fri, 11 Jul 2025 17:45:25 -0700 Subject: [PATCH 40/78] dynamically calculating max tokens param; it was unused before --- .../coding/text2sql/eval/llama_text2sql.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py b/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py index e0addccfc..aaa7fdae7 100644 --- a/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py +++ b/end-to-end-use-cases/coding/text2sql/eval/llama_text2sql.py @@ -24,6 +24,7 @@ pipeline, ) +MAX_NEW_TOKENS=10240 # If API has max tokens (vs max new tokens), we calculate it def local_llama(prompt, pipe): SYSTEM_PROMPT = "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement." @@ -45,7 +46,7 @@ def local_llama(prompt, pipe): outputs = pipe( raw_prompt, - max_new_tokens=10240, + max_new_tokens=MAX_NEW_TOKENS, do_sample=False, temperature=0.0, top_k=50, @@ -187,22 +188,26 @@ def cloud_llama(api_key, model, prompt, max_tokens, temperature, stop): SYSTEM_PROMPT = "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement." try: if model.startswith("meta-llama/"): + final_prompt = SYSTEM_PROMPT + "\n\n" + prompt + final_max_tokens = len(final_prompt) + MAX_NEW_TOKENS llm = ChatTogether( model=model, temperature=0, + max_tokens=final_max_tokens, ) - answer = llm.invoke(SYSTEM_PROMPT + "\n\n" + prompt).content + answer = llm.invoke(final_prompt).content else: client = LlamaAPIClient() messages = [ {"content": SYSTEM_PROMPT, "role": "system"}, {"role": "user", "content": prompt}, ] - + final_max_tokens = len(messages) + MAX_NEW_TOKENS response = client.chat.completions.create( model=model, messages=messages, temperature=0, + max_completion_tokens=final_max_tokens, ) answer = response.completion_message.content.text From c4573ba5ff44c321ee6e32b2d30c3dfa19a833f8 Mon Sep 17 00:00:00 2001 From: Amir Youssefi <328194+ghd3v@users.noreply.github.com> Date: Fri, 11 Jul 2025 18:14:34 -0700 Subject: [PATCH 41/78] fixing github we viewing --- ...ama_3_1_8b_with_text2sql_sft_dataset.ipynb | 2414 +---------------- 1 file changed, 1 insertion(+), 2413 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/finetuning_llama_3_1_8b_with_text2sql_sft_dataset.ipynb b/end-to-end-use-cases/coding/text2sql/fine-tuning/finetuning_llama_3_1_8b_with_text2sql_sft_dataset.ipynb index f3e26abd0..7a369fb5b 100644 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/finetuning_llama_3_1_8b_with_text2sql_sft_dataset.ipynb +++ b/end-to-end-use-cases/coding/text2sql/fine-tuning/finetuning_llama_3_1_8b_with_text2sql_sft_dataset.ipynb @@ -1140,2419 +1140,7 @@ ] } ], - "metadata": { - "accelerator": "GPU", - "colab": { - "gpuType": "T4", - "provenance": [], - "machine_shape": "hm" - }, - "kernelspec": { - "display_name": "Python 3", - "name": "python3" - }, - "language_info": { - "name": "python" - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "08cbd090cd594a998fc641cf4880df55": { - "model_module": "@jupyter-widgets/controls", - "model_name": "HBoxModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_cfad6b5f4ce5418ba6555668de71fc5e", - "IPY_MODEL_c9797e0a5d1746ffa9719278b8c6df97", - "IPY_MODEL_bca3230d0f5841348e1d52bb965eb88a" - ], - "layout": "IPY_MODEL_eb24a737e7f949bbba05c97fc3930509" - } - }, - "cfad6b5f4ce5418ba6555668de71fc5e": { - "model_module": "@jupyter-widgets/controls", - "model_name": "HTMLModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_c1e4dbfa522e432cadaae898dc38b6d2", - "placeholder": "​", - "style": "IPY_MODEL_98a307da59ce474d83c078c4969e5bba", - "value": "Loading checkpoint shards: 100%" - } - }, - "c9797e0a5d1746ffa9719278b8c6df97": { - "model_module": "@jupyter-widgets/controls", - "model_name": "FloatProgressModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "success", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_2e9a5b5f7bfc4205a2b7fc4d07527127", - "max": 4, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_d8ff81bca7e44192bfc610cfebc78a99", - "value": 4 - } - }, - "bca3230d0f5841348e1d52bb965eb88a": { - "model_module": "@jupyter-widgets/controls", - "model_name": "HTMLModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_fba7465393574fc4a188a0126dc42c63", - "placeholder": "​", - "style": "IPY_MODEL_a4215bedeb224a37a40edf231308c247", - "value": " 4/4 [00:05<00:00,  1.14s/it]" - } - }, - "eb24a737e7f949bbba05c97fc3930509": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "c1e4dbfa522e432cadaae898dc38b6d2": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "98a307da59ce474d83c078c4969e5bba": { - "model_module": "@jupyter-widgets/controls", - "model_name": "DescriptionStyleModel", - "model_module_version": "1.5.0", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "2e9a5b5f7bfc4205a2b7fc4d07527127": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "d8ff81bca7e44192bfc610cfebc78a99": { - "model_module": "@jupyter-widgets/controls", - "model_name": "ProgressStyleModel", - "model_module_version": "1.5.0", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "fba7465393574fc4a188a0126dc42c63": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "a4215bedeb224a37a40edf231308c247": { - "model_module": "@jupyter-widgets/controls", - "model_name": "DescriptionStyleModel", - "model_module_version": "1.5.0", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "637dedfe81724192b863c2b131aeb933": { - "model_module": "@jupyter-widgets/controls", - "model_name": "HBoxModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_781541b6bc7c473ea2cf33f83017b648", - "IPY_MODEL_c36068a9af284e31890f576d50da2c5f", - "IPY_MODEL_c3930523cc43497dbcd21eba69dc3b6d" - ], - "layout": "IPY_MODEL_32c851dd54954b72950a9e0f06d01aa1" - } - }, - "781541b6bc7c473ea2cf33f83017b648": { - "model_module": "@jupyter-widgets/controls", - "model_name": "HTMLModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_49e949498a004d2ca5f06edd67304327", - "placeholder": "​", - "style": "IPY_MODEL_70f55e99c7944da9ae8a6445a0ce9b6b", - "value": "Generating train split: " - } - }, - "c36068a9af284e31890f576d50da2c5f": { - "model_module": "@jupyter-widgets/controls", - "model_name": "FloatProgressModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "success", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_4c13c8d1c64e4d1893ebcc7712907951", - "max": 1, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_8ad04e1707b74a0b89e1aa7e511584e0", - "value": 1 - } - }, - "c3930523cc43497dbcd21eba69dc3b6d": { - "model_module": "@jupyter-widgets/controls", - "model_name": "HTMLModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_4250701d8d3849feb9d00e94f259d980", - "placeholder": "​", - "style": "IPY_MODEL_91e6c3a9ea524d5ab7b7c8fce66d7a36", - "value": " 6599/0 [00:00<00:00, 86629.77 examples/s]" - } - }, - "32c851dd54954b72950a9e0f06d01aa1": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "49e949498a004d2ca5f06edd67304327": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "70f55e99c7944da9ae8a6445a0ce9b6b": { - "model_module": "@jupyter-widgets/controls", - "model_name": "DescriptionStyleModel", - "model_module_version": "1.5.0", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "4c13c8d1c64e4d1893ebcc7712907951": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": "20px" - } - }, - "8ad04e1707b74a0b89e1aa7e511584e0": { - "model_module": "@jupyter-widgets/controls", - "model_name": "ProgressStyleModel", - "model_module_version": "1.5.0", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "4250701d8d3849feb9d00e94f259d980": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "91e6c3a9ea524d5ab7b7c8fce66d7a36": { - "model_module": "@jupyter-widgets/controls", - "model_name": "DescriptionStyleModel", - "model_module_version": "1.5.0", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "61ad4905a7c448fea70755c44a9ee7f3": { - "model_module": "@jupyter-widgets/controls", - "model_name": "HBoxModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_9dbc55420dd349f79b4fcbebe9cb98bd", - "IPY_MODEL_2d8b27dd71884459ace7a252ff86603f", - "IPY_MODEL_f505fbfb17064ba59d2bfc6ff4bc41b2" - ], - "layout": "IPY_MODEL_446fd4d425a840799c06c1bae0ab133b" - } - }, - "9dbc55420dd349f79b4fcbebe9cb98bd": { - "model_module": "@jupyter-widgets/controls", - "model_name": "HTMLModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_95bae4f5e1424f1480aec8d53490bba4", - "placeholder": "​", - "style": "IPY_MODEL_6223f835a0164b6ea52b1889b0bcd0f8", - "value": "Map: 100%" - } - }, - "2d8b27dd71884459ace7a252ff86603f": { - "model_module": "@jupyter-widgets/controls", - "model_name": "FloatProgressModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "success", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_b5a0439f345d4e6ba6f18f9ac9dfe771", - "max": 6599, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_cce40322aa7f48d6abfa03506d0e2630", - "value": 6599 - } - }, - "f505fbfb17064ba59d2bfc6ff4bc41b2": { - "model_module": "@jupyter-widgets/controls", - "model_name": "HTMLModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_42581a1a1e364903974416b11989f0f6", - "placeholder": "​", - "style": "IPY_MODEL_29a85fb494734faca4baf1ecb00f0c3c", - "value": " 6599/6599 [00:00<00:00, 11443.52 examples/s]" - } - }, - "446fd4d425a840799c06c1bae0ab133b": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "95bae4f5e1424f1480aec8d53490bba4": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "6223f835a0164b6ea52b1889b0bcd0f8": { - "model_module": "@jupyter-widgets/controls", - "model_name": "DescriptionStyleModel", - "model_module_version": "1.5.0", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "b5a0439f345d4e6ba6f18f9ac9dfe771": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "cce40322aa7f48d6abfa03506d0e2630": { - "model_module": "@jupyter-widgets/controls", - "model_name": "ProgressStyleModel", - "model_module_version": "1.5.0", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "42581a1a1e364903974416b11989f0f6": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "29a85fb494734faca4baf1ecb00f0c3c": { - "model_module": "@jupyter-widgets/controls", - "model_name": "DescriptionStyleModel", - "model_module_version": "1.5.0", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "1e212fe262544328967e36fb26e06073": { - "model_module": "@jupyter-widgets/controls", - "model_name": "HBoxModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_0badc1c8b9424b8cb2c526a3bc80294a", - "IPY_MODEL_d0c3e1bc46314b3a822e8350f6ed4904", - "IPY_MODEL_46538c8c222a4ebb81abf0daad5bfa79" - ], - "layout": "IPY_MODEL_52711139b56948fcbeca651623d194a0" - } - }, - "0badc1c8b9424b8cb2c526a3bc80294a": { - "model_module": "@jupyter-widgets/controls", - "model_name": "HTMLModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_78a35430e1bd47549124eac98be01fdd", - "placeholder": "​", - "style": "IPY_MODEL_701bbc75e7214abc93e7d15d42f7c22f", - "value": "Unsloth: Tokenizing ["text"]: 100%" - } - }, - "d0c3e1bc46314b3a822e8350f6ed4904": { - "model_module": "@jupyter-widgets/controls", - "model_name": "FloatProgressModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "success", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_09d61405fbb4468cb49a430b6b462276", - "max": 6599, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_4e36e192ac3947efbb9a8a4e2f4cfbe2", - "value": 6599 - } - }, - "46538c8c222a4ebb81abf0daad5bfa79": { - "model_module": "@jupyter-widgets/controls", - "model_name": "HTMLModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_a2e091222faa4d38877b613f8036025d", - "placeholder": "​", - "style": "IPY_MODEL_7d56d8683551408182969f6201605c86", - "value": " 6599/6599 [00:03<00:00, 2120.71 examples/s]" - } - }, - "52711139b56948fcbeca651623d194a0": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "78a35430e1bd47549124eac98be01fdd": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "701bbc75e7214abc93e7d15d42f7c22f": { - "model_module": "@jupyter-widgets/controls", - "model_name": "DescriptionStyleModel", - "model_module_version": "1.5.0", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "09d61405fbb4468cb49a430b6b462276": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "4e36e192ac3947efbb9a8a4e2f4cfbe2": { - "model_module": "@jupyter-widgets/controls", - "model_name": "ProgressStyleModel", - "model_module_version": "1.5.0", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "a2e091222faa4d38877b613f8036025d": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "7d56d8683551408182969f6201605c86": { - "model_module": "@jupyter-widgets/controls", - "model_name": "DescriptionStyleModel", - "model_module_version": "1.5.0", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "b89abd16ac7645c2af3861be2a53e7a4": { - "model_module": "@jupyter-widgets/controls", - "model_name": "HBoxModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_0a3dbf62929640f5b670bb9932ff9e85", - "IPY_MODEL_774bc595ccdf4fcfbc078ae69e31cce2", - "IPY_MODEL_a401420ba5a84c4e8e09d189ae31791f" - ], - "layout": "IPY_MODEL_d9338d0b5aa14d98a230f64a96dacfc6" - } - }, - "0a3dbf62929640f5b670bb9932ff9e85": { - "model_module": "@jupyter-widgets/controls", - "model_name": "HTMLModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_da237a8e84234e9ab6eb73c8cc41dac5", - "placeholder": "​", - "style": "IPY_MODEL_6b730c841c28487596cb1358402f618b", - "value": "README.md: 100%" - } - }, - "774bc595ccdf4fcfbc078ae69e31cce2": { - "model_module": "@jupyter-widgets/controls", - "model_name": "FloatProgressModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "success", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_954b8f5078384488b503919bb47b380e", - "max": 587, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_2e589652d1b641b1bd49109f3a963a63", - "value": 587 - } - }, - "a401420ba5a84c4e8e09d189ae31791f": { - "model_module": "@jupyter-widgets/controls", - "model_name": "HTMLModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_9db7e5022a1a4c82a4b218c4f0e58a7d", - "placeholder": "​", - "style": "IPY_MODEL_ec69d72c400d497cb43db1a2c4d3ffd0", - "value": " 587/587 [00:00<00:00, 71.1kB/s]" - } - }, - "d9338d0b5aa14d98a230f64a96dacfc6": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "da237a8e84234e9ab6eb73c8cc41dac5": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "6b730c841c28487596cb1358402f618b": { - "model_module": "@jupyter-widgets/controls", - "model_name": "DescriptionStyleModel", - "model_module_version": "1.5.0", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "954b8f5078384488b503919bb47b380e": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "2e589652d1b641b1bd49109f3a963a63": { - "model_module": "@jupyter-widgets/controls", - "model_name": "ProgressStyleModel", - "model_module_version": "1.5.0", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "9db7e5022a1a4c82a4b218c4f0e58a7d": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "ec69d72c400d497cb43db1a2c4d3ffd0": { - "model_module": "@jupyter-widgets/controls", - "model_name": "DescriptionStyleModel", - "model_module_version": "1.5.0", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "9124002ea80946079b05669b8edf2e93": { - "model_module": "@jupyter-widgets/controls", - "model_name": "HBoxModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_2418f4815f8e4db38821f04715509a87", - "IPY_MODEL_8b024ae17b3d4f9d9458e0d24c4ba858", - "IPY_MODEL_3aca95703e0b4da195020b22e03794d5" - ], - "layout": "IPY_MODEL_888e1a411dd84e68a9fb45319a384e53" - } - }, - "2418f4815f8e4db38821f04715509a87": { - "model_module": "@jupyter-widgets/controls", - "model_name": "HTMLModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_2aa533d9f8154a2890442924f939b936", - "placeholder": "​", - "style": "IPY_MODEL_f7f0f1b891454fcb8271c2fd9afa5e39", - "value": "Uploading...: 100%" - } - }, - "8b024ae17b3d4f9d9458e0d24c4ba858": { - "model_module": "@jupyter-widgets/controls", - "model_name": "FloatProgressModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "success", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_032982a7372d47c09a039de0f89e7626", - "max": 167832240, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_e909536897824b8492ed21651d7cdcc2", - "value": 167832240 - } - }, - "3aca95703e0b4da195020b22e03794d5": { - "model_module": "@jupyter-widgets/controls", - "model_name": "HTMLModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_56f54ec10c5a411d97a8add4e37419e7", - "placeholder": "​", - "style": "IPY_MODEL_9ae2b77ef66949a8ac1a2c073adf654e", - "value": " 168M/168M [00:11<00:00, 20.7MB/s]" - } - }, - "888e1a411dd84e68a9fb45319a384e53": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "2aa533d9f8154a2890442924f939b936": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "f7f0f1b891454fcb8271c2fd9afa5e39": { - "model_module": "@jupyter-widgets/controls", - "model_name": "DescriptionStyleModel", - "model_module_version": "1.5.0", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "032982a7372d47c09a039de0f89e7626": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "e909536897824b8492ed21651d7cdcc2": { - "model_module": "@jupyter-widgets/controls", - "model_name": "ProgressStyleModel", - "model_module_version": "1.5.0", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "56f54ec10c5a411d97a8add4e37419e7": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "9ae2b77ef66949a8ac1a2c073adf654e": { - "model_module": "@jupyter-widgets/controls", - "model_name": "DescriptionStyleModel", - "model_module_version": "1.5.0", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "be77d2c16a8544ffae3c3224a88ceac7": { - "model_module": "@jupyter-widgets/controls", - "model_name": "HBoxModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_18730cc628544463be32a527143908e7", - "IPY_MODEL_783f0b6997c04133a92e75c8c1970555", - "IPY_MODEL_317c60b6371b4f0b8903659a48915549" - ], - "layout": "IPY_MODEL_3299e112ee0e4b948383d0965e000665" - } - }, - "18730cc628544463be32a527143908e7": { - "model_module": "@jupyter-widgets/controls", - "model_name": "HTMLModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_123983553f524c86b2e34137c3e15a81", - "placeholder": "​", - "style": "IPY_MODEL_f8f4c7d3484040f5b7cc63dd507e7cac", - "value": "Uploading...: 100%" - } - }, - "783f0b6997c04133a92e75c8c1970555": { - "model_module": "@jupyter-widgets/controls", - "model_name": "FloatProgressModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "success", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_bb9630f74a664507ac5fa5e7c3b28287", - "max": 17209920, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_b80165d852f547f28d0ef91276586a4d", - "value": 17209920 - } - }, - "317c60b6371b4f0b8903659a48915549": { - "model_module": "@jupyter-widgets/controls", - "model_name": "HTMLModel", - "model_module_version": "1.5.0", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_a46d09b6a9b649bd95b48d1ec9430a55", - "placeholder": "​", - "style": "IPY_MODEL_358661cd13c14e6eb64591b288f9f02f", - "value": " 17.2M/17.2M [00:04<00:00, 85.7MB/s]" - } - }, - "3299e112ee0e4b948383d0965e000665": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "123983553f524c86b2e34137c3e15a81": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "f8f4c7d3484040f5b7cc63dd507e7cac": { - "model_module": "@jupyter-widgets/controls", - "model_name": "DescriptionStyleModel", - "model_module_version": "1.5.0", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "bb9630f74a664507ac5fa5e7c3b28287": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "b80165d852f547f28d0ef91276586a4d": { - "model_module": "@jupyter-widgets/controls", - "model_name": "ProgressStyleModel", - "model_module_version": "1.5.0", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "a46d09b6a9b649bd95b48d1ec9430a55": { - "model_module": "@jupyter-widgets/base", - "model_name": "LayoutModel", - "model_module_version": "1.2.0", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "358661cd13c14e6eb64591b288f9f02f": { - "model_module": "@jupyter-widgets/controls", - "model_name": "DescriptionStyleModel", - "model_module_version": "1.5.0", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - } - } - } - }, + "metadata": {}, "nbformat": 4, "nbformat_minor": 0 } \ No newline at end of file From 7b508ecb32c64e3e882a1a1793f77d3806933926 Mon Sep 17 00:00:00 2001 From: Amir Youssefi <328194+ghd3v@users.noreply.github.com> Date: Fri, 11 Jul 2025 18:25:02 -0700 Subject: [PATCH 42/78] testing fix of github notebook viewing --- .../text2sql/quickstart/quickstart_test.ipynb | 226 ++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 end-to-end-use-cases/coding/text2sql/quickstart/quickstart_test.ipynb diff --git a/end-to-end-use-cases/coding/text2sql/quickstart/quickstart_test.ipynb b/end-to-end-use-cases/coding/text2sql/quickstart/quickstart_test.ipynb new file mode 100644 index 000000000..e9a0a1c97 --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/quickstart/quickstart_test.ipynb @@ -0,0 +1,226 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e8cba0b6", + "metadata": {}, + "source": [ + "## Quick Demo of Text2SQL Using Llama 3.3\n", + "\n", + "This demo shows how to use Llama 3.3 to answer questions about a SQLite DB. \n", + "\n", + "We'll use LangChain and the Llama cloud provider [Together.ai](https://api.together.ai/), where you can easily get a free API key (or you can use any other Llama cloud provider or even Ollama running Llama locally)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "33fb3190-59fb-4edd-82dd-f20f6eab3e47", + "metadata": {}, + "outputs": [], + "source": [ + "!pip install --upgrade -r requirements.txt" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fa4562d3", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "from langchain_together import ChatTogether\n", + "\n", + "os.environ['TOGETHER_API_KEY'] = 'your_api_key'\n", + "\n", + "llm = ChatTogether(\n", + " model=\"meta-llama/Llama-3.3-70B-Instruct-Turbo\",\n", + " temperature=0,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "6d421ae7", + "metadata": {}, + "source": [ + "To recreate the `nba_roster.db` file, run the two commands below:\n", + "- `python txt2csv.py` to convert the `nba.txt` file to `nba_roster.csv`. The `nba.txt` file was created by scraping the NBA roster info from the web.\n", + "- `python csv2db.py` to convert `nba_roster.csv` to `nba_roster.db`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "56f0360e-fca3-49a8-9a70-0416f84e15fc", + "metadata": {}, + "outputs": [], + "source": [ + "# uncomment if you don't want to create the db yourself\n", + "#! wget https://github.com/meta-llama/llama-recipes/raw/3649841b426999fdc61c30a9fc8721106bec769b/recipes/use_cases/coding/text2sql/nba_roster.db" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3bb99f39-cd7a-4db6-91dd-02f3bf80347c", + "metadata": {}, + "outputs": [], + "source": [ + "from langchain_community.utilities import SQLDatabase\n", + "\n", + "# Note: to run in Colab, you need to upload the nba_roster.db file in the repo to the Colab folder first.\n", + "db = SQLDatabase.from_uri(\"sqlite:///nba_roster.db\", sample_rows_in_table_info=0)\n", + "\n", + "def get_schema():\n", + " return db.get_table_info()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8d793ce7-324b-4861-926c-54973d7c9b43", + "metadata": {}, + "outputs": [], + "source": [ + "question = \"What team is Stephen Curry on?\"\n", + "prompt = f\"\"\"Based on the table schema below, write a SQL query that would answer the user's question; just return the SQL query and nothing else.\n", + "\n", + "Scheme:\n", + "{get_schema()}\n", + "\n", + "Question: {question}\n", + "\n", + "SQL Query:\"\"\"\n", + "\n", + "print(prompt)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "70776558", + "metadata": {}, + "outputs": [], + "source": [ + "answer = llm.invoke(prompt).content\n", + "print(answer)" + ] + }, + { + "cell_type": "markdown", + "id": "afcf423a", + "metadata": {}, + "source": [ + "***Note:*** If you don't have the \"just return the SQL query and nothing else\" in the prompt above, you'll likely get more text other than the SQL query back in the answer, making some extra post-processing necessary before running the db query below." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "62472ce6-794b-4a61-b88c-a1e031e28e4e", + "metadata": {}, + "outputs": [], + "source": [ + "# note this is a dangerous operation and for demo purpose only; in production app you'll need to safe-guard any DB operation\n", + "result = db.run(answer)\n", + "result" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "39ed4bc3", + "metadata": {}, + "outputs": [], + "source": [ + "# how about a follow up question\n", + "follow_up = \"What's his salary?\"\n", + "print(llm.invoke(follow_up).content)" + ] + }, + { + "cell_type": "markdown", + "id": "98b2c523", + "metadata": {}, + "source": [ + "Since we did not pass any context along with the follow-up to Llama, it doesn't know the answer. Let's try to fix it by adding context to the follow-up prompt." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0c305278-29d2-4e88-9b3d-ad67c94ce0f2", + "metadata": {}, + "outputs": [], + "source": [ + "prompt = f\"\"\"Based on the table schema, question, SQL query, and SQL response below, write a new SQL response; be concise, just output the SQL response.\n", + "\n", + "Scheme:\n", + "{get_schema()}\n", + "\n", + "Question: {follow_up}\n", + "SQL Query: {question}\n", + "SQL Result: {result}\n", + "\n", + "New SQL Response:\n", + "\"\"\"\n", + "print(prompt)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "03739b96-e607-4fa9-bc5c-df118198dc7f", + "metadata": {}, + "outputs": [], + "source": [ + "new_answer = llm.invoke(prompt).content\n", + "print(new_answer)" + ] + }, + { + "cell_type": "markdown", + "id": "c782abb6-3b44-45be-8694-70fc29b82523", + "metadata": {}, + "source": [ + "Because we have \"be concise, just output the SQL response\", Llama 3 is able to just generate the SQL statement; otherwise output parsing will be needed." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6ecfca53-be7e-4668-bad1-5ca7571817d7", + "metadata": {}, + "outputs": [], + "source": [ + "db.run(new_answer)" + ] + } + ], + "metadata": { + "fileHeader": "", + "fileUid": "559664fd-826e-43fa-86b4-78edb9bbf80e", + "isAdHoc": false, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 3c23112ed2218f57c6a40533a2c2c07bf03f1e27 Mon Sep 17 00:00:00 2001 From: Amir Youssefi <328194+ghd3v@users.noreply.github.com> Date: Fri, 11 Jul 2025 18:27:27 -0700 Subject: [PATCH 43/78] fixing github web rendering of the notebook --- .../text2sql/quickstart/quickstart.ipynb | 147 ++---------- .../text2sql/quickstart/quickstart_test.ipynb | 226 ------------------ 2 files changed, 19 insertions(+), 354 deletions(-) delete mode 100644 end-to-end-use-cases/coding/text2sql/quickstart/quickstart_test.ipynb diff --git a/end-to-end-use-cases/coding/text2sql/quickstart/quickstart.ipynb b/end-to-end-use-cases/coding/text2sql/quickstart/quickstart.ipynb index 3b04f9890..e9a0a1c97 100644 --- a/end-to-end-use-cases/coding/text2sql/quickstart/quickstart.ipynb +++ b/end-to-end-use-cases/coding/text2sql/quickstart/quickstart.ipynb @@ -5,8 +5,6 @@ "id": "e8cba0b6", "metadata": {}, "source": [ - "\"Open \n", - "\n", "## Quick Demo of Text2SQL Using Llama 3.3\n", "\n", "This demo shows how to use Llama 3.3 to answer questions about a SQLite DB. \n", @@ -26,7 +24,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "fa4562d3", "metadata": {}, "outputs": [], @@ -65,7 +63,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "3bb99f39-cd7a-4db6-91dd-02f3bf80347c", "metadata": {}, "outputs": [], @@ -81,36 +79,10 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "8d793ce7-324b-4861-926c-54973d7c9b43", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Based on the table schema below, write a SQL query that would answer the user's question; just return the SQL query and nothing else.\n", - "\n", - "Scheme:\n", - "\n", - "CREATE TABLE nba_roster (\n", - "\t\"Team\" TEXT, \n", - "\t\"NAME\" TEXT, \n", - "\t\"Jersey\" TEXT, \n", - "\t\"POS\" TEXT, \n", - "\t\"AGE\" INTEGER, \n", - "\t\"HT\" TEXT, \n", - "\t\"WT\" TEXT, \n", - "\t\"COLLEGE\" TEXT, \n", - "\t\"SALARY\" TEXT\n", - ")\n", - "\n", - "Question: What team is Stephen Curry on?\n", - "\n", - "SQL Query:\n" - ] - } - ], + "outputs": [], "source": [ "question = \"What team is Stephen Curry on?\"\n", "prompt = f\"\"\"Based on the table schema below, write a SQL query that would answer the user's question; just return the SQL query and nothing else.\n", @@ -127,18 +99,10 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "70776558", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "SELECT Team FROM nba_roster WHERE NAME = 'Stephen Curry'\n" - ] - } - ], + "outputs": [], "source": [ "answer = llm.invoke(prompt).content\n", "print(answer)" @@ -154,21 +118,10 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "id": "62472ce6-794b-4a61-b88c-a1e031e28e4e", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\"[('Golden State Warriors',)]\"" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# note this is a dangerous operation and for demo purpose only; in production app you'll need to safe-guard any DB operation\n", "result = db.run(answer)\n", @@ -177,18 +130,10 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "id": "39ed4bc3", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "I don't have enough information to determine whose salary you are referring to. Could you please provide more context or specify the person you are asking about?\n" - ] - } - ], + "outputs": [], "source": [ "# how about a follow up question\n", "follow_up = \"What's his salary?\"\n", @@ -205,39 +150,10 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "id": "0c305278-29d2-4e88-9b3d-ad67c94ce0f2", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Based on the table schema, question, SQL query, and SQL response below, write a new SQL response; be concise, just output the SQL response.\n", - "\n", - "Scheme:\n", - "\n", - "CREATE TABLE nba_roster (\n", - "\t\"Team\" TEXT, \n", - "\t\"NAME\" TEXT, \n", - "\t\"Jersey\" TEXT, \n", - "\t\"POS\" TEXT, \n", - "\t\"AGE\" INTEGER, \n", - "\t\"HT\" TEXT, \n", - "\t\"WT\" TEXT, \n", - "\t\"COLLEGE\" TEXT, \n", - "\t\"SALARY\" TEXT\n", - ")\n", - "\n", - "Question: What's his salary?\n", - "SQL Query: What team is Stephen Curry on?\n", - "SQL Result: [('Golden State Warriors',)]\n", - "\n", - "New SQL Response:\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "prompt = f\"\"\"Based on the table schema, question, SQL query, and SQL response below, write a new SQL response; be concise, just output the SQL response.\n", "\n", @@ -255,18 +171,10 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "id": "03739b96-e607-4fa9-bc5c-df118198dc7f", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "SELECT SALARY FROM nba_roster WHERE NAME = \"Stephen Curry\"\n" - ] - } - ], + "outputs": [], "source": [ "new_answer = llm.invoke(prompt).content\n", "print(new_answer)" @@ -282,32 +190,13 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "id": "6ecfca53-be7e-4668-bad1-5ca7571817d7", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "\"[('$51,915,615',)]\"" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "db.run(new_answer)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9d79bbb1-e91d-4b56-b6ef-98c94ff414d0", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { @@ -331,5 +220,7 @@ "pygments_lexer": "ipython3", "version": "3.10.14" } - } + }, + "nbformat": 4, + "nbformat_minor": 5 } diff --git a/end-to-end-use-cases/coding/text2sql/quickstart/quickstart_test.ipynb b/end-to-end-use-cases/coding/text2sql/quickstart/quickstart_test.ipynb deleted file mode 100644 index e9a0a1c97..000000000 --- a/end-to-end-use-cases/coding/text2sql/quickstart/quickstart_test.ipynb +++ /dev/null @@ -1,226 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "e8cba0b6", - "metadata": {}, - "source": [ - "## Quick Demo of Text2SQL Using Llama 3.3\n", - "\n", - "This demo shows how to use Llama 3.3 to answer questions about a SQLite DB. \n", - "\n", - "We'll use LangChain and the Llama cloud provider [Together.ai](https://api.together.ai/), where you can easily get a free API key (or you can use any other Llama cloud provider or even Ollama running Llama locally)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "33fb3190-59fb-4edd-82dd-f20f6eab3e47", - "metadata": {}, - "outputs": [], - "source": [ - "!pip install --upgrade -r requirements.txt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fa4562d3", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "from langchain_together import ChatTogether\n", - "\n", - "os.environ['TOGETHER_API_KEY'] = 'your_api_key'\n", - "\n", - "llm = ChatTogether(\n", - " model=\"meta-llama/Llama-3.3-70B-Instruct-Turbo\",\n", - " temperature=0,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "6d421ae7", - "metadata": {}, - "source": [ - "To recreate the `nba_roster.db` file, run the two commands below:\n", - "- `python txt2csv.py` to convert the `nba.txt` file to `nba_roster.csv`. The `nba.txt` file was created by scraping the NBA roster info from the web.\n", - "- `python csv2db.py` to convert `nba_roster.csv` to `nba_roster.db`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "56f0360e-fca3-49a8-9a70-0416f84e15fc", - "metadata": {}, - "outputs": [], - "source": [ - "# uncomment if you don't want to create the db yourself\n", - "#! wget https://github.com/meta-llama/llama-recipes/raw/3649841b426999fdc61c30a9fc8721106bec769b/recipes/use_cases/coding/text2sql/nba_roster.db" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3bb99f39-cd7a-4db6-91dd-02f3bf80347c", - "metadata": {}, - "outputs": [], - "source": [ - "from langchain_community.utilities import SQLDatabase\n", - "\n", - "# Note: to run in Colab, you need to upload the nba_roster.db file in the repo to the Colab folder first.\n", - "db = SQLDatabase.from_uri(\"sqlite:///nba_roster.db\", sample_rows_in_table_info=0)\n", - "\n", - "def get_schema():\n", - " return db.get_table_info()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8d793ce7-324b-4861-926c-54973d7c9b43", - "metadata": {}, - "outputs": [], - "source": [ - "question = \"What team is Stephen Curry on?\"\n", - "prompt = f\"\"\"Based on the table schema below, write a SQL query that would answer the user's question; just return the SQL query and nothing else.\n", - "\n", - "Scheme:\n", - "{get_schema()}\n", - "\n", - "Question: {question}\n", - "\n", - "SQL Query:\"\"\"\n", - "\n", - "print(prompt)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "70776558", - "metadata": {}, - "outputs": [], - "source": [ - "answer = llm.invoke(prompt).content\n", - "print(answer)" - ] - }, - { - "cell_type": "markdown", - "id": "afcf423a", - "metadata": {}, - "source": [ - "***Note:*** If you don't have the \"just return the SQL query and nothing else\" in the prompt above, you'll likely get more text other than the SQL query back in the answer, making some extra post-processing necessary before running the db query below." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "62472ce6-794b-4a61-b88c-a1e031e28e4e", - "metadata": {}, - "outputs": [], - "source": [ - "# note this is a dangerous operation and for demo purpose only; in production app you'll need to safe-guard any DB operation\n", - "result = db.run(answer)\n", - "result" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "39ed4bc3", - "metadata": {}, - "outputs": [], - "source": [ - "# how about a follow up question\n", - "follow_up = \"What's his salary?\"\n", - "print(llm.invoke(follow_up).content)" - ] - }, - { - "cell_type": "markdown", - "id": "98b2c523", - "metadata": {}, - "source": [ - "Since we did not pass any context along with the follow-up to Llama, it doesn't know the answer. Let's try to fix it by adding context to the follow-up prompt." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0c305278-29d2-4e88-9b3d-ad67c94ce0f2", - "metadata": {}, - "outputs": [], - "source": [ - "prompt = f\"\"\"Based on the table schema, question, SQL query, and SQL response below, write a new SQL response; be concise, just output the SQL response.\n", - "\n", - "Scheme:\n", - "{get_schema()}\n", - "\n", - "Question: {follow_up}\n", - "SQL Query: {question}\n", - "SQL Result: {result}\n", - "\n", - "New SQL Response:\n", - "\"\"\"\n", - "print(prompt)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "03739b96-e607-4fa9-bc5c-df118198dc7f", - "metadata": {}, - "outputs": [], - "source": [ - "new_answer = llm.invoke(prompt).content\n", - "print(new_answer)" - ] - }, - { - "cell_type": "markdown", - "id": "c782abb6-3b44-45be-8694-70fc29b82523", - "metadata": {}, - "source": [ - "Because we have \"be concise, just output the SQL response\", Llama 3 is able to just generate the SQL statement; otherwise output parsing will be needed." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6ecfca53-be7e-4668-bad1-5ca7571817d7", - "metadata": {}, - "outputs": [], - "source": [ - "db.run(new_answer)" - ] - } - ], - "metadata": { - "fileHeader": "", - "fileUid": "559664fd-826e-43fa-86b4-78edb9bbf80e", - "isAdHoc": false, - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.14" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From cc93b731bd005bb57bc595960ed6174d2e48f13d Mon Sep 17 00:00:00 2001 From: Amir Youssefi <328194+ghd3v@users.noreply.github.com> Date: Fri, 11 Jul 2025 18:29:14 -0700 Subject: [PATCH 44/78] rm unsloth quantization notebook --- ...ama_3_1_8b_with_text2sql_sft_dataset.ipynb | 1146 ----------------- 1 file changed, 1146 deletions(-) delete mode 100644 end-to-end-use-cases/coding/text2sql/fine-tuning/finetuning_llama_3_1_8b_with_text2sql_sft_dataset.ipynb diff --git a/end-to-end-use-cases/coding/text2sql/fine-tuning/finetuning_llama_3_1_8b_with_text2sql_sft_dataset.ipynb b/end-to-end-use-cases/coding/text2sql/fine-tuning/finetuning_llama_3_1_8b_with_text2sql_sft_dataset.ipynb deleted file mode 100644 index 7a369fb5b..000000000 --- a/end-to-end-use-cases/coding/text2sql/fine-tuning/finetuning_llama_3_1_8b_with_text2sql_sft_dataset.ipynb +++ /dev/null @@ -1,1146 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "mdDXB8ivjXwB" - }, - "source": [ - "# Finetuning Llama-3.1 8b with text2sql SFT dataset\n", - "\n", - "This notebook implements necessary data transformations and installation of libraries. It works with Google Colab A-100 GPU (paid) instances. There are comments for changing it into int4 quantizations on T4 GPU.\n", - "\n", - "Unsloth library and code is used to lower GPU memory requirement and increase performance. See https://github.com/unslothai/unsloth\n", - "\n", - "To upload training dataset, click on Folder Icon on the left hand side of your Colab Notebook and upload your training data file: train_text2sql_sft_dataset.json (see instructions for generating the dataset under \"finetuning\" parent directory)." - ] - }, - { - "cell_type": "code", - "source": [ - "# Click on Folder icon on the left hand side of your Colab Notebook and upload your training data file: train_text2sql_sft_dataset.json\n", - "training_data_file = \"train_text2sql_sft_dataset.json\"" - ], - "metadata": { - "id": "LNDhsv0kfBih" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "5_K2EX0ejXwC" - }, - "outputs": [], - "source": [ - "# install libraries\n", - "!pip install -U datasets\n", - "\n", - "!pip install --no-deps bitsandbytes accelerate xformers==0.0.29.post3 peft trl==0.15.2 triton cut_cross_entropy unsloth_zoo\n", - "!pip install sentencepiece protobuf \"datasets>=3.4.1\" huggingface_hub hf_transfer\n", - "!pip install --no-deps unsloth" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 153, - "referenced_widgets": [ - "08cbd090cd594a998fc641cf4880df55", - "cfad6b5f4ce5418ba6555668de71fc5e", - "c9797e0a5d1746ffa9719278b8c6df97", - "bca3230d0f5841348e1d52bb965eb88a", - "eb24a737e7f949bbba05c97fc3930509", - "c1e4dbfa522e432cadaae898dc38b6d2", - "98a307da59ce474d83c078c4969e5bba", - "2e9a5b5f7bfc4205a2b7fc4d07527127", - "d8ff81bca7e44192bfc610cfebc78a99", - "fba7465393574fc4a188a0126dc42c63", - "a4215bedeb224a37a40edf231308c247" - ] - }, - "id": "QmUBVEnvCDJv", - "outputId": "41922c6c-825f-4cf8-e857-d3dda55050c5" - }, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "==((====))== Unsloth 2025.6.8: Fast Llama patching. Transformers: 4.52.4.\n", - " \\\\ /| NVIDIA A100-SXM4-40GB. Num GPUs = 1. Max memory: 39.557 GB. Platform: Linux.\n", - "O^O/ \\_/ \\ Torch: 2.6.0+cu124. CUDA: 8.0. CUDA Toolkit: 12.4. Triton: 3.2.0\n", - "\\ / Bfloat16 = TRUE. FA [Xformers = 0.0.29.post3. FA2 = False]\n", - " \"-____-\" Free license: http://github.com/unslothai/unsloth\n", - "Unsloth: Fast downloading is enabled - ignore downloading bars which are red colored!\n" - ] - }, - { - "output_type": "display_data", - "data": { - "text/plain": [ - "Loading checkpoint shards: 0%| | 0/4 [00:00Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.\n", - "\n", - "### Instruction:\n", - "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement.\n", - "\n", - "### Input:\n", - "-- DB Schema: CREATE TABLE \"lists\"\n", - "(\n", - " user_id INTEGER\n", - " references lists_users (user_id),\n", - " list_id INTEGER not null\n", - " primary key,\n", - " list_title TEXT,\n", - " list_movie_number INTEGER,\n", - " list_update_timestamp_utc TEXT,\n", - " list_creation_timestamp_utc TEXT,\n", - " list_followers INTEGER,\n", - " list_url TEXT,\n", - " list_comments INTEGER,\n", - " list_description TEXT,\n", - " list_cover_image_url TEXT,\n", - " list_first_image_url TEXT,\n", - " list_second_image_url TEXT,\n", - " list_third_image_url TEXT\n", - ")\n", - "\n", - "CREATE TABLE \"movies\"\n", - "(\n", - " movie_id INTEGER not null\n", - " primary key,\n", - " movie_title TEXT,\n", - " movie_release_year INTEGER,\n", - " movie_url TEXT,\n", - " movie_title_language TEXT,\n", - " movie_popularity INTEGER,\n", - " movie_image_url TEXT,\n", - " director_id TEXT,\n", - " director_name TEXT,\n", - " director_url TEXT\n", - ")\n", - "\n", - "CREATE TABLE \"ratings_users\"\n", - "(\n", - " user_id INTEGER\n", - " references lists_users (user_id),\n", - " rating_date_utc TEXT,\n", - " user_trialist INTEGER,\n", - " user_subscriber INTEGER,\n", - " user_avatar_image_url TEXT,\n", - " user_cover_image_url TEXT,\n", - " user_eligible_for_trial INTEGER,\n", - " user_has_payment_method INTEGER\n", - ")\n", - "\n", - "CREATE TABLE lists_users\n", - "(\n", - " user_id INTEGER not null,\n", - " list_id INTEGER not null,\n", - " list_update_date_utc TEXT,\n", - " list_creation_date_utc TEXT,\n", - " user_trialist INTEGER,\n", - " user_subscriber INTEGER,\n", - " user_avatar_image_url TEXT,\n", - " user_cover_image_url TEXT,\n", - " user_eligible_for_trial TEXT,\n", - " user_has_payment_method TEXT,\n", - " primary key (user_id, list_id),\n", - " foreign key (list_id) references lists(list_id),\n", - " foreign key (user_id) references lists(user_id)\n", - ")\n", - "\n", - "CREATE TABLE ratings\n", - "(\n", - " movie_id INTEGER,\n", - " rating_id INTEGER,\n", - " rating_url TEXT,\n", - " rating_score INTEGER,\n", - " rating_timestamp_utc TEXT,\n", - " critic TEXT,\n", - " critic_likes INTEGER,\n", - " critic_comments INTEGER,\n", - " user_id INTEGER,\n", - " user_trialist INTEGER,\n", - " user_subscriber INTEGER,\n", - " user_eligible_for_trial INTEGER,\n", - " user_has_payment_method INTEGER,\n", - " foreign key (movie_id) references movies(movie_id),\n", - " foreign key (user_id) references lists_users(user_id),\n", - " foreign key (rating_id) references ratings(rating_id),\n", - " foreign key (user_id) references ratings_users(user_id)\n", - ")\n", - "\n", - "-- External Knowledge: longest movie title refers to MAX(LENGTH(movie_title)); when it was released refers to movie_release_year;\n", - "\n", - "-- Question: What is the name of the longest movie title? When was it released?\n", - "\n", - "### Response:\n", - "<|eot_id|><|start_header_id|>assistant<|end_header_id|>\n", - "\n", - "SELECT movie_title, movie_release_year FROM movies ORDER BY LENGTH(movie_title) DESC LIMIT 1;<|eot_id|>\n" - ] - } - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "SXd9bTZd1aaL" - }, - "source": [ - "We now add LoRA adapters so we only need to update 1 to 10% of all parameters!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "6bZsfBuZDeCL", - "outputId": "1473bfc7-ed18-4ad5-a115-b2872c7d5f93" - }, - "outputs": [ - { - "output_type": "stream", - "name": "stderr", - "text": [ - "Unsloth 2025.6.8 patched 32 layers with 32 QKV layers, 32 O layers and 32 MLP layers.\n" - ] - } - ], - "source": [ - "model = FastLanguageModel.get_peft_model(\n", - " model,\n", - " r = 16, # Choose any number > 0 ! Suggested 8, 16, 32, 64, 128\n", - " target_modules = [\"q_proj\", \"k_proj\", \"v_proj\", \"o_proj\",\n", - " \"gate_proj\", \"up_proj\", \"down_proj\",],\n", - " lora_alpha = 16,\n", - " lora_dropout = 0, # Supports any, but = 0 is optimized\n", - " bias = \"none\", # Supports any, but = \"none\" is optimized\n", - " # [NEW] \"unsloth\" uses 30% less VRAM, fits 2x larger batch sizes!\n", - " use_gradient_checkpointing = \"unsloth\", # True or \"unsloth\" for very long context\n", - " random_state = 3407,\n", - " use_rslora = False, # We support rank stabilized LoRA\n", - " loftq_config = None, # And LoftQ\n", - ")" - ] - }, - { - "cell_type": "code", - "source": [ - "# Data Prep\n", - "# We transform data from existing .json format into new prompt format.\n", - "\n", - "# **[NOTE]** Remember to add the **EOS_TOKEN** to the tokenized output!! Otherwise you'll get infinite generations!\n", - "\n", - "lines = []\n", - "with open(training_data_file, \"r\") as f:\n", - " lines = f.readlines()\n", - "\n", - "print(lines[:2])\n", - "\n", - "alpaca_prompt = \"\"\"Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.\n", - "\n", - "### Instruction:\n", - "{}\n", - "\n", - "### Input:\n", - "{}\n", - "\n", - "### Response:\n", - "{}\"\"\"\n", - "\n", - "EOS_TOKEN = tokenizer.eos_token # Must add EOS_TOKEN\n", - "def formatting_prompts_func(messages):\n", - " instruction = messages['messages'][0][\"content\"]\n", - " input = messages['messages'][1][\"content\"]\n", - " output = messages['messages'][2][\"content\"]\n", - " text = alpaca_prompt.format(instruction, input, output) + EOS_TOKEN\n", - " return { \"text\" : text, }\n", - "pass\n", - "\n", - "from datasets import load_dataset, load_from_disk\n", - "dataset_raw = load_dataset(\"json\", data_files=\"train_text2sql_sft_dataset.json\", split=\"train\")\n", - "dataset = dataset_raw.map(formatting_prompts_func, batched = False,)\n", - "dataset" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 188, - "referenced_widgets": [ - "637dedfe81724192b863c2b131aeb933", - "781541b6bc7c473ea2cf33f83017b648", - "c36068a9af284e31890f576d50da2c5f", - "c3930523cc43497dbcd21eba69dc3b6d", - "32c851dd54954b72950a9e0f06d01aa1", - "49e949498a004d2ca5f06edd67304327", - "70f55e99c7944da9ae8a6445a0ce9b6b", - "4c13c8d1c64e4d1893ebcc7712907951", - "8ad04e1707b74a0b89e1aa7e511584e0", - "4250701d8d3849feb9d00e94f259d980", - "91e6c3a9ea524d5ab7b7c8fce66d7a36", - "61ad4905a7c448fea70755c44a9ee7f3", - "9dbc55420dd349f79b4fcbebe9cb98bd", - "2d8b27dd71884459ace7a252ff86603f", - "f505fbfb17064ba59d2bfc6ff4bc41b2", - "446fd4d425a840799c06c1bae0ab133b", - "95bae4f5e1424f1480aec8d53490bba4", - "6223f835a0164b6ea52b1889b0bcd0f8", - "b5a0439f345d4e6ba6f18f9ac9dfe771", - "cce40322aa7f48d6abfa03506d0e2630", - "42581a1a1e364903974416b11989f0f6", - "29a85fb494734faca4baf1ecb00f0c3c" - ] - }, - "id": "rruFkJLzmBp8", - "outputId": "b340cf82-3d91-4270-8e5c-584804c3186f" - }, - "execution_count": null, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "['{\"messages\":[{\"content\":\"You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement.\",\"role\":\"system\"},{\"content\":\"-- DB Schema: CREATE TABLE \\\\\"lists\\\\\"\\\\n(\\\\n user_id INTEGER\\\\n references lists_users (user_id),\\\\n list_id INTEGER not null\\\\n primary key,\\\\n list_title TEXT,\\\\n list_movie_number INTEGER,\\\\n list_update_timestamp_utc TEXT,\\\\n list_creation_timestamp_utc TEXT,\\\\n list_followers INTEGER,\\\\n list_url TEXT,\\\\n list_comments INTEGER,\\\\n list_description TEXT,\\\\n list_cover_image_url TEXT,\\\\n list_first_image_url TEXT,\\\\n list_second_image_url TEXT,\\\\n list_third_image_url TEXT\\\\n)\\\\n\\\\nCREATE TABLE \\\\\"movies\\\\\"\\\\n(\\\\n movie_id INTEGER not null\\\\n primary key,\\\\n movie_title TEXT,\\\\n movie_release_year INTEGER,\\\\n movie_url TEXT,\\\\n movie_title_language TEXT,\\\\n movie_popularity INTEGER,\\\\n movie_image_url TEXT,\\\\n director_id TEXT,\\\\n director_name TEXT,\\\\n director_url TEXT\\\\n)\\\\n\\\\nCREATE TABLE \\\\\"ratings_users\\\\\"\\\\n(\\\\n user_id INTEGER\\\\n references lists_users (user_id),\\\\n rating_date_utc TEXT,\\\\n user_trialist INTEGER,\\\\n user_subscriber INTEGER,\\\\n user_avatar_image_url TEXT,\\\\n user_cover_image_url TEXT,\\\\n user_eligible_for_trial INTEGER,\\\\n user_has_payment_method INTEGER\\\\n)\\\\n\\\\nCREATE TABLE lists_users\\\\n(\\\\n user_id INTEGER not null ,\\\\n list_id INTEGER not null ,\\\\n list_update_date_utc TEXT,\\\\n list_creation_date_utc TEXT,\\\\n user_trialist INTEGER,\\\\n user_subscriber INTEGER,\\\\n user_avatar_image_url TEXT,\\\\n user_cover_image_url TEXT,\\\\n user_eligible_for_trial TEXT,\\\\n user_has_payment_method TEXT,\\\\n primary key (user_id, list_id),\\\\n foreign key (list_id) references lists(list_id),\\\\n foreign key (user_id) references lists(user_id)\\\\n)\\\\n\\\\nCREATE TABLE ratings\\\\n(\\\\n movie_id INTEGER,\\\\n rating_id INTEGER,\\\\n rating_url TEXT,\\\\n rating_score INTEGER,\\\\n rating_timestamp_utc TEXT,\\\\n critic TEXT,\\\\n critic_likes INTEGER,\\\\n critic_comments INTEGER,\\\\n user_id INTEGER,\\\\n user_trialist INTEGER,\\\\n user_subscriber INTEGER,\\\\n user_eligible_for_trial INTEGER,\\\\n user_has_payment_method INTEGER,\\\\n foreign key (movie_id) references movies(movie_id),\\\\n foreign key (user_id) references lists_users(user_id),\\\\n foreign key (rating_id) references ratings(rating_id),\\\\n foreign key (user_id) references ratings_users(user_id)\\\\n)\\\\n\\\\n-- External Knowledge: released in the year 1945 refers to movie_release_year = 1945;\\\\n\\\\n-- Question: Name movie titles released in year 1945. Sort the listing by the descending order of movie popularity.\",\"role\":\"user\"},{\"content\":\"SELECT movie_title FROM movies WHERE movie_release_year = 1945 ORDER BY movie_popularity DESC LIMIT 1\",\"role\":\"assistant\"}]}\\n', '{\"messages\":[{\"content\":\"You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement.\",\"role\":\"system\"},{\"content\":\"-- DB Schema: CREATE TABLE \\\\\"lists\\\\\"\\\\n(\\\\n user_id INTEGER\\\\n references lists_users (user_id),\\\\n list_id INTEGER not null\\\\n primary key,\\\\n list_title TEXT,\\\\n list_movie_number INTEGER,\\\\n list_update_timestamp_utc TEXT,\\\\n list_creation_timestamp_utc TEXT,\\\\n list_followers INTEGER,\\\\n list_url TEXT,\\\\n list_comments INTEGER,\\\\n list_description TEXT,\\\\n list_cover_image_url TEXT,\\\\n list_first_image_url TEXT,\\\\n list_second_image_url TEXT,\\\\n list_third_image_url TEXT\\\\n)\\\\n\\\\nCREATE TABLE \\\\\"movies\\\\\"\\\\n(\\\\n movie_id INTEGER not null\\\\n primary key,\\\\n movie_title TEXT,\\\\n movie_release_year INTEGER,\\\\n movie_url TEXT,\\\\n movie_title_language TEXT,\\\\n movie_popularity INTEGER,\\\\n movie_image_url TEXT,\\\\n director_id TEXT,\\\\n director_name TEXT,\\\\n director_url TEXT\\\\n)\\\\n\\\\nCREATE TABLE \\\\\"ratings_users\\\\\"\\\\n(\\\\n user_id INTEGER\\\\n references lists_users (user_id),\\\\n rating_date_utc TEXT,\\\\n user_trialist INTEGER,\\\\n user_subscriber INTEGER,\\\\n user_avatar_image_url TEXT,\\\\n user_cover_image_url TEXT,\\\\n user_eligible_for_trial INTEGER,\\\\n user_has_payment_method INTEGER\\\\n)\\\\n\\\\nCREATE TABLE lists_users\\\\n(\\\\n user_id INTEGER not null ,\\\\n list_id INTEGER not null ,\\\\n list_update_date_utc TEXT,\\\\n list_creation_date_utc TEXT,\\\\n user_trialist INTEGER,\\\\n user_subscriber INTEGER,\\\\n user_avatar_image_url TEXT,\\\\n user_cover_image_url TEXT,\\\\n user_eligible_for_trial TEXT,\\\\n user_has_payment_method TEXT,\\\\n primary key (user_id, list_id),\\\\n foreign key (list_id) references lists(list_id),\\\\n foreign key (user_id) references lists(user_id)\\\\n)\\\\n\\\\nCREATE TABLE ratings\\\\n(\\\\n movie_id INTEGER,\\\\n rating_id INTEGER,\\\\n rating_url TEXT,\\\\n rating_score INTEGER,\\\\n rating_timestamp_utc TEXT,\\\\n critic TEXT,\\\\n critic_likes INTEGER,\\\\n critic_comments INTEGER,\\\\n user_id INTEGER,\\\\n user_trialist INTEGER,\\\\n user_subscriber INTEGER,\\\\n user_eligible_for_trial INTEGER,\\\\n user_has_payment_method INTEGER,\\\\n foreign key (movie_id) references movies(movie_id),\\\\n foreign key (user_id) references lists_users(user_id),\\\\n foreign key (rating_id) references ratings(rating_id),\\\\n foreign key (user_id) references ratings_users(user_id)\\\\n)\\\\n\\\\n-- External Knowledge: most popular movie refers to MAX(movie_popularity); when it was released refers to movie_release_year; director for the movie refers to director_name;\\\\n\\\\n-- Question: State the most popular movie? When was it released and who is the director for the movie?\",\"role\":\"user\"},{\"content\":\"SELECT movie_title, movie_release_year, director_name FROM movies ORDER BY movie_popularity DESC LIMIT 1 \",\"role\":\"assistant\"}]}\\n']\n" - ] - }, - { - "output_type": "display_data", - "data": { - "text/plain": [ - "Generating train split: 0 examples [00:00, ? examples/s]" - ], - "application/vnd.jupyter.widget-view+json": { - "version_major": 2, - "version_minor": 0, - "model_id": "637dedfe81724192b863c2b131aeb933" - } - }, - "metadata": {} - }, - { - "output_type": "display_data", - "data": { - "text/plain": [ - "Map: 0%| | 0/6599 [00:00\n", - "### Train the model\n", - "Now let's use Huggingface TRL's `SFTTrainer`! More docs here: [TRL SFT docs](https://huggingface.co/docs/trl/sft_trainer). We do 60 steps to speed things up, but you can set `num_train_epochs=1` for a full run, and turn off `max_steps=None`. We also support TRL's `DPOTrainer`!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 49, - "referenced_widgets": [ - "1e212fe262544328967e36fb26e06073", - "0badc1c8b9424b8cb2c526a3bc80294a", - "d0c3e1bc46314b3a822e8350f6ed4904", - "46538c8c222a4ebb81abf0daad5bfa79", - "52711139b56948fcbeca651623d194a0", - "78a35430e1bd47549124eac98be01fdd", - "701bbc75e7214abc93e7d15d42f7c22f", - "09d61405fbb4468cb49a430b6b462276", - "4e36e192ac3947efbb9a8a4e2f4cfbe2", - "a2e091222faa4d38877b613f8036025d", - "7d56d8683551408182969f6201605c86" - ] - }, - "id": "95_Nn-89DhsL", - "outputId": "49490f23-f927-424b-8e88-2b77b0f18aed" - }, - "outputs": [ - { - "output_type": "display_data", - "data": { - "text/plain": [ - "Unsloth: Tokenizing [\"text\"]: 0%| | 0/6599 [00:00" - ], - "text/html": [ - "\n", - "

l>(pOyKkLU8|S5jUQKm&kVd@S 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 literal 0 HcmV?d00001 From 79945b6b8dc385eb449919992e5c506de828c47d Mon Sep 17 00:00:00 2001 From: Jeff Tang Date: Sat, 28 Jun 2025 11:20:33 -0700 Subject: [PATCH 18/78] parent README update --- .../coding/text2sql/README.md | 26 +++++-------------- .../coding/text2sql/tool/README.md | 2 +- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/end-to-end-use-cases/coding/text2sql/README.md b/end-to-end-use-cases/coding/text2sql/README.md index 1198a2d88..eaaa91a9c 100644 --- a/end-to-end-use-cases/coding/text2sql/README.md +++ b/end-to-end-use-cases/coding/text2sql/README.md @@ -1,30 +1,16 @@ -## Text2SQL: Natural Language to SQL Interface +## Text2SQL: Eval and Fine-tuning Tools and Quick Start Notebook -This project provides a set of scripts to convert natural language queries into SQL statements using Meta's Llama model. The goal is to enable users to interact with databases using natural language inputs, making it easier for non-technical users to access and analyze data. +This folder contains the `tool` subfolder, which has e2e scripts for evaluating Llama (original and fine-tuned) models on the Text2SQL task using the popular [BIRD](https://bird-bench.github.io) dataset, and e2e scripts for generating fine-tuning datasets and fine-tuning Llama 3.1 8B with the datasets. -For detailed instructions on setting up the environment, creating a database, and executing natural language queries using the Text2SQL interface, please refer to the quickstart.ipynb notebook. +Before looking into the `tool` folder, you may start with the scripts and notebook in this folder to get familiar with how to interact with a database using natural language inputs bu asking Llama to convert natural language queries into SQL queries. + +For detailed instructions on setting up the environment, creating a database, and executing natural language queries using the Text2SQL interface, please refer to the [quickstart.ipynb](quickstart.ipynb) notebook. ### Structure: +- tool: A folder containing scripts for evaluating and fine-tuning Llama models on the Text2SQL task. - quickstart.ipynb: A Quick Demo of Text2SQL Using Llama 3.3. This Jupyter Notebook includes examples of how to use the interface to execute natural language queries on the sample data. It uses Llama 3.3 to answer questions about a SQLite database using LangChain and the Llama cloud provider Together.ai. - nba.txt: A text file containing NBA roster information, which is used as sample data for demonstration purposes. - txt2csv.py: A script that converts text data into a CSV format. This script is used to preprocess the input data before it is fed into csv2db.py. - csv2db.py: A script that imports data from a CSV file into a SQLite database. This script is used to populate the database with sample data. - nba_roster.db: A SQLite database file created from the nba.txt data, used to test the Text2SQL interface. - -### Detailed steps on running the notebook: - -- Before getting started, please make sure to setup Together.ai and get an API key from [here](https://www.together.ai/). - -- First, please install the requirements from [here](https://github.com/meta-llama/llama-cookbook/blob/main/end-to-end-use-cases/coding/text2sql/requirements.txt) by running inside the folder: - -``` -git clone https://github.com/meta-llama/llama-cookbook.git -cd llama-cookbook/end-to-end-use-cases/coding/text2sql/ -pip install -r requirements.txt -``` - -### Contributing -Contributions are welcome! If you'd like to add new features or improve existing ones, please submit a pull request. We encourage contributions in the following areas: -- Adding support for additional databases -- Developing new interfaces or applications that use the Text2SQL interface \ No newline at end of file diff --git a/end-to-end-use-cases/coding/text2sql/tool/README.md b/end-to-end-use-cases/coding/text2sql/tool/README.md index c4ba12422..98ef76d20 100644 --- a/end-to-end-use-cases/coding/text2sql/tool/README.md +++ b/end-to-end-use-cases/coding/text2sql/tool/README.md @@ -2,7 +2,7 @@ ## Overview -This folder contains the scripts for evaluating Llama (original and fine-tuned) models on the Text2SQL task using the popular [BIRD](https://bird-bench.github.io) dataset, generating fine-tuning datasets, and fine-tuning Llama 3.1 8B with the datasets. +This folder contains scripts for evaluating Llama (original and fine-tuned) models on the Text2SQL task using the popular [BIRD](https://bird-bench.github.io) dataset, and scripts for generating fine-tuning datasets and fine-tuning Llama 3.1 8B with the datasets. We have updated and significantly simplified the original eval scripts from the BIRD [repo](https://github.com/AlibabaResearch/DAMO-ConvAI/tree/main/bird) for Llama 3 & 4 models hosted via Meta's [Llama API](https://llama.developer.meta.com) or [Together.ai](https://together.ai), as well as the fine-tuned Llama 3.1 model, so you can quickly evaluate in 1-2-3 steps how well different Llama models perform on the Text2SQL task. From 0aa42d8d6e5b4fdd5f6e497668caa2de0cc077b7 Mon Sep 17 00:00:00 2001 From: Amir Youssefi Date: Mon, 30 Jun 2025 18:25:29 -0700 Subject: [PATCH 19/78] adding text2sql colab notebook for fine-tuning --- ...ama_3_1_8b_with_text2sql_sft_dataset.ipynb | 3558 +++++++++++++++++ 1 file changed, 3558 insertions(+) create mode 100644 end-to-end-use-cases/coding/text2sql/tool/fine_tuning/finetuning_llama_3_1_8b_with_text2sql_sft_dataset.ipynb diff --git a/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/finetuning_llama_3_1_8b_with_text2sql_sft_dataset.ipynb b/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/finetuning_llama_3_1_8b_with_text2sql_sft_dataset.ipynb new file mode 100644 index 000000000..f3e26abd0 --- /dev/null +++ b/end-to-end-use-cases/coding/text2sql/tool/fine_tuning/finetuning_llama_3_1_8b_with_text2sql_sft_dataset.ipynb @@ -0,0 +1,3558 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "mdDXB8ivjXwB" + }, + "source": [ + "# Finetuning Llama-3.1 8b with text2sql SFT dataset\n", + "\n", + "This notebook implements necessary data transformations and installation of libraries. It works with Google Colab A-100 GPU (paid) instances. There are comments for changing it into int4 quantizations on T4 GPU.\n", + "\n", + "Unsloth library and code is used to lower GPU memory requirement and increase performance. See https://github.com/unslothai/unsloth\n", + "\n", + "To upload training dataset, click on Folder Icon on the left hand side of your Colab Notebook and upload your training data file: train_text2sql_sft_dataset.json (see instructions for generating the dataset under \"finetuning\" parent directory)." + ] + }, + { + "cell_type": "code", + "source": [ + "# Click on Folder icon on the left hand side of your Colab Notebook and upload your training data file: train_text2sql_sft_dataset.json\n", + "training_data_file = \"train_text2sql_sft_dataset.json\"" + ], + "metadata": { + "id": "LNDhsv0kfBih" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "5_K2EX0ejXwC" + }, + "outputs": [], + "source": [ + "# install libraries\n", + "!pip install -U datasets\n", + "\n", + "!pip install --no-deps bitsandbytes accelerate xformers==0.0.29.post3 peft trl==0.15.2 triton cut_cross_entropy unsloth_zoo\n", + "!pip install sentencepiece protobuf \"datasets>=3.4.1\" huggingface_hub hf_transfer\n", + "!pip install --no-deps unsloth" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 153, + "referenced_widgets": [ + "08cbd090cd594a998fc641cf4880df55", + "cfad6b5f4ce5418ba6555668de71fc5e", + "c9797e0a5d1746ffa9719278b8c6df97", + "bca3230d0f5841348e1d52bb965eb88a", + "eb24a737e7f949bbba05c97fc3930509", + "c1e4dbfa522e432cadaae898dc38b6d2", + "98a307da59ce474d83c078c4969e5bba", + "2e9a5b5f7bfc4205a2b7fc4d07527127", + "d8ff81bca7e44192bfc610cfebc78a99", + "fba7465393574fc4a188a0126dc42c63", + "a4215bedeb224a37a40edf231308c247" + ] + }, + "id": "QmUBVEnvCDJv", + "outputId": "41922c6c-825f-4cf8-e857-d3dda55050c5" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "==((====))== Unsloth 2025.6.8: Fast Llama patching. Transformers: 4.52.4.\n", + " \\\\ /| NVIDIA A100-SXM4-40GB. Num GPUs = 1. Max memory: 39.557 GB. Platform: Linux.\n", + "O^O/ \\_/ \\ Torch: 2.6.0+cu124. CUDA: 8.0. CUDA Toolkit: 12.4. Triton: 3.2.0\n", + "\\ / Bfloat16 = TRUE. FA [Xformers = 0.0.29.post3. FA2 = False]\n", + " \"-____-\" Free license: http://github.com/unslothai/unsloth\n", + "Unsloth: Fast downloading is enabled - ignore downloading bars which are red colored!\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "Loading checkpoint shards: 0%| | 0/4 [00:00Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.\n", + "\n", + "### Instruction:\n", + "You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement.\n", + "\n", + "### Input:\n", + "-- DB Schema: CREATE TABLE \"lists\"\n", + "(\n", + " user_id INTEGER\n", + " references lists_users (user_id),\n", + " list_id INTEGER not null\n", + " primary key,\n", + " list_title TEXT,\n", + " list_movie_number INTEGER,\n", + " list_update_timestamp_utc TEXT,\n", + " list_creation_timestamp_utc TEXT,\n", + " list_followers INTEGER,\n", + " list_url TEXT,\n", + " list_comments INTEGER,\n", + " list_description TEXT,\n", + " list_cover_image_url TEXT,\n", + " list_first_image_url TEXT,\n", + " list_second_image_url TEXT,\n", + " list_third_image_url TEXT\n", + ")\n", + "\n", + "CREATE TABLE \"movies\"\n", + "(\n", + " movie_id INTEGER not null\n", + " primary key,\n", + " movie_title TEXT,\n", + " movie_release_year INTEGER,\n", + " movie_url TEXT,\n", + " movie_title_language TEXT,\n", + " movie_popularity INTEGER,\n", + " movie_image_url TEXT,\n", + " director_id TEXT,\n", + " director_name TEXT,\n", + " director_url TEXT\n", + ")\n", + "\n", + "CREATE TABLE \"ratings_users\"\n", + "(\n", + " user_id INTEGER\n", + " references lists_users (user_id),\n", + " rating_date_utc TEXT,\n", + " user_trialist INTEGER,\n", + " user_subscriber INTEGER,\n", + " user_avatar_image_url TEXT,\n", + " user_cover_image_url TEXT,\n", + " user_eligible_for_trial INTEGER,\n", + " user_has_payment_method INTEGER\n", + ")\n", + "\n", + "CREATE TABLE lists_users\n", + "(\n", + " user_id INTEGER not null,\n", + " list_id INTEGER not null,\n", + " list_update_date_utc TEXT,\n", + " list_creation_date_utc TEXT,\n", + " user_trialist INTEGER,\n", + " user_subscriber INTEGER,\n", + " user_avatar_image_url TEXT,\n", + " user_cover_image_url TEXT,\n", + " user_eligible_for_trial TEXT,\n", + " user_has_payment_method TEXT,\n", + " primary key (user_id, list_id),\n", + " foreign key (list_id) references lists(list_id),\n", + " foreign key (user_id) references lists(user_id)\n", + ")\n", + "\n", + "CREATE TABLE ratings\n", + "(\n", + " movie_id INTEGER,\n", + " rating_id INTEGER,\n", + " rating_url TEXT,\n", + " rating_score INTEGER,\n", + " rating_timestamp_utc TEXT,\n", + " critic TEXT,\n", + " critic_likes INTEGER,\n", + " critic_comments INTEGER,\n", + " user_id INTEGER,\n", + " user_trialist INTEGER,\n", + " user_subscriber INTEGER,\n", + " user_eligible_for_trial INTEGER,\n", + " user_has_payment_method INTEGER,\n", + " foreign key (movie_id) references movies(movie_id),\n", + " foreign key (user_id) references lists_users(user_id),\n", + " foreign key (rating_id) references ratings(rating_id),\n", + " foreign key (user_id) references ratings_users(user_id)\n", + ")\n", + "\n", + "-- External Knowledge: longest movie title refers to MAX(LENGTH(movie_title)); when it was released refers to movie_release_year;\n", + "\n", + "-- Question: What is the name of the longest movie title? When was it released?\n", + "\n", + "### Response:\n", + "<|eot_id|><|start_header_id|>assistant<|end_header_id|>\n", + "\n", + "SELECT movie_title, movie_release_year FROM movies ORDER BY LENGTH(movie_title) DESC LIMIT 1;<|eot_id|>\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SXd9bTZd1aaL" + }, + "source": [ + "We now add LoRA adapters so we only need to update 1 to 10% of all parameters!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "6bZsfBuZDeCL", + "outputId": "1473bfc7-ed18-4ad5-a115-b2872c7d5f93" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "Unsloth 2025.6.8 patched 32 layers with 32 QKV layers, 32 O layers and 32 MLP layers.\n" + ] + } + ], + "source": [ + "model = FastLanguageModel.get_peft_model(\n", + " model,\n", + " r = 16, # Choose any number > 0 ! Suggested 8, 16, 32, 64, 128\n", + " target_modules = [\"q_proj\", \"k_proj\", \"v_proj\", \"o_proj\",\n", + " \"gate_proj\", \"up_proj\", \"down_proj\",],\n", + " lora_alpha = 16,\n", + " lora_dropout = 0, # Supports any, but = 0 is optimized\n", + " bias = \"none\", # Supports any, but = \"none\" is optimized\n", + " # [NEW] \"unsloth\" uses 30% less VRAM, fits 2x larger batch sizes!\n", + " use_gradient_checkpointing = \"unsloth\", # True or \"unsloth\" for very long context\n", + " random_state = 3407,\n", + " use_rslora = False, # We support rank stabilized LoRA\n", + " loftq_config = None, # And LoftQ\n", + ")" + ] + }, + { + "cell_type": "code", + "source": [ + "# Data Prep\n", + "# We transform data from existing .json format into new prompt format.\n", + "\n", + "# **[NOTE]** Remember to add the **EOS_TOKEN** to the tokenized output!! Otherwise you'll get infinite generations!\n", + "\n", + "lines = []\n", + "with open(training_data_file, \"r\") as f:\n", + " lines = f.readlines()\n", + "\n", + "print(lines[:2])\n", + "\n", + "alpaca_prompt = \"\"\"Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.\n", + "\n", + "### Instruction:\n", + "{}\n", + "\n", + "### Input:\n", + "{}\n", + "\n", + "### Response:\n", + "{}\"\"\"\n", + "\n", + "EOS_TOKEN = tokenizer.eos_token # Must add EOS_TOKEN\n", + "def formatting_prompts_func(messages):\n", + " instruction = messages['messages'][0][\"content\"]\n", + " input = messages['messages'][1][\"content\"]\n", + " output = messages['messages'][2][\"content\"]\n", + " text = alpaca_prompt.format(instruction, input, output) + EOS_TOKEN\n", + " return { \"text\" : text, }\n", + "pass\n", + "\n", + "from datasets import load_dataset, load_from_disk\n", + "dataset_raw = load_dataset(\"json\", data_files=\"train_text2sql_sft_dataset.json\", split=\"train\")\n", + "dataset = dataset_raw.map(formatting_prompts_func, batched = False,)\n", + "dataset" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 188, + "referenced_widgets": [ + "637dedfe81724192b863c2b131aeb933", + "781541b6bc7c473ea2cf33f83017b648", + "c36068a9af284e31890f576d50da2c5f", + "c3930523cc43497dbcd21eba69dc3b6d", + "32c851dd54954b72950a9e0f06d01aa1", + "49e949498a004d2ca5f06edd67304327", + "70f55e99c7944da9ae8a6445a0ce9b6b", + "4c13c8d1c64e4d1893ebcc7712907951", + "8ad04e1707b74a0b89e1aa7e511584e0", + "4250701d8d3849feb9d00e94f259d980", + "91e6c3a9ea524d5ab7b7c8fce66d7a36", + "61ad4905a7c448fea70755c44a9ee7f3", + "9dbc55420dd349f79b4fcbebe9cb98bd", + "2d8b27dd71884459ace7a252ff86603f", + "f505fbfb17064ba59d2bfc6ff4bc41b2", + "446fd4d425a840799c06c1bae0ab133b", + "95bae4f5e1424f1480aec8d53490bba4", + "6223f835a0164b6ea52b1889b0bcd0f8", + "b5a0439f345d4e6ba6f18f9ac9dfe771", + "cce40322aa7f48d6abfa03506d0e2630", + "42581a1a1e364903974416b11989f0f6", + "29a85fb494734faca4baf1ecb00f0c3c" + ] + }, + "id": "rruFkJLzmBp8", + "outputId": "b340cf82-3d91-4270-8e5c-584804c3186f" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "['{\"messages\":[{\"content\":\"You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement.\",\"role\":\"system\"},{\"content\":\"-- DB Schema: CREATE TABLE \\\\\"lists\\\\\"\\\\n(\\\\n user_id INTEGER\\\\n references lists_users (user_id),\\\\n list_id INTEGER not null\\\\n primary key,\\\\n list_title TEXT,\\\\n list_movie_number INTEGER,\\\\n list_update_timestamp_utc TEXT,\\\\n list_creation_timestamp_utc TEXT,\\\\n list_followers INTEGER,\\\\n list_url TEXT,\\\\n list_comments INTEGER,\\\\n list_description TEXT,\\\\n list_cover_image_url TEXT,\\\\n list_first_image_url TEXT,\\\\n list_second_image_url TEXT,\\\\n list_third_image_url TEXT\\\\n)\\\\n\\\\nCREATE TABLE \\\\\"movies\\\\\"\\\\n(\\\\n movie_id INTEGER not null\\\\n primary key,\\\\n movie_title TEXT,\\\\n movie_release_year INTEGER,\\\\n movie_url TEXT,\\\\n movie_title_language TEXT,\\\\n movie_popularity INTEGER,\\\\n movie_image_url TEXT,\\\\n director_id TEXT,\\\\n director_name TEXT,\\\\n director_url TEXT\\\\n)\\\\n\\\\nCREATE TABLE \\\\\"ratings_users\\\\\"\\\\n(\\\\n user_id INTEGER\\\\n references lists_users (user_id),\\\\n rating_date_utc TEXT,\\\\n user_trialist INTEGER,\\\\n user_subscriber INTEGER,\\\\n user_avatar_image_url TEXT,\\\\n user_cover_image_url TEXT,\\\\n user_eligible_for_trial INTEGER,\\\\n user_has_payment_method INTEGER\\\\n)\\\\n\\\\nCREATE TABLE lists_users\\\\n(\\\\n user_id INTEGER not null ,\\\\n list_id INTEGER not null ,\\\\n list_update_date_utc TEXT,\\\\n list_creation_date_utc TEXT,\\\\n user_trialist INTEGER,\\\\n user_subscriber INTEGER,\\\\n user_avatar_image_url TEXT,\\\\n user_cover_image_url TEXT,\\\\n user_eligible_for_trial TEXT,\\\\n user_has_payment_method TEXT,\\\\n primary key (user_id, list_id),\\\\n foreign key (list_id) references lists(list_id),\\\\n foreign key (user_id) references lists(user_id)\\\\n)\\\\n\\\\nCREATE TABLE ratings\\\\n(\\\\n movie_id INTEGER,\\\\n rating_id INTEGER,\\\\n rating_url TEXT,\\\\n rating_score INTEGER,\\\\n rating_timestamp_utc TEXT,\\\\n critic TEXT,\\\\n critic_likes INTEGER,\\\\n critic_comments INTEGER,\\\\n user_id INTEGER,\\\\n user_trialist INTEGER,\\\\n user_subscriber INTEGER,\\\\n user_eligible_for_trial INTEGER,\\\\n user_has_payment_method INTEGER,\\\\n foreign key (movie_id) references movies(movie_id),\\\\n foreign key (user_id) references lists_users(user_id),\\\\n foreign key (rating_id) references ratings(rating_id),\\\\n foreign key (user_id) references ratings_users(user_id)\\\\n)\\\\n\\\\n-- External Knowledge: released in the year 1945 refers to movie_release_year = 1945;\\\\n\\\\n-- Question: Name movie titles released in year 1945. Sort the listing by the descending order of movie popularity.\",\"role\":\"user\"},{\"content\":\"SELECT movie_title FROM movies WHERE movie_release_year = 1945 ORDER BY movie_popularity DESC LIMIT 1\",\"role\":\"assistant\"}]}\\n', '{\"messages\":[{\"content\":\"You are a text to SQL query translator. Using the SQLite DB Schema and the External Knowledge, translate the following text question into a SQLite SQL select statement.\",\"role\":\"system\"},{\"content\":\"-- DB Schema: CREATE TABLE \\\\\"lists\\\\\"\\\\n(\\\\n user_id INTEGER\\\\n references lists_users (user_id),\\\\n list_id INTEGER not null\\\\n primary key,\\\\n list_title TEXT,\\\\n list_movie_number INTEGER,\\\\n list_update_timestamp_utc TEXT,\\\\n list_creation_timestamp_utc TEXT,\\\\n list_followers INTEGER,\\\\n list_url TEXT,\\\\n list_comments INTEGER,\\\\n list_description TEXT,\\\\n list_cover_image_url TEXT,\\\\n list_first_image_url TEXT,\\\\n list_second_image_url TEXT,\\\\n list_third_image_url TEXT\\\\n)\\\\n\\\\nCREATE TABLE \\\\\"movies\\\\\"\\\\n(\\\\n movie_id INTEGER not null\\\\n primary key,\\\\n movie_title TEXT,\\\\n movie_release_year INTEGER,\\\\n movie_url TEXT,\\\\n movie_title_language TEXT,\\\\n movie_popularity INTEGER,\\\\n movie_image_url TEXT,\\\\n director_id TEXT,\\\\n director_name TEXT,\\\\n director_url TEXT\\\\n)\\\\n\\\\nCREATE TABLE \\\\\"ratings_users\\\\\"\\\\n(\\\\n user_id INTEGER\\\\n references lists_users (user_id),\\\\n rating_date_utc TEXT,\\\\n user_trialist INTEGER,\\\\n user_subscriber INTEGER,\\\\n user_avatar_image_url TEXT,\\\\n user_cover_image_url TEXT,\\\\n user_eligible_for_trial INTEGER,\\\\n user_has_payment_method INTEGER\\\\n)\\\\n\\\\nCREATE TABLE lists_users\\\\n(\\\\n user_id INTEGER not null ,\\\\n list_id INTEGER not null ,\\\\n list_update_date_utc TEXT,\\\\n list_creation_date_utc TEXT,\\\\n user_trialist INTEGER,\\\\n user_subscriber INTEGER,\\\\n user_avatar_image_url TEXT,\\\\n user_cover_image_url TEXT,\\\\n user_eligible_for_trial TEXT,\\\\n user_has_payment_method TEXT,\\\\n primary key (user_id, list_id),\\\\n foreign key (list_id) references lists(list_id),\\\\n foreign key (user_id) references lists(user_id)\\\\n)\\\\n\\\\nCREATE TABLE ratings\\\\n(\\\\n movie_id INTEGER,\\\\n rating_id INTEGER,\\\\n rating_url TEXT,\\\\n rating_score INTEGER,\\\\n rating_timestamp_utc TEXT,\\\\n critic TEXT,\\\\n critic_likes INTEGER,\\\\n critic_comments INTEGER,\\\\n user_id INTEGER,\\\\n user_trialist INTEGER,\\\\n user_subscriber INTEGER,\\\\n user_eligible_for_trial INTEGER,\\\\n user_has_payment_method INTEGER,\\\\n foreign key (movie_id) references movies(movie_id),\\\\n foreign key (user_id) references lists_users(user_id),\\\\n foreign key (rating_id) references ratings(rating_id),\\\\n foreign key (user_id) references ratings_users(user_id)\\\\n)\\\\n\\\\n-- External Knowledge: most popular movie refers to MAX(movie_popularity); when it was released refers to movie_release_year; director for the movie refers to director_name;\\\\n\\\\n-- Question: State the most popular movie? When was it released and who is the director for the movie?\",\"role\":\"user\"},{\"content\":\"SELECT movie_title, movie_release_year, director_name FROM movies ORDER BY movie_popularity DESC LIMIT 1 \",\"role\":\"assistant\"}]}\\n']\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "Generating train split: 0 examples [00:00, ? examples/s]" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "637dedfe81724192b863c2b131aeb933" + } + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "Map: 0%| | 0/6599 [00:00\n", + "### Train the model\n", + "Now let's use Huggingface TRL's `SFTTrainer`! More docs here: [TRL SFT docs](https://huggingface.co/docs/trl/sft_trainer). We do 60 steps to speed things up, but you can set `num_train_epochs=1` for a full run, and turn off `max_steps=None`. We also support TRL's `DPOTrainer`!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 49, + "referenced_widgets": [ + "1e212fe262544328967e36fb26e06073", + "0badc1c8b9424b8cb2c526a3bc80294a", + "d0c3e1bc46314b3a822e8350f6ed4904", + "46538c8c222a4ebb81abf0daad5bfa79", + "52711139b56948fcbeca651623d194a0", + "78a35430e1bd47549124eac98be01fdd", + "701bbc75e7214abc93e7d15d42f7c22f", + "09d61405fbb4468cb49a430b6b462276", + "4e36e192ac3947efbb9a8a4e2f4cfbe2", + "a2e091222faa4d38877b613f8036025d", + "7d56d8683551408182969f6201605c86" + ] + }, + "id": "95_Nn-89DhsL", + "outputId": "49490f23-f927-424b-8e88-2b77b0f18aed" + }, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "Unsloth: Tokenizing [\"text\"]: 0%| | 0/6599 [00:00" + ], + "text/html": [ + "\n", + "