Yan Ma1,3,4, Yu Qiao3, Pengfei Liu2,3,4
1Fudan University, 2Shanghai Jiao Tong University,
3Shanghai AI Laboratory, 4Generative AI Research Lab (GAIR)
"If a story is going to fail, it will do so first at the premise level." โ Anatomy of a Premise Line
A story premise succinctly defines a storyโs main idea, foundation, and trajectory. It serves as the initial trigger in automatic story generation.
Existing sources of story premises are limited by a lack of diversity, uneven quality, and high costs that make them difficult to scale. In response, we introduce Modular Story Premise Synthesis (MoPS) which breaks down story premises into modules like background and persona for automated design and generation. MoPS consists of three phases: (1) Precollect a consistent set of candidates for each module to form a nested dictionary. (2) Extract a key path from the nested dictionary as the premise design. (3) Instruct an LLM to integrate the design into a coherent premise sentence.
git clone https://github.com/GAIR-NLP/MoPS
pip install -r requirements.txt
poetry install
We use OpenAI model as the language backend and manage environment variables in .env
via python-dotenv.
Warning
After setting up, please add .env
to .gitignore
to prevent uploading sensitive information.
#!/usr/bin/env bash
OPENAI_API_KEY="your openai api key"
OPENAI_API_BASE="your openai api url"
OPENAI_MODEL="gpt-3.5-turbo-1106"
Module candidates in our paper:
./assets/modules
Mops & 5 baselines premises and corresponding evaluation in our paper:
./assets/premises
Mops & 5 baselines stories extended from premises and the corresponding evaluation in our paper:
./assets/stories
Stories come in two genres: scripts and novels.
Scripts are generated using Dramatron, and novels are generated using RecurrentGPT.
We created a huggingface dataset including three versions of the MoPS dataset:
complete
,moderate
, andcurated
, with each entry containing a premise and the extented stories.
from datasets import load_dataset
dataset=load_dataset("ManTle/mops")
print(dataset)
>>> python mops/induce.py --help
usage: induce.py [-h] [OPTIONS]
โญโ options โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ -h, --help show this help message and exit โ
โ --module-dir PATH (required) โ
โ --step STR (required) โ
โ --max-backgrounds-per-theme INT โ
โ (default: 30) โ
โ --max-personas-per-background INT โ
โ (default: 9) โ
โ --max-events-per-persona INT โ
โ (default: 2) โ
โ --max-endings-per-event INT โ
โ (default: 1) โ
โ --max-twists-per-ending INT โ
โ (default: 1) โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
See examples: ./data/modules/theme.json
where module_dir=./data/modules
python mops/induce.py --module-dir ./data/modules --step background --max-backgrounds-per-theme 1
python mops/induce.py --module-dir ./data/modules --step persona --max-personas-per-background 1
python mops/induce.py --module-dir ./data/modules --step event --max-endings-per-event 1
python mops/induce.py --module-dir ./data/modules --step ending --max-endings-per-event 1
python mops/induce.py --module-dir ./data/modules --step twist --max-twists-per-ending 1
>>> python mops/synthesize.py --help
usage: synthesize.py [-h] [OPTIONS]
โญโ options โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ -h, --help show this help message and exit โ
โ --module-dir PATH (required) โ
โ --premise-dir PATH (required) โ
โ --enable-verify, --no-enable-verify โ
โ (default: False) โ
โ --masks {None}|{[{theme,background,persona,event,ending,twist} [...]]} โ
โ (default: None) โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
For example, you can run the following command after stage 1:
python mops/synthesize.py --module_dir ./data/modules --premise_dir ./data
You can flexibly control the required modules through masks
flag , and the candidates for corresponding modules in the masks will be set as empty strings.
For example, if you want to remove ending
and twist
during synthesis, you can run the following:
python mops/synthesize.py --module_dir ./data/modules --premise_dir ./data --masks ending twist
We use the semantic Breadth and Density metrics proposed in the paper to evaluate diversity, and evaluate quality based on LLM in the three dimensions of Fascination, Completeness, and Originality.
Please refer to files in notebooks for the implementation details of evaluation.
Stage 4 [Optional]: Use your favorite premise-based automatic story generation pipeline to create long stories
We use Dramatron and RecurrentGPT in our paper.
If you are looking for more story generation work, we recommend you refer to Awesome-Story-Generation
@misc{ma2024mops,
title={MoPS: Modular Story Premise Synthesis for Open-Ended Automatic Story Generation},
author={Yan Ma and Yu Qiao and Pengfei Liu},
booktitle={Proceedings of the 62nd Annual Meeting of the Association for Computational Linguistics (Volume 3: System Demonstrations)},
address={Bangkok, Thailand},
publisher={Association for Computational Linguistics},
year={2024},
url={http://arxiv.org/abs/2406.05690}
}