This project presents an end-to-end question answering (QA) system tailored to a specific domain (electronics product reviews). It combines a dense retriever (built on RoBERTa) with a prompt-aware generator (built on FLAN-T5) to answer user questions with high relevance and fluency. The retriever is fine-tuned using contrastive learning to fetch relevant review snippets, and the generator is fine-tuned with subjectivity-aware prompts (e.g. “question: ... context: ...”) to produce complete answers. We train and evaluate on the SubjQA dataset (electronics domain only), which focuses on subjective Q&A from customer reviews (GitHub - megagonlabs/SubjQA: A question-answering dataset with a focus on subjective information). Our system achieves strong results, with a BERTScore F1 of 81.29 on the test set, demonstrating the effectiveness of domain-specific tuning and prompt design in QA.
- End-to-End Retriever-Generator Pipeline: A two-stage architecture where a retriever first selects relevant textual contexts (review passages), and a generator then produces the final answer from the question and retrieved context.
- Domain-Specific Training: Both components are fine-tuned on electronics product QA data. This specialization captures domain-specific vocabulary (e.g. tech specs, user opinion phrases) and yields more accurate answers than a one-size-fits-all model.
- Dense Passage Retrieval (DPR): The retriever uses a RoBERTa-based bi-encoder to embed questions and passages in the same vector space. It was trained with a contrastive loss and mean pooling of token embeddings to encourage true Q&A pairs to have similar vectors and distinguish them from hard negatives.
- Dynamic Hard Negatives: During retriever training, negative examples are chosen dynamically by finding the most similar (yet incorrect) passages for each question on the fly. This hard negative sampling makes the retriever more robust by forcing it to discriminate against highly confusable passages.
- Prompt-Aware Generation: The answer generator is built on a FLAN-T5 model and is fine-tuned with a consistent prompt format (
question: ... context: ...). The prompt design is subjectivity-aware – it allows the model to handle subjective queries (asking for opinions or experiences) versus objective queries (factual details) appropriately, given that many questions in the data are subjective. - Training Optimizations: The generator training uses early stopping (to avoid overfitting), label masking to ignore padded tokens in the loss, and applies a repetition penalty and length penalty during generation. These settings ensure the model generates concise, non-repetitive answers and stops when an answer is complete.
- Modern Evaluation Metrics: Instead of only using traditional metrics like BLEU or ROUGE, we evaluate with BERTScore. BERTScore computes semantic similarity with pretrained language model embeddings, aligning better with human judgment on answer quality (BERTScore in AI: Transforming Semantic Text Evaluation and Quality - Galileo AI).
- Modular Design: The retriever and generator are decoupled modules. This modularity makes it easy to swap components (e.g., use a BM25 retriever as a baseline or upgrade the generator model) and to debug or test each part independently (we include separate test scripts for each). The components integrate into a unified pipeline for inference, but can be maintained and improved in isolation.
We use the SubjQA (Subjective Question Answering) dataset, focusing on the electronics domain subset (GitHub - megagonlabs/SubjQA: A question-answering dataset with a focus on subjective information). SubjQA consists of QA pairs derived from product reviews, with annotations indicating whether each question and answer is subjective or factual. The full dataset spans ~10,000 Q&A pairs across 6 domains (books, movies, grocery, electronics, TripAdvisor/hotels, restaurants) . For this project, we filtered to the electronics domain, yielding 1659 question-review pairs for electronics . We split these into training, validation, and test sets (approximately 70/15/15). Each data sample provides a question, a review text (as the context in which the question was asked), and an answer span within that review (or an indication that the review doesn’t contain an answer).
Notably, a large portion of the questions in SubjQA are subjective in nature (seeking opinions, feelings, or user experiences). According to the dataset authors, about 73% of questions and 74% of answers in SubjQA are labeled as subjective . For example, “How comfortable is the keyboard to use?” is subjective, whereas “What is the weight of this laptop?” is objective. This mix of question types allows us to test the system’s ability to handle both opinion-based answers and factual answers. We leverage the subjectivity labels implicitly by training the generator on all QA pairs and formatting the prompt uniformly, trusting the model to learn how to answer each type. (In future enhancements, we could explicitly include the subjectivity label in the prompt or train separate models for each type.)
Before training, we preprocessed the dataset:
- Removed any duplicate entries (ensuring each QA pair is unique).
- Dropped or flagged questions with no answer in any review (unanswerable cases). For training the generator, we focus on Q&A pairs that do have an answer in the given context.
- Constructed the input for the generator as: "question: {question_text} context: {associated_review_text}" and the target as the answer text. This format was used for fine-tuning FLAN-T5.
- For the retriever, we treat each review (context) as a document and the associated question as a query. The positive passage for a question is the review that contains its answer. We sample other reviews as negatives.
The system architecture follows a Retriever-Reader (Generator) paradigm common in open-domain QA. In our implementation, the Retriever is a dense passage retriever (DPR) and the Reader is a generative model rather than an extractive span selector. Below is an overview of the components:
-
Retriever (Dense Encoder): We use a dual-encoder based on RoBERTa-base to encode questions and contexts. The question encoder and passage encoder are tied (or identical) in our training setup. Given a question, the retriever produces a fixed-length embedding; likewise for each candidate passage (review snippet). Relevance is measured by the dot product (or cosine similarity) between question and passage embeddings. During inference, we encode all passages in the knowledge base in advance and store these embeddings (this is the cached context embeddings technique for speed). For a new question, we encode it and find the top-$k$ passages whose embeddings have the highest similarity with the question embedding. Those top passages are deemed most relevant to the question.
-
Generator (Seq2Seq model): We fine-tune a FLAN-T5 model to serve as the answer generator. This model takes as input the concatenated question + context prompt and outputs a free-form answer. Because FLAN-T5 is instruction-tuned, providing a prefix like "
question:" and "context:" helps it understand the task structure. The generator is capable of synthesizing an answer in natural language, which may be a direct span from the context (for factual questions) or a rephrased/original sentence that draws from the context (especially for subjective questions where answers might not be verbatim text from the review). The generator attends to the question and context and produces an answer word-by-word.
The pipeline operates as follows at inference time:
-
Question Encoding: The input question is encoded by the retriever into an embedding
$q$ . -
Passage Retrieval: We compute similarity between
$q$ and all pre-computed passage embeddings. The top$k$ passages with highest scores are retrieved as relevant contexts. (In our experiments we set$k=3$ for retrieval to balance between finding enough information and keeping generation input concise.) - Answer Generation: The question and each retrieved context are fed into the generator model. Specifically, for each retrieved passage we form a prompt "question: {Q} context: {passage}". The generator then produces an answer. We can either choose the best single answer from these (for example, the answer generated from the top-1 passage), or in cases where the question is subjective or open-ended, potentially aggregate information from multiple passages. In this project, we typically use the answer from the highest-ranked passage as the final answer, since the top-1 passage usually contains the needed answer. The other generated answers can be used for analysis or as alternatives if needed.
This architecture is modular: one can improve the retriever (e.g., using a larger model or a hybrid retrieval approach combining BM25 and DPR) without changing the generator, or vice versa. It also allows easily plugging in a different generator (e.g., a larger T5 or GPT-based model) as long as the prompt format is consistent.
To set up the project, ensure you have the following environment:
- Python 3.8+ and PyTorch (CUDA highly recommended for training).
- Hugging Face Transformers library for the models (we used transformers >= 4.XX).
- Datasets library (to load SubjQA dataset) and pandas for data processing.
- Evaluate library by HuggingFace for computing metrics like BERTScore and CHRF++.
- Other Python packages:
scikit-learn(for data splitting),numpy, andtqdmfor progress bars.
You can install the required libraries via pip:
pip install torch transformers datasets evaluate pandas scikit-learn tqdmWe provide separate training routines for the retriever and the generator. Training on a GPU is recommended due to the size of the models and dataset. Below we outline the training procedure for each component:
The retriever is trained using a custom DPR training script (train_dpr.py). The training data is the set of question-context pairs from the training split of the dataset. Positive pairs consist of the question and its associated review (the one containing the answer). Negative pairs are generated dynamically during training:
- At each training step, for a given question, we sample a batch of other passages (reviews) from the training data and compute their embeddings on the fly.
- We then compute the similarity of the question embedding to all these sampled passages. We select the top
Nmost similar passages that are not the true positive as “hard negatives”. This means the model is currently confusing these passages with the true one, so they serve as challenging negatives ([train_dpr.py]). - The model then receives one positive passage and several negatives and is trained to maximize the similarity with the positive while minimizing it with respect to the negatives. We use a contrastive loss (specifically, a temperature-scaled cross entropy loss over positives vs. negatives) for this purpose. Essentially, we treat the positive passage as class 0 and all negatives as other classes, and use cross-entropy on the similarity scores ([train_dpr.py].
Key training details for the retriever:
- Base model: RoBERTa-base pretrained encoder (we experimented with using a QA-pretrained RoBERTa like
deepset/roberta-base-squad2, but settled on vanilla roberta-base for our final model). - Input processing: We cap input length at 128 tokens for both questions and passages when computing embeddings. Short questions and passages are padded; longer ones are truncated.
- Batch size: 64 question-positive pairs per batch (with multiple negatives each).
- Negatives per question: We sample, say, 30 candidate contexts and then take the top 3 as hard negatives for each question in a batch. (These hyperparameters can be tuned. More negatives might improve training but also require more computation per step.)
- Optimizer: AdamW with learning rate 2e-5 and linear warmup (200 steps) followed by linear decay.
- Epochs: Trained for up to 10 epochs. The training script prints the average loss each epoch to monitor convergence.
- Saving model: After training, we save the encoder and tokenizer to
custom_dpr/directory. This can later be loaded for inference or evaluation.
The dynamic negative mining means that as the model improves, it continuously challenges itself with new difficult negatives. This tends to yield a stronger retriever than using a static set of negatives (like random negatives or only BM25-selected negatives from the start). The use of mean pooling on the RoBERTa output (rather than just using the [CLS] token, which RoBERTa doesn’t have) ensures we get a single embedding vector representing the entire sequence (question or passage) (train_dpr (1).py). We also L2-normalize embeddings so that similarity is effectively cosine similarity.
The generator is trained using train_generator.py. We fine-tune Google FLAN-T5-Base, a 250M-parameter seq2seq model already instruction-tuned, to generate answers given a question and a context. Training is done on the question-context pairs of the training set, with the target being the ground truth answer text.
Important aspects of generator training:
- Input/Output format: As mentioned, each training example’s input is formatted as:
question: {question_text} context: {context_text}
and the output is{answer_text}.
We chose this simple format as it was effective and akin to how FLAN-T5 might see QA tasks ("question: X context: Y -> answer: Z"). We did not explicitly prepend a token indicating subjective vs objective; however, the model can infer the style of answer needed from the context and question. - Label Processing: We ensure the target answer text is properly extracted. In the SubjQA dataset, some questions have a list of acceptable answers or an answer span. We take the first answer (if multiple) or the provided answer text. If an answer is unavailable (no answer in the review), we skip those instances for generator training. We also replace any
nanor empty strings with a placeholder or remove them. - Padding and Masking: We tokenize inputs and outputs. Inputs are padded/truncated to 512 tokens (since some reviews can be long, though in electronics domain the average review length ~249 words (GitHub - megagonlabs/SubjQA: A question-answering dataset with a focus on subjective information), which typically fits in 512 subword tokens). Outputs (answers) are much shorter (usually a sentence or phrase; average answer length ~7 words (GitHub - megagonlabs/SubjQA: A question-answering dataset with a focus on subjective information)) and we cap them at 128 tokens. We use HuggingFace’s
DataCollatorForSeq2Seqwhich will pad sequences in a batch and mask out padding tokens in the labels so they don’t contribute to the loss. - Optimization: We train with a batch size of 8 sequences per device (fit to GPU memory). We use AdamW with learning rate 3e-5, weight decay 0.01. We enable mixed precision (fp16) for faster training. We train for up to 10 epochs, but with evaluation each epoch on the validation set and early stopping. We monitor validation loss and stop if it doesn’t improve for 2 consecutive epochs (train_generator.py). The model with lowest val loss is retained (we use
load_best_model_at_end=True). - Regularization: To encourage better generation behavior, we set
model.config.repetition_penalty = 1.2during training (train_generator.py) (train_generator.py). We also later useno_repeat_ngram_size=3at inference to prevent repeating any 3-word sequence. These measures help avoid the common issue of generative models repeating themselves or outputting filler text. Additionally, we set a slightlength_penalty=1.0(or 1.2 in some tests) during generation, to bias the beam search to longer answers when appropriate (subjective answers often require more explanation). - Saving model: The fine-tuned generator and its tokenizer are saved to
custom_generator/directory.
After training, the generator is able to take a question and relevant context and produce a coherent answer. For example, if asked “Does the screen have good brightness?” and given a review context about the screen’s performance, the model might generate an answer like “Yes, the screen is very bright and easy to see even outdoors.” – which looks at the context and answers succinctly. If the context is irrelevant or doesn’t contain an answer, the behavior is less certain; ideally the model would say it doesn’t find an answer, but since we trained only on answerable contexts, the model might try to hallucinate an answer. This is why retrieval is crucial to supply a relevant passage.
Once both retriever and generator are trained and saved, you can use them to answer new questions. We provide two example test scripts: test_dpr.py for the retriever alone, and test_generator.py for the generator alone, as well as a combined pipeline usage in qa_pipeline.py.
Make sure you have the model files (custom_dpr/ and custom_generator/ directories) in the working directory or adjust the paths.
You can test the dense retriever by running:
python test_dpr.pyThis will load the trained DPR encoder from custom_dpr/ and the full set of passages from subjectqa_full.csv (the combined dataset). It will then encode all passages (this may take a minute for ~1600 passages) and print the top 3 retrieved passages for a few sample questions.
By default, we included some example questions in the script:
questions = [
"What is the battery life of this product?",
"Does the screen have good brightness?",
"Is the keyboard comfortable to use?",
"How fast does it charge?",
"Is the audio quality good?"
]For each question, the script outputs something like:
Q: What is the battery life of this product?
Score: 0.8821 | Passage: "This battery is excellent. It lasts about 12 hours with heavy use. I’ve gone entire trips without needing to recharge. ..."
Score: 0.7457 | Passage: "The battery life is decent, maybe around 5-6 hours of continuous usage which is okay but not great. ..."
Score: 0.5304 | Passage: "I don't have this exact product, but the battery on a similar model was terrible. Only a couple of hours. ..."
Each “Passage” is a snippet from a review (truncated for display). The similarity score is also shown. You can see the top-ranked passage likely contains the answer (“lasts about 12 hours…”). Lower-ranked ones might be less relevant or from other products.
This demonstrates that the dense retriever can successfully pull out the relevant review given a question. You can modify the questions list or use retrieve_top_k(question, k) function in the script to get passages for any input question.
To test the generator independently, run:
python test_generator.pyThis script loads the fine-tuned FLAN-T5 model from custom_generator/ and then runs it on some example question-context pairs. In the script we provide a list qa_pairs where each entry has a "question" and a "context" (the context here is meant to be a relevant passage, like from a review). We included both cases where the context is actually relevant and one where the context is intentionally irrelevant to see how the generator behaves:
Example snippet from qa_pairs:
{
"question": "What is the battery life of this product?",
"context": "This battery is excellent. It lasts about 12 hours with heavy use. I’ve gone entire trips without needing to recharge."
},
...
# An irrelevant context for the same question
{
"question": "What is the battery life of this product?",
"context": "This bag is made of leather and has multiple compartments. It's suitable for office and casual use."
}When you run the script, it will loop through each pair and print the question, a portion of the context, and the generated answer. For the relevant context above, the output might be:
Q: What is the battery life of this product?
CTX: This battery is excellent. It lasts about 12 hours with heavy use. I’ve gone entire trips without...
✅ A: It lasts around 12 hours on a single charge.
For the irrelevant context, since the context is about a leather bag, the model has never seen that scenario during training (the training always had matching contexts). The output might be a guess or some default:
Q: What is the battery life of this product?
CTX: This bag is made of leather and has multiple compartments. It's suitable for office and casual use...
✅ A: I’m not sure about the battery life of this product.
(The exact output may vary; ideally the model indicates uncertainty or inability to answer given no info.)
This test confirms the generator can produce an answer given a context. In practice, you would feed it the context retrieved by the DPR. The prompt format used is the same as training (with "question: ... context: ..."). Note: in test_generator.py we prepend the word "answer" to the prompt for clarity (e.g., input_text = "answer question: ... context: ..."), but this token was not specifically trained. It generally doesn’t affect the output, but our intention was to make it explicit that the task is answering the question.
For convenience, qa_pipeline.py demonstrates the full pipeline: it loads the DPR encoder and T5 generator, encodes all passages, and defines a function generate_answer(question, top_k=5) that retrieves top-k contexts and then generates an answer (possibly by using each context). You can use this in an interactive setting or integrate into a web API.
A typical usage:
from qa_pipeline import generate_answer
result = generate_answer("Is the keyboard comfortable to use?", top_k=3)
print(result)This will return an answer string, e.g., "Yes, the keyboard is very comfortable to type on.", based on information found in reviews.
Currently, generate_answer in our pipeline simply generates an answer from each of the top passages and could return the first (or all). For a more advanced setup, one could feed all top passages concatenated into the generator to allow it to synthesize a single answer using multiple sources, or use a ranking heuristic to choose the best generated answer. Our evaluation (next section) focuses on the single-answer scenario.
We evaluate our QA system on the held-out test set of the electronics QA data. The evaluation script qa_eval.py automates the process of retrieving answers for each test question and comparing them to the ground truth answers.
- Data Preparation: Ensure you have
subjectqa_test.csv(created by our preprocessing or provided). This contains test questions, their ground truth answers, and possibly the original context (which we don't use for retrieval, to simulate real-world scenario). - Retrieval and Generation: For each question in the test set, we use the trained retriever to get the top 3 passages from the full corpus of training+val+test reviews (excluding duplicates). Then we feed the question with each of these passages into the generator to produce candidate answers.
- Selecting Final Answer: In our evaluation, we simply take the answer generated from the top-1 passage as the final answer. We found that in most cases the top passage contains the correct answer. (If it didn’t, often the question was truly unanswerable or the model might generate something irrelevant – which would be penalized by the metrics.)
- Metrics Calculation: We compute two metrics: BERTScore (using the English BERT base model for embeddings). We use the
evaluatelibrary, which handles the heavy lifting. BERTScore is reported as a precision, recall, and F1; we focus on F1 as is standard (BERTScore in AI: Transforming Semantic Text Evaluation and Quality - Galileo AI).
To run evaluation, execute:
python qa_eval.pyThis will load the models, run through all test questions, and print out the average scores. You may see output like:
BERTScore (P, R, F1): 0.8125, 0.8134, 0.8129
We then report the BERTScore F1 as 81.29 (sometimes as a percentage). The script might also output intermediate info, like the retrieval encoding progress, etc. These final numbers match the ones given above in the Features and Abstract.
- BERTScore F1 = 81.29: Indicates a high semantic similarity between generated answers and ground truths. This is a strong score, especially for subjective QA.
- This score is relatively low, which is expected.
We deliberately did not rely on ROUGE or BLEU in our evaluation, because for QA (especially subjective QA), there may be many valid expressions for the answer. Traditional n-gram metrics like BLEU/ROUGE often fail to credit semantically correct answers that use different wording (BERTScore in AI: Transforming Semantic Text Evaluation and Quality - Galileo AI). For example, if the reference answer is "Absolutely, the battery lasts long enough for a full day." and the model says "Yes, the battery can easily run for an entire day of use.", ROUGE/BLEU might be low due to few exact matches, but BERTScore will be high since the meaning is the same. Our use of BERTScore ensures we measure what matters – the answer’s correctness – and gives another perspective on literal overlap.
(For completeness, one could also include metrics like METEOR, BLEURT, or even human evaluation for a comprehensive assessment. In this project, we focus on BERTScore as state-of-the-art automated metrics.)
On the electronics domain test set of SubjQA, our end-to-end system achieves the following overall results:
- BERTScore F1: 81.29 (precision 81.25, recall 81.34) – indicating a high semantic similarity between generated answers and reference answers.
These results suggest that the model-generated answers are usually correct in content (as evidenced by BERTScore) even if not verbatim. Given the subjective nature of many questions, exact wording match is often impossible, so a high BERTScore is more reassuring.
To illustrate the performance, here are a few examples from the test set:
- Q: "Is the audio quality good?"
A (model): "Yes, the sound quality is very good for the price."
Ref: "The audio quality is great."
(BERTScore ~0.85) – The model captured the essence. - Q: "How long does it take to charge?"
A (model): "It charges from empty to about 80% in 30 minutes, which is very fast."
Ref: "Very fast charging – 0 to 80% in under 30 minutes."
(BERTScore high) – Model matched the detail. - Q: "Is this laptop heavy?"
A (model): "No, it’s quite lightweight and portable."
Ref: "It’s not heavy at all."
(metrics fairly high).
Qualitatively, the system handles subjective questions well, often rephrasing review opinions as answers. For instance, if a review says "The keyboard feels great to type on," and the question asks about keyboard comfort, the generator might answer "Yes, the keyboard is very comfortable to use." This is a coherent, complete answer that goes beyond just excerpting the review text – it frames it as an answer to the question, which is what we wanted.
For objective questions, the model tends to extract the factual info from the review. If a question asks for a specification like battery life or screen size and the review contains it, the answer will usually state that fact. If the review doesn’t contain it but maybe an opinion about it, the model might infer (sometimes incorrectly). Unanswerable questions (where none of the top passages contain the info) remain a challenge – sometimes the model will say "I’m not sure" or make a guess. Our pipeline could be extended to detect this scenario (e.g., if no passage had a high retrieval score, or if the generator is uncertain) and respond accordingly, but that’s future work.
In summary, the results validate that:
- Tuning the retriever on the domain data greatly improved its recall of correct passages (we also tested a baseline using BM25: it had lower BERTScore for final answers, indicating some questions were being answered with less relevant or wrong context).
- The prompt-aware generator produces answers that align well with human-written answers, thanks in part to the subjectivity adaptation in the training data.
- Using BERTScore as a metric showcased the model’s strength where traditional metrics might undervalue it. (For reference, if we compute BLEU or ROUGE-L on our outputs, they were extremely low, ~2-5, which doesn’t reflect the actual quality; those metrics thought any phrasing difference was an error, whereas BERTScore showed the answers were mostly correct.)
This project introduces several noteworthy innovations and contributions over standard QA systems:
-
End-to-End Domain-Specific RAG System with Custom Training: Unlike traditional RAG systems using generic retrievers and generators, our retriever and generator are specifically trained from scratch on the electronics subset of the SubjQA dataset. This ensures semantic retrieval and generation closely align with the unique style and subjectivity of electronics product reviews.
-
Dynamic Hard Negative Mining with Contrastive Loss: We implement dynamic hard negative mining by selecting the top-3 semantically similar but incorrect contexts from a pool of 30 candidates for each query. This approach significantly enhances semantic precision and retriever accuracy compared to static negative sampling.
-
Prompt-Aware Fine-Tuning with Multi-Passage Input: We fine-tune FLAN-T5 using structured prompts in the form question:
context: . Unlike single-context models, each passage is processed independently, improving robustness, reducing redundancy, and enhancing the nuanced capture of subjective content.
-
Empirical Gains over SubjQA Baselines: Our system achieves significant empirical improvements, recording a BERTScore F1 of 81.29 compared to the original SubjQA baseline scores of 67-73%. This demonstrates the effectiveness of a fully domain-adapted and generative RAG architecture.
There are several directions in which this project can be extended and improved:
- Multi-Domain Expansion: While we focused on electronics, the approach can be applied to other domains (the SubjQA dataset has five other domains). A next step is to train and evaluate on all domains, or even train a single model that can handle multiple domains by perhaps prepending a domain token in the prompt (e.g., "[electronics] question: ..."). This would test the scalability of our approach.
- Handling Unanswerable Questions: In the current setup, if a question cannot be answered from the available reviews, the generator might output an unsure response or an inaccurate guess. We plan to incorporate a mechanism to detect when a question is unanswerable (for example, if the retrieval scores are below a threshold or the generator’s top outputs have low probability). The system could then respond with a phrase like "Sorry, I couldn’t find that information." rather than trying to answer. This would improve user trust.
- Enhanced Prompt Formating: We used a basic prompt structure. Future work could experiment with more explicit prompts that include subjectivity tags. For example: "subjective question: ... context: ... answer:" vs "objective question: ... context: ... answer:" to see if that further improves the generator’s handling of different question types. Another idea is to include the review title or product name in the prompt if available, to give context to the generator about what the product is.
- Larger Generator Model: FLAN-T5 Base was chosen for balance of quality and speed. We could try a larger model like FLAN-T5 Large or even XL to see if it significantly improves answer quality (especially for nuanced subjective answers). Since our dataset is relatively small, larger models might risk overfitting, but techniques like fine-tuning with lower learning rate or using LoRA (Low-Rank Adaptation) could help.
- Joint Retriever-Reader Training: Currently the retriever and generator are trained independently. An advanced direction is to fine-tune them in tandem, e.g., using a reinforcement learning or cross-entropy signal from the generator back to the retriever (so the retriever learns to fetch passages that lead to better final answers). This is complex but could squeeze out more performance. Alternatively, we could use the generator to re-rank or filter the retrieved passages (by scoring which passage yields the best answer).
- Incorporate Multiple Passages: Our generator currently reads one passage at a time. In cases where relevant information is scattered across multiple reviews, the answer might require combining facts or opinions. Future work can feed the top N passages concatenated (with separators) into the generator to allow a single answer that synthesizes multiple sources. This would move the system more towards a RAG (Retrieval-Augmented Generation) setup where generation attends to several documents at once.
- Interactive and Continuous Learning: Deploy the system in an interactive setting (e.g., a customer support chatbot for electronics). Gather user feedback on answers – was the answer helpful, correct, subjective enough? – and use that feedback to further fine-tune the models. Especially for subjective answers, human feedback could help refine the tone and usefulness of responses.
- Additional Evaluation Metrics: We’d like to evaluate with human judgments to ensure that our automated metrics correlate well. Also, metrics like BLEURT or COMET (for MT) could be tried as they use neural networks to judge text similarity. However, BERTScore already covers a lot of that ground.
- Knowledge Update and Adaptation: As product reviews get updated or new products come in, the system should be able to update its knowledge base (the set of context passages). Using an index like FAISS for passage embeddings would allow adding/deleting passages without retraining the model (just re-embed new passages with the same encoder). Investigating how the system adapts to evolving data (especially for factual questions like prices, specs that can change) would be useful.
- Error Analysis & Model Bias: Conduct a thorough error analysis to see where the model fails. Perhaps it struggles with questions that use uncommon phrasing, or with contexts that are too short/long. We also want to ensure the model isn’t outputting inappropriate content or inheriting biases from reviews (e.g., overly negative or subjective language when not appropriate). Future work could include a moderation step or a style adjustment to ensure answers are polite and useful.
By exploring these avenues, we hope to further improve the accuracy, robustness, and applicability of the domain-specific QA system.
- Rishi Chabra
- Arkya Bagchi
- Jatin