English (unofficial) translations of posts at kexue.fm
Source

Seq2Seq + Prefix Tree: A New Paradigm for Retrieval Tasks (Taking KgCLUE as an Example)

Translated by DeepSeek V4 Pro. Translations can be inaccurate, please refer to the original post for important stuff.

Two years ago, in "The Universal Seq2Seq: Reading Comprehension QA Based on Seq2Seq" and "’Non-Autoregressive’ is Not Bad: Reading Comprehension QA Based on MLM", we experimented with using "Seq2Seq + Prefix Tree" and "MLM + Prefix Tree" for extractive reading comprehension tasks and achieved good results. In last year’s ICLR 2021, Facebook’s paper "Autoregressive Entity Retrieval" also utilized the "Seq2Seq + Prefix Tree" combination to achieve a "win-win" in both effectiveness and efficiency for entity linking and document retrieval.

In fact, the "Seq2Seq + Prefix Tree" combination can theoretically be applied to any retrieval-type task, making it a "new paradigm" for retrieval. This article will revisit the "Seq2Seq + Prefix Tree" approach and use it to implement a baseline for the recently released KgCLUE Knowledge Graph QA benchmark.

Retrieval Tasks

When it comes to retrieval tasks, most are familiar with them. Beyond conventional similar question retrieval, many tasks in NLP can be viewed as retrieval, such as extractive reading comprehension, entity linking, and even Knowledge Graph-based Question Answering (KGQA).

Taking similar question retrieval as an example, the workflow of a conventional retrieval system is:

  1. Train a sentence encoding model, which usually involves a complex negative sample construction process; the quality of negative samples directly affects the final performance.

  2. Encode each sentence into a vector and store it in a vector retrieval library such as Faiss, which typically consumes a significant amount of space.

  3. Encode the query sentence into a vector, then perform retrieval to return the Top-k results and their similarities.

If I told you there is a new retrieval scheme that doesn’t require worrying about negative samples or consuming massive memory for vector libraries, and its final performance and speed are no worse than the old scheme, would you be eager to try it? That is exactly our protagonist: "Seq2Seq + Prefix Tree."

Seq2Seq

First, let’s set aside the tedious details and think about what a retrieval task actually does. For similar question retrieval, we input a question and hope to output the most similar sentence in the database. For entity linking, we input a sentence containing an entity and hope to output the entity name or ID from the knowledge base that correctly interprets that entity.

Ignoring certain constraint rules, we can find that these tasks can essentially be abstracted as:

Input one sentence, output another sentence.

This is precisely what Seq2Seq is best at! So, isn’t using Seq2Seq a natural choice? Of course, some readers might argue: "I need to output a sentence that already exists in the database. What if Seq2Seq ’overflows’ (decodes a sentence not in the database)?" This is where the prefix tree comes in. We can use a prefix tree to constrain the decoding process, ensuring the generated result is in the database. We will discuss this in detail shortly.

Without the worry of "overflow," we find that the Seq2Seq approach possesses many advantages:

  1. Training a Seq2Seq model only requires inputs and targets. This means we only need positive samples, eliminating the trouble of constructing negative samples—or rather, it treats all other sentences as negative samples.

  2. Seq2Seq directly decodes the target sentence, saving the storage and retrieval of sentence vectors and eliminating the need for tools like Faiss.

  3. Seq2Seq includes token-level interaction between the target and input sentences, which theoretically allows for finer comparison than inner-product-based vector retrieval, leading to better retrieval results.

Prefix Decoding

Now let’s detail the process of using a prefix tree to constrain decoding and see how it ensures the output is in the database. Suppose the database contains the following sentences (translated for illustration):

  • When is the bright moon

  • Tomorrow will be better

  • It will rain tomorrow

  • Meeting tomorrow afternoon

  • Holiday tomorrow afternoon

  • See you next year

  • What year is tonight

  • Where to play today

We would use a prefix tree like the following to store these sentences:

Prefix tree schematic: essentially a compressed representation of sequences.

Essentially, it aggregates the same tokens at the same positions from left to right. Every complete path on the tree (starting with [BOS] and ending with [EOS]) represents a sentence in the database. It is called a "prefix tree" because this structure allows us to quickly find which words/sentences start with a certain prefix. For example, in the figure, the first word can only be "Bright" or "Today." If "Bright" is chosen, the next word can only be "moon," and so on.

With a prefix tree, constraining Seq2Seq decoding is not difficult. For example, if the first word can only be [BOS] followed by "Bright" or "Today," then when predicting the first word, we can set the probabilities of all other words to zero. Thus, the model can only choose between these two. If the first word is determined to be "Bright," then when predicting the second word, we similarly zero out probabilities for words other than "moon," ensuring the model follows the tree’s branches until the end. This guarantees the decoded result is an existing sentence in the database.

