is an all-in-one embeddings database for semantic search, LLM orchestration and language model workflows.
This article will analyze .
from datasets import load_dataset
from tqdm.auto import tqdm
from txtai import Embeddings, LLM
def title(text):
prompt = f"""
Create a simple, concise topic for the following text. Only return the topic name.
Text:
{text}
"""
return llm([{"role": "user", "content": prompt}], maxlength=2048)
def data():
for x in posts:
x["url"] = x.pop("Post link")
x["text"] = x.pop("Post title")
x["id"] = title(x["text"])
yield {k.lower().replace(" ", ""): v for k, v in x.items()}
posts = load_dataset("neuml/neuml-linkedin-202501", split="train")
llm = LLM("hugging-quants/Meta-Llama-3.1-8B-Instruct-AWQ-INT4")
embeddings = Embeddings(
autoid="uuid5",
path="intfloat/e5-large",
instructions={"query": "query: ", "data": "passage: "},
content=True,
functions = [
{"name": "graph", "function": "graph.attribute"}
],
expressions = [
{"name": "topic", "expression": "graph(indexid, 'topic')"}
],
graph={
"approximate": False,
"topics": {"resolution": 6}
},
)
embeddings.index(tqdm(data(), total=len(posts)))
Now that the embeddings database is built, let's generate the topic names using an LLM.
def topic(text):
prompt = f"""
Create a simple, concise topic for the following text. Only return the topic name.
Text:
{text}"""
return llm([{"role": "user", "content": prompt}], maxlength=5000)
topics = {}
for name, nodes in tqdm(embeddings.graph.topics.items()):
name = topic("\n".join(embeddings.graph.attribute(x, "text") for x in nodes))
topics[name] = nodes
# Set topic on each node
for node in nodes:
embeddings.graph.addattribute(node, "topic", name)
embeddings.graph.topics = topics
Both of the sections above should run within a minute on a modern GPU. Building the embeddings database and generating the topics can optionally be skipped using the following model from the Hugging Face Hub.
embeddings = Embeddings()
embeddings.load(provider="huggingface-hub", container="neuml/txtai-neuml-linkedin")
Popular topics
Now that we have an embeddings database, graph and topics, let's explore the data! The next section shows the Top 5 posts for each of the Top 5 most popular topics.
from IPython.display import display, Markdown
# Get top 5 topics by popularity
popular = embeddings.search("SELECT topic FROM txtai GROUP BY topic ORDER BY sum(impressions) DESC LIMIT 5")
output = ""
for topic in popular:
topic = topic["topic"]
output += f"#### {topic}\n"
results = embeddings.search(
"SELECT text, createddate, impressions FROM txtai WHERE topic = :topic ORDER BY impressions DESC LIMIT 5",
parameters={"topic": topic}
)
for i, x in enumerate(results):
text = x["text"].replace("\n", " ")
output += f"{i + 1}. _{x['createddate']} - {x['impressions']} views_ - {text}\n"
display(Markdown(output))
Graph RAG
06/09/2024 - 2567 views - Knowledge Graphs (KGs) are a 🔥 topic now. But how do you build them? Check out this article that uses embeddings models to automatically build a semantic graph. And it's multimodal!
06/16/2024 - 2141 views - Want to use LLMs to automatically extraction entity-relationship models? And load them into a knowledge graph? Then check out this article.
03/05/2024 - 1803 views - 📈 Let's talk about Graph RAG. We've been looking at graph-based approaches for context generation since 2022. The best use case we've seen for Graph RAG is for more complex questions and research. For example, think of a problem as a road trip with multiple stops. A graph path traversal is a great way to pick up various concepts as context, concepts which may not be directly related and not picked up by a simple keyword/vector search. The attached image shows two graph path traversal examples. The first shows the path between a squirrel and the Red Sox winning the world series. The 2nd shows an image path from a person parachuting and someone holding a french horn. Note the progression of both the text and images along the way. There is also another example of traversing history from the end of the Roman Empire to the Norman Conquest of England. For problems like this, graphs do a great job. If the answer is a simple retrieval of a single entry, Graph RAG doesn't add much value. Like all things, Graph RAG isn't the be-all and end-all. Read more in the articles below. Semantic Graph Intro:
Vector Embeddings Innovations
02/24/2024 - 7202 views - 🚀 Excited to release an updated version of PubMedBERT Embeddings with Matryoshka Representation Learning support! With this model, dynamic embeddings sizes of 64, 128, 256, 384 and 512 can be used in addition to the full size of 768. It's a great way to save space with a relatively low level of accuracy tradeoff. Thank you to Tom Aarsen, Philipp Schmid and the Hugging Face team for adding this feature to Sentence Transformers! GitHub Project:
01/03/2025 - 2850 views - 🧬⚕️🔬 What if we said you can have a competitive 8 million parameter model that can index as fast as BM25? Or a 100K parameter 200KB model that retains knowledge? We're excited to release static PubMedBERT Embeddings models! These are a set of static models distilled with the great Model2Vec library by The Minish Lab Thank you to Stéphan Tulkens and Thomas van Dongen for creating Model2Vec!
03/01/2024 - 1722 views - Would you trade 1% of accuracy to only have to store 1% of the data? Exciting to see the innovation happening in the vector space and we're not talking about 1.58-bit LLMs. With Matryoshka Embeddings, we can drastically reduce vector dimensionality while maintaining a strong level of accuracy. Check out this example that combines Matryoshka Embeddings with Faiss 4-bit scalar quantization 🚀
Text Summarization with txtai
05/20/2024 - 2703 views - LLMs can translate and summarize but that doesn't mean they should. Check out this simple summarization method that's still quite popular.
07/09/2024 - 1884 views - 🤔 Machine translation just ask a LLM to do it? While LLMs can translate that doesn't mean they should. What if we could utilize smaller models that were trained to translate between specific languages? What if there was a pipeline that automatically loads models based on the source to target language? 🚀 Enter txtai's translation pipeline! The Translation pipeline automatically detects languages and searches the Hugging Face Hub for the best specialized model to perform the translation. These specialized models are often smaller than LLMs and much faster. Link to code:
07/07/2024 - 1326 views - 🗎 Want to summarize webpages, word documents, PDFs and more? Did you know there are models pre-built for summarization that pre-date the latest LLMs? And that they do a decent job and are faster? txtai supports pre-trained summarization models and LLMs for summarization. Either can be run as Python workflows or FastAPI services. Link to code:
07/05/2024 - 2096 views - ⚡ LangChain and LlamaIndex both use the Rank-BM25 library to provide in-line BM25 document retrieval. Rank-BM25 is a great way to quickly stand up a BM25 search index for a small number of documents. But it doesn't scale as it's built to run in memory. txtai has it's own BM25 implementation in Python. Term vectors are built harnessing the native performance of the Python arrays package. These term vectors are stored in a SQLite database. LRU caching stores frequently used vectors in memory. This combination of factors enables a highly performant index. For this comparison, 2.3M ArXiv abstracts were used. LangChain ran out of memory (32 GB of RAM). The test was scaled to 1.6M abstracts. txtai had 2x slower index times but 13x faster search times than LangChain. LangChain used 25 GB of RAM, txtai used 3.8 GB of RAM. Link to code:
07/01/2024 - 1095 views - ⚡ Faiss is a great vector indexing library. It has so many features past just a flat index. txtai automatically creates a performant Faiss index scaled by the size of the incoming data. The index type can also be fully customized with configuration. This shows the power of a full-featured and long-standing integration. See how this compares to LlamaIndex:
txtai Community Updates
02/21/2024 - 1322 views - 🕒 The countdown to txtai 7.0 is on. In the meantime, checkout this notebook with the code showing how all these graphs you've seen work!
03/22/2024 - 908 views - 🔥 Excellent tutorial on building a product search engine with txtai from NeuralNine! Check out the NeuML YouTube channel for links to this video and more:
And lets also look at the top 5 most popular posts overall.
output = ""
for i, x in enumerate(embeddings.search("SELECT id, text, createddate, impressions FROM txtai ORDER BY impressions DESC", 5)):
text = x["text"].replace("\n", " ")
output += f"{i + 1}. _{x['createddate']} - {x['impressions']} views_ - {text}\n"
display(Markdown(output))
02/24/2024 - 7202 views - 🚀 Excited to release an updated version of PubMedBERT Embeddings with Matryoshka Representation Learning support! With this model, dynamic embeddings sizes of 64, 128, 256, 384 and 512 can be used in addition to the full size of 768. It's a great way to save space with a relatively low level of accuracy tradeoff. Thank you to Tom Aarsen, Philipp Schmid and the Hugging Face team for adding this feature to Sentence Transformers! paperetl: GitHub Project:
01/03/2025 - 2850 views - 🧬⚕️🔬 What if we said you can have a competitive 8 million parameter model that can index as fast as BM25? Or a 100K parameter 200KB model that retains knowledge? We're excited to release static PubMedBERT Embeddings models! These are a set of static models distilled with the great Model2Vec library by The Minish Lab Thank you to Stéphan Tulkens and Thomas van Dongen for creating Model2Vec!
A couple themes are shown in the data. Posts covering Graph RAG, Vector Embeddings Innovations and medical literature related models all had high engagement.
Let's plot a subgraph of the nodes related to medical literature.
import matplotlib.pyplot as plt
import networkx as nx
def plot(graph):
labels = {x: f"{graph.attribute(x, 'id')}" for x in graph.scan()}
options = {
"node_size": 700,
"node_color": "#0277bd",
"edge_color": "#454545",
"font_color": "#efefef",
"font_size": 10,
"alpha": 1.0,
}
# Draw graph
fig, ax = plt.subplots(figsize=(20, 9))
pos = nx.spring_layout(graph.backend, seed=0, k=0.9, iterations=50)
nx.draw_networkx(graph.backend, pos=pos, labels=labels, **options)
# Disable axes and draw margins
ax.axis("off")
plt.margins(x=0.15)
# Set background color
ax.set_facecolor("#303030")
fig.set_facecolor("#303030")
plt.show()
plot(embeddings.search("medical literature", 10, graph=True))
. It presented ideas on how to increase future social media engagement by analyzing what's worked in the past. It was very illuminating 💡.
SOCIAL SHARE CARD GENERATOR