Advancing Neural Search with Jina 2.0
Author(s): Shubham Saboo
With the onset of the Information Age, the ability to intelligently search through massive amounts of information has become an integral part of our day-to-day lives…
To understand the basics of neural search and how it differs from conventional search please go through my previous blog on “Next-gen powered by Jina”. It explains how Jina- a cloud-native, open-source company is pioneering the field of neural search. It builds on the idea of semantic search and explains the basic building blocks of the Jina framework required to build intelligent search applications.
RE: Neural Search
Just as a recap the idea behind neural search is to leverage state-of-the-art deep neural networks to intelligently retrieve contextual and semantically relevant information from the heaps of data. A neural search system can go way beyond simple text search by allowing you to search through all the formats of data including images, videos, audios, and even PDFs.
Applications of Neural Search
- A question-answering chatbot can be powered by neural search: by first indexing all hard-coded QA pairs and then semantically mapping the user dialog to those pairs.
- A smart speaker can be powered by neural search: by applying STT (speech-to-text) recognition and then semantically mapping text to internal commands.
- A recommendation system can be powered by neural search: by embedding user-item information in the form of numerical vectors and finding top-K nearest neighbors of a particular user/item.
Neural Search has created a new way to comprehend the world and provided us with the capability to perform intelligent information retrieval on heaps and heaps of data that is universal across the internet. Jina is a cloud-native neural search platform that is at the forefront of creating the future of search!
Jina 2.0 — What’s Changed?
Jina 1.x was a complex beast with lots of boilerplate code and not so much transparency but Jina 2.0 embraces the principle of “explicit above implicit”. To embrace the power of neural search and make it accessible to a wider audience, Jina launched its version 2.0 which is easier to learn, leaner to adopt, and faster to learn.
Jina 1.x was harder to learn and was difficult to get used to the different components and put them in a coherent fashion for the application to work. All these individual components are abstracted by a simple layer of just a Flow and Executor, all the middle layers including the pods, peas are hidden behind the scenes allowing you to just focus on “What really matters”.
To get started with Jina 2.0 on the journey to build intelligent search systems, you just need to know three concepts – Document, Executor, and Flow and with the user-friendly pythonic interface you will get to speed within no time.
Fundamental Components of Jina 2.0
Document, Executor, and Flow are the three fundamental concepts in Jina.
- A Document is the basic data type in Jina
- An Executor is how Jina processes Documents
- A Flow is how Jina streamlines and scales Executors
Document is the basic data type that Jina operates with, it is agnostic to the type /format of data. Text, picture, audio, video are all considered as documents in Jina. The superset of document data type is DocumentArray, it wraps up multiple individual documents and acts as a container for them.
You can think of a DocumentArray as a text file composed of multiple sentences where each sentence represents a Document. A DocumentArray is a first-class citizen of Jina’s Executor serving as the Executor’s input and output. For the data folks, you can understand the “document” by a simple analogy to the famous Numpy library.
Document = np.float; DocumentArray = np.ndarray
Executor is the smallest algorithmic unit in Jina that is used to process the documents be it encoding images into vectors, storing vectors on the disk, ranking results all of them are formulated as executors. Executor provides intuitive interfaces, allowing AI developers and engineers to really focus on the algorithm. Some common executors are as follows:
- Crafter: Crafter is used for pre-processing the documents into chunks.
- Encoder: The encoder takes the input pre-processed chuck of documents from the crafter and encodes them into embedding vectors.
- Indexer: Indexer takes the encoded vectors as input and indexes and stores the vectors in a key-value fashion.
- Ranker: Ranker runs on the indexed storage and sorts the results based on a certain ranking.
Executor process DocumentArray in-place via functions decorated with @requests. Following are the features of an executor in Jina:
- An Executor should subclass directly from jina.Executor class.
- An Executor class is a bag of functions with a shared state (via self) allowing it to contain an arbitrary number of functions with arbitrary names.
- Functions decorated with @requests the decorator will be invoked according to their on= endpoint.
There are mainly two ways to design an executor in Jina, so let’s look at a simple example of how we can create an executor using both Python and YAML:
- Using Python
To create an executor in python, you just need to import the native executor class from the Jina core and create a subclass of the same. Under the MyExecutorsubclass, you can define a number of functions by attaching the @requests a decorator on top of these functions to make them accessible within the flow.
After defining the executor subclass, you can create a flow and call the executor via the endpoint of the request /random_work, the following is the code snippet showing how to use an executor:
- Using YAML
An Executor can be loaded from and stored to a YAML file. Following is a replica of the python executor created above, you can save this file as “exec.yml”.
After saving the exec.yml file, you can construct an executor using the same and add it to a new or existing Jina flow:
Flow is how Jina streamlines and scales executors, it represents high-level tasks like indexing, searching, training, etc. It acts as a context manager and orchestrates a group of executors to accomplish a single task e.g. if you want to index the data you need a sequence of executors like crafter, encoder, indexer to work in tandem with each other in order to achieve the desired result.
Flow is a service, allowing multiple clients to access it via gRPC / REST / WebSocket from a public or private network.
Flow follows a lazy construction pattern, so it won’t actually run until you use with to open it. Flows can be created by simply importing them from the jina core library, and then adding executors to it. To run a flow you can simply open it via with and can send the data requests as we do in the below example:
If you would like to learn more or want to me write more on this subject, feel free to reach out.
If you liked this post or found it helpful, please take a minute to press the clap button, it increases the post visibility for other medium users.
Published via Towards AI