Compared to conventional vector retrieval, the "Seq2Seq + Prefix Tree" scheme replaces stored retrieval vectors with a prefix tree. Since a prefix tree is essentially a "compressed representation" of the original sentences, it is easy to imagine that the storage space required is much smaller than that of dense retrieval vectors. In Python, a simple way to implement a prefix tree is using nested dictionary structures; specific examples can be found in the KgCLUE code later.

KgCLUE

Practice is the sole criterion for testing truth. Now, let’s implement a KgCLUE baseline using the "Seq2Seq + Prefix Tree" scheme to verify its effectiveness.

Task Introduction

KgCLUE is a Chinese knowledge graph QA evaluation task recently launched by the CLUE organization. The data is standardized and suitable for scientific research testing. Specifically, it uses a knowledge base of approximately 20 million triples, where each triple is in the format (S, P, O) (Subject-Predicate-Object), as shown below:

KgCLUE Knowledge Base Screenshot

It also provides a set of annotated corpora for training. Each sample is in a simple question-and-answer format. Essentially, questions can be abstracted as "What is the P of S?", and the answer is the corresponding triple (S, P, O), as shown below:

KgCLUE Annotated Corpus Screenshot

In principle, as long as (S, P) is determined, the corresponding O can be extracted from the knowledge base. Therefore, our main task is to parse the correct S and P from the question.

General Approach

A simple way to complete this task is in two steps: first, train a labeling model to extract S from the question, then find all triples corresponding to that S in the knowledge base, combine S with each P, and calculate the similarity with the question one by one. Thus, the second step is a similarity model.

However, it is important to note that there may be many homonymous entities in the knowledge base. To distinguish them, the knowledge base includes the concept of "Meaning (M)" to specify the exact referent. In the KgCLUE knowledge base, meanings are added in parentheses after the Subject, such as "Cowherd and Weaver Girl (Chinese folk tale)." When extracting from a question, usually only the part outside the parentheses is extracted. Therefore, in practice, we often treat each piece of knowledge as a quadruple (S, M, P, O) rather than a triple.

Determining which Meaning a Subject belongs to based on a given question is the "Entity Linking" problem, a necessary step in KGQA. However, within the current KgCLUE task, since the corpus is not very large, for a two-step model, we can consider the entity linking step to be integrated into the similarity model rather than performing it separately.

Proposed Solution

If we use "Seq2Seq + Prefix Tree," the model training becomes very simple.

Specifically, we only need a Seq2Seq model. We treat the question as the Seq2Seq input and use (S, P, M) connected by [SEP] as the target for standard Seq2Seq training. One trick here is that concatenating in the order (S, P, M) yields much better results (8–10 percentage points higher) than the order (S, M, P). This is because predicting S and P from the question is easier than predicting M; we should predict the easier parts first to reduce the number of candidate answers.

Baseline model schematic of this article

In the reference code, the Seq2Seq model used is the RoFormer-Sim-FT model introduced in "SimBERTv2 is here! RoFormer-Sim Model Integrating Retrieval and Generation" and "Enhancing RoFormer-Sim with Open Source Manual Annotations". It is a similar-question generation model pre-trained using the UniLM framework. Comparisons show that using RoFormer-Sim-FT improves performance by at least 2 percentage points over using RoFormer directly. This also indicates that similar-question generation is an effective pre-training method for this scheme.

Error Analysis

During decoding, we first build a prefix tree for all (S, P, M) and then decode according to the prefix tree. This ensures the decoding result falls into a triple in the knowledge base. The detailed prefix decoding steps were introduced earlier.

However, when observing bad cases, I found that the model occasionally makes very "simple" mistakes. For example, for the question "How far is the Shangri-La Hotel Pudong Shanghai from the railway station?", the correct (S, P) should be "(Shangri-La Hotel Pudong Shanghai, Distance to railway station)," but the model generated "(Shangri-La Hotel Pudong Shanghai, Hotel star rating)." Sometimes for "What does XXX hate?", the model generates "(XXX, Like)." Sometimes for "What courses does XXX mainly teach?", the correct answer is "(XXX, Main courses)," but the model generates "(XXX, Main achievements)." That is, the model seems to fail on questions that look very simple literally (generating the wrong P).

