How I Built a Multi-Document Summarizer with Python, Hugging Face, and Docker
A step-by-step journey from a complex NLP problem to a fully deployed web application.
Live Demo: Hugging Face Space
Source Code: GitHub
The Problem: Finding the Signal in the Noise
In a world of constant information, summarizing a single article is useful, but the real challenge arises when you need to understand an event covered by dozens of different sources. How do you get the key points from all of them without reading the same facts over and over again?
This is a challenge of redundancy. A truly useful summary must identify the core topics across all documents and present them concisely, without repetition. This is precisely the problem I set out to solve.
To tackle this, I developed a full-stack web application that implements a hybrid summarization pipeline. It intelligently filters out repetitive information before generating a final, coherent summary. In this post, I’ll walk you through the entire project: the NLP strategy, the technologies I chose, and how I containerized the application with Docker for a seamless deployment.
The Strategy: A Hybrid Extractive-Abstractive Pipeline
A naive approach would be to simply combine all the articles and ask an AI to summarize the result. This often fails because the model gets overwhelmed by repetitive noise. My solution uses a more robust, two-stage approach.
- The Extractive Stage (Finding the Core Topics): Before writing anything, the first step is to act like a detective. My pipeline reads all the documents and identifies the main themes by automatically grouping similar sentences together. Each group, or “cluster,” represents a single core topic. From each of these clusters, I select only the single most representative sentence. The output is a short, information-dense set of unique key points.
- The Abstractive Stage (Generating a Fluent Summary): With a concise, non-redundant list of facts, the second stage is to act like an author. This list is passed to a powerful pre-trained language model (BART). This model’s job is not to copy the sentences, but to understand and rewrite them into a completely new, fluent, and human-like paragraph.
Building the NLP Engine: The Tech Stack in Action
1. Turning Sentences into Meaning with sentence-transformers
To group sentences by topic, a computer first needs to understand their meaning. I used the sentence-transformers library to convert each sentence into a high-dimensional vector, or “embedding.” This process maps each sentence to a point on a complex “meaning map,” where sentences with similar meanings have vectors that are mathematically close to each other.
This visualization demonstrates the power of embeddings. Using a sample text about both space exploration and cooking, the model automatically grouped all the “space” sentences into one cluster and all the “cooking” sentences into another. This is the foundation of our topic-finding system.
2. Finding the Clusters with scikit-learn
With the sentences converted to vectors, I used the robust KMeans algorithm from scikit-learn to programmatically find these clusters. A key feature of the final application is that the user can choose the number of clusters, which directly controls the level of detail and the number of key topics in the final summary.
After clustering, the most import step is to select the single best sentence from each topic group. I achieved this by finding the sentence whose embedding was mathematically closest to the centre (the “centroid”) of its cluster. The code for this is surprisingly elegant:
This is the core logic that solves the redundancy problem by ensuring only one sentence per major topic is chosen for the final summary.
3. Writing the Summary with Hugging Face transformers
For the abstractive stage, I used the powerful facebook/bart-large-cnn model, made accessible through the Hugging Face transformers library’s pipeline function. This model is specifically pre-trained on news articles, making it the perfect tool for this task.
Get Neel More’s stories in your inbox
Join Medium for free to get updates from this writer.
The beauty of the Hugging Face Library is its simplicity. The core of my summarization logic, where the model is loaded and prepared, is incredibly concise:
This snippet shows the model being initialized just once when the application starts. This is a crucial optimization that ensures the multi-gigabyte model isn’t reloaded for every user request, making the application fast and efficient.
From a Script to a System: Building the Application
An algorithm is only useful if people can interact with it. This is where software engineering comes in.
Serving the Model with FastAPI
To make the NLP pipeline usable, I wrapped it in a REST API using FastAPI. I chose FastAPI for its high performance and its incredible feature of generating automatic, interactive API documentation.
This documentation, generated automatically by FastAPI, was invaluable for testing the endpoint and serves as detailed technical documentation for the API.
The endpoint for the summarizer is clean and robust, using Pydantic for automatic data validation to ensure the input is correct before it ever hits the model.
This code defines a /summarize/ endpoint that accepts a list of documents and an optimal number of clusters (which must be between 2 and 10), then passes them to the NLP pipeline.
Containerizing with Docker for Perfect Reproducibility
To ensure the application could run anywhere without dependency issues, I containerized it with Docker. The Dockerfile packages the Python code, all the libraries, and even the pre-downloaded NLTK data and multi-gigabyte ML models into a single, portable image. This was the key to a smooth and reliable deployment on Hugging Face Spaces.
One of the biggest challenges in deploying ML application is handling large model files. Instead of downloading them every time the application starts (which is slow and unreliable), I baked them directly into the Docker image during the build process. This is a critical MLOps practice for creating self-contained and fast-starting services.
These lines in the Dockerfile ensure that all necessary data and models are included in the final image, making the deployed application faster and more robust.
The Final Product: A Live Demo
The result is a simple, intuitive web application where anyone can paste text from multiple sources, select their desired summary length, and get a high-quality summary in seconds.
Conclusion and Key Takeaways
Building this project was an incredible learning experience, taking a complex NLP concept all the way to a deployed, interactive application.
One of my biggest takeaways was the importance of a robust deployment pipeline. Debugging Docker and the Hugging Face Spaces environment taught me invaluable lessons about creating self-contained, reproducible machine learning systems — a critical skill in real-world MLOps.
Thank you for reading! I encourage you to try the live application and explore the source code on GitHub. Please feel free to connect with me on LinkedIn if you have any questions or feedback.
Live Demo: Hugging Face Space
Source Code: GitHub
My LinkedIn: LindedIn




