Implementation:Microsoft LoRA WebNLG Train Dataset
| Knowledge Sources | |
|---|---|
| Domains | NLG, Data_to_Text, Benchmarking, RDF_to_Text |
| Last Updated | 2026-02-10 06:00 GMT |
Overview
Training split of the WebNLG Challenge 2017 dataset, containing the largest collection of RDF triple-to-text examples for training natural language generation models on structured data verbalization.
Description
The WebNLG training set provides 499,715 lines of JSON data containing RDF triples from DBpedia paired with human-written lexicalisations. This is the largest of the three WebNLG splits and serves as the primary training corpus for LoRA-adapted GPT-2 models on the RDF-to-text task. Each entry includes a category label from one of 10 "seen" DBpedia domains (Airport, Astronaut, Building, City, ComicsCharacter, Food, Monument, SportsTeam, University, WrittenWork), modified RDF triples with subject/property/object fields, and multiple reference lexicalisations rated for quality. The training data defines the "seen" category set; categories appearing only in the test set are considered "unseen" and are used to evaluate generalization. Properties in the modified triplesets use camelCase DBpedia naming conventions (e.g., cityServed, leaderName, runwayLength).
Usage
Use this dataset as the training split for fine-tuning GPT-2 with LoRA on RDF-to-text generation. The format_converting_webnlg.py script first converts this JSON into line-delimited context/completion pairs (filtering for "good" quality lexicalisations only), which are then encoded with gpt2_encode.py and fed to gpt2_ft.py for parameter-efficient fine-tuning. The training process updates only low-rank adapter weights while keeping GPT-2 base parameters frozen.
Code Reference
Source Location
- Repository: Microsoft_LoRA
- File: examples/NLG/data/webnlg_challenge_2017/train.json
- Converter: examples/NLG/src/format_converting_webnlg.py
- Training script: examples/NLG/src/gpt2_ft.py
Data Schema
{
"entries": [
{
"1": {
"category": "Airport",
"dbpedialinks": [],
"lexicalisations": [
{
"comment": "good",
"lang": "",
"lex": "The Aarhus is the airport of Aarhus, Denmark.",
"xml_id": "Id1"
},
{
"comment": "good",
"lang": "",
"lex": "Aarhus Airport serves the city of Aarhus, Denmark.",
"xml_id": "Id2"
}
],
"links": [],
"modifiedtripleset": [
{
"subject": "Aarhus_Airport",
"property": "cityServed",
"object": "\"Aarhus, Denmark\""
}
],
"originaltriplesets": {
"originaltripleset": [
[
{
"subject": "Aarhus_Airport",
"property": "cityServed",
"object": "\"Aarhus, Denmark\"@en"
}
]
]
},
"shape": "NA",
"shape_type": "NA",
"size": "1",
"xml_id": "Id1"
}
}
]
}
Format Conversion
The format_converting_webnlg.py script processes entries by extracting modified triplesets, filtering for "good" lexicalisations, and tagging each example with a seen/unseen category indicator:
# From format_converting_webnlg.py:
seen = ['Airport', 'Astronaut', 'Building', 'City', 'ComicsCharacter',
'Food', 'Monument', 'SportsTeam', 'University', 'WrittenWork']
for i, example in enumerate(lines_dict['entries']):
sents = example[str(i+1)]['lexicalisations']
triples = example[str(i+1)]['modifiedtripleset']
cate = example[str(i+1)]['category']
for i, tripleset in enumerate(triples):
subj, rela, obj = tripleset['subject'], tripleset['property'], tripleset['object']
# Joins as: "subj : rela : obj | subj2 : rela2 : obj2"
for sent in sents:
if sent["comment"] == 'good':
# Only include good-quality lexicalisations
x = {"context": temp_triples, "completion": sent['lex'], "cate": cate in seen}
Loading
import json
with open("examples/NLG/data/webnlg_challenge_2017/train.json", "r") as f:
data = json.load(f)
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| file_path | str | Yes | Path to the JSON file (e.g., examples/NLG/data/webnlg_challenge_2017/train.json)
|
Outputs
| Name | Type | Description |
|---|---|---|
| data | Dict | Top-level dictionary with an entries key
|
| entries | List[Dict] | List of numbered entry dictionaries (1-indexed keys as strings) |
| category | str | DBpedia category from the 10 seen training domains |
| modifiedtripleset | List[Dict] | RDF triples with subject, property, object keys (cleaned values)
|
| lexicalisations | List[Dict] | Human-written texts with comment (quality rating), lex (text), lang, and xml_id
|
| originaltriplesets | Dict | Original DBpedia triplesets preserving raw RDF formatting with language tags and type annotations |
Usage Examples
Loading and Inspecting WebNLG Training Data
import json
# Load the training set
with open("examples/NLG/data/webnlg_challenge_2017/train.json", "r") as f:
train_data = json.load(f)
entries = train_data['entries']
print(f"Total entries: {len(entries)}")
# Inspect first example
first_entry = entries[0]["1"]
print(f"Category: {first_entry['category']}")
print(f"Triples: {first_entry['modifiedtripleset']}")
print(f"Lexicalisations ({len(first_entry['lexicalisations'])} references):")
for lex in first_entry['lexicalisations']:
print(f" [{lex['comment']}] {lex['lex']}")
Analyzing Category Distribution
import json
from collections import Counter
with open("examples/NLG/data/webnlg_challenge_2017/train.json", "r") as f:
train_data = json.load(f)
categories = Counter()
for i, entry in enumerate(train_data['entries']):
cat = entry[str(i + 1)]['category']
categories[cat] += 1
print("Training category distribution:")
for cat, count in categories.most_common():
print(f" {cat}: {count}")
Full Training Pipeline
# Step 1: Convert training JSON to line-delimited format
python examples/NLG/src/format_converting_webnlg.py \
examples/NLG/data/webnlg_challenge_2017/train.json \
examples/NLG/data/webnlg_challenge_2017/train.jsonl
# Step 2: Encode for GPT-2
python examples/NLG/src/gpt2_encode.py \
--vocab examples/NLG/vocab \
--input_file examples/NLG/data/webnlg_challenge_2017/train.jsonl \
--output_file examples/NLG/data/webnlg_challenge_2017/train.encoded
# Step 3: Fine-tune GPT-2 with LoRA
python examples/NLG/src/gpt2_ft.py \
--train_data examples/NLG/data/webnlg_challenge_2017/train.encoded \
--valid_data examples/NLG/data/webnlg_challenge_2017/dev.encoded \
--lora_dim 4 \
--lora_alpha 32