After reflection, I believe these bad cases are essentially caused by inherent weaknesses of Seq2Seq, mainly involving two aspects: 1. Exposure Bias during training; 2. The greedy nature of Beam Search during decoding. First, because Seq2Seq knows the previous true label during training, it weakens the training difficulty, leading to a lack of "global vision." Second, even with Beam Search, decoding is essentially greedy, making it difficult to predict the current token by considering several subsequent tokens.

Theoretically, applying strategies to mitigate Exposure Bias in Seq2Seq, such as those in "Analysis and Countermeasures of Exposure Bias in Seq2Seq" or "TeaForN: Making Teacher Forcing More ’Farsighted’", should help. These methods are numerous and vary in complexity; I leave them for readers to try.

"Look-ahead" Strategy

Here, I propose another "look-ahead" strategy that can mitigate this problem.

In the "Seq2Seq + Prefix Tree" scheme, our Seq2Seq is not truly generating arbitrary text but performing what is essentially a retrieval operation under the constraint of a prefix tree. Therefore, after generating S, we know the allowed subsequent Ps. Generally, there aren’t too many allowed Ps, so we can directly enumerate them and adjust the current token’s prediction based on the coverage of the question by P.

The specific steps are: assume the current question Q has already decoded S and the first t-1 characters of P, denoted as P_{< t}. Now, to predict the t-th character P_t, we retrieve all possible P^{(1)}, P^{(2)}, \dots, P^{(n)} based on S and P_{< t}. Each P^{(k)} can be represented as [P_{< t}, P_t^{(k)}, P_{> t}^{(k)}]. We then use a coverage function—here, we directly use the Longest Common Subsequence (LCS) length—to calculate the coverage gain brought by each candidate P: \Delta^{(k)} = \text{LCS}(P^{(k)}, Q) - \text{LCS}(P_{< t}, Q) This gain is regarded as the "potential benefit" of predicting P_t as P_t^{(k)}. If multiple P_t^{(k)} correspond to the same character, we take the maximum.

Thus, for all candidate values k of P_t, we have calculated a "potential benefit" \Delta^{(k)}. We can adjust the Seq2Seq prediction probability to strengthen tokens with higher \Delta^{(k)}. The reinforcement rule I used is: p_k \leftarrow p_k^{1/(\Delta^{(k)} + 1)} That is, if the potential benefit is \Delta^{(k)}, the corresponding probability is raised to the power of 1/(\Delta^{(k)} + 1), and then re-normalized. This strategy brought an improvement of about 4 percentage points.

Effectiveness Analysis

The code for this article is shared at:

Github: https://github.com/bojone/KgCLUE-bert4keras

The final results are:

F1 EM Average
valid 89.20 91.04 90.12
test 90.25 92.48 91.37
online 86.03 88.45 87.24

It currently ranks second on the leaderboard:

Current KgCLUE Leaderboard Screenshot

The debugging journey was roughly:

  1. Initially used RoFormer + UniLM predicting in (S, M, P) order; validation EM was around 70+.

  2. After changing to (S, P, M) order, validation EM reached 82.

  3. After switching the pre-trained model to RoFormer-Sim-FT, it improved to 84–85.

  4. Finally, adding the "look-ahead" strategy brought it to the current 89.

Some Disadvantages

So far, we have introduced the "Seq2Seq + Prefix Tree" scheme in detail and shared a baseline using KgCLUE. Overall, "Seq2Seq + Prefix Tree" has obvious advantages and can achieve competitive results in retrieval tasks, but there are still issues worth considering.

The most typical problem is the inherent issue of Seq2Seq itself. Although the "look-ahead" strategy has brought good improvements, the corresponding problem is not completely solved. Additionally, I have not yet tried the general strategies for solving Exposure Bias mentioned earlier.

Another issue is that the "Seq2Seq + Prefix Tree" scheme relies on the model "generating" the result. Once an uncommon character is identified as [UNK], it will likely fail. Therefore, how to better solve the [UNK] problem is a research-worthy topic.

Finally, while "Seq2Seq + Prefix Tree" may achieve good results on evaluation metrics, it has a feature that is not very friendly for engineering: correcting bad cases becomes difficult. In traditional methods, you only need to keep adding samples to correct bad cases, whereas "Seq2Seq + Prefix Tree" requires you to modify the decoding process, which is usually much harder.

Conclusion

This article introduced a new scheme for retrieval models—"Seq2Seq + Prefix Tree"—and provided a specific baseline using KgCLUE. The "Seq2Seq + Prefix Tree" scheme has advantages such as simple training and low space occupancy, as well as some shortcomings. Overall, it can be considered a concise and competitive solution.

Reprinting: Please include the original address of this article: https://kexue.fm/archives/8802

For more detailed reprinting matters, please refer to: "Scientific Space FAQ"