Sara Han
commited on
Add RAG generation (#19)
Browse files* feat: add pipelines for RAG
* feat: add the app for rag
* feat: update required dependencies
* feat: update add rag tab
* fix: correct unstructured dependency
* fix: fix layout, arg and input errors
* fix: rename generator
* feat: generate without ground data
* organize dependencies and add pydantic version
* update with feedback
* fix errors and update with latest changes
* remove temperature as value ini pipeline code
* fix pipeline errors
* update TODOs and review prompt generator
* Update READMES
* remove unneeded imports
* use llm.dump() instead of llm.model_dump()
* fix pipeline code
* apply feedback
* fix progress, messages and clear buttons
- README.md +1 -0
- pyproject.toml +6 -4
- src/synthetic_dataset_generator/_distiset.py +16 -1
- src/synthetic_dataset_generator/app.py +3 -2
- src/synthetic_dataset_generator/apps/about.py +1 -1
- src/synthetic_dataset_generator/apps/base.py +22 -2
- src/synthetic_dataset_generator/apps/chat.py +9 -9
- src/synthetic_dataset_generator/apps/eval.py +9 -23
- src/synthetic_dataset_generator/apps/rag.py +896 -0
- src/synthetic_dataset_generator/apps/textcat.py +4 -6
- src/synthetic_dataset_generator/pipelines/base.py +1 -1
- src/synthetic_dataset_generator/pipelines/chat.py +4 -2
- src/synthetic_dataset_generator/pipelines/rag.py +302 -0
- src/synthetic_dataset_generator/pipelines/textcat.py +8 -5
README.md
CHANGED
@@ -34,6 +34,7 @@ Supported Tasks:
|
|
34 |
|
35 |
- Text Classification
|
36 |
- Chat Data for Supervised Fine-Tuning
|
|
|
37 |
|
38 |
This tool simplifies the process of creating custom datasets, enabling you to:
|
39 |
|
|
|
34 |
|
35 |
- Text Classification
|
36 |
- Chat Data for Supervised Fine-Tuning
|
37 |
+
- Retrieval Augmented Generation
|
38 |
|
39 |
This tool simplifies the process of creating custom datasets, enabling you to:
|
40 |
|
pyproject.toml
CHANGED
@@ -18,13 +18,15 @@ readme = "README.md"
|
|
18 |
license = {text = "Apache 2"}
|
19 |
|
20 |
dependencies = [
|
|
|
21 |
"distilabel[argilla,hf-inference-endpoints,hf-transformers,instructor,llama-cpp,ollama,openai,outlines,vllm] @ git+https://github.com/argilla-io/distilabel.git@develop",
|
22 |
"gradio[oauth]>=5.4.0,<6.0.0",
|
23 |
-
"transformers>=4.44.2,<5.0.0",
|
24 |
-
"sentence-transformers>=3.2.0,<4.0.0",
|
25 |
-
"model2vec>=0.2.4,<1.0.0",
|
26 |
"gradio-huggingfacehub-search>=0.0.12,<1.0.0",
|
27 |
-
"
|
|
|
|
|
|
|
|
|
28 |
]
|
29 |
|
30 |
[build-system]
|
|
|
18 |
license = {text = "Apache 2"}
|
19 |
|
20 |
dependencies = [
|
21 |
+
"argilla>=2.4.0,<3.0.0",
|
22 |
"distilabel[argilla,hf-inference-endpoints,hf-transformers,instructor,llama-cpp,ollama,openai,outlines,vllm] @ git+https://github.com/argilla-io/distilabel.git@develop",
|
23 |
"gradio[oauth]>=5.4.0,<6.0.0",
|
|
|
|
|
|
|
24 |
"gradio-huggingfacehub-search>=0.0.12,<1.0.0",
|
25 |
+
"model2vec>=0.2.4,<1.0.0",
|
26 |
+
"pydantic>=2.10.5,<3.0.0",
|
27 |
+
"sentence-transformers>=3.2.0,<4.0.0",
|
28 |
+
"transformers>=4.44.2,<5.0.0",
|
29 |
+
"unstructured[md,pdf,docx]>=0.16.0,<1.0.0",
|
30 |
]
|
31 |
|
32 |
[build-system]
|
src/synthetic_dataset_generator/_distiset.py
CHANGED
@@ -92,7 +92,22 @@ class CustomDistisetWithAdditionalTag(distilabel.distiset.Distiset):
|
|
92 |
elif ("prompt" in columns and "completion" in columns) or (
|
93 |
"messages" in columns
|
94 |
):
|
95 |
-
task_categories: list[str] = [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
else:
|
97 |
task_categories: list[str] = []
|
98 |
gr.Info(
|
|
|
92 |
elif ("prompt" in columns and "completion" in columns) or (
|
93 |
"messages" in columns
|
94 |
):
|
95 |
+
task_categories: list[str] = [
|
96 |
+
"text-generation",
|
97 |
+
"text2text-generation",
|
98 |
+
"question-answering",
|
99 |
+
]
|
100 |
+
elif "context" in columns and "question" in columns and "response" in columns:
|
101 |
+
task_categories: list[str] = [
|
102 |
+
"text-generation",
|
103 |
+
"text2text-generation",
|
104 |
+
"text-retrieval",
|
105 |
+
"question-answering"
|
106 |
+
]
|
107 |
+
if (
|
108 |
+
"positive_retrieval" in columns and "negative_retrieval" in columns
|
109 |
+
) or ("positive_reranking" in columns and "negative_reranking" in columns):
|
110 |
+
task_categories.append("sentence-similarity")
|
111 |
else:
|
112 |
task_categories: list[str] = []
|
113 |
gr.Info(
|
src/synthetic_dataset_generator/app.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
from synthetic_dataset_generator._tabbedinterface import TabbedInterface
|
2 |
|
3 |
# from synthetic_dataset_generator.apps.eval import app as eval_app
|
|
|
4 |
from synthetic_dataset_generator.apps.about import app as about_app
|
5 |
from synthetic_dataset_generator.apps.chat import app as chat_app
|
6 |
from synthetic_dataset_generator.apps.textcat import app as textcat_app
|
@@ -22,8 +23,8 @@ button[role="tab"][aria-selected="true"]:hover {border-color: var(--button-prima
|
|
22 |
image = """<br><img src="https://raw.githubusercontent.com/argilla-io/synthetic-data-generator/main/assets/logo.svg" alt="Synthetic Data Generator Logo" style="display: block; margin-left: auto; margin-right: auto; width: clamp(50%, 400px, 100%)"/>"""
|
23 |
|
24 |
demo = TabbedInterface(
|
25 |
-
[textcat_app, chat_app, about_app],
|
26 |
-
["Text Classification", "Chat Data", "About"],
|
27 |
css=css,
|
28 |
title=image,
|
29 |
theme=theme,
|
|
|
1 |
from synthetic_dataset_generator._tabbedinterface import TabbedInterface
|
2 |
|
3 |
# from synthetic_dataset_generator.apps.eval import app as eval_app
|
4 |
+
from synthetic_dataset_generator.apps.rag import app as rag_app
|
5 |
from synthetic_dataset_generator.apps.about import app as about_app
|
6 |
from synthetic_dataset_generator.apps.chat import app as chat_app
|
7 |
from synthetic_dataset_generator.apps.textcat import app as textcat_app
|
|
|
23 |
image = """<br><img src="https://raw.githubusercontent.com/argilla-io/synthetic-data-generator/main/assets/logo.svg" alt="Synthetic Data Generator Logo" style="display: block; margin-left: auto; margin-right: auto; width: clamp(50%, 400px, 100%)"/>"""
|
24 |
|
25 |
demo = TabbedInterface(
|
26 |
+
[textcat_app, chat_app, rag_app, about_app],
|
27 |
+
["Text Classification", "Chat Data", "RAG", "About"],
|
28 |
css=css,
|
29 |
title=image,
|
30 |
theme=theme,
|
src/synthetic_dataset_generator/apps/about.py
CHANGED
@@ -7,7 +7,7 @@ with gr.Blocks() as app:
|
|
7 |
|
8 |
Introducing the Synthetic Data Generator, a user-friendly application that takes a no-code approach to creating custom datasets with Large Language Models (LLMs). The best part: A simple step-by-step process, making dataset creation a non-technical breeze, allowing anyone to create datasets and models in minutes and without any code.
|
9 |
|
10 |
-
The synthetic data generator takes your custom prompt and returns a dataset for your use case, using a synthetic data pipeline. In the background this is powered by [distilabel](https://distilabel.argilla.io/latest/) and the [free Hugging Face text-generation API](https://huggingface.co/docs/api-inference/en/index) but we don
|
11 |
|
12 |
- Read more in [our announcement blog post](https://huggingface.co/blog/synthetic-data-generator)
|
13 |
- Find the library on [GitHub](https://github.com/argilla-io/synthetic-data-generator)
|
|
|
7 |
|
8 |
Introducing the Synthetic Data Generator, a user-friendly application that takes a no-code approach to creating custom datasets with Large Language Models (LLMs). The best part: A simple step-by-step process, making dataset creation a non-technical breeze, allowing anyone to create datasets and models in minutes and without any code.
|
9 |
|
10 |
+
The synthetic data generator takes your custom prompt and returns a dataset for your use case, using a synthetic data pipeline. In the background this is powered by [distilabel](https://distilabel.argilla.io/latest/) and the [free Hugging Face text-generation API](https://huggingface.co/docs/api-inference/en/index) but we don't need to worry about these complexities and we can focus on using the UI.
|
11 |
|
12 |
- Read more in [our announcement blog post](https://huggingface.co/blog/synthetic-data-generator)
|
13 |
- Find the library on [GitHub](https://github.com/argilla-io/synthetic-data-generator)
|
src/synthetic_dataset_generator/apps/base.py
CHANGED
@@ -6,7 +6,7 @@ import argilla as rg
|
|
6 |
import gradio as gr
|
7 |
from datasets import Dataset, concatenate_datasets, load_dataset
|
8 |
from gradio import OAuthToken
|
9 |
-
from huggingface_hub import HfApi, upload_file
|
10 |
|
11 |
from synthetic_dataset_generator.constants import MAX_NUM_ROWS
|
12 |
from synthetic_dataset_generator.utils import get_argilla_client
|
@@ -18,7 +18,7 @@ def validate_argilla_user_workspace_dataset(
|
|
18 |
oauth_token: Union[OAuthToken, None] = None,
|
19 |
progress=gr.Progress(),
|
20 |
) -> str:
|
21 |
-
progress(0, desc="Validating dataset configuration")
|
22 |
hf_user = HfApi().whoami(token=oauth_token.token)["name"]
|
23 |
client = get_argilla_client()
|
24 |
if dataset_name is None or dataset_name == "":
|
@@ -38,6 +38,7 @@ def validate_argilla_user_workspace_dataset(
|
|
38 |
dataset = client.datasets(name=dataset_name, workspace=hf_user)
|
39 |
if dataset and not add_to_existing_dataset:
|
40 |
raise gr.Error(f"Dataset {dataset_name} already exists")
|
|
|
41 |
return ""
|
42 |
|
43 |
|
@@ -159,3 +160,22 @@ def test_max_num_rows(num_rows: int) -> int:
|
|
159 |
f"Number of rows is larger than the configured maximum. Setting number of rows to {MAX_NUM_ROWS}. Set environment variable `MAX_NUM_ROWS` to change this behavior."
|
160 |
)
|
161 |
return num_rows
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
import gradio as gr
|
7 |
from datasets import Dataset, concatenate_datasets, load_dataset
|
8 |
from gradio import OAuthToken
|
9 |
+
from huggingface_hub import HfApi, upload_file, repo_exists
|
10 |
|
11 |
from synthetic_dataset_generator.constants import MAX_NUM_ROWS
|
12 |
from synthetic_dataset_generator.utils import get_argilla_client
|
|
|
18 |
oauth_token: Union[OAuthToken, None] = None,
|
19 |
progress=gr.Progress(),
|
20 |
) -> str:
|
21 |
+
progress(0.1, desc="Validating dataset configuration")
|
22 |
hf_user = HfApi().whoami(token=oauth_token.token)["name"]
|
23 |
client = get_argilla_client()
|
24 |
if dataset_name is None or dataset_name == "":
|
|
|
38 |
dataset = client.datasets(name=dataset_name, workspace=hf_user)
|
39 |
if dataset and not add_to_existing_dataset:
|
40 |
raise gr.Error(f"Dataset {dataset_name} already exists")
|
41 |
+
progress(1.0, desc="Dataset configuration validated")
|
42 |
return ""
|
43 |
|
44 |
|
|
|
160 |
f"Number of rows is larger than the configured maximum. Setting number of rows to {MAX_NUM_ROWS}. Set environment variable `MAX_NUM_ROWS` to change this behavior."
|
161 |
)
|
162 |
return num_rows
|
163 |
+
|
164 |
+
|
165 |
+
def get_iframe(hub_repo_id: str) -> str:
|
166 |
+
if not hub_repo_id:
|
167 |
+
return ""
|
168 |
+
|
169 |
+
if not repo_exists(repo_id=hub_repo_id, repo_type="dataset"):
|
170 |
+
return ""
|
171 |
+
|
172 |
+
url = f"https://huggingface.co/datasets/{hub_repo_id}/embed/viewer"
|
173 |
+
iframe = f"""
|
174 |
+
<iframe
|
175 |
+
src="{url}"
|
176 |
+
frameborder="0"
|
177 |
+
width="100%"
|
178 |
+
height="600px"
|
179 |
+
></iframe>
|
180 |
+
"""
|
181 |
+
return iframe
|
src/synthetic_dataset_generator/apps/chat.py
CHANGED
@@ -25,7 +25,7 @@ from synthetic_dataset_generator.constants import (
|
|
25 |
MODEL,
|
26 |
SFT_AVAILABLE,
|
27 |
)
|
28 |
-
from synthetic_dataset_generator.pipelines.base import
|
29 |
from synthetic_dataset_generator.pipelines.chat import (
|
30 |
DEFAULT_DATASET_DESCRIPTIONS,
|
31 |
generate_pipeline_code,
|
@@ -61,10 +61,9 @@ def convert_dataframe_messages(dataframe: pd.DataFrame) -> pd.DataFrame:
|
|
61 |
|
62 |
|
63 |
def generate_system_prompt(dataset_description, progress=gr.Progress()):
|
64 |
-
progress(0.
|
65 |
-
progress(0.3, desc="Initializing")
|
66 |
generate_description = get_prompt_generator()
|
67 |
-
progress(0.
|
68 |
result = next(
|
69 |
generate_description.process(
|
70 |
[
|
@@ -79,6 +78,7 @@ def generate_system_prompt(dataset_description, progress=gr.Progress()):
|
|
79 |
|
80 |
|
81 |
def generate_sample_dataset(system_prompt, num_turns, progress=gr.Progress()):
|
|
|
82 |
dataframe = generate_dataset(
|
83 |
system_prompt=system_prompt,
|
84 |
num_turns=num_turns,
|
@@ -86,6 +86,7 @@ def generate_sample_dataset(system_prompt, num_turns, progress=gr.Progress()):
|
|
86 |
progress=progress,
|
87 |
is_sample=True,
|
88 |
)
|
|
|
89 |
return dataframe
|
90 |
|
91 |
|
@@ -117,7 +118,7 @@ def generate_dataset(
|
|
117 |
batch_size = DEFAULT_BATCH_SIZE
|
118 |
|
119 |
# create prompt rewrites
|
120 |
-
prompt_rewrites =
|
121 |
|
122 |
# create instructions
|
123 |
n_processed = 0
|
@@ -274,6 +275,7 @@ def push_dataset(
|
|
274 |
client = get_argilla_client()
|
275 |
if client is None:
|
276 |
return ""
|
|
|
277 |
if "messages" in dataframe.columns:
|
278 |
settings = rg.Settings(
|
279 |
fields=[
|
@@ -370,7 +372,6 @@ def push_dataset(
|
|
370 |
dataframe["completion_length"] = dataframe["completion"].apply(len)
|
371 |
dataframe["prompt_embeddings"] = get_embeddings(dataframe["prompt"])
|
372 |
|
373 |
-
progress(0.5, desc="Creating dataset")
|
374 |
rg_dataset = client.datasets(name=repo_name, workspace=hf_user)
|
375 |
if rg_dataset is None:
|
376 |
rg_dataset = rg.Dataset(
|
@@ -516,7 +517,6 @@ with gr.Blocks() as app:
|
|
516 |
system_prompt=system_prompt.value,
|
517 |
num_turns=num_turns.value,
|
518 |
num_rows=num_rows.value,
|
519 |
-
temperature=temperature.value,
|
520 |
)
|
521 |
pipeline_code = gr.Code(
|
522 |
value=code,
|
@@ -582,7 +582,7 @@ with gr.Blocks() as app:
|
|
582 |
outputs=[success_message],
|
583 |
).success(
|
584 |
fn=generate_pipeline_code,
|
585 |
-
inputs=[system_prompt, num_turns, num_rows
|
586 |
outputs=[pipeline_code],
|
587 |
).success(
|
588 |
fn=show_pipeline_code_visibility,
|
@@ -593,7 +593,7 @@ with gr.Blocks() as app:
|
|
593 |
triggers=[clear_btn_part.click, clear_btn_full.click],
|
594 |
fn=lambda _: ("", "", 1, _get_dataframe()),
|
595 |
inputs=[dataframe],
|
596 |
-
outputs=[
|
597 |
)
|
598 |
app.load(fn=get_org_dropdown, outputs=[org_name])
|
599 |
app.load(fn=get_random_repo_name, outputs=[repo_name])
|
|
|
25 |
MODEL,
|
26 |
SFT_AVAILABLE,
|
27 |
)
|
28 |
+
from synthetic_dataset_generator.pipelines.base import get_rewritten_prompts
|
29 |
from synthetic_dataset_generator.pipelines.chat import (
|
30 |
DEFAULT_DATASET_DESCRIPTIONS,
|
31 |
generate_pipeline_code,
|
|
|
61 |
|
62 |
|
63 |
def generate_system_prompt(dataset_description, progress=gr.Progress()):
|
64 |
+
progress(0.1, desc="Initializing")
|
|
|
65 |
generate_description = get_prompt_generator()
|
66 |
+
progress(0.5, desc="Generating")
|
67 |
result = next(
|
68 |
generate_description.process(
|
69 |
[
|
|
|
78 |
|
79 |
|
80 |
def generate_sample_dataset(system_prompt, num_turns, progress=gr.Progress()):
|
81 |
+
progress(0.1, desc="Generating sample dataset")
|
82 |
dataframe = generate_dataset(
|
83 |
system_prompt=system_prompt,
|
84 |
num_turns=num_turns,
|
|
|
86 |
progress=progress,
|
87 |
is_sample=True,
|
88 |
)
|
89 |
+
progress(1.0, desc="Sample dataset generated")
|
90 |
return dataframe
|
91 |
|
92 |
|
|
|
118 |
batch_size = DEFAULT_BATCH_SIZE
|
119 |
|
120 |
# create prompt rewrites
|
121 |
+
prompt_rewrites = get_rewritten_prompts(system_prompt, num_rows)
|
122 |
|
123 |
# create instructions
|
124 |
n_processed = 0
|
|
|
275 |
client = get_argilla_client()
|
276 |
if client is None:
|
277 |
return ""
|
278 |
+
progress(0.5, desc="Creating dataset in Argilla")
|
279 |
if "messages" in dataframe.columns:
|
280 |
settings = rg.Settings(
|
281 |
fields=[
|
|
|
372 |
dataframe["completion_length"] = dataframe["completion"].apply(len)
|
373 |
dataframe["prompt_embeddings"] = get_embeddings(dataframe["prompt"])
|
374 |
|
|
|
375 |
rg_dataset = client.datasets(name=repo_name, workspace=hf_user)
|
376 |
if rg_dataset is None:
|
377 |
rg_dataset = rg.Dataset(
|
|
|
517 |
system_prompt=system_prompt.value,
|
518 |
num_turns=num_turns.value,
|
519 |
num_rows=num_rows.value,
|
|
|
520 |
)
|
521 |
pipeline_code = gr.Code(
|
522 |
value=code,
|
|
|
582 |
outputs=[success_message],
|
583 |
).success(
|
584 |
fn=generate_pipeline_code,
|
585 |
+
inputs=[system_prompt, num_turns, num_rows],
|
586 |
outputs=[pipeline_code],
|
587 |
).success(
|
588 |
fn=show_pipeline_code_visibility,
|
|
|
593 |
triggers=[clear_btn_part.click, clear_btn_full.click],
|
594 |
fn=lambda _: ("", "", 1, _get_dataframe()),
|
595 |
inputs=[dataframe],
|
596 |
+
outputs=[system_prompt, num_turns, dataframe],
|
597 |
)
|
598 |
app.load(fn=get_org_dropdown, outputs=[org_name])
|
599 |
app.load(fn=get_random_repo_name, outputs=[repo_name])
|
src/synthetic_dataset_generator/apps/eval.py
CHANGED
@@ -19,6 +19,7 @@ from huggingface_hub import HfApi, repo_exists
|
|
19 |
|
20 |
from synthetic_dataset_generator.apps.base import (
|
21 |
combine_datasets,
|
|
|
22 |
hide_success_message,
|
23 |
push_pipeline_code_to_hub,
|
24 |
show_success_message,
|
@@ -48,25 +49,6 @@ from synthetic_dataset_generator.utils import (
|
|
48 |
)
|
49 |
|
50 |
|
51 |
-
def get_iframe(hub_repo_id: str) -> str:
|
52 |
-
if not hub_repo_id:
|
53 |
-
return ""
|
54 |
-
|
55 |
-
if not repo_exists(repo_id=hub_repo_id, repo_type="dataset"):
|
56 |
-
return ""
|
57 |
-
|
58 |
-
url = f"https://huggingface.co/datasets/{hub_repo_id}/embed/viewer"
|
59 |
-
iframe = f"""
|
60 |
-
<iframe
|
61 |
-
src="{url}"
|
62 |
-
frameborder="0"
|
63 |
-
width="100%"
|
64 |
-
height="600px"
|
65 |
-
></iframe>
|
66 |
-
"""
|
67 |
-
return iframe
|
68 |
-
|
69 |
-
|
70 |
def get_valid_columns(dataframe: pd.DataFrame):
|
71 |
instruction_valid_columns = []
|
72 |
response_valid_columns = []
|
@@ -357,11 +339,15 @@ def push_dataset_to_hub(
|
|
357 |
oauth_token: Union[gr.OAuthToken, None],
|
358 |
private: bool,
|
359 |
pipeline_code: str,
|
|
|
360 |
):
|
|
|
361 |
repo_id = validate_push_to_hub(org_name, repo_name)
|
|
|
362 |
dataset = Dataset.from_pandas(dataframe)
|
363 |
dataset = combine_datasets(repo_id, dataset, oauth_token)
|
364 |
distiset = Distiset({"default": dataset})
|
|
|
365 |
distiset.push_to_hub(
|
366 |
repo_id=repo_id,
|
367 |
private=private,
|
@@ -370,6 +356,8 @@ def push_dataset_to_hub(
|
|
370 |
create_pr=False,
|
371 |
)
|
372 |
push_pipeline_code_to_hub(pipeline_code, org_name, repo_name, oauth_token)
|
|
|
|
|
373 |
|
374 |
|
375 |
def push_dataset(
|
@@ -408,6 +396,7 @@ def push_dataset(
|
|
408 |
client = get_argilla_client()
|
409 |
if client is None:
|
410 |
return ""
|
|
|
411 |
if eval_type == "chat-eval":
|
412 |
num_generations = len((dataframe["generations"][0]))
|
413 |
fields = [
|
@@ -488,7 +477,6 @@ def push_dataset(
|
|
488 |
dataframe["instruction"].to_list()
|
489 |
)
|
490 |
|
491 |
-
progress(0.5, desc="Creating dataset")
|
492 |
rg_dataset = client.datasets(name=repo_name, workspace=hf_user)
|
493 |
if rg_dataset is None:
|
494 |
rg_dataset = rg.Dataset(
|
@@ -628,7 +616,6 @@ def push_dataset(
|
|
628 |
dataframe[f"{column}_length"] = dataframe[column].apply(len)
|
629 |
dataframe[f"{column}_embeddings"] = get_embeddings(dataframe[column])
|
630 |
|
631 |
-
progress(0.5, desc="Creating dataset")
|
632 |
rg_dataset = client.datasets(name=repo_name, workspace=hf_user)
|
633 |
if rg_dataset is None:
|
634 |
rg_dataset = rg.Dataset(
|
@@ -895,12 +882,11 @@ with gr.Blocks() as app:
|
|
895 |
outputs=[pipeline_code_ui],
|
896 |
)
|
897 |
|
898 |
-
clear_btn_part.click(fn=lambda
|
899 |
clear_btn_full.click(
|
900 |
fn=lambda df: ("", "", pd.DataFrame(columns=df.columns)),
|
901 |
inputs=[dataframe],
|
902 |
outputs=[
|
903 |
-
search_in,
|
904 |
instruction_instruction_response,
|
905 |
response_instruction_response,
|
906 |
],
|
|
|
19 |
|
20 |
from synthetic_dataset_generator.apps.base import (
|
21 |
combine_datasets,
|
22 |
+
get_iframe,
|
23 |
hide_success_message,
|
24 |
push_pipeline_code_to_hub,
|
25 |
show_success_message,
|
|
|
49 |
)
|
50 |
|
51 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
def get_valid_columns(dataframe: pd.DataFrame):
|
53 |
instruction_valid_columns = []
|
54 |
response_valid_columns = []
|
|
|
339 |
oauth_token: Union[gr.OAuthToken, None],
|
340 |
private: bool,
|
341 |
pipeline_code: str,
|
342 |
+
progress=gr.Progress(),
|
343 |
):
|
344 |
+
progress(0.0, desc="Validating")
|
345 |
repo_id = validate_push_to_hub(org_name, repo_name)
|
346 |
+
progress(0.5, desc="Creating dataset")
|
347 |
dataset = Dataset.from_pandas(dataframe)
|
348 |
dataset = combine_datasets(repo_id, dataset, oauth_token)
|
349 |
distiset = Distiset({"default": dataset})
|
350 |
+
progress(0.9, desc="Pushing dataset")
|
351 |
distiset.push_to_hub(
|
352 |
repo_id=repo_id,
|
353 |
private=private,
|
|
|
356 |
create_pr=False,
|
357 |
)
|
358 |
push_pipeline_code_to_hub(pipeline_code, org_name, repo_name, oauth_token)
|
359 |
+
progress(1.0, desc="Dataset pushed")
|
360 |
+
return dataframe
|
361 |
|
362 |
|
363 |
def push_dataset(
|
|
|
396 |
client = get_argilla_client()
|
397 |
if client is None:
|
398 |
return ""
|
399 |
+
progress(0.5, desc="Creating dataset in Argilla")
|
400 |
if eval_type == "chat-eval":
|
401 |
num_generations = len((dataframe["generations"][0]))
|
402 |
fields = [
|
|
|
477 |
dataframe["instruction"].to_list()
|
478 |
)
|
479 |
|
|
|
480 |
rg_dataset = client.datasets(name=repo_name, workspace=hf_user)
|
481 |
if rg_dataset is None:
|
482 |
rg_dataset = rg.Dataset(
|
|
|
616 |
dataframe[f"{column}_length"] = dataframe[column].apply(len)
|
617 |
dataframe[f"{column}_embeddings"] = get_embeddings(dataframe[column])
|
618 |
|
|
|
619 |
rg_dataset = client.datasets(name=repo_name, workspace=hf_user)
|
620 |
if rg_dataset is None:
|
621 |
rg_dataset = rg.Dataset(
|
|
|
882 |
outputs=[pipeline_code_ui],
|
883 |
)
|
884 |
|
885 |
+
clear_btn_part.click(fn=lambda : "", inputs=[], outputs=[search_in])
|
886 |
clear_btn_full.click(
|
887 |
fn=lambda df: ("", "", pd.DataFrame(columns=df.columns)),
|
888 |
inputs=[dataframe],
|
889 |
outputs=[
|
|
|
890 |
instruction_instruction_response,
|
891 |
response_instruction_response,
|
892 |
],
|
src/synthetic_dataset_generator/apps/rag.py
ADDED
@@ -0,0 +1,896 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import random
|
2 |
+
import uuid
|
3 |
+
from tqdm import tqdm
|
4 |
+
from typing import Union
|
5 |
+
|
6 |
+
import argilla as rg
|
7 |
+
import gradio as gr
|
8 |
+
import pandas as pd
|
9 |
+
from datasets import (
|
10 |
+
Dataset,
|
11 |
+
get_dataset_config_names,
|
12 |
+
get_dataset_split_names,
|
13 |
+
load_dataset,
|
14 |
+
)
|
15 |
+
from distilabel.distiset import Distiset
|
16 |
+
from gradio.oauth import OAuthToken
|
17 |
+
from gradio_huggingfacehub_search import HuggingfaceHubSearch
|
18 |
+
from huggingface_hub import HfApi
|
19 |
+
from unstructured.chunking.title import chunk_by_title
|
20 |
+
from unstructured.partition.auto import partition
|
21 |
+
|
22 |
+
from synthetic_dataset_generator.apps.base import (
|
23 |
+
combine_datasets,
|
24 |
+
get_iframe,
|
25 |
+
hide_success_message,
|
26 |
+
push_pipeline_code_to_hub,
|
27 |
+
show_success_message,
|
28 |
+
test_max_num_rows,
|
29 |
+
validate_argilla_user_workspace_dataset,
|
30 |
+
validate_push_to_hub,
|
31 |
+
)
|
32 |
+
from synthetic_dataset_generator.constants import DEFAULT_BATCH_SIZE
|
33 |
+
from synthetic_dataset_generator.pipelines.base import get_rewritten_prompts
|
34 |
+
from synthetic_dataset_generator.pipelines.embeddings import (
|
35 |
+
get_embeddings,
|
36 |
+
get_sentence_embedding_dimensions,
|
37 |
+
)
|
38 |
+
from synthetic_dataset_generator.pipelines.rag import (
|
39 |
+
DEFAULT_DATASET_DESCRIPTIONS,
|
40 |
+
get_chunks_generator,
|
41 |
+
get_prompt_generator,
|
42 |
+
generate_pipeline_code,
|
43 |
+
get_sentence_pair_generator,
|
44 |
+
get_response_generator,
|
45 |
+
)
|
46 |
+
from synthetic_dataset_generator.utils import (
|
47 |
+
column_to_list,
|
48 |
+
get_argilla_client,
|
49 |
+
get_org_dropdown,
|
50 |
+
get_random_repo_name,
|
51 |
+
swap_visibility,
|
52 |
+
)
|
53 |
+
|
54 |
+
|
55 |
+
def _get_valid_columns(dataframe: pd.DataFrame):
|
56 |
+
doc_valid_columns = []
|
57 |
+
|
58 |
+
for col in dataframe.columns:
|
59 |
+
sample_val = dataframe[col].iloc[0]
|
60 |
+
if isinstance(sample_val, str):
|
61 |
+
doc_valid_columns.append(col)
|
62 |
+
|
63 |
+
return doc_valid_columns
|
64 |
+
|
65 |
+
|
66 |
+
def _load_dataset_from_hub(
|
67 |
+
repo_id: str,
|
68 |
+
num_rows: int = 10,
|
69 |
+
token: Union[OAuthToken, None] = None,
|
70 |
+
progress=gr.Progress(track_tqdm=True),
|
71 |
+
):
|
72 |
+
if not repo_id:
|
73 |
+
raise gr.Error("Hub repo id is required")
|
74 |
+
subsets = get_dataset_config_names(repo_id, token=token)
|
75 |
+
splits = get_dataset_split_names(repo_id, subsets[0], token=token)
|
76 |
+
ds = load_dataset(repo_id, subsets[0], split=splits[0], token=token, streaming=True)
|
77 |
+
rows = []
|
78 |
+
for idx, row in enumerate(tqdm(ds, desc="Loading the dataset", total=num_rows)):
|
79 |
+
rows.append(row)
|
80 |
+
if idx == num_rows:
|
81 |
+
break
|
82 |
+
ds = Dataset.from_list(rows)
|
83 |
+
dataframe = ds.to_pandas()
|
84 |
+
doc_valid_columns = _get_valid_columns(dataframe)
|
85 |
+
col_doc = doc_valid_columns[0] if doc_valid_columns else ""
|
86 |
+
return (
|
87 |
+
dataframe,
|
88 |
+
gr.Dropdown(
|
89 |
+
choices=doc_valid_columns,
|
90 |
+
label="Documents column",
|
91 |
+
value=col_doc,
|
92 |
+
interactive=(False if col_doc == "" else True),
|
93 |
+
multiselect=False,
|
94 |
+
),
|
95 |
+
)
|
96 |
+
|
97 |
+
|
98 |
+
def _preprocess_input_data(file_paths, num_rows, progress=gr.Progress(track_tqdm=True)):
|
99 |
+
data = {}
|
100 |
+
total_chunks = 0
|
101 |
+
|
102 |
+
for file_path in tqdm(file_paths, desc="Processing files", total=len(file_paths)):
|
103 |
+
partitioned_file = partition(filename=file_path)
|
104 |
+
chunks = [str(chunk) for chunk in chunk_by_title(partitioned_file)]
|
105 |
+
data[file_path] = chunks
|
106 |
+
total_chunks += len(chunks)
|
107 |
+
if total_chunks >= num_rows:
|
108 |
+
break
|
109 |
+
|
110 |
+
dataframe = pd.DataFrame.from_records(
|
111 |
+
[(k, v) for k, values in data.items() for v in values],
|
112 |
+
columns=["filename", "chunks"],
|
113 |
+
)
|
114 |
+
col_doc = "chunks"
|
115 |
+
|
116 |
+
return (
|
117 |
+
dataframe,
|
118 |
+
gr.Dropdown(
|
119 |
+
choices=["chucks"],
|
120 |
+
label="Documents column",
|
121 |
+
value=col_doc,
|
122 |
+
interactive=(False if col_doc == "" else True),
|
123 |
+
multiselect=False,
|
124 |
+
),
|
125 |
+
)
|
126 |
+
|
127 |
+
|
128 |
+
def generate_system_prompt(dataset_description, progress=gr.Progress()):
|
129 |
+
progress(0.1, desc="Initializing")
|
130 |
+
generate_description = get_prompt_generator()
|
131 |
+
progress(0.5, desc="Generating")
|
132 |
+
result = next(
|
133 |
+
generate_description.process(
|
134 |
+
[
|
135 |
+
{
|
136 |
+
"instruction": dataset_description,
|
137 |
+
}
|
138 |
+
]
|
139 |
+
)
|
140 |
+
)[0]["generation"]
|
141 |
+
progress(1.0, desc="Prompt generated")
|
142 |
+
return result
|
143 |
+
|
144 |
+
|
145 |
+
def load_dataset_file(
|
146 |
+
repo_id: str,
|
147 |
+
file_paths: list[str],
|
148 |
+
input_type: str,
|
149 |
+
num_rows: int = 10,
|
150 |
+
token: Union[OAuthToken, None] = None,
|
151 |
+
progress=gr.Progress(),
|
152 |
+
):
|
153 |
+
progress(0.1, desc="Loading the source data")
|
154 |
+
if input_type == "dataset-input":
|
155 |
+
return _load_dataset_from_hub(repo_id, num_rows, token)
|
156 |
+
else:
|
157 |
+
return _preprocess_input_data(file_paths, num_rows)
|
158 |
+
|
159 |
+
|
160 |
+
def generate_dataset(
|
161 |
+
input_type: str,
|
162 |
+
dataframe: pd.DataFrame,
|
163 |
+
system_prompt: str,
|
164 |
+
document_column: str,
|
165 |
+
retrieval: bool = False,
|
166 |
+
reranking: bool = False,
|
167 |
+
num_rows: int = 10,
|
168 |
+
temperature: float = 0.7,
|
169 |
+
is_sample: bool = False,
|
170 |
+
progress=gr.Progress(),
|
171 |
+
):
|
172 |
+
num_rows = test_max_num_rows(num_rows)
|
173 |
+
progress(0.0, desc="Generating questions")
|
174 |
+
if input_type == "prompt-input":
|
175 |
+
chunk_generator = get_chunks_generator(
|
176 |
+
temperature=temperature, is_sample=is_sample
|
177 |
+
)
|
178 |
+
else:
|
179 |
+
document_data = column_to_list(dataframe, document_column)
|
180 |
+
if len(document_data) < num_rows:
|
181 |
+
document_data += random.choices(
|
182 |
+
document_data, k=num_rows - len(document_data)
|
183 |
+
)
|
184 |
+
|
185 |
+
retrieval_generator = get_sentence_pair_generator(
|
186 |
+
action="query",
|
187 |
+
triplet=True if retrieval else False,
|
188 |
+
temperature=temperature,
|
189 |
+
is_sample=is_sample,
|
190 |
+
)
|
191 |
+
response_generator = get_response_generator(
|
192 |
+
temperature=temperature, is_sample=is_sample
|
193 |
+
)
|
194 |
+
if reranking:
|
195 |
+
reranking_generator = get_sentence_pair_generator(
|
196 |
+
action="semantically-similar",
|
197 |
+
triplet=True,
|
198 |
+
temperature=temperature,
|
199 |
+
is_sample=is_sample,
|
200 |
+
)
|
201 |
+
steps = 2 + sum([1 if reranking else 0, 1 if input_type == "prompt-type" else 0])
|
202 |
+
total_steps: int = num_rows * steps
|
203 |
+
step_progress = round(1 / steps, 2)
|
204 |
+
batch_size = DEFAULT_BATCH_SIZE
|
205 |
+
|
206 |
+
# generate chunks
|
207 |
+
if input_type == "prompt-input":
|
208 |
+
n_processed = 0
|
209 |
+
chunk_results = []
|
210 |
+
rewritten_system_prompts = get_rewritten_prompts(system_prompt, num_rows)
|
211 |
+
while n_processed < num_rows:
|
212 |
+
progress(
|
213 |
+
step_progress * n_processed / num_rows,
|
214 |
+
total=total_steps,
|
215 |
+
desc="Generating chunks",
|
216 |
+
)
|
217 |
+
remaining_rows = num_rows - n_processed
|
218 |
+
batch_size = min(batch_size, remaining_rows)
|
219 |
+
inputs = [
|
220 |
+
{"task": random.choice(rewritten_system_prompts)}
|
221 |
+
for _ in range(batch_size)
|
222 |
+
]
|
223 |
+
chunks = list(chunk_generator.process(inputs=inputs))
|
224 |
+
chunk_results.extend(chunks[0])
|
225 |
+
n_processed += batch_size
|
226 |
+
random.seed(a=random.randint(0, 2**32 - 1))
|
227 |
+
document_data = [chunk["generation"] for chunk in chunk_results]
|
228 |
+
progress(step_progress, desc="Generating chunks")
|
229 |
+
|
230 |
+
# generate questions
|
231 |
+
n_processed = 0
|
232 |
+
retrieval_results = []
|
233 |
+
while n_processed < num_rows:
|
234 |
+
progress(
|
235 |
+
step_progress * n_processed / num_rows,
|
236 |
+
total=total_steps,
|
237 |
+
desc="Generating questions",
|
238 |
+
)
|
239 |
+
remaining_rows = num_rows - n_processed
|
240 |
+
batch_size = min(batch_size, remaining_rows)
|
241 |
+
inputs = [
|
242 |
+
{"anchor": document}
|
243 |
+
for document in document_data[n_processed : n_processed + batch_size]
|
244 |
+
]
|
245 |
+
questions = list(retrieval_generator.process(inputs=inputs))
|
246 |
+
retrieval_results.extend(questions[0])
|
247 |
+
n_processed += batch_size
|
248 |
+
for result in retrieval_results:
|
249 |
+
result["context"] = result["anchor"]
|
250 |
+
if retrieval:
|
251 |
+
result["question"] = result["positive"]
|
252 |
+
result["positive_retrieval"] = result.pop("positive")
|
253 |
+
result["negative_retrieval"] = result.pop("negative")
|
254 |
+
else:
|
255 |
+
result["question"] = result.pop("positive")
|
256 |
+
|
257 |
+
progress(step_progress, desc="Generating questions")
|
258 |
+
|
259 |
+
# generate responses
|
260 |
+
n_processed = 0
|
261 |
+
response_results = []
|
262 |
+
while n_processed < num_rows:
|
263 |
+
progress(
|
264 |
+
step_progress + step_progress * n_processed / num_rows,
|
265 |
+
total=total_steps,
|
266 |
+
desc="Generating responses",
|
267 |
+
)
|
268 |
+
batch = retrieval_results[n_processed : n_processed + batch_size]
|
269 |
+
responses = list(response_generator.process(inputs=batch))
|
270 |
+
response_results.extend(responses[0])
|
271 |
+
n_processed += batch_size
|
272 |
+
for result in response_results:
|
273 |
+
result["response"] = result["generation"]
|
274 |
+
progress(step_progress, desc="Generating responses")
|
275 |
+
|
276 |
+
# generate reranking
|
277 |
+
if reranking:
|
278 |
+
n_processed = 0
|
279 |
+
reranking_results = []
|
280 |
+
while n_processed < num_rows:
|
281 |
+
progress(
|
282 |
+
step_progress * n_processed / num_rows,
|
283 |
+
total=total_steps,
|
284 |
+
desc="Generating reranking data",
|
285 |
+
)
|
286 |
+
batch = response_results[n_processed : n_processed + batch_size]
|
287 |
+
batch = list(reranking_generator.process(inputs=batch))
|
288 |
+
reranking_results.extend(batch[0])
|
289 |
+
n_processed += batch_size
|
290 |
+
for result in reranking_results:
|
291 |
+
result["positive_reranking"] = result.pop("positive")
|
292 |
+
result["negative_reranking"] = result.pop("negative")
|
293 |
+
progress(
|
294 |
+
1,
|
295 |
+
total=total_steps,
|
296 |
+
desc="Creating dataset",
|
297 |
+
)
|
298 |
+
|
299 |
+
# create distiset
|
300 |
+
distiset_results = []
|
301 |
+
source_results = reranking_results if reranking else response_results
|
302 |
+
base_keys = ["context", "question", "response"]
|
303 |
+
retrieval_keys = ["positive_retrieval", "negative_retrieval"] if retrieval else []
|
304 |
+
reranking_keys = ["positive_reranking", "negative_reranking"] if reranking else []
|
305 |
+
relevant_keys = base_keys + retrieval_keys + reranking_keys
|
306 |
+
|
307 |
+
for result in source_results:
|
308 |
+
record = {key: result.get(key) for key in relevant_keys if key in result}
|
309 |
+
distiset_results.append(record)
|
310 |
+
|
311 |
+
dataframe = pd.DataFrame(distiset_results)
|
312 |
+
|
313 |
+
progress(1.0, desc="Dataset generation completed")
|
314 |
+
return dataframe
|
315 |
+
|
316 |
+
|
317 |
+
def generate_sample_dataset(
|
318 |
+
repo_id: str,
|
319 |
+
file_paths: list[str],
|
320 |
+
input_type: str,
|
321 |
+
system_prompt: str,
|
322 |
+
document_column: str,
|
323 |
+
retrieval_reranking: list[str],
|
324 |
+
num_rows: str,
|
325 |
+
oauth_token: Union[OAuthToken, None],
|
326 |
+
progress=gr.Progress(),
|
327 |
+
):
|
328 |
+
retrieval = "Retrieval" in retrieval_reranking
|
329 |
+
reranking = "Reranking" in retrieval_reranking
|
330 |
+
|
331 |
+
if input_type == "prompt-input":
|
332 |
+
dataframe = pd.DataFrame(columns=["context", "question", "response"])
|
333 |
+
else:
|
334 |
+
dataframe, _ = load_dataset_file(
|
335 |
+
repo_id=repo_id,
|
336 |
+
file_paths=file_paths,
|
337 |
+
input_type=input_type,
|
338 |
+
num_rows=num_rows,
|
339 |
+
token=oauth_token,
|
340 |
+
)
|
341 |
+
progress(0.5, desc="Generating dataset")
|
342 |
+
dataframe = generate_dataset(
|
343 |
+
input_type=input_type,
|
344 |
+
dataframe=dataframe,
|
345 |
+
system_prompt=system_prompt,
|
346 |
+
document_column=document_column,
|
347 |
+
retrieval=retrieval,
|
348 |
+
reranking=reranking,
|
349 |
+
num_rows=10,
|
350 |
+
is_sample=True,
|
351 |
+
)
|
352 |
+
return dataframe
|
353 |
+
|
354 |
+
|
355 |
+
def push_dataset_to_hub(
|
356 |
+
dataframe: pd.DataFrame,
|
357 |
+
org_name: str,
|
358 |
+
repo_name: str,
|
359 |
+
oauth_token: Union[gr.OAuthToken, None],
|
360 |
+
private: bool,
|
361 |
+
pipeline_code: str,
|
362 |
+
progress=gr.Progress(),
|
363 |
+
):
|
364 |
+
progress(0.0, desc="Validating")
|
365 |
+
repo_id = validate_push_to_hub(org_name, repo_name)
|
366 |
+
progress(0.5, desc="Creating dataset")
|
367 |
+
dataset = Dataset.from_pandas(dataframe)
|
368 |
+
dataset = combine_datasets(repo_id, dataset, oauth_token)
|
369 |
+
distiset = Distiset({"default": dataset})
|
370 |
+
progress(0.9, desc="Pushing dataset")
|
371 |
+
distiset.push_to_hub(
|
372 |
+
repo_id=repo_id,
|
373 |
+
private=private,
|
374 |
+
include_script=False,
|
375 |
+
token=oauth_token.token,
|
376 |
+
create_pr=False,
|
377 |
+
)
|
378 |
+
push_pipeline_code_to_hub(pipeline_code, org_name, repo_name, oauth_token)
|
379 |
+
progress(1.0, desc="Dataset pushed")
|
380 |
+
return dataframe
|
381 |
+
|
382 |
+
|
383 |
+
def push_dataset(
|
384 |
+
org_name: str,
|
385 |
+
repo_name: str,
|
386 |
+
private: bool,
|
387 |
+
original_repo_id: str,
|
388 |
+
file_paths: list[str],
|
389 |
+
input_type: str,
|
390 |
+
system_prompt: str,
|
391 |
+
document_column: str,
|
392 |
+
retrieval_reranking: list[str],
|
393 |
+
num_rows: int,
|
394 |
+
temperature: float,
|
395 |
+
pipeline_code: str,
|
396 |
+
oauth_token: Union[gr.OAuthToken, None] = None,
|
397 |
+
progress=gr.Progress(),
|
398 |
+
) -> pd.DataFrame:
|
399 |
+
retrieval = "Retrieval" in retrieval_reranking
|
400 |
+
reranking = "Reranking" in retrieval_reranking
|
401 |
+
|
402 |
+
if input_type != "prompt-input":
|
403 |
+
dataframe, _ = load_dataset_file(
|
404 |
+
repo_id=original_repo_id,
|
405 |
+
file_paths=file_paths,
|
406 |
+
input_type=input_type,
|
407 |
+
num_rows=num_rows,
|
408 |
+
token=oauth_token,
|
409 |
+
)
|
410 |
+
progress(0.5, desc="Generating dataset")
|
411 |
+
dataframe = generate_dataset(
|
412 |
+
input_type=input_type,
|
413 |
+
dataframe=dataframe,
|
414 |
+
system_prompt=system_prompt,
|
415 |
+
document_column=document_column,
|
416 |
+
retrieval=retrieval,
|
417 |
+
reranking=reranking,
|
418 |
+
num_rows=num_rows,
|
419 |
+
temperature=temperature,
|
420 |
+
is_sample=True,
|
421 |
+
)
|
422 |
+
push_dataset_to_hub(
|
423 |
+
dataframe, org_name, repo_name, oauth_token, private, pipeline_code
|
424 |
+
)
|
425 |
+
try:
|
426 |
+
progress(0.1, desc="Setting up user and workspace")
|
427 |
+
hf_user = HfApi().whoami(token=oauth_token.token)["name"]
|
428 |
+
client = get_argilla_client()
|
429 |
+
if client is None:
|
430 |
+
return ""
|
431 |
+
|
432 |
+
progress(0.5, desc="Creating dataset in Argilla")
|
433 |
+
fields = [
|
434 |
+
rg.TextField(
|
435 |
+
name="context",
|
436 |
+
title="Context",
|
437 |
+
description="Context for the generation",
|
438 |
+
),
|
439 |
+
rg.ChatField(
|
440 |
+
name="chat",
|
441 |
+
title="Chat",
|
442 |
+
description="User and assistant conversation based on the context",
|
443 |
+
),
|
444 |
+
]
|
445 |
+
for item in ["positive", "negative"]:
|
446 |
+
if retrieval:
|
447 |
+
fields.append(
|
448 |
+
rg.TextField(
|
449 |
+
name=f"{item}_retrieval",
|
450 |
+
title=f"{item.capitalize()} retrieval",
|
451 |
+
description=f"The {item} query for retrieval",
|
452 |
+
)
|
453 |
+
)
|
454 |
+
if reranking:
|
455 |
+
fields.append(
|
456 |
+
rg.TextField(
|
457 |
+
name=f"{item}_reranking",
|
458 |
+
title=f"{item.capitalize()} reranking",
|
459 |
+
description=f"The {item} query for reranking",
|
460 |
+
)
|
461 |
+
)
|
462 |
+
|
463 |
+
questions = [
|
464 |
+
rg.LabelQuestion(
|
465 |
+
name="relevant",
|
466 |
+
title="Are the question and response relevant to the given context?",
|
467 |
+
labels=["yes", "no"],
|
468 |
+
),
|
469 |
+
rg.LabelQuestion(
|
470 |
+
name="is_response_correct",
|
471 |
+
title="Is the response correct?",
|
472 |
+
labels=["yes", "no"],
|
473 |
+
),
|
474 |
+
]
|
475 |
+
for item in ["positive", "negative"]:
|
476 |
+
if retrieval:
|
477 |
+
questions.append(
|
478 |
+
rg.LabelQuestion(
|
479 |
+
name=f"is_{item}_retrieval_relevant",
|
480 |
+
title=f"Is the {item} retrieval relevant?",
|
481 |
+
labels=["yes", "no"],
|
482 |
+
required=False,
|
483 |
+
)
|
484 |
+
)
|
485 |
+
if reranking:
|
486 |
+
questions.append(
|
487 |
+
rg.LabelQuestion(
|
488 |
+
name=f"is_{item}_reranking_relevant",
|
489 |
+
title=f"Is the {item} reranking relevant?",
|
490 |
+
labels=["yes", "no"],
|
491 |
+
required=False,
|
492 |
+
)
|
493 |
+
)
|
494 |
+
metadata = [
|
495 |
+
rg.IntegerMetadataProperty(
|
496 |
+
name=f"{item}_length", title=f"{item.capitalize()} length"
|
497 |
+
)
|
498 |
+
for item in ["context", "question", "response"]
|
499 |
+
]
|
500 |
+
|
501 |
+
vectors = [
|
502 |
+
rg.VectorField(
|
503 |
+
name=f"{item}_embeddings",
|
504 |
+
dimensions=get_sentence_embedding_dimensions(),
|
505 |
+
)
|
506 |
+
for item in ["context", "question", "response"]
|
507 |
+
]
|
508 |
+
settings = rg.Settings(
|
509 |
+
fields=fields,
|
510 |
+
questions=questions,
|
511 |
+
metadata=metadata,
|
512 |
+
vectors=vectors,
|
513 |
+
guidelines="Please review the conversation and provide an evaluation.",
|
514 |
+
)
|
515 |
+
|
516 |
+
dataframe["chat"] = dataframe.apply(
|
517 |
+
lambda row: [
|
518 |
+
{"role": "user", "content": row["question"]},
|
519 |
+
{"role": "assistant", "content": row["response"]},
|
520 |
+
],
|
521 |
+
axis=1,
|
522 |
+
)
|
523 |
+
|
524 |
+
for item in ["context", "question", "response"]:
|
525 |
+
dataframe[f"{item}_length"] = dataframe[item].apply(len)
|
526 |
+
dataframe[f"{item}_embeddings"] = get_embeddings(dataframe[item].to_list())
|
527 |
+
|
528 |
+
rg_dataset = client.datasets(name=repo_name, workspace=hf_user)
|
529 |
+
if rg_dataset is None:
|
530 |
+
rg_dataset = rg.Dataset(
|
531 |
+
name=repo_name,
|
532 |
+
workspace=hf_user,
|
533 |
+
settings=settings,
|
534 |
+
client=client,
|
535 |
+
)
|
536 |
+
rg_dataset = rg_dataset.create()
|
537 |
+
|
538 |
+
progress(0.7, desc="Pushing dataset to Argilla")
|
539 |
+
hf_dataset = Dataset.from_pandas(dataframe)
|
540 |
+
rg_dataset.records.log(records=hf_dataset)
|
541 |
+
progress(1.0, desc="Dataset pushed to Argilla")
|
542 |
+
except Exception as e:
|
543 |
+
raise gr.Error(f"Error pushing dataset to Argilla: {e}")
|
544 |
+
return ""
|
545 |
+
|
546 |
+
|
547 |
+
def show_system_prompt_visibility():
|
548 |
+
return {system_prompt: gr.Textbox(visible=True)}
|
549 |
+
|
550 |
+
|
551 |
+
def hide_system_prompt_visibility():
|
552 |
+
return {system_prompt: gr.Textbox(visible=False)}
|
553 |
+
|
554 |
+
|
555 |
+
def show_document_column_visibility():
|
556 |
+
return {document_column: gr.Dropdown(visible=True)}
|
557 |
+
|
558 |
+
|
559 |
+
def hide_document_column_visibility():
|
560 |
+
return {document_column: gr.Dropdown(visible=False)}
|
561 |
+
|
562 |
+
|
563 |
+
def show_pipeline_code_visibility():
|
564 |
+
return {pipeline_code_ui: gr.Accordion(visible=True)}
|
565 |
+
|
566 |
+
|
567 |
+
def hide_pipeline_code_visibility():
|
568 |
+
return {pipeline_code_ui: gr.Accordion(visible=False)}
|
569 |
+
|
570 |
+
|
571 |
+
######################
|
572 |
+
# Gradio UI
|
573 |
+
######################
|
574 |
+
|
575 |
+
|
576 |
+
with gr.Blocks() as app:
|
577 |
+
with gr.Column() as main_ui:
|
578 |
+
gr.Markdown("## 1. Select your input")
|
579 |
+
with gr.Row(equal_height=False):
|
580 |
+
with gr.Column(scale=2):
|
581 |
+
input_type = gr.Dropdown(
|
582 |
+
label="Input type",
|
583 |
+
choices=["dataset-input", "file-input", "prompt-input"],
|
584 |
+
value="dataset-input",
|
585 |
+
multiselect=False,
|
586 |
+
visible=False,
|
587 |
+
)
|
588 |
+
with gr.Tab("Load from Hub") as tab_dataset_input:
|
589 |
+
with gr.Row(equal_height=False):
|
590 |
+
with gr.Column(scale=2):
|
591 |
+
search_in = HuggingfaceHubSearch(
|
592 |
+
label="Search",
|
593 |
+
placeholder="Search for a dataset",
|
594 |
+
search_type="dataset",
|
595 |
+
sumbit_on_select=True,
|
596 |
+
)
|
597 |
+
with gr.Row():
|
598 |
+
clear_dataset_btn_part = gr.Button(
|
599 |
+
"Clear", variant="secondary"
|
600 |
+
)
|
601 |
+
load_dataset_btn = gr.Button("Load", variant="primary")
|
602 |
+
with gr.Column(scale=3):
|
603 |
+
examples = gr.Examples(
|
604 |
+
examples=[
|
605 |
+
"charris/wikipedia_sample",
|
606 |
+
"plaguss/argilla_sdk_docs_raw_unstructured",
|
607 |
+
"BeIR/hotpotqa-generated-queries",
|
608 |
+
],
|
609 |
+
label="Example datasets",
|
610 |
+
fn=lambda x: x,
|
611 |
+
inputs=[search_in],
|
612 |
+
run_on_click=True,
|
613 |
+
)
|
614 |
+
search_out = gr.HTML(label="Dataset preview", visible=False)
|
615 |
+
with gr.Tab("Load your file") as tab_file_input:
|
616 |
+
with gr.Row(equal_height=False):
|
617 |
+
with gr.Column(scale=2):
|
618 |
+
file_in = gr.File(
|
619 |
+
label="Upload your file. Supported formats: .md, .txt, .docx, .pdf",
|
620 |
+
file_count="multiple",
|
621 |
+
file_types=[".md", ".txt", ".docx", ".pdf"],
|
622 |
+
)
|
623 |
+
with gr.Row():
|
624 |
+
clear_file_btn_part = gr.Button(
|
625 |
+
"Clear", variant="secondary"
|
626 |
+
)
|
627 |
+
load_file_btn = gr.Button("Load", variant="primary")
|
628 |
+
with gr.Column(scale=3):
|
629 |
+
file_out = gr.HTML(label="Dataset preview", visible=False)
|
630 |
+
with gr.Tab("Generate from prompt") as tab_prompt_input:
|
631 |
+
with gr.Row(equal_height=False):
|
632 |
+
with gr.Column(scale=2):
|
633 |
+
dataset_description = gr.Textbox(
|
634 |
+
label="Dataset description",
|
635 |
+
placeholder="Give a precise description of your desired dataset.",
|
636 |
+
)
|
637 |
+
with gr.Row():
|
638 |
+
clear_prompt_btn_part = gr.Button(
|
639 |
+
"Clear", variant="secondary"
|
640 |
+
)
|
641 |
+
load_prompt_btn = gr.Button("Create", variant="primary")
|
642 |
+
with gr.Column(scale=3):
|
643 |
+
examples = gr.Examples(
|
644 |
+
examples=DEFAULT_DATASET_DESCRIPTIONS,
|
645 |
+
inputs=[dataset_description],
|
646 |
+
cache_examples=False,
|
647 |
+
label="Examples",
|
648 |
+
)
|
649 |
+
|
650 |
+
gr.HTML(value="<hr>")
|
651 |
+
gr.Markdown(value="## 2. Configure your task")
|
652 |
+
with gr.Row(equal_height=True):
|
653 |
+
with gr.Row(equal_height=False):
|
654 |
+
with gr.Column(scale=2):
|
655 |
+
system_prompt = gr.Textbox(
|
656 |
+
label="System prompt",
|
657 |
+
placeholder="You are a helpful assistant.",
|
658 |
+
visible=False,
|
659 |
+
)
|
660 |
+
document_column = gr.Dropdown(
|
661 |
+
label="Document Column",
|
662 |
+
info="Select the document column to generate the RAG dataset",
|
663 |
+
choices=["Load your data first in step 1."],
|
664 |
+
value="Load your data first in step 1.",
|
665 |
+
interactive=False,
|
666 |
+
multiselect=False,
|
667 |
+
allow_custom_value=False,
|
668 |
+
)
|
669 |
+
retrieval_reranking = gr.CheckboxGroup(
|
670 |
+
choices=[("Retrieval", "Retrieval"), ("Reranking", "Reranking")],
|
671 |
+
type="value",
|
672 |
+
label="Data for RAG",
|
673 |
+
info="Indicate the additional data you want to generate for RAG.",
|
674 |
+
)
|
675 |
+
with gr.Row():
|
676 |
+
clear_btn_full = gr.Button("Clear", variant="secondary")
|
677 |
+
btn_apply_to_sample_dataset = gr.Button(
|
678 |
+
"Save", variant="primary"
|
679 |
+
)
|
680 |
+
with gr.Column(scale=3):
|
681 |
+
dataframe = gr.Dataframe(
|
682 |
+
headers=["context", "question", "response"],
|
683 |
+
wrap=True,
|
684 |
+
interactive=False,
|
685 |
+
)
|
686 |
+
|
687 |
+
gr.HTML(value="<hr>")
|
688 |
+
gr.Markdown(value="## 3. Generate your dataset")
|
689 |
+
with gr.Row(equal_height=False):
|
690 |
+
with gr.Column(scale=2):
|
691 |
+
org_name = get_org_dropdown()
|
692 |
+
repo_name = gr.Textbox(
|
693 |
+
label="Repo name",
|
694 |
+
placeholder="dataset_name",
|
695 |
+
value=f"my-distiset-{str(uuid.uuid4())[:8]}",
|
696 |
+
interactive=True,
|
697 |
+
)
|
698 |
+
num_rows = gr.Number(
|
699 |
+
label="Number of rows",
|
700 |
+
value=10,
|
701 |
+
interactive=True,
|
702 |
+
scale=1,
|
703 |
+
)
|
704 |
+
temperature = gr.Slider(
|
705 |
+
label="Temperature",
|
706 |
+
minimum=0.1,
|
707 |
+
maximum=1,
|
708 |
+
value=0.7,
|
709 |
+
step=0.1,
|
710 |
+
interactive=True,
|
711 |
+
)
|
712 |
+
private = gr.Checkbox(
|
713 |
+
label="Private dataset",
|
714 |
+
value=False,
|
715 |
+
interactive=True,
|
716 |
+
scale=1,
|
717 |
+
)
|
718 |
+
btn_push_to_hub = gr.Button("Push to Hub", variant="primary", scale=2)
|
719 |
+
with gr.Column(scale=3):
|
720 |
+
success_message = gr.Markdown(
|
721 |
+
visible=True,
|
722 |
+
min_height=100, # don't remove this otherwise progress is not visible
|
723 |
+
)
|
724 |
+
with gr.Accordion(
|
725 |
+
"Customize your pipeline with distilabel",
|
726 |
+
open=False,
|
727 |
+
visible=False,
|
728 |
+
) as pipeline_code_ui:
|
729 |
+
code = generate_pipeline_code(
|
730 |
+
repo_id=search_in.value,
|
731 |
+
file_paths=file_in.value,
|
732 |
+
input_type=input_type.value,
|
733 |
+
system_prompt=system_prompt.value,
|
734 |
+
document_column=document_column.value,
|
735 |
+
retrieval_reranking=retrieval_reranking.value,
|
736 |
+
num_rows=num_rows.value,
|
737 |
+
)
|
738 |
+
pipeline_code = gr.Code(
|
739 |
+
value=code,
|
740 |
+
language="python",
|
741 |
+
label="Distilabel Pipeline Code",
|
742 |
+
)
|
743 |
+
|
744 |
+
tab_dataset_input.select(
|
745 |
+
fn=lambda: "dataset-input",
|
746 |
+
inputs=[],
|
747 |
+
outputs=[input_type],
|
748 |
+
).then(fn=hide_system_prompt_visibility, inputs=[], outputs=[system_prompt]).then(
|
749 |
+
fn=show_document_column_visibility, inputs=[], outputs=[document_column]
|
750 |
+
)
|
751 |
+
|
752 |
+
tab_file_input.select(
|
753 |
+
fn=lambda: "file-input",
|
754 |
+
inputs=[],
|
755 |
+
outputs=[input_type],
|
756 |
+
).then(fn=hide_system_prompt_visibility, inputs=[], outputs=[system_prompt]).then(
|
757 |
+
fn=show_document_column_visibility, inputs=[], outputs=[document_column]
|
758 |
+
)
|
759 |
+
|
760 |
+
tab_prompt_input.select(
|
761 |
+
fn=lambda: "prompt-input",
|
762 |
+
inputs=[],
|
763 |
+
outputs=[input_type],
|
764 |
+
).then(fn=show_system_prompt_visibility, inputs=[], outputs=[system_prompt]).then(
|
765 |
+
fn=hide_document_column_visibility, inputs=[], outputs=[document_column]
|
766 |
+
)
|
767 |
+
|
768 |
+
search_in.submit(fn=get_iframe, inputs=search_in, outputs=search_out).then(
|
769 |
+
fn=lambda df: pd.DataFrame(columns=df.columns),
|
770 |
+
inputs=[dataframe],
|
771 |
+
outputs=[dataframe],
|
772 |
+
)
|
773 |
+
|
774 |
+
load_dataset_btn.click(
|
775 |
+
fn=load_dataset_file,
|
776 |
+
inputs=[search_in, file_in, input_type],
|
777 |
+
outputs=[
|
778 |
+
dataframe,
|
779 |
+
document_column,
|
780 |
+
],
|
781 |
+
)
|
782 |
+
|
783 |
+
load_file_btn.click(
|
784 |
+
fn=load_dataset_file,
|
785 |
+
inputs=[search_in, file_in, input_type],
|
786 |
+
outputs=[
|
787 |
+
dataframe,
|
788 |
+
document_column,
|
789 |
+
],
|
790 |
+
)
|
791 |
+
|
792 |
+
load_prompt_btn.click(
|
793 |
+
fn=generate_system_prompt,
|
794 |
+
inputs=[dataset_description],
|
795 |
+
outputs=[system_prompt],
|
796 |
+
show_progress=True,
|
797 |
+
).success(
|
798 |
+
fn=generate_sample_dataset,
|
799 |
+
inputs=[
|
800 |
+
search_in,
|
801 |
+
file_in,
|
802 |
+
input_type,
|
803 |
+
system_prompt,
|
804 |
+
document_column,
|
805 |
+
retrieval_reranking,
|
806 |
+
num_rows,
|
807 |
+
],
|
808 |
+
outputs=dataframe,
|
809 |
+
)
|
810 |
+
|
811 |
+
btn_apply_to_sample_dataset.click(
|
812 |
+
fn=generate_sample_dataset,
|
813 |
+
inputs=[
|
814 |
+
search_in,
|
815 |
+
file_in,
|
816 |
+
input_type,
|
817 |
+
system_prompt,
|
818 |
+
document_column,
|
819 |
+
retrieval_reranking,
|
820 |
+
num_rows,
|
821 |
+
],
|
822 |
+
outputs=dataframe,
|
823 |
+
)
|
824 |
+
|
825 |
+
btn_push_to_hub.click(
|
826 |
+
fn=validate_argilla_user_workspace_dataset,
|
827 |
+
inputs=[repo_name],
|
828 |
+
outputs=[success_message],
|
829 |
+
show_progress=True,
|
830 |
+
).then(
|
831 |
+
fn=validate_push_to_hub,
|
832 |
+
inputs=[org_name, repo_name],
|
833 |
+
outputs=[success_message],
|
834 |
+
show_progress=True,
|
835 |
+
).success(
|
836 |
+
fn=hide_success_message,
|
837 |
+
outputs=[success_message],
|
838 |
+
show_progress=True,
|
839 |
+
).success(
|
840 |
+
fn=hide_pipeline_code_visibility,
|
841 |
+
inputs=[],
|
842 |
+
outputs=[pipeline_code_ui],
|
843 |
+
).success(
|
844 |
+
fn=push_dataset,
|
845 |
+
inputs=[
|
846 |
+
org_name,
|
847 |
+
repo_name,
|
848 |
+
private,
|
849 |
+
search_in,
|
850 |
+
file_in,
|
851 |
+
input_type,
|
852 |
+
system_prompt,
|
853 |
+
document_column,
|
854 |
+
retrieval_reranking,
|
855 |
+
num_rows,
|
856 |
+
temperature,
|
857 |
+
pipeline_code,
|
858 |
+
],
|
859 |
+
outputs=[success_message],
|
860 |
+
show_progress=True,
|
861 |
+
).success(
|
862 |
+
fn=show_success_message,
|
863 |
+
inputs=[org_name, repo_name],
|
864 |
+
outputs=[success_message],
|
865 |
+
).success(
|
866 |
+
fn=generate_pipeline_code,
|
867 |
+
inputs=[
|
868 |
+
search_in,
|
869 |
+
file_in,
|
870 |
+
input_type,
|
871 |
+
system_prompt,
|
872 |
+
document_column,
|
873 |
+
retrieval_reranking,
|
874 |
+
num_rows,
|
875 |
+
],
|
876 |
+
outputs=[pipeline_code],
|
877 |
+
).success(
|
878 |
+
fn=show_pipeline_code_visibility,
|
879 |
+
inputs=[],
|
880 |
+
outputs=[pipeline_code_ui],
|
881 |
+
)
|
882 |
+
|
883 |
+
clear_dataset_btn_part.click(fn=lambda : "", inputs=[], outputs=[search_in])
|
884 |
+
clear_file_btn_part.click(fn=lambda: None, inputs=[], outputs=[file_in])
|
885 |
+
clear_prompt_btn_part.click(
|
886 |
+
fn=lambda : "", inputs=[], outputs=[dataset_description]
|
887 |
+
)
|
888 |
+
clear_btn_full.click(
|
889 |
+
fn=lambda df: ("", [], pd.DataFrame(columns=df.columns)),
|
890 |
+
inputs=[dataframe],
|
891 |
+
outputs=[document_column, retrieval_reranking, dataframe],
|
892 |
+
)
|
893 |
+
|
894 |
+
app.load(fn=swap_visibility, outputs=main_ui)
|
895 |
+
app.load(fn=get_org_dropdown, outputs=[org_name])
|
896 |
+
app.load(fn=get_random_repo_name, outputs=[repo_name])
|
src/synthetic_dataset_generator/apps/textcat.py
CHANGED
@@ -20,7 +20,7 @@ from synthetic_dataset_generator.apps.base import (
|
|
20 |
validate_push_to_hub,
|
21 |
)
|
22 |
from synthetic_dataset_generator.constants import DEFAULT_BATCH_SIZE
|
23 |
-
from synthetic_dataset_generator.pipelines.base import
|
24 |
from synthetic_dataset_generator.pipelines.embeddings import (
|
25 |
get_embeddings,
|
26 |
get_sentence_embedding_dimensions,
|
@@ -120,7 +120,7 @@ def generate_dataset(
|
|
120 |
# create text classification data
|
121 |
n_processed = 0
|
122 |
textcat_results = []
|
123 |
-
rewritten_system_prompts =
|
124 |
while n_processed < num_rows:
|
125 |
progress(
|
126 |
2 * 0.5 * n_processed / num_rows,
|
@@ -314,6 +314,7 @@ def push_dataset(
|
|
314 |
if client is None:
|
315 |
return ""
|
316 |
labels = get_preprocess_labels(labels)
|
|
|
317 |
settings = rg.Settings(
|
318 |
fields=[
|
319 |
rg.TextField(
|
@@ -354,7 +355,6 @@ def push_dataset(
|
|
354 |
dataframe["text_length"] = dataframe["text"].apply(len)
|
355 |
dataframe["text_embeddings"] = get_embeddings(dataframe["text"].to_list())
|
356 |
|
357 |
-
progress(0.5, desc="Creating dataset")
|
358 |
rg_dataset = client.datasets(name=repo_name, workspace=hf_user)
|
359 |
if rg_dataset is None:
|
360 |
rg_dataset = rg.Dataset(
|
@@ -559,7 +559,6 @@ with gr.Blocks() as app:
|
|
559 |
labels=labels.value,
|
560 |
num_labels=len(labels.value) if multi_label.value else 1,
|
561 |
num_rows=num_rows.value,
|
562 |
-
temperature=temperature.value,
|
563 |
)
|
564 |
pipeline_code = gr.Code(
|
565 |
value=code,
|
@@ -644,7 +643,6 @@ with gr.Blocks() as app:
|
|
644 |
labels,
|
645 |
multi_label,
|
646 |
num_rows,
|
647 |
-
temperature,
|
648 |
],
|
649 |
outputs=[pipeline_code],
|
650 |
).success(
|
@@ -662,7 +660,7 @@ with gr.Blocks() as app:
|
|
662 |
_get_dataframe(),
|
663 |
),
|
664 |
inputs=[dataframe],
|
665 |
-
outputs=[dataset_description, system_prompt, labels, dataframe],
|
666 |
)
|
667 |
|
668 |
app.load(fn=swap_visibility, outputs=main_ui)
|
|
|
20 |
validate_push_to_hub,
|
21 |
)
|
22 |
from synthetic_dataset_generator.constants import DEFAULT_BATCH_SIZE
|
23 |
+
from synthetic_dataset_generator.pipelines.base import get_rewritten_prompts
|
24 |
from synthetic_dataset_generator.pipelines.embeddings import (
|
25 |
get_embeddings,
|
26 |
get_sentence_embedding_dimensions,
|
|
|
120 |
# create text classification data
|
121 |
n_processed = 0
|
122 |
textcat_results = []
|
123 |
+
rewritten_system_prompts = get_rewritten_prompts(system_prompt, num_rows)
|
124 |
while n_processed < num_rows:
|
125 |
progress(
|
126 |
2 * 0.5 * n_processed / num_rows,
|
|
|
314 |
if client is None:
|
315 |
return ""
|
316 |
labels = get_preprocess_labels(labels)
|
317 |
+
progress(0.5, desc="Creating dataset in Argilla")
|
318 |
settings = rg.Settings(
|
319 |
fields=[
|
320 |
rg.TextField(
|
|
|
355 |
dataframe["text_length"] = dataframe["text"].apply(len)
|
356 |
dataframe["text_embeddings"] = get_embeddings(dataframe["text"].to_list())
|
357 |
|
|
|
358 |
rg_dataset = client.datasets(name=repo_name, workspace=hf_user)
|
359 |
if rg_dataset is None:
|
360 |
rg_dataset = rg.Dataset(
|
|
|
559 |
labels=labels.value,
|
560 |
num_labels=len(labels.value) if multi_label.value else 1,
|
561 |
num_rows=num_rows.value,
|
|
|
562 |
)
|
563 |
pipeline_code = gr.Code(
|
564 |
value=code,
|
|
|
643 |
labels,
|
644 |
multi_label,
|
645 |
num_rows,
|
|
|
646 |
],
|
647 |
outputs=[pipeline_code],
|
648 |
).success(
|
|
|
660 |
_get_dataframe(),
|
661 |
),
|
662 |
inputs=[dataframe],
|
663 |
+
outputs=[dataset_description, system_prompt, labels, multi_label, dataframe],
|
664 |
)
|
665 |
|
666 |
app.load(fn=swap_visibility, outputs=main_ui)
|
src/synthetic_dataset_generator/pipelines/base.py
CHANGED
@@ -39,7 +39,7 @@ def _get_prompt_rewriter():
|
|
39 |
return prompt_rewriter
|
40 |
|
41 |
|
42 |
-
def
|
43 |
prompt_rewriter = _get_prompt_rewriter()
|
44 |
# create prompt rewrites
|
45 |
inputs = [
|
|
|
39 |
return prompt_rewriter
|
40 |
|
41 |
|
42 |
+
def get_rewritten_prompts(prompt: str, num_rows: int):
|
43 |
prompt_rewriter = _get_prompt_rewriter()
|
44 |
# create prompt rewrites
|
45 |
inputs = [
|
src/synthetic_dataset_generator/pipelines/chat.py
CHANGED
@@ -227,7 +227,7 @@ def get_response_generator(system_prompt, num_turns, temperature, is_sample):
|
|
227 |
return response_generator
|
228 |
|
229 |
|
230 |
-
def generate_pipeline_code(system_prompt, num_turns, num_rows
|
231 |
input_mappings = _get_output_mappings(num_turns)
|
232 |
|
233 |
code = f"""
|
@@ -242,7 +242,9 @@ SYSTEM_PROMPT = "{system_prompt}"
|
|
242 |
|
243 |
with Pipeline(name="sft") as pipeline:
|
244 |
magpie = MagpieGenerator(
|
245 |
-
llm={_get_llm_class()}.from_dict(
|
|
|
|
|
246 |
n_turns={num_turns},
|
247 |
num_rows={num_rows},
|
248 |
batch_size=1,
|
|
|
227 |
return response_generator
|
228 |
|
229 |
|
230 |
+
def generate_pipeline_code(system_prompt, num_turns, num_rows):
|
231 |
input_mappings = _get_output_mappings(num_turns)
|
232 |
|
233 |
code = f"""
|
|
|
242 |
|
243 |
with Pipeline(name="sft") as pipeline:
|
244 |
magpie = MagpieGenerator(
|
245 |
+
llm={_get_llm_class()}.from_dict(
|
246 |
+
{_get_llm().dump()}
|
247 |
+
),
|
248 |
n_turns={num_turns},
|
249 |
num_rows={num_rows},
|
250 |
batch_size=1,
|
src/synthetic_dataset_generator/pipelines/rag.py
ADDED
@@ -0,0 +1,302 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
|
3 |
+
from typing import List
|
4 |
+
|
5 |
+
from datasets import get_dataset_config_names, get_dataset_split_names
|
6 |
+
from distilabel.steps.tasks import (
|
7 |
+
GenerateSentencePair,
|
8 |
+
TextGeneration,
|
9 |
+
)
|
10 |
+
|
11 |
+
from synthetic_dataset_generator.constants import MAX_NUM_TOKENS
|
12 |
+
from synthetic_dataset_generator.pipelines.base import _get_llm, _get_llm_class
|
13 |
+
|
14 |
+
DEFAULT_DATASET_DESCRIPTIONS = [
|
15 |
+
"A dataset to retrieve information from legal documents.",
|
16 |
+
"A dataset to search for economical techniques.",
|
17 |
+
]
|
18 |
+
|
19 |
+
PROMPT_CREATION_PROMPT = """
|
20 |
+
|
21 |
+
You are an AI assistant specialized in designing retrieval-augmented generation (RAG) tasks for dataset creation.
|
22 |
+
|
23 |
+
Your task is to generate a well-structured and descriptive prompt based on the provided dataset description and company context. Respond with only the generated prompt and nothing else.
|
24 |
+
|
25 |
+
The prompt should closely follow the style and structure of the example prompts below. Ensure that you include all relevant details from the dataset description and reflect the company context accurately.
|
26 |
+
|
27 |
+
Description: A dataset to retrieve information from legal documents.
|
28 |
+
Output: A dataset to retrieve information from a collection of legal documents related to the US law system and the status of contracts.
|
29 |
+
|
30 |
+
Description: A dataset to search for economical techniques.
|
31 |
+
Output: A dataset to search for economical techniques and strategies for the European market and the financial sector.
|
32 |
+
|
33 |
+
Description: A dataset covering FAQ questions for a tech company called Argilla that sells technology datasets within the open-source Natural Language Processing space.
|
34 |
+
Output: A dataset covering FAQ questions for a tech company called Argilla that sells technology datasets within the open-source Natural Language Processing space.
|
35 |
+
|
36 |
+
Description:
|
37 |
+
"""
|
38 |
+
|
39 |
+
SYSTEM_PROMPT_CHUCKS = """
|
40 |
+
You are a helpful and knowledgeable AI assistant. Your task is to generate concise and informative text chunks relevant to the given retrieval task.
|
41 |
+
|
42 |
+
Ensure the text chunks are:
|
43 |
+
- Focused and directly related to the retrieval task.
|
44 |
+
- Clear, truthful, and based on your general knowledge.
|
45 |
+
|
46 |
+
Do not include or reference the retrieval task itself in the generated chunks.
|
47 |
+
"""
|
48 |
+
|
49 |
+
CHUNKS_TEMPLATE = """You have been assigned to generate text chunks based on the following retrieval task: {{ task }}.
|
50 |
+
|
51 |
+
Provide only the text chunks without explaining your process or reasoning.
|
52 |
+
|
53 |
+
Ensure the chunks are clear, accurate, and directly relevant to the task.
|
54 |
+
|
55 |
+
Use your general knowledge to create informative and precise outputs.
|
56 |
+
"""
|
57 |
+
|
58 |
+
SYSTEM_PROMPT_RAG = """
|
59 |
+
You are a helpful AI assistant. Your task is to answer the following question based on the provided document.
|
60 |
+
|
61 |
+
If the answer is not explicitly stated in the document, use your knowledge to provide the most relevant and accurate answer possible.
|
62 |
+
|
63 |
+
If you cannot answer the question based on the given information, state that clearly.
|
64 |
+
"""
|
65 |
+
|
66 |
+
RAG_TEMPLATE = """Document:
|
67 |
+
{{ context }}
|
68 |
+
|
69 |
+
Question: {{ question }}
|
70 |
+
|
71 |
+
Please provide a clear and concise answer to the question based on the information in the document:
|
72 |
+
""".rstrip()
|
73 |
+
|
74 |
+
|
75 |
+
def get_prompt_generator():
|
76 |
+
generation_kwargs = {
|
77 |
+
"temperature": 0.8,
|
78 |
+
"max_new_tokens": MAX_NUM_TOKENS,
|
79 |
+
}
|
80 |
+
text_generator = TextGeneration(
|
81 |
+
llm=_get_llm(generation_kwargs=generation_kwargs),
|
82 |
+
system_prompt=PROMPT_CREATION_PROMPT,
|
83 |
+
use_system_prompt=True,
|
84 |
+
)
|
85 |
+
|
86 |
+
text_generator.load()
|
87 |
+
return text_generator
|
88 |
+
|
89 |
+
|
90 |
+
def get_chunks_generator(temperature, is_sample):
|
91 |
+
generation_kwargs = {
|
92 |
+
"temperature": temperature,
|
93 |
+
"max_new_tokens": MAX_NUM_TOKENS if is_sample else 256,
|
94 |
+
}
|
95 |
+
text_generator = TextGeneration(
|
96 |
+
llm=_get_llm(generation_kwargs=generation_kwargs),
|
97 |
+
system_prompt=SYSTEM_PROMPT_CHUCKS,
|
98 |
+
template=CHUNKS_TEMPLATE,
|
99 |
+
columns=["task"],
|
100 |
+
use_system_prompt=True,
|
101 |
+
)
|
102 |
+
|
103 |
+
text_generator.load()
|
104 |
+
return text_generator
|
105 |
+
|
106 |
+
|
107 |
+
def get_sentence_pair_generator(action, triplet, temperature, is_sample):
|
108 |
+
generation_kwargs = {
|
109 |
+
"temperature": temperature,
|
110 |
+
"max_new_tokens": 256 if is_sample else MAX_NUM_TOKENS,
|
111 |
+
}
|
112 |
+
sentence_pair_generator = GenerateSentencePair(
|
113 |
+
llm=_get_llm(generation_kwargs=generation_kwargs),
|
114 |
+
triplet=triplet,
|
115 |
+
action=action,
|
116 |
+
hard_negative=True,
|
117 |
+
)
|
118 |
+
sentence_pair_generator.load()
|
119 |
+
return sentence_pair_generator
|
120 |
+
|
121 |
+
|
122 |
+
def get_response_generator(temperature, is_sample):
|
123 |
+
generation_kwargs = {
|
124 |
+
"temperature": temperature,
|
125 |
+
"max_new_tokens": MAX_NUM_TOKENS if is_sample else 256,
|
126 |
+
}
|
127 |
+
text_generator = TextGeneration(
|
128 |
+
llm=_get_llm(generation_kwargs=generation_kwargs),
|
129 |
+
system_prompt=SYSTEM_PROMPT_RAG,
|
130 |
+
template=RAG_TEMPLATE,
|
131 |
+
columns=["context", "question"],
|
132 |
+
use_system_prompt=True,
|
133 |
+
)
|
134 |
+
|
135 |
+
text_generator.load()
|
136 |
+
return text_generator
|
137 |
+
|
138 |
+
|
139 |
+
def generate_pipeline_code(
|
140 |
+
repo_id: str,
|
141 |
+
file_paths: List[str],
|
142 |
+
input_type: str,
|
143 |
+
system_prompt: str,
|
144 |
+
document_column: str,
|
145 |
+
retrieval_reranking: list[str],
|
146 |
+
num_rows: int = 10,
|
147 |
+
) -> str:
|
148 |
+
if repo_id is None:
|
149 |
+
subset = "default"
|
150 |
+
split = "train"
|
151 |
+
else:
|
152 |
+
subset = get_dataset_config_names(repo_id)[0]
|
153 |
+
split = get_dataset_split_names(repo_id, subset)[0]
|
154 |
+
retrieval = "Retrieval" in retrieval_reranking
|
155 |
+
reranking = "Reranking" in retrieval_reranking
|
156 |
+
base_code = f"""
|
157 |
+
# Requirements: `pip install distilabel[hf-inference-endpoints]`
|
158 |
+
{"import random" if input_type == "prompt-input" else ""}
|
159 |
+
from distilabel.models import {_get_llm_class()}
|
160 |
+
from distilabel.pipeline import Pipeline
|
161 |
+
from distilabel.steps import KeepColumns{", LoadDataFromDicts" if input_type != "dataset-input" else ""}{", LoadDataFromHub" if input_type == "dataset-input" else ""}{", CombineOutputs" if retrieval and reranking else ""}
|
162 |
+
from distilabel.steps.tasks import GenerateSentencePair, TextGeneration {", GenerateTextRetrievalData" if input_type == "prompt-input" else ""}
|
163 |
+
|
164 |
+
SYSTEM_PROMPT_RAG = '''
|
165 |
+
You are a helpful AI assistant. Your task is to answer the following question based on the provided document.
|
166 |
+
|
167 |
+
If the answer is not explicitly stated in the document, use your knowledge to provide the most relevant and accurate answer possible.
|
168 |
+
|
169 |
+
If you cannot answer the question based on the given information, state that clearly.
|
170 |
+
'''
|
171 |
+
|
172 |
+
RAG_TEMPLATE = '''Document:
|
173 |
+
{{{{ filename }}}}
|
174 |
+
|
175 |
+
Question: {{{{ question }}}}
|
176 |
+
|
177 |
+
Please provide a clear and concise answer to the question based on the information in the document:
|
178 |
+
'''.rstrip()
|
179 |
+
"""
|
180 |
+
|
181 |
+
if input_type == "file-input":
|
182 |
+
base_code += """
|
183 |
+
data = process_and_chunk_files(files=[files])
|
184 |
+
"""
|
185 |
+
|
186 |
+
if input_type == "prompt-input":
|
187 |
+
pipeline = f"""
|
188 |
+
TASK_SYSTEM_PROMPT = '''
|
189 |
+
|
190 |
+
{system_prompt}
|
191 |
+
'''
|
192 |
+
|
193 |
+
with Pipeline(name="rag") as pipeline:
|
194 |
+
|
195 |
+
task_generator = LoadDataFromDicts(data=[{{"task": TASK_SYSTEM_PROMPT}}])
|
196 |
+
|
197 |
+
sentence_similarity_generation = GenerateTextRetrievalData(
|
198 |
+
llm={_get_llm_class()}.from_dict(
|
199 |
+
{_get_llm().dump()}
|
200 |
+
),
|
201 |
+
seed=random.randint(0, 2**32 - 1),
|
202 |
+
query_type="common",
|
203 |
+
difficulty="high school",
|
204 |
+
clarity="clear",
|
205 |
+
num_generations={num_rows},
|
206 |
+
output_mappings={{"positive_document": "anchor"}},
|
207 |
+
)
|
208 |
+
|
209 |
+
keep_columns_prompt = KeepColumns(
|
210 |
+
columns=["anchor"],
|
211 |
+
)
|
212 |
+
"""
|
213 |
+
else:
|
214 |
+
pipeline = """
|
215 |
+
with Pipeline(name="rag") as pipeline:
|
216 |
+
"""
|
217 |
+
if input_type == "file-input":
|
218 |
+
pipeline += """
|
219 |
+
load_the_dataset = LoadDataFromDicts(
|
220 |
+
data = data,
|
221 |
+
)
|
222 |
+
"""
|
223 |
+
else:
|
224 |
+
pipeline += f"""
|
225 |
+
load_the_dataset = LoadDataFromHub(
|
226 |
+
repo_id="{repo_id}",
|
227 |
+
config="{subset}",
|
228 |
+
split="{split}",
|
229 |
+
num_examples={num_rows},
|
230 |
+
batch_size=2,
|
231 |
+
output_mappings={{'{document_column}': 'anchor'}}
|
232 |
+
)
|
233 |
+
"""
|
234 |
+
|
235 |
+
pipeline += f"""
|
236 |
+
generate_retrieval_pairs = GenerateSentencePair(
|
237 |
+
triplet={str(retrieval)},
|
238 |
+
hard_negative=True,
|
239 |
+
action="query",
|
240 |
+
llm={_get_llm_class()}.from_dict(
|
241 |
+
{_get_llm().dump()}
|
242 |
+
),
|
243 |
+
output_mappings={{"positive": "positive_retrieval"{', "negative": "negative_retrieval"' if retrieval else ""}}},
|
244 |
+
input_batch_size=10,
|
245 |
+
)
|
246 |
+
"""
|
247 |
+
|
248 |
+
if reranking:
|
249 |
+
pipeline += f"""
|
250 |
+
generate_reranking_pairs = GenerateSentencePair(
|
251 |
+
triplet=True,
|
252 |
+
hard_negative=True,
|
253 |
+
action="semantically-similar",
|
254 |
+
llm={_get_llm_class()}.from_dict(
|
255 |
+
{_get_llm().dump()}
|
256 |
+
),
|
257 |
+
input_batch_size=10,
|
258 |
+
output_mappings={{"positive": "positive_reranking", "negative": "negative_reranking"}},
|
259 |
+
)
|
260 |
+
|
261 |
+
combine_outputs = CombineOutputs()
|
262 |
+
"""
|
263 |
+
|
264 |
+
pipeline += f"""
|
265 |
+
generate_response = TextGeneration(
|
266 |
+
llm={_get_llm_class()}.from_dict(
|
267 |
+
{_get_llm().dump()}
|
268 |
+
),
|
269 |
+
system_prompt=SYSTEM_PROMPT_RAG,
|
270 |
+
template=RAG_TEMPLATE,
|
271 |
+
columns=["filename", "question"],
|
272 |
+
use_system_prompt=True,
|
273 |
+
input_mappings={{"filename": "anchor", "question": "positive_retrieval"}},
|
274 |
+
output_mappings={{"generation": "response"}},
|
275 |
+
)
|
276 |
+
|
277 |
+
keep_columns = KeepColumns(
|
278 |
+
columns=["anchor", "positive_retrieval", "response"{', "negative_retrieval"' if retrieval else ""}{', "positive_reranking", "negative_reranking"' if reranking else ""}],
|
279 |
+
)
|
280 |
+
"""
|
281 |
+
|
282 |
+
pipeline_steps = (
|
283 |
+
"[generate_retrieval_pairs, generate_reranking_pairs] >> combine_outputs >> generate_response >> keep_columns"
|
284 |
+
if reranking
|
285 |
+
else "generate_retrieval_pairs >> generate_response >> keep_columns"
|
286 |
+
)
|
287 |
+
|
288 |
+
pipeline += """
|
289 |
+
task_generator >> sentence_similarity_generation >> keep_columns_prompt >> {pipeline_steps}
|
290 |
+
""".format(pipeline_steps=pipeline_steps) if input_type == "prompt-input" else """
|
291 |
+
load_the_dataset >> {pipeline_steps}
|
292 |
+
""".format(pipeline_steps=pipeline_steps)
|
293 |
+
|
294 |
+
pipeline += """
|
295 |
+
if __name__ == "__main__":
|
296 |
+
distiset = pipeline.run(use_cache=False)
|
297 |
+
print(distiset)
|
298 |
+
if distiset:
|
299 |
+
print(distiset["default"]["train"][0])
|
300 |
+
"""
|
301 |
+
|
302 |
+
return base_code + pipeline
|
src/synthetic_dataset_generator/pipelines/textcat.py
CHANGED
@@ -126,7 +126,6 @@ def generate_pipeline_code(
|
|
126 |
labels: List[str] = None,
|
127 |
num_labels: int = 1,
|
128 |
num_rows: int = 10,
|
129 |
-
temperature: float = 0.9,
|
130 |
) -> str:
|
131 |
labels = get_preprocess_labels(labels)
|
132 |
base_code = f"""
|
@@ -142,10 +141,12 @@ SYSTEM_PROMPT = "{system_prompt}"
|
|
142 |
|
143 |
with Pipeline(name="textcat") as pipeline:
|
144 |
|
145 |
-
task_generator = LoadDataFromDicts(data=[{{"task":
|
146 |
|
147 |
textcat_generation = GenerateTextClassificationData(
|
148 |
-
llm={_get_llm_class()}.from_dict(
|
|
|
|
|
149 |
seed=random.randint(0, 2**32 - 1),
|
150 |
difficulty={None if difficulty == "mixed" else repr(difficulty)},
|
151 |
clarity={None if clarity == "mixed" else repr(clarity)},
|
@@ -178,10 +179,12 @@ with Pipeline(name="textcat") as pipeline:
|
|
178 |
)
|
179 |
|
180 |
textcat_labeller = TextClassification(
|
181 |
-
llm={_get_llm_class()}.from_dict(
|
|
|
|
|
182 |
n={num_labels},
|
183 |
available_labels={labels},
|
184 |
-
context=
|
185 |
default_label="unknown"
|
186 |
)
|
187 |
|
|
|
126 |
labels: List[str] = None,
|
127 |
num_labels: int = 1,
|
128 |
num_rows: int = 10,
|
|
|
129 |
) -> str:
|
130 |
labels = get_preprocess_labels(labels)
|
131 |
base_code = f"""
|
|
|
141 |
|
142 |
with Pipeline(name="textcat") as pipeline:
|
143 |
|
144 |
+
task_generator = LoadDataFromDicts(data=[{{"task": SYSTEM_PROMPT}}])
|
145 |
|
146 |
textcat_generation = GenerateTextClassificationData(
|
147 |
+
llm={_get_llm_class()}.from_dict(
|
148 |
+
{_get_llm().dump()}
|
149 |
+
),
|
150 |
seed=random.randint(0, 2**32 - 1),
|
151 |
difficulty={None if difficulty == "mixed" else repr(difficulty)},
|
152 |
clarity={None if clarity == "mixed" else repr(clarity)},
|
|
|
179 |
)
|
180 |
|
181 |
textcat_labeller = TextClassification(
|
182 |
+
llm={_get_llm_class()}.from_dict(
|
183 |
+
{_get_llm().dump()}
|
184 |
+
),
|
185 |
n={num_labels},
|
186 |
available_labels={labels},
|
187 |
+
context=SYSTEM_PROMPT,
|
188 |
default_label="unknown"
|
189 |
)
|
190 |
|