Query & move data
Generate Synthetic Data with LLMs
Create high-quality synthetic data using LLMs, overcoming privacy concerns and data sparsity for enhanced model training and application development.
Without it
Piece it together by hand, every time.
With it
Leverage LLMs to generate diverse, structured, and privacy-compliant synthetic data for various applications, including model training, demo building, and scenario testing.
What you get
- Generate CSV data with structured prompts.
- Create Python programs for scalable synthetic data generation.
- Produce multi-table CSVs with relational data.
- Generate textual data for fine-tuning models or product descriptions.
Use this prompt chain
Synthetic Data generation (Part 1)
Synthetic data generation using large language models (LLMs) offers a powerful solution to a commonly faced problem: the availability of high-quality, diverse, and privacy-compliant data. This could be used in a number of scenarios such as training a data science machine learning model (SVMs, decision trees, KNN's), finetuning a different GPT model on the data, as a solution to the coldstart problem, helping build compelling demos/apps with realistic data, scenario testing etc.
There are a number of key drivers which may see you wanting to leverage synthetic data.
- Human data may have privacy restrictions and/or identifiable data within it which we do not want to be used.
- Synthetic data can be much more structured and therefore easier to manipulate than real data.
- In domains where data is sparse or data of certain categories is sparse we may want to augment the data.
- When dealing with imbalanced datasets or datasets which lack diversity, we may want to create data to improve the richness of our datasets.
Unlike traditional data augmentation or manual data creation methods, using LLMs allows for the generation of rich, nuanced, and contextually relevant datasets that can significantly enhance it's usefulness to enterprises and developers.
We split this tutorial into 2 parts. In this cookbook, we will have the following agenda:
- CSV with a structured prompt
- CSV with a Python program
- Multitable CSV with a python program
- Simply creating textual data
- Dealing with imbalanced or non-diverse textual data
while in part 2, we will look at prompting strategies for getting better textual data.
The last two in particular are useful for creating synthetic data to finetune another GPT model. For example using higher quality data produced by gpt-4o to finetune the cheaper and quicker gpt-3.5-turbo for improved performance while reducing costs.
Getting setup
1. CSV with a structure prompt
Here we create data in the simplest way. You can quickly generate data by addressing 3 key points: telling it the format of the data (CSV), the schema, and useful information regarding how columns relate (the LLM will be able to deduce this from the column names but a helping hand will improve performance).
2. CSV with a Python program
The issue with generating data directly is we are limited in the amount of data we can generate because of the context. Instead what we can do is ask the LLM to generate a python program to generate the synthetic data. This allows us to scale to much more data while also providing us a view into how the data was generated by inspecting the python program.
This would then let us edit the python program as we desire while giving us a good basis to start from.
We need to make sure to parse the output of this appropriately as often there may be surrounding text to the python code. We can also explicitly ask it to state all assumptions it made about the data it's generating, however in this circumstance it told us that automatically.
3. Multitable CSV with a python program
For more complex relationships however we need to make sure to specify a few more characteristics.
To create multiple different datasets which relate to each other (for example housing, location, house type), as before we would need to specify the format, schema and useful information. However, the useful information required to get good performance is higher now. It's case-specific but a good amount of things to describe would be how the datasets relate to each other, addressing the size of the datasets in relation to one another, making sure foreign and primary keys are made appropriately and ideally using previously generated datasets to populate new ones so the actual data values match where necessary.
4. Simply creating textual data
Here we take a first look at creating textual data. This can be used to finetune another GPT model for example. In this case we imagine ourselves a retailer trying to streamline the process of creating descriptions for items they are selling. We again need to specify the format of the data, in particular in this case we want one which is easy to parse as an output.
The example we consider below is one in which we want to create input output training pairs for GPT model to finetune on. We will have the products' name and the category it belongs to as input and the output will be a description.
Specifying the structure of the output explicitly and giving commands to not deviate from this help enforce the output structure. You can run this in a loop and append the data to generate more synthetic data. Again, as before we will need to parse the data well so that our code further downstream does not break.
Note: the above output is truncated. And now we can parse it as below to get a list of products, categories and their descriptions. For example, let's take a look at the products it's generated.
5. Dealing with imbalanced or non-diverse textual data
Some of the most important aspects of generating high-quality synthetic data are accuracy (does the data make sense), consistency (are two separate data points for the same input roughly the same) and diversity (making sure our data distribution matches as much of the distribution that exists in production).
To increase the diversity of our data, we start first by clustering the data. This will provide us information about which clusters are underrepresented (imbalanced dataset) or which data is not addressed at all (widening the data distribution). Then, we will either suggest new clusters (using self-reflection type call from GPT) or ask the next iteration of our synthetic generation calls to explicitly target the underrepresented clusters.
We can then recursively run this generation and analysis of cluster loop to automate generating diverse synthetic data.
For demonstrative purposes, we explicitly prompt the LLM to generate information about 4 different topical areas: vehicle, clothing, toiletries, food. We will then cluster the data and see if it managed to find these 4 topic areas.
Note: The above output is truncated. In the example above, we would explicitly include the topic area as part of the response per example as it helps condition the proceeding output and tends to give better performance. We can also give it an actual example of what the output should look like so it gets the right idea of style of output but also to help enforce structure.
We will now cluster the data to analyze it. We will use K-means clustering to segregate the data. An important parameter of K-means to set is K, the number of clusters.
We know that there should be 4 cluster (4 topics) since we specified this in prompt: vehicle, electronics, clothing, food. However in general for our data, we do not know the number of clusters that exist. Therefore we will use the elbow method to find the optimal number of clusters.
In the elbow method, we iterate through a range of different K's, each time storing the inertia. The inertia measures the sum of the squared distances between each point in a cluster and the centroid of that cluster thus telling us how well-separated and dense each cluster is. If we plot K against the inertia, we are able to see how the inertia drops and where the drop in inertia is least rapid (often making an elbow shape) we can set our optimal number of clusters. You can read into more depth about the elbow method here.
First let's store our data into a pandas dataframe for ease of analysis
Next let us embed our data as the embeddings is what we will cluster since they should be close to each other in vector space if they are similar.
Now we perform the elbow method.
This will output a chart for us in which we have to visually tell where the optimal cluster point is. We can see below that we see a gradual decrease of inertia rather than a sharp elbow but the point of steepest decrease appears to occur around 3, 4 or 5 clusters which lines up with our expectations given our prompt.

For demonstration purposes we will pick 5 as the optimal cluster number to show it doesn't matter exactly where we pick it as long as we are approximately right. There are numerous correct ways to categorize data. We also store which cluster each data point belongs to.
We will analyze the cluster data now. There are two separate things we will look to address. 1. imbalanced data, 2. Expanding the data distribution.
First for imbalanced data we count the number of examples in each cluster. Then we select a few examples from each cluster at random and ask the LLM what topics these map to.
We can see the topics found here:
Eco-friendly Transportation, Luxury and Leisure Items, Personal Care Products, Electronic Toothbrushes and Clothing and Apparel
match well enough but not exactly to our initial prompt of:
vehicle, clothing, toiletries, food.
As we chose 5 clusters, it split up toiletries into Skincare and Personal Care which doesn't affect us too much further downstream.
We now have the clusters and their counts so we could prompt the LLM to generate more examples within the topics we want. However for this example we won't take that further as they are well-split and you would just follow the procedure above for prompting the model to generate data while passing in the underrepresented topics.
Next, we will try and deal with increasing the diversity of our data distribution.
First we start in a similar way by finding a few examples from each cluster at random and ask the LLM what topics these map to. In addition to this in the same LLM call, we will ask it to generate more topics to increase the diversity of our data. We do this in one call to save time/cost.
We can see here again that we explicitly prompt the output structure it should follow. I also tell it the purpose of generating topics (to promote diversity) so the model has full context.
We then parse the data into a list of cluster-mapping jsons and a list of topics
And finally we can use this information to further prompt a model to keep generating synthetic data. We do this by passing all the topics in the list of jsons to the prompt below.
You can run this in a loop to append to your previous data and in this way you can keep generating more textual synthetic data to train another GPT model while making sure that we cater to imbalanced datasets and generating a diversity of data.
You have now completed part 1 of the synthetic data generation tutorial where we have gone through:
- CSV with a structured prompt
- CSV with a Python program
- Multitable CSV with a python program
- Simply creating textual data
- Dealing with imbalanced or non-diverse textual data
In part 2 you will find find out techniques for better prompting an LLM to enhance textual synthetic data generation.