{"id":20064459,"url":"https://github.com/xlang-ai/unifiedskg","last_synced_at":"2025-04-04T22:07:39.099Z","repository":{"id":37339926,"uuid":"438187736","full_name":"xlang-ai/UnifiedSKG","owner":"xlang-ai","description":"[EMNLP 2022] Unifying and multi-tasking structured knowledge grounding with language models","archived":false,"fork":false,"pushed_at":"2023-08-22T07:18:00.000Z","size":22071,"stargazers_count":556,"open_issues_count":4,"forks_count":59,"subscribers_count":12,"default_branch":"main","last_synced_at":"2025-03-28T21:07:25.856Z","etag":null,"topics":["data-to-text","fact-verification","huggingface-datasets","huggingface-transformers","multi-task-learning","natural-language-processing","nlp","prompt-learning","pytorch","question-answering","semantic-parsing","structured-knowledge-grounding","text-generation"],"latest_commit_sha":null,"homepage":"https://arxiv.org/abs/2201.05966","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xlang-ai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-12-14T09:14:05.000Z","updated_at":"2025-03-25T15:03:14.000Z","dependencies_parsed_at":"2023-12-13T05:05:12.177Z","dependency_job_id":null,"html_url":"https://github.com/xlang-ai/UnifiedSKG","commit_stats":null,"previous_names":["hkunlp/unifiedskg"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xlang-ai%2FUnifiedSKG","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xlang-ai%2FUnifiedSKG/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xlang-ai%2FUnifiedSKG/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xlang-ai%2FUnifiedSKG/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xlang-ai","download_url":"https://codeload.github.com/xlang-ai/UnifiedSKG/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247256112,"owners_count":20909240,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["data-to-text","fact-verification","huggingface-datasets","huggingface-transformers","multi-task-learning","natural-language-processing","nlp","prompt-learning","pytorch","question-answering","semantic-parsing","structured-knowledge-grounding","text-generation"],"created_at":"2024-11-13T13:46:21.508Z","updated_at":"2025-04-04T22:07:39.078Z","avatar_url":"https://github.com/xlang-ai.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# UnifiedSKG:books:: Unifying and Multi-Tasking Structured Knowledge Grounding with Text-to-Text Language Models\n\n\u003cp align=\"left\"\u003e\n    \u003ca href=\"https://img.shields.io/badge/PRs-Welcome-red\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/PRs-Welcome-red\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://img.shields.io/github/last-commit/HKUNLP/UnifiedSKG?color=green\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/last-commit/HKUNLP/UnifiedSKG?color=green\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://colab.research.google.com/drive/1f9yTXC3GpSyRJOjzsKceG_bhk-Cw71Ga#scrollTo=r_3-DN0SvC97\"\u003e\n        \u003cimg alt=\"Open In Colab\" src=\"https://colab.research.google.com/assets/colab-badge.svg\"\u003e\n    \u003c/a\u003e\n    \u003cbr/\u003e\n\u003c/p\u003e\n\nCode for EMNLP 2022 (oral) paper [UnifiedSKG: Unifying and Multi-Tasking Structured Knowledge Grounding with Text-to-Text Language Models](https://arxiv.org/abs/2201.05966). Please refer to our [project page](https://unifiedskg.com/) for up-to-date related resources (e.g., papers, code, tools, tutorials) for Structured Knowledge Grounding. Load our checkpoints from [HuggingFace Model Hub](https://huggingface.co/hkunlp).\n\n\u003cimg src=\"pics/unifiedskg.png\" align=\"middle\" width=\"100%\"\u003e\n\n**S**tructured **k**nowledge **g**rounding (**SKG**) leverages structured knowledge to complete user requests, such as semantic parsing over databases and question answering over knowledge bases. Since the inputs and outputs of SKG tasks are heterogeneous, they were historically studied in separate by different communities,  which limits systematic and compatible research on SKG. In this paper, we overcome this limitation by proposing the **UnifiedSKG framework**, which unifies **21 SKG tasks** into the text-to-text format, aiming to promote systematic SKG research, instead of being exclusive to a single task, domain, or dataset. We show that large language models like T5, with simple modification when necessary, achieve **state-of-the-art performance on nearly all 21 tasks**. UnifiedSKG facilitates **multi-task learning**. We show that multi-task prefix-tuning benefits most tasks, largely improving the overall performance. UnifiedSKG is a challenging testbed for **zero-shot and few-shot learning**, which T0, GPT-3, and Codex struggle in. UnifiedSKG also enables a series of controlled experiments on **structured knowledge encoding** variants across SKG tasks. We find that T5’s sensitivity to structured knowledge encoding variations varies across tasks. \n\n**UnifiedSKG** is easily extensible. Your **pull requests** to add datasets, settings, metrics, models, and new features to UnifiedSKG are highly welcome! \n\n## Updates\n- **2022-03-12**: Check out the seq2seq data we processed for you [here](https://drive.google.com/drive/folders/1GXigUv3MU-Sh4XiY6Wz3xVeNT_s0SuON) by UnifiedSKG if you want to make your own attempts instead of using the huggingface loaders in our framework. \n- **2022-01-12**: We released our [code](https://github.com/HKUNLP/UnifiedSKG), [colab demo](https://colab.research.google.com/drive/1f9yTXC3GpSyRJOjzsKceG_bhk-Cw71Ga#scrollTo=r_3-DN0SvC97), [weights](https://huggingface.co/hkunlp) and [project page](https://unifiedskg.com). Check it out!\n\n## Content\n\n- [UnifiedSKG: Unifying and Multi-Tasking **S**tructured **K**nowledge **G**rounding with Text-to-Text Language Models](#unifiedskgbooks-unifying-and-multi-tasking-structured-knowledge-grounding-with-text-to-text-language-models)\n  * [Cloning this Repo](#cloning-this-repo)\n  * [Dependencies](#dependencies)\n  * [Usage](#usage)\n    + [Environment setup](#environment-setup)\n    + [Wandb setup](#wandb-setup)\n    + [Training](#training)\n    + [Load weights](#load-weights)\n  * Introduction of each directory\n    + [configure](https://github.com/HKUNLP/UnifiedSKG/tree/master/configure)\n    + [metrics](https://github.com/HKUNLP/UnifiedSKG/tree/master/metrics)\n    + [models](https://github.com/HKUNLP/UnifiedSKG/tree/master/models)\n    + [seq2seq_construction](https://github.com/HKUNLP/UnifiedSKG/tree/master/seq2seq_construction)\n    + [third_party](https://github.com/HKUNLP/UnifiedSKG/tree/master/third_party)\n    + [utils](https://github.com/HKUNLP/UnifiedSKG/tree/master/utils)\n  * [Code structure overview of UnifiedSKG](#code-structure-overview-of-unifiedskg)\n  * [Add a new task into UnifiedSKG](#add-a-new-task-into-unifiedskg)\n  * [Misc](#misc)\n  * [Contributors](#contributors)\n\n\n\n\n## Cloning this repo\n\nIn order to include third-party dependencies in this repository, make sure to clone recursively, e.g.:\n\n```\ngit clone --recurse-submodules git@github.com:HKUNLP/UnifiedSKG.git\n```\n\n## Dependencies\n\nTo establish the environment run this code in the shell (the third line is for CUDA11.1):\n\n``````\nconda env create -f py3.7pytorch1.8.yaml\nconda activate py3.7pytorch1.8new\npip install datasets==1.14.0\n# The following line to be replaced depending on your cuda version.\npip install torch==1.8.0+cu111 torchvision==0.9.0+cu111 torchaudio==0.8.0 -f https://download.pytorch.org/whl/torch_stable.html\n``````\n\nThat will create the environment `py3.7pytorch1.8new` we used. \n\n\u003c!--\n### Sub-Modules\n\nSome third party libraries stored in sub-modules need installation\n\n#### ~~TaPEx~~（we adopted its table processor into our code to do some changes）\n\n~~For TaPEx, you can run~~\n\n```\ncd third_party/table_pretraining/\npip install --editable ./\ncd ../..\n```\n\n\n#### TaBERT\n\nRun the following with the conda env activated and *after* installing the main dependencies for UniPSP:\n``````\npip install --editable=git+https://github.com/huggingface/transformers.git@372a5c1ceec49b52c503707e9657bfaae7c236a0#egg=pytorch_pretrained_bert fairseq==0.8.0 torch-scatter==1.3.2 ujson msgpack redis zmq h5py\n``````\n\nThen, navigate to the TaBERT directory and install it:\n\n``````\ncd third_party/tabert/\npip install --editable ./\ncd ../..\n``````\n\nAnd if you add more modification to the env or more commands during you adding for unification, \nplease note in the block below of this README:\n\n``````\n*add*me*\n``````\nwe will compress them to create a docker environment in the end. \n\n--\u003e\n\n## Usage\n\n### Environment setup\nActivate the environment by running\n``````shell\nconda activate py3.7pytorch1.8new\n``````\n\n### WandB setup\n\nSetup [WandB](https://wandb.ai/) for logging (registration needed):\n``````shell\nexport WANDB_API_KEY=YOUR_WANDB_API_KEY\nexport WANDB_PROJECT=YOUR_PROJECT_NAME\nexport WANDB_ENTITY=YOUR_TEAM_NAME\n``````\n\n### Training\n\nT5-base finetuning on WikiTQ (4 GPUs, 128 effective batch size)\n``````shell\npython -m torch.distributed.launch --nproc_per_node 4 --master_port 1234 train.py --seed 2 --cfg Salesforce/T5_base_finetune_wikitq.cfg --run_name T5_base_finetune_wikitq --logging_strategy steps --logging_first_step true --logging_steps 4 --evaluation_strategy steps --eval_steps 500 --metric_for_best_model avr --greater_is_better true --save_strategy steps --save_steps 500 --save_total_limit 1 --load_best_model_at_end --gradient_accumulation_steps 8 --num_train_epochs 400 --adafactor true --learning_rate 5e-5 --do_train --do_eval --do_predict --predict_with_generate --output_dir output/T5_base_finetune_wikitq --overwrite_output_dir --per_device_train_batch_size 4 --per_device_eval_batch_size 16 --generation_num_beams 4 --generation_max_length 128 --input_max_length 1024 --ddp_find_unused_parameters true\n``````\nIf you want to resume training, remove the ``--overwrite_output_dir`` flag from the above command:\n``````shell\npython -m torch.distributed.launch --nproc_per_node 4 --master_port 1234 train.py --seed 2 --cfg Salesforce/T5_base_finetune_wikitq.cfg --run_name T5_base_finetune_wikitq --logging_strategy steps --logging_first_step true --logging_steps 4 --evaluation_strategy steps --eval_steps 500 --metric_for_best_model avr --greater_is_better true --save_strategy steps --save_steps 500 --save_total_limit 1 --load_best_model_at_end --gradient_accumulation_steps 8 --num_train_epochs 400 --adafactor true --learning_rate 5e-5 --do_train --do_eval --do_predict --predict_with_generate --output_dir output/T5_base_finetune_wikitq --per_device_train_batch_size 4 --per_device_eval_batch_size 16 --generation_num_beams 4 --generation_max_length 128 --input_max_length 1024 --ddp_find_unused_parameters true\n``````\n\nT5-base prefix-tuning on WikiTQ (4 GPUs, 128 effective batch size)\n``````shell\npython -m torch.distributed.launch --nproc_per_node 4 --master_port 1234 train.py --seed 2 --cfg Salesforce/T5_base_prefix_wikitq.cfg --run_name T5_base_prefix_wikitq --logging_strategy steps --logging_first_step true --logging_steps 4 --evaluation_strategy steps --eval_steps 500 --metric_for_best_model avr --greater_is_better true --save_strategy steps --save_steps 500 --save_total_limit 1 --load_best_model_at_end --gradient_accumulation_steps 8 --num_train_epochs 400 --adafactor true --learning_rate 5e-5 --do_train --do_eval --do_predict --predict_with_generate --output_dir output/T5_base_prefix_wikitq --overwrite_output_dir --per_device_train_batch_size 4 --per_device_eval_batch_size 16 --generation_num_beams 4 --generation_max_length 128 --input_max_length 1024 --ddp_find_unused_parameters true\n``````\n\nT5-3b finetuning on WikiTQ (8 GPUs, 128 effective batch size)\n``````shell\ndeepspeed train.py --deepspeed deepspeed/ds_config_zero2.json --seed 2 --cfg Salesforce/T5_3b_finetune_wikitq.cfg --run_name T5_3b_finetune_wikitq --logging_strategy steps --logging_first_step true --logging_steps 4 --evaluation_strategy steps --eval_steps 500 --metric_for_best_model avr --greater_is_better true --save_strategy steps --save_steps 500 --save_total_limit 1 --load_best_model_at_end --gradient_accumulation_steps 16 --num_train_epochs 50 --adafactor false --learning_rate 5e-5 --do_train --do_eval --do_predict --predict_with_generate --output_dir output/T5_3b_finetune_wikitq --overwrite_output_dir --per_device_train_batch_size 1 --per_device_eval_batch_size 1 --generation_num_beams 4 --generation_max_length 128 --input_max_length 1024 --ddp_find_unused_parameters true\n``````\n\n### Load weights\nSee \u003ca href=\"https://colab.research.google.com/drive/1f9yTXC3GpSyRJOjzsKceG_bhk-Cw71Ga#scrollTo=r_3-DN0SvC97\"\u003e\n        \u003cimg alt=\"Open In Colab\" src=\"https://colab.research.google.com/assets/colab-badge.svg\"\u003e\n    \u003c/a\u003e\n \n\u003c!--\n## Introduction of each file\n\n### [configure](https://github.com/HKUNLP/UnifiedSKG/tree/master/configure)\n\nCode for configuration of different tasks/settings, more details see README in [./configure](https://github.com/HKUNLP/UnifiedSKG/tree/master/configure)\n\n### [metrics](https://github.com/HKUNLP/UnifiedSKG/tree/master/metrics)\nCode for evaluating the prediction of our model, more details see README in [./metrics](https://github.com/HKUNLP/UnifiedSKG/tree/master/metrics)\n\n### [models](https://github.com/HKUNLP/UnifiedSKG/tree/master/models)\nCode for models(for now, we have seq2seq models(T5 and BART) and prompt-tuning models(prefix-tuning)\n\n### [seq2seq_construction](https://github.com/HKUNLP/UnifiedSKG/tree/master/seq2seq_construction)\nCode for evaluating the prediction of our model, more details see README in [./seq2seq_construction](https://github.com/HKUNLP/UnifiedSKG/tree/master/seq2seq_construction)\n\n### [third_party](https://github.com/HKUNLP/UnifiedSKG/tree/master/third_party)\nPackages from the third party for us to tmp store, and we will redirect them by git recursive deployment in the end. \n\n### [utils](https://github.com/HKUNLP/UnifiedSKG/tree/master/utils)\nCode for some useful(or not) stuff, it contains:\n- **configure.py**: The \"args\" data-structure for **parsing and store the config files** in ./configure. (and we are trying to change it \ninto a more main-stream structure which also support read from the file and create nested config object.)\n- **dataset.py**: Wrap the seq2seq dataset to tokenize the \"seq_in\" and \"seq_out\", since the trainer only support tokenized tensors of \"seq_input\" and \"seq_output\" as input\n- **tool.py**: The tool to **get datasets, models and evaluators in a unified way**. \n- **trainer.py**: The **modified trainer version** of huggingface trainer class **for supporting meta-tuning**(we want get our training sampler under our control), \n**easier evaluation**(the metrics of huggingface's input format(numbers) is contradicted with ones of all official evaluations) and **further changes in this project**(for example, we want to feed more para in a model.forward function).\n- **training_arguments.py**: The **customized wrapped training_arguments**.\n\n### train.py\n- together with the config file, act as the start and main-control of the experiment.\n\n### Procedure\nThe working procedure of our work follows:\nraw data(s) -\u003e + seq2seq data(s) (\"seq_in\" and \"seq_out\") -\u003e tokenized -\u003e seq2seq_trainer -\u003e predictions -\u003e eval(s)\n--\u003e\n\n## Code structure overview of UnifiedSKG\n    .\n    ├── configure                              # Config files for experiments, tasks, and settings\n    │   ├── META_TUNING                        # Config files for tasks and settings\n    │   └── Salesforce                         # Config files for experiments (see Misc)\n    │\n    ├── metrics                                # Code for evaluation\n    │   └── ...                                # Please check the README of the ./seq2seq_construction.\n    ├── models                                 # Code for models\n    │   ├── adapter                            # Code for T5 and BART with adapters (based on HuggingFace Transformers)\n    │   ├── prompt                             # Code for T5 and BART with prefix-tuning (based on HuggingFace Transformers)\n    │   └── unified\n    │           ├── base.py                    # Code for the base model that enables an arbitrary model to be pushed to HuggingFace Model Hub (namely, PushToHubFriendlyModel)\n    │           ├── finetune.py                # Code for finetuning\n    │           ├── adaptertuning.py           # Code for adapter-tuning\n    │           ├── prefixtuning.py            # Code for prefix-tuning\n    │           └── combined_prefixtuning.py   # Code for combined prefix-tuning (not used in our paper, see Misc)\n    │\n    ├── seq2seq_construction                   # Code for converting raw data into sequences\n    │    └──  ...                              # Please check the README in this directory.\n    │\n    ├── tasks                                  # Code for loading raw data\n    │    └──  ...                              # Please check the README in this directory.\n    │\n    ├── third_party                            # Packages from third parties\n    │    └──  ...                              # Please check the README in this directory.\n    │\n    ├── utils                                  # Code for some (probably) useful stuff\n    │       ├── processor                      # Adopted from Tapex: the processor that handles table truncation and linearization\n            │        └──  ...            \n    │       ├── configure.py                   # Code for parsing config files in ./configure\n    │       ├── dataset.py                     # Code for converting input and output sequences into Datasets for training\n    │       ├── tool.py                        # Code for loading models, seq2seq constructors, and evaluators\n    │       ├── trainer.py                     # Code for EvaluationFriendlyTrainer. If you want make training-specific modifications, you may want to change something here.\n    │       └── training_arguments.py          # Code for seq2seq training arguments\n    │\n    ├── .gitignore                 \n    ├── .gitmodules                    \n    ├── py3.7pytorch1.8.yaml                   # Anaconda environment config file\n    ├── README.md                              # The README file you are looking at :)\n    └── train.py                               # Entry code, which controls train, eval, test, storage, and logging\n\n\n\n## Add a new task into UnifiedSKG\n\n(READMEs in `./tasks`, `./seq2seq_construction`, `./metrics`, `./configure` can also be helpful)\n\n1. Add a \"Loader\" of raw data under `./tasks`. You can search [HuggingFace Datasets](https://github.com/huggingface/datasets) for possibly useful scripts. If not, you can be the contributor of both this project and the HuggingFace community.\n2. Add a \"Sequence Wrapper\" under `./seq2seq_construction` to construct sequence inputs (user request and structured knowledge) and sequene outputs from raw data for the unification.\n3. Add an \"Evaluator\" for your task under `./metrics`. If a third-party repository is used, remember to add it into [.gitmodules](https://git-scm.com/docs/gitmodules). \n4. *(optional)* You can add a new \"Model\" under `./models` for a new model architecture or a new learning algorithm.\n5. Add a config file for your task under `./configure/META_TUNING`.\n6. Add a config file for each of your experiment under `./configure/Salesforce`.\n\n## Misc\n- We name the diretory for experimental config files as Salesforce because we would like to thank Salesforce Research for providing a large number of GPUs. We would also like to thank Amazon Research Awards, ServiceNow Research, and Yale NLP for providing computing resources generously. \n- `./models/unified/combined_prefixtuning.py` is not used in our paper. This file contains code for the *interaction* between multiple prefixes in a single training loop. We tried some variants of such interaction but did not find any of them to outperform the (extremely simple) transfer learning-based approach used in our paper. However, we open-source our failed attempts and call for potential future exploration. \n\n\u003cimg src=\"pics/logos.png\" align=\"middle\" width=\"98%\"\u003e\n\n**That's all for it :D**\n\n## Citation\nIf you find our work helpful, please cite as\n```\n@article{UnifiedSKG,\n      title={UnifiedSKG: Unifying and Multi-Tasking Structured Knowledge Grounding with Text-to-Text Language Models}, \n      author={Tianbao Xie and Chen Henry Wu and Peng Shi and Ruiqi Zhong and Torsten Scholak and Michihiro Yasunaga and Chien-Sheng Wu and Ming Zhong and Pengcheng Yin and Sida I. Wang and Victor Zhong and Bailin Wang and Chengzu Li and Connor Boyle and Ansong Ni and Ziyu Yao and Dragomir Radev and Caiming Xiong and Lingpeng Kong and Rui Zhang and Noah A. Smith and Luke Zettlemoyer and Tao Yu},\n      journal={EMNLP},\n      year={2022},\n}\n```\n\n## Contributors\n\u003ca href=\"https://github.com/Timothyxxx\"\u003e  \u003cimg src=\"https://avatars.githubusercontent.com/u/47296835?v=4\"  width=\"50\" /\u003e\u003c/a\u003e \n\u003ca href=\"https://github.com/ChenWu98\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/28187501?v=4\"  width=\"50\" /\u003e\u003c/a\u003e \n\u003ca href=\"https://github.com/Impavidity\"\u003e  \u003cimg src=\"https://avatars.githubusercontent.com/u/9245607?v=4\"  width=\"50\" /\u003e\u003c/a\u003e \n\u003ca href=\"https://github.com/michiyasunaga\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/25519127?v=4\"  width=\"50\" /\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/cascadianblue\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/6520892?v=4\"  width=\"50\" /\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/chengzu-li\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/69832207?v=4\"  width=\"50\" /\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/jasonwu0731\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/14951842?v=4\"  width=\"50\" /\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/HKUNLP/UnifiedSKG/pulls\"\u003e\u003cimg src=\"https://blog.simtics.com/wp-content/uploads/2016/03/you.jpg\"  width=\"50\" /\u003e\u003c/a\u003e\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxlang-ai%2Funifiedskg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxlang-ai%2Funifiedskg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxlang-ai%2Funifiedskg/lists"}