Buckets:
| <meta charset="utf-8" /><meta name="hf:doc:metadata" content="{"title":"Information Extraction with Haystack and NuExtract","local":"information-extraction-with-haystack-and-nuextract","sections":[{"title":"Install dependencies","local":"install-dependencies","sections":[],"depth":2},{"title":"Components","local":"components","sections":[{"title":"LinkContentFetcher and HTMLToDocument : extract text from web pages","local":"linkcontentfetcher-and-htmltodocument--extract-text-from-web-pages","sections":[],"depth":3},{"title":"HuggingFaceLocalGenerator : load and try the model","local":"huggingfacelocalgenerator--load-and-try-the-model","sections":[{"title":"Notes on Flash Attention","local":"notes-on-flash-attention","sections":[],"depth":4}],"depth":3},{"title":"PromptBuilder : dynamically create prompts","local":"promptbuilder--dynamically-create-prompts","sections":[],"depth":3},{"title":"OutputAdapter","local":"outputadapter","sections":[],"depth":3}],"depth":2},{"title":"Information Extraction Pipeline","local":"information-extraction-pipeline","sections":[{"title":"Build the Pipeline","local":"build-the-pipeline","sections":[],"depth":3},{"title":"Define the sources and the extraction schema","local":"define-the-sources-and-the-extraction-schema","sections":[],"depth":3},{"title":"Run the Pipeline!","local":"run-the-pipeline","sections":[],"depth":3}],"depth":2},{"title":"Data exploration and visualization","local":"data-exploration-and-visualization","sections":[{"title":"Dataframe","local":"dataframe","sections":[],"depth":3},{"title":"Build a simple graph","local":"build-a-simple-graph","sections":[],"depth":3}],"depth":2},{"title":"Conclusion and ideas","local":"conclusion-and-ideas","sections":[],"depth":2}],"depth":1}"> | |
| <link href="/docs/cookbook/main/en/_app/immutable/assets/0.e3b0c442.css" rel="modulepreload"> | |
| <link rel="modulepreload" href="/docs/cookbook/main/en/_app/immutable/entry/start.96b44205.js"> | |
| <link rel="modulepreload" href="/docs/cookbook/main/en/_app/immutable/chunks/scheduler.65852ee5.js"> | |
| <link rel="modulepreload" href="/docs/cookbook/main/en/_app/immutable/chunks/singletons.a64a46c3.js"> | |
| <link rel="modulepreload" href="/docs/cookbook/main/en/_app/immutable/chunks/paths.f88132ad.js"> | |
| <link rel="modulepreload" href="/docs/cookbook/main/en/_app/immutable/entry/app.e92a3d99.js"> | |
| <link rel="modulepreload" href="/docs/cookbook/main/en/_app/immutable/chunks/index.aa74147d.js"> | |
| <link rel="modulepreload" href="/docs/cookbook/main/en/_app/immutable/nodes/0.0809e592.js"> | |
| <link rel="modulepreload" href="/docs/cookbook/main/en/_app/immutable/chunks/each.e59479a4.js"> | |
| <link rel="modulepreload" href="/docs/cookbook/main/en/_app/immutable/nodes/26.4ee0f5a8.js"> | |
| <link rel="modulepreload" href="/docs/cookbook/main/en/_app/immutable/chunks/DocNotebookDropdown.479f4286.js"> | |
| <link rel="modulepreload" href="/docs/cookbook/main/en/_app/immutable/chunks/EditOnGithub.4eda6a96.js"><!-- HEAD_svelte-u9bgzb_START --><meta name="hf:doc:metadata" content="{"title":"Information Extraction with Haystack and NuExtract","local":"information-extraction-with-haystack-and-nuextract","sections":[{"title":"Install dependencies","local":"install-dependencies","sections":[],"depth":2},{"title":"Components","local":"components","sections":[{"title":"LinkContentFetcher and HTMLToDocument : extract text from web pages","local":"linkcontentfetcher-and-htmltodocument--extract-text-from-web-pages","sections":[],"depth":3},{"title":"HuggingFaceLocalGenerator : load and try the model","local":"huggingfacelocalgenerator--load-and-try-the-model","sections":[{"title":"Notes on Flash Attention","local":"notes-on-flash-attention","sections":[],"depth":4}],"depth":3},{"title":"PromptBuilder : dynamically create prompts","local":"promptbuilder--dynamically-create-prompts","sections":[],"depth":3},{"title":"OutputAdapter","local":"outputadapter","sections":[],"depth":3}],"depth":2},{"title":"Information Extraction Pipeline","local":"information-extraction-pipeline","sections":[{"title":"Build the Pipeline","local":"build-the-pipeline","sections":[],"depth":3},{"title":"Define the sources and the extraction schema","local":"define-the-sources-and-the-extraction-schema","sections":[],"depth":3},{"title":"Run the Pipeline!","local":"run-the-pipeline","sections":[],"depth":3}],"depth":2},{"title":"Data exploration and visualization","local":"data-exploration-and-visualization","sections":[{"title":"Dataframe","local":"dataframe","sections":[],"depth":3},{"title":"Build a simple graph","local":"build-a-simple-graph","sections":[],"depth":3}],"depth":2},{"title":"Conclusion and ideas","local":"conclusion-and-ideas","sections":[],"depth":2}],"depth":1}"><!-- HEAD_svelte-u9bgzb_END --> <p></p> <div class="flex space-x-1 absolute z-10 right-0 top-0"> <a href="https://colab.research.google.com/github/huggingface/cookbook/blob/multiagent_assist_improvements/notebooks/en/information_extraction_haystack_nuextract.ipynb" target="_blank"><img alt="Open In Colab" class="!m-0" src="https://colab.research.google.com/assets/colab-badge.svg"></a> </div> <h1 class="relative group"><a id="information-extraction-with-haystack-and-nuextract" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#information-extraction-with-haystack-and-nuextract"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Information Extraction with Haystack and NuExtract</span></h1> <p data-svelte-h="svelte-rkb7ro"><em>Authored by: <a href="https://github.com/anakin87" rel="nofollow">Stefano Fiorucci</a></em></p> <p data-svelte-h="svelte-104h6o6">In this notebook, we will see how to automate Information Extraction from textual data using Language Models.</p> <p data-svelte-h="svelte-oe15xo">🎯 Goal: create an application to extract specific information from a given text or URL, following a user-defined structure.</p> <p data-svelte-h="svelte-6mdv8h">🧰 <strong>Stack</strong></p> <ul data-svelte-h="svelte-17btve3"><li><p><a href="https://haystack.deepset.ai?utm_campaign=developer-relations&utm_source=hf-cookbook" rel="nofollow">Haystack 🏗️</a>: a customizable orchestration framework for building LLM applications. We will use Haystack to build the Information Extraction Pipeline.</p></li> <li><p><a href="https://huggingface.co/numind/NuExtract" rel="nofollow">NuExtract</a>: a small Language Model, specifically fine-tuned for structured data extraction.</p></li></ul> <h2 class="relative group"><a id="install-dependencies" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#install-dependencies"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Install dependencies</span></h2> <div class="code-block relative"><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->! pip install haystack-ai trafilatura transformers pyvis<!-- HTML_TAG_END --></pre></div> <h2 class="relative group"><a id="components" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#components"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Components</span></h2> <p data-svelte-h="svelte-1vopozu">Haystack has two main concepts: <a href="https://docs.haystack.deepset.ai/docs/components_overview?utm_campaign=developer-relations&utm_source=hf-cookbook" rel="nofollow">Components and Pipelines</a>.</p> <p data-svelte-h="svelte-gdgnsl">🧩 <strong>Components</strong> are building blocks that perform a single task: file conversion, text generation, embedding creation…</p> <p data-svelte-h="svelte-1xpf1o9">➿ <strong>Pipelines</strong> allow you to define the flow of data through your LLM application, by combining Components in a directed (cyclic) graph.</p> <p data-svelte-h="svelte-8ewd03"><em>We will now introduce the various components of our Information Extraction application. Afterwards, we will integrate them into a Pipeline.</em></p> <h3 class="relative group"><a id="linkcontentfetcher-and-htmltodocument--extract-text-from-web-pages" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#linkcontentfetcher-and-htmltodocument--extract-text-from-web-pages"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>LinkContentFetcher and HTMLToDocument : extract text from web pages</span></h3> <p data-svelte-h="svelte-1uowp1d">In our experiment, we will extract data from startup funding announcements found on the web.</p> <p data-svelte-h="svelte-1vdo8il">To download web pages and extract text, we use two components:</p> <ul data-svelte-h="svelte-1s9hsvv"><li><a href="https://docs.haystack.deepset.ai/docs/linkcontentfetcher?utm_campaign=developer-relations&utm_source=hf-cookbook" rel="nofollow"><code>LinkContentFetcher</code></a>: fetches the content of some URLs and returns a list of content streams (as <a href="https://docs.haystack.deepset.ai/docs/data-classes#bytestream?utm_campaign=developer-relations&utm_source=hf-cookbook" rel="nofollow"><code>ByteStream</code> objects</a>).</li> <li><a href="https://docs.haystack.deepset.ai/docs/htmltodocument?utm_campaign=developer-relations&utm_source=hf-cookbook" rel="nofollow"><code>HTMLToDocument</code></a>: converts HTML sources into textual <a href="https://docs.haystack.deepset.ai/docs/data-classes#document?utm_campaign=developer-relations&utm_source=hf-cookbook" rel="nofollow"><code>Documents</code></a>.</li></ul> <div class="code-block relative"><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-meta">>>> </span><span class="hljs-keyword">from</span> haystack.components.fetchers <span class="hljs-keyword">import</span> LinkContentFetcher | |
| <span class="hljs-meta">>>> </span><span class="hljs-keyword">from</span> haystack.components.converters <span class="hljs-keyword">import</span> HTMLToDocument | |
| <span class="hljs-meta">>>> </span>fetcher = LinkContentFetcher() | |
| <span class="hljs-meta">>>> </span>streams = fetcher.run(urls=[<span class="hljs-string">"https://example.com/"</span>])[<span class="hljs-string">"streams"</span>] | |
| <span class="hljs-meta">>>> </span>converter = HTMLToDocument() | |
| <span class="hljs-meta">>>> </span>docs = converter.run(sources=streams) | |
| <span class="hljs-meta">>>> </span><span class="hljs-built_in">print</span>(docs)<!-- HTML_TAG_END --></pre></div> <pre data-svelte-h="svelte-k03ckz">&#123;'documents': [Document(id=65bb1ce4b6db2f154d3acfa145fa03363ef93f751fb8599dcec3aaf75aa325b9, content: 'This domain is for use in illustrative examples in documents. You may use this domain in literature ...', meta: &#123;'content_type': 'text/html', 'url': 'https://example.com/'})]} | |
| </pre> <h3 class="relative group"><a id="huggingfacelocalgenerator--load-and-try-the-model" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#huggingfacelocalgenerator--load-and-try-the-model"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>HuggingFaceLocalGenerator : load and try the model</span></h3> <p data-svelte-h="svelte-1i3hvwr">We use the <a href="https://docs.haystack.deepset.ai/docs/huggingfacelocalgenerator?utm_campaign=developer-relations&utm_source=hf-cookbook" rel="nofollow"><code>HuggingFaceLocalGenerator</code></a>, a text generation component that allows loading a model hosted on Hugging Face using the Transformers library.</p> <p data-svelte-h="svelte-reuftc">Haystack supports many other <a href="https://docs.haystack.deepset.ai/docs/generators?utm_campaign=developer-relations&utm_source=hf-cookbook" rel="nofollow">Generators</a>, including <a href="https://docs.haystack.deepset.ai/docs/huggingfaceapigenerator?utm_campaign=developer-relations&utm_source=hf-cookbook" rel="nofollow"><code>HuggingFaceAPIGenerator</code></a> (compatible with Hugging Face APIs and TGI).</p> <p data-svelte-h="svelte-31med3">We load <a href="https://huggingface.co/numind/NuExtract" rel="nofollow">NuExtract</a>, a model fine-tuned from <code>microsoft/Phi-3-mini-4k-instruct</code> to perform structured data extraction from text. The model size is 3.8B parameters. Other variants are also available: <code>NuExtract-tiny</code> (0.5B) and <code>NuExtract-large</code> (7B).</p> <p data-svelte-h="svelte-omf6q3">The model is loaded with <code>bfloat16</code> precision to fit in Colab with negligible performance loss compared to FP32, as suggested in the model card.</p> <h4 class="relative group"><a id="notes-on-flash-attention" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#notes-on-flash-attention"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Notes on Flash Attention</span></h4> <p data-svelte-h="svelte-14yr3cm">At inference time, you will probably see a warning saying: “You are not running the flash-attention implementation”.</p> <p data-svelte-h="svelte-16u8dhj">GPUs available on free environments like Colab or Kaggle do not support it, so we decided to not use it in this notebook.</p> <p data-svelte-h="svelte-bs7dzw">In case your GPU architecture supports it (<a href="https://github.com/Dao-AILab/flash-attention" rel="nofollow">details</a>), you can install it and get a speed-up as follows:</p> <div class="code-block relative"><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->pip install flash-attn --no-build-isolation<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1uramho">Then add <code>"attn_implementation": "flash_attention_2"</code> to <code>model_kwargs</code>.</p> <div class="code-block relative"><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> haystack.components.generators <span class="hljs-keyword">import</span> HuggingFaceLocalGenerator | |
| <span class="hljs-keyword">import</span> torch | |
| generator = HuggingFaceLocalGenerator( | |
| model=<span class="hljs-string">"numind/NuExtract"</span>, huggingface_pipeline_kwargs={<span class="hljs-string">"model_kwargs"</span>: {<span class="hljs-string">"torch_dtype"</span>: torch.bfloat16}} | |
| ) | |
| <span class="hljs-comment"># effectively load the model (warm_up is automatically invoked when the generator is part of a Pipeline)</span> | |
| generator.warm_up()<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1l2ntjq">The model supports a specific prompt structure, as can be inferred from the model card.</p> <p data-svelte-h="svelte-7hrtkf">Let’s manually create a prompt to try the model. Later, we will see how to dynamically create the prompt based on different inputs.</p> <div class="code-block relative"><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-meta">>>> </span>prompt = <span class="hljs-string">"""<|input|>\n### Template: | |
| <span class="hljs-meta">... </span>{ | |
| <span class="hljs-meta">... </span> "Car": { | |
| <span class="hljs-meta">... </span> "Name": "", | |
| <span class="hljs-meta">... </span> "Manufacturer": "", | |
| <span class="hljs-meta">... </span> "Designers": [], | |
| <span class="hljs-meta">... </span> "Number of units produced": "", | |
| <span class="hljs-meta">... </span> } | |
| <span class="hljs-meta">... </span>} | |
| <span class="hljs-meta">... </span>### Text: | |
| <span class="hljs-meta">... </span>The Fiat Panda is a city car manufactured and marketed by Fiat since 1980, currently in its third generation. The first generation Panda, introduced in 1980, was a two-box, three-door hatchback designed by Giorgetto Giugiaro and Aldo Mantovani of Italdesign and was manufactured through 2003 — receiving an all-wheel drive variant in 1983. SEAT of Spain marketed a variation of the first generation Panda under license to Fiat, initially as the Panda and subsequently as the Marbella (1986–1998). | |
| <span class="hljs-meta">... </span>The second-generation Panda, launched in 2003 as a 5-door hatchback, was designed by Giuliano Biasio of Bertone, and won the European Car of the Year in 2004. The third-generation Panda debuted at the Frankfurt Motor Show in September 2011, was designed at Fiat Centro Stilo under the direction of Roberto Giolito and remains in production in Italy at Pomigliano d'Arco.[1] The fourth-generation Panda is marketed as Grande Panda, to differentiate it with the third-generation that is sold alongside it. Developed under Stellantis, the Grande Panda is produced in Serbia. | |
| <span class="hljs-meta">... </span>In 40 years, Panda production has reached over 7.8 million,[2] of those, approximately 4.5 million were the first generation.[3] In early 2020, its 23-year production was counted as the twenty-ninth most long-lived single generation car in history by Autocar.[4] During its initial design phase, Italdesign referred to the car as il Zero. Fiat later proposed the name Rustica. Ultimately, the Panda was named after Empanda, the Roman goddess and patroness of travelers. | |
| <span class="hljs-meta">... </span><|output|> | |
| <span class="hljs-meta">... </span>"""</span> | |
| <span class="hljs-meta">>>> </span>result = generator.run(prompt=prompt) | |
| <span class="hljs-meta">>>> </span><span class="hljs-built_in">print</span>(result)<!-- HTML_TAG_END --></pre></div> <pre data-svelte-h="svelte-1u05zs1">&#123;'replies': ['&#123;\n "Car": &#123;\n "Name": "Fiat Panda",\n "Manufacturer": "Fiat",\n "Designers": [\n "Giorgetto Giugiaro",\n "Aldo Mantovani",\n "Giuliano Biasio",\n "Roberto Giolito"\n ],\n "Number of units produced": "over 7.8 million"\n }\n}\n']} | |
| </pre> <p data-svelte-h="svelte-p43l1y">Nice ✅</p> <h3 class="relative group"><a id="promptbuilder--dynamically-create-prompts" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#promptbuilder--dynamically-create-prompts"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>PromptBuilder : dynamically create prompts</span></h3> <p data-svelte-h="svelte-g9okh1">The <a href="https://docs.haystack.deepset.ai/docs/promptbuilder?utm_campaign=developer-relations&utm_source=hf-cookbook" rel="nofollow"><code>PromptBuilder</code></a> is initialized with a Jinja2 prompt template and renders it by filling in parameters passed through keyword arguments.</p> <p data-svelte-h="svelte-14eqp9s">Our prompt template reproduces the structure shown in <a href="https://huggingface.co/numind/NuExtract" rel="nofollow">model card</a>.</p> <p data-svelte-h="svelte-s2v4vp">During our experiments, we discovered that indenting the schema is particularly important to ensure good results. This probably stems from how the model was trained.</p> <div class="code-block relative"><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> haystack.components.builders <span class="hljs-keyword">import</span> PromptBuilder | |
| <span class="hljs-keyword">from</span> haystack <span class="hljs-keyword">import</span> Document | |
| prompt_template = <span class="hljs-string">"""<|input|> | |
| ### Template: | |
| {{ schema | tojson(indent=4) }} | |
| {% for example in examples %} | |
| ### Example: | |
| {{ example | tojson(indent=4) }}\n | |
| {% endfor %} | |
| ### Text | |
| {{documents[0].content}} | |
| <|output|> | |
| """</span> | |
| prompt_builder = PromptBuilder(template=prompt_template)<!-- HTML_TAG_END --></pre></div> <div class="code-block relative"><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-meta">>>> </span>example_document = Document(content=<span class="hljs-string">"The Fiat Panda is a city car..."</span>) | |
| <span class="hljs-meta">>>> </span>example_schema = { | |
| <span class="hljs-meta">... </span> <span class="hljs-string">"Car"</span>: { | |
| <span class="hljs-meta">... </span> <span class="hljs-string">"Name"</span>: <span class="hljs-string">""</span>, | |
| <span class="hljs-meta">... </span> <span class="hljs-string">"Manufacturer"</span>: <span class="hljs-string">""</span>, | |
| <span class="hljs-meta">... </span> <span class="hljs-string">"Designers"</span>: [], | |
| <span class="hljs-meta">... </span> <span class="hljs-string">"Number of units produced"</span>: <span class="hljs-string">""</span>, | |
| <span class="hljs-meta">... </span> } | |
| <span class="hljs-meta">... </span>} | |
| <span class="hljs-meta">>>> </span>prompt = prompt_builder.run(documents=[example_document], schema=example_schema)[<span class="hljs-string">"prompt"</span>] | |
| <span class="hljs-meta">>>> </span><span class="hljs-built_in">print</span>(prompt)<!-- HTML_TAG_END --></pre></div> <pre data-svelte-h="svelte-14cse3c"><|input|> | |
| ### Template: | |
| &#123; | |
| "Car": &#123; | |
| "Designers": [], | |
| "Manufacturer": "", | |
| "Name": "", | |
| "Number of units produced": "" | |
| } | |
| } | |
| ### Text | |
| The Fiat Panda is a city car... | |
| <|output|> | |
| </pre> <p data-svelte-h="svelte-jlrrrr">Works well ✅</p> <h3 class="relative group"><a id="outputadapter" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#outputadapter"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>OutputAdapter</span></h3> <p data-svelte-h="svelte-1jqdrzm">You may have noticed that the result of the extraction is the first element of the <code>replies</code> list and consists of a JSON string.</p> <p data-svelte-h="svelte-19ficfy">We would like to have a dictionary for each source document. | |
| To perform this transformation in a pipeline, we can use the <a href="https://docs.haystack.deepset.ai/docs/outputadapter?utm_campaign=developer-relations&utm_source=hf-cookbook" rel="nofollow"><code>OutputAdapter</code></a>.</p> <div class="code-block relative"><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-meta">>>> </span><span class="hljs-keyword">import</span> json | |
| <span class="hljs-meta">>>> </span><span class="hljs-keyword">from</span> haystack.components.converters <span class="hljs-keyword">import</span> OutputAdapter | |
| <span class="hljs-meta">>>> </span>adapter = OutputAdapter( | |
| <span class="hljs-meta">... </span> template=<span class="hljs-string">"""{{ replies[0]| replace("'",'"') | json_loads}}"""</span>, | |
| <span class="hljs-meta">... </span> output_type=<span class="hljs-built_in">dict</span>, | |
| <span class="hljs-meta">... </span> custom_filters={<span class="hljs-string">"json_loads"</span>: json.loads}, | |
| <span class="hljs-meta">... </span>) | |
| <span class="hljs-meta">... </span><span class="hljs-built_in">print</span>(adapter.run(**result))<!-- HTML_TAG_END --></pre></div> <pre data-svelte-h="svelte-e5elmm">&#123;'output': &#123;'Car': &#123;'Name': 'Fiat Panda', 'Manufacturer': 'Fiat', 'Designers': ['Giorgetto Giugiaro', 'Aldo Mantovani', 'Giuliano Biasio', 'Roberto Giolito'], 'Number of units produced': 'over 7.8 million'}}} | |
| </pre> <h2 class="relative group"><a id="information-extraction-pipeline" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#information-extraction-pipeline"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Information Extraction Pipeline</span></h2> <h3 class="relative group"><a id="build-the-pipeline" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#build-the-pipeline"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Build the Pipeline</span></h3> <p data-svelte-h="svelte-9r88s4">We can now <a href="https://docs.haystack.deepset.ai/docs/creating-pipelines?utm_campaign=developer-relations&utm_source=hf-cookbook" rel="nofollow">create our Pipeline</a> by adding and connecting the individual components.</p> <div class="code-block relative"><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> haystack <span class="hljs-keyword">import</span> Pipeline | |
| ie_pipe = Pipeline() | |
| ie_pipe.add_component(<span class="hljs-string">"fetcher"</span>, fetcher) | |
| ie_pipe.add_component(<span class="hljs-string">"converter"</span>, converter) | |
| ie_pipe.add_component(<span class="hljs-string">"prompt_builder"</span>, prompt_builder) | |
| ie_pipe.add_component(<span class="hljs-string">"generator"</span>, generator) | |
| ie_pipe.add_component(<span class="hljs-string">"adapter"</span>, adapter) | |
| ie_pipe.connect(<span class="hljs-string">"fetcher"</span>, <span class="hljs-string">"converter"</span>) | |
| ie_pipe.connect(<span class="hljs-string">"converter"</span>, <span class="hljs-string">"prompt_builder"</span>) | |
| ie_pipe.connect(<span class="hljs-string">"prompt_builder"</span>, <span class="hljs-string">"generator"</span>) | |
| ie_pipe.connect(<span class="hljs-string">"generator"</span>, <span class="hljs-string">"adapter"</span>)<!-- HTML_TAG_END --></pre></div> <div class="code-block relative"><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-comment"># IN CASE YOU NEED TO RECREATE THE PIPELINE FROM SCRATCH, YOU CAN UNCOMMENT THIS CELL</span> | |
| <span class="hljs-comment"># ie_pipe = Pipeline()</span> | |
| <span class="hljs-comment"># ie_pipe.add_component("fetcher", LinkContentFetcher())</span> | |
| <span class="hljs-comment"># ie_pipe.add_component("converter", HTMLToDocument())</span> | |
| <span class="hljs-comment"># ie_pipe.add_component("prompt_builder", PromptBuilder(template=prompt_template))</span> | |
| <span class="hljs-comment"># ie_pipe.add_component("generator", HuggingFaceLocalGenerator(model="numind/NuExtract",</span> | |
| <span class="hljs-comment"># huggingface_pipeline_kwargs={"model_kwargs": {"torch_dtype":torch.bfloat16}})</span> | |
| <span class="hljs-comment"># )</span> | |
| <span class="hljs-comment"># ie_pipe.add_component("adapter", OutputAdapter(template="""{{ replies[0]| replace("'",'"') | json_loads}}""",</span> | |
| <span class="hljs-comment"># output_type=dict,</span> | |
| <span class="hljs-comment"># custom_filters={"json_loads": json.loads}))</span> | |
| <span class="hljs-comment"># ie_pipe.connect("fetcher", "converter")</span> | |
| <span class="hljs-comment"># ie_pipe.connect("converter", "prompt_builder")</span> | |
| <span class="hljs-comment"># ie_pipe.connect("prompt_builder", "generator")</span> | |
| <span class="hljs-comment"># ie_pipe.connect("generator", "adapter")</span><!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1k707m6">Let’s review our pipeline setup:</p> <div class="code-block relative"><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-meta">>>> </span>ie_pipe.show()<!-- HTML_TAG_END --></pre></div> <img src="data:image/jpeg;base64,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lczQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUV3HwhvrbTPibpl/eSeXa2sV1NM+0nai20pY4HJwAelfW765p0dxp0DXGJdRRntV2N+8CrvY9OPl55xQB8bXv8AyT/Tf+vk/wA5K5mvsfVviRpr+FrrVfDk63skSxOjSW0ohKvKiEbiFG4B/u5yO4revfFuiadrMekXN7i+k2YiSF327zhdxVSFyem4jNAHw1RXQeO/+Sh+Jf8AsK3X/o1q5+gAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKK94+Cnw78K+LvBt5f65pX2u6j1B4Vf7RLHhBHGQMIwHVj+dAHmHw8sJ9V8Xrp1qoa4urC/giBOMs1pMo/U19FW1zear4i8F7NE1a3j0+2uEupbm0eNI3MAULkjnkdeh4wTW5onwt8G+HNYg1bSdG+z30G7y5ftUz7dylTwzkHgkciuwoA8vj0PUj+z/aaXFp041CO0hc2hj2SFllV2G04+bAPHrUuvXN4viC31bw1pevQazdpaiVXsz9kuYieVnJ4jdFZuflI6c16Xjnr+FFAHxB47/5KH4l/7Ct1/wCjWrn6+x7/AOEHgTU9Rub+80LzLq6leaZ/tc43OxJY4D4GST0rwD41+FtG8I+MrOw0Oz+yWsmnpMyea8mXMkgJy5J6KPyoA83ooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK96+CN1cNo2jabBPLEsuu3VzOI3K744rWMbTjqu+SPg+grwWvX/hXrnw/wBO8MyR+KtQubTUo72VoDbyXcbCJ0iB5gwOTH0P90UAe5arqGqJ43khsh9pSz0SW6js1Zk82dn2orHdtIOxgMrkc881iS+INe1rTdFgs9VsoNQvNWEMwSxljMCxRmWSORGkDAgptPI3BhjGaoD4i/CYRzp/bc5M9vFbSSFb0yGOMsUG/G4EFmOQcnPJNQt46+DzW1tB/asii3na4jlR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febAGfyApt1dQWVrLdXMqxQRKXd26KB1NebXnh1bGbQbO3srrVHtzzb3Ng32XZNLudlb7sLxjOAScKAozXU+MBJNJ4fswCYLnV4hOOxVFeUA+xaNaAJPEcmgSx6QdcjZxcXkUVpA5Zd0rn5QyZAOMZwwOMetbotoRdNciNfPZBGZMc7QScfTJNeZeLrHxDrcuqaxBpAlg07bHp0ckkiT7opVkeVIvLO4uyKq/MMqvH3qm1bQZNVbWtRbS5zfXOtWkVlI0Lb4Ik8lWlXjKjiQlh2HXFAHplQWl5BepI8D7hHK8L8YKupII/MfiMHvXnen2k934xuPDUkLrY2Gpy6xMxHyyK+HhUHv+8aRj/1yro/A6yS2Gp6i+fK1HU57q3z3iyERvowTcPZqAOoooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAOU+JX/JO9c/69JP/QTXx5X2H8Sv+Sd65/16Sf8AoJr48oAKKKKACtPw5/yNGkf9fsP/AKGKzK0/Dn/I0aR/1+w/+higD7Usf+PC2/65L/IVPUFj/wAeFt/1yX+QqegAooooAKKKKACiiigApk0STwSQyAlJFKsASMgjB5FPooAhtLWCxs4LS2jEcEEaxRoCTtVRgDn2FTUUUAFRzQRXCqs0auFdXXI6MDkH86kooAKKKKAMyz8P6XYQXkVvagLeMWuS7s7SkjHzMxJIxxjPHatJEWNFRFCqowFAwAPSlooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDlPiV/yTvXP+vST/0E18eV9h/Er/kneuf9ekn/AKCa+PKACiiigArT8Of8jRpH/X7D/wChisyigD7btNVsEsoFa7iDLGoILdDipv7X07/n8h/76r4eooA+4f7X07/n8h/76o/tfTv+fyH/AL6r4eooA+4f7X07/n8h/wC+qP7X07/n8h/76r4eooA+4f7X07/n8h/76o/tfTv+fyH/AL6r4eooA+4f7X07/n8h/wC+qP7X07/n8h/76r4eooA+4f7X07/n8h/76o/tfTv+fyH/AL6r4eooA+4f7X07/n8h/wC+qP7X07/n8h/76r4eooA+4f7X07/n8h/76o/tfTv+fyH/AL6r4eooA+4f7X07/n8h/wC+qP7X07/n8h/76r4e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"> <h3 class="relative group"><a id="define-the-sources-and-the-extraction-schema" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#define-the-sources-and-the-extraction-schema"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Define the sources and the extraction schema</span></h3> <p data-svelte-h="svelte-1afh9r">We select a list of URLs related to recent startup funding announcements.</p> <p data-svelte-h="svelte-37es2j">Additionally, we define a schema for the structured information we aim to extract.</p> <div class="code-block relative"><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->urls = [ | |
| <span class="hljs-string">"https://techcrunch.com/2023/04/27/pinecone-drops-100m-investment-on-750m-valuation-as-vector-database-demand-grows/"</span>, | |
| <span class="hljs-string">"https://techcrunch.com/2023/04/27/replit-funding-100m-generative-ai/"</span>, | |
| <span class="hljs-string">"https://www.cnbc.com/2024/06/12/mistral-ai-raises-645-million-at-a-6-billion-valuation.html"</span>, | |
| <span class="hljs-string">"https://techcrunch.com/2024/01/23/qdrant-open-source-vector-database/"</span>, | |
| <span class="hljs-string">"https://www.intelcapital.com/anyscale-secures-100m-series-c-at-1b-valuation-to-radically-simplify-scaling-and-productionizing-ai-applications/"</span>, | |
| <span class="hljs-string">"https://techcrunch.com/2023/04/28/openai-funding-valuation-chatgpt/"</span>, | |
| <span class="hljs-string">"https://techcrunch.com/2024/03/27/amazon-doubles-down-on-anthropic-completing-its-planned-4b-investment/"</span>, | |
| <span class="hljs-string">"https://techcrunch.com/2024/01/22/voice-cloning-startup-elevenlabs-lands-80m-achieves-unicorn-status/"</span>, | |
| <span class="hljs-string">"https://techcrunch.com/2023/08/24/hugging-face-raises-235m-from-investors-including-salesforce-and-nvidia"</span>, | |
| <span class="hljs-string">"https://www.prnewswire.com/news-releases/ai21-completes-208-million-oversubscribed-series-c-round-301994393.html"</span>, | |
| <span class="hljs-string">"https://techcrunch.com/2023/03/15/adept-a-startup-training-ai-to-use-existing-software-and-apis-raises-350m/"</span>, | |
| <span class="hljs-string">"https://www.cnbc.com/2023/03/23/characterai-valued-at-1-billion-after-150-million-round-from-a16z.html"</span>, | |
| ] | |
| schema = { | |
| <span class="hljs-string">"Funding"</span>: { | |
| <span class="hljs-string">"New funding"</span>: <span class="hljs-string">""</span>, | |
| <span class="hljs-string">"Investors"</span>: [], | |
| }, | |
| <span class="hljs-string">"Company"</span>: {<span class="hljs-string">"Name"</span>: <span class="hljs-string">""</span>, <span class="hljs-string">"Activity"</span>: <span class="hljs-string">""</span>, <span class="hljs-string">"Country"</span>: <span class="hljs-string">""</span>, <span class="hljs-string">"Total valuation"</span>: <span class="hljs-string">""</span>, <span class="hljs-string">"Total funding"</span>: <span class="hljs-string">""</span>}, | |
| }<!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="run-the-pipeline" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#run-the-pipeline"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Run the Pipeline!</span></h3> <p data-svelte-h="svelte-edorr6">We pass the required data to each component.</p> <p data-svelte-h="svelte-gvee3z">Note that most of them receive data from previously executed components.</p> <div class="code-block relative"><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> tqdm <span class="hljs-keyword">import</span> tqdm | |
| extracted_data = [] | |
| <span class="hljs-keyword">for</span> url <span class="hljs-keyword">in</span> tqdm(urls): | |
| result = ie_pipe.run({<span class="hljs-string">"fetcher"</span>: {<span class="hljs-string">"urls"</span>: [url]}, <span class="hljs-string">"prompt_builder"</span>: {<span class="hljs-string">"schema"</span>: schema}}) | |
| extracted_data.append(result[<span class="hljs-string">"adapter"</span>][<span class="hljs-string">"output"</span>])<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-qeorgn">Let’s inspect some of the extracted data</p> <div class="code-block relative"><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->extracted_data[:<span class="hljs-number">2</span>]<!-- HTML_TAG_END --></pre></div> <h2 class="relative group"><a id="data-exploration-and-visualization" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#data-exploration-and-visualization"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Data exploration and visualization</span></h2> <p data-svelte-h="svelte-dgdmgy">Let’s explore the extracted data to assess its correctness and gain insights.</p> <h3 class="relative group"><a id="dataframe" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#dataframe"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Dataframe</span></h3> <p data-svelte-h="svelte-1p0vl1g">We start by creating a Pandas Dataframe. For simplicity, we flatten the extracted data.</p> <div class="code-block relative"><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">def</span> <span class="hljs-title function_">flatten_dict</span>(<span class="hljs-params">d, parent_key=<span class="hljs-string">""</span></span>): | |
| items = [] | |
| <span class="hljs-keyword">for</span> k, v <span class="hljs-keyword">in</span> d.items(): | |
| new_key = <span class="hljs-string">f"<span class="hljs-subst">{parent_key}</span> - <span class="hljs-subst">{k}</span>"</span> <span class="hljs-keyword">if</span> parent_key <span class="hljs-keyword">else</span> k | |
| <span class="hljs-keyword">if</span> <span class="hljs-built_in">isinstance</span>(v, <span class="hljs-built_in">dict</span>): | |
| items.extend(flatten_dict(v, new_key).items()) | |
| <span class="hljs-keyword">elif</span> <span class="hljs-built_in">isinstance</span>(v, <span class="hljs-built_in">list</span>): | |
| items.append((new_key, <span class="hljs-string">", "</span>.join(v))) | |
| <span class="hljs-keyword">else</span>: | |
| items.append((new_key, v)) | |
| <span class="hljs-keyword">return</span> <span class="hljs-built_in">dict</span>(items)<!-- HTML_TAG_END --></pre></div> <div class="code-block relative"><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">import</span> pandas <span class="hljs-keyword">as</span> pd | |
| df = pd.DataFrame([flatten_dict(el) <span class="hljs-keyword">for</span> el <span class="hljs-keyword">in</span> extracted_data]) | |
| df = df.sort_values(by=<span class="hljs-string">"Company - Name"</span>) | |
| df<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-uwqcg7"><img src="https://huggingface.co/datasets/huggingface/cookbook-images/resolve/main/haystack_dataframe.png" alt="dataframe"></p> <p data-svelte-h="svelte-1wtey9">Apart from some errors in “Company - Country”, the extracted data looks good.</p> <h3 class="relative group"><a id="build-a-simple-graph" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#build-a-simple-graph"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Build a simple graph</span></h3> <p data-svelte-h="svelte-jkza22">To understand the relationships between companies and investors, we construct a graph and visualize it.</p> <p data-svelte-h="svelte-14n1be1">First, we build a graph using NetworkX.</p> <p data-svelte-h="svelte-j3yza3"><a href="https://networkx.org/" rel="nofollow">NetworkX</a> is a Python package that allows to create and manipulate networks/graphs in a simple way.</p> <p data-svelte-h="svelte-1enu4ba">Our simple graph will have companies and investors as nodes. We will connect investors to companies if they are mentioned in the same document.</p> <div class="code-block relative"><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">import</span> networkx <span class="hljs-keyword">as</span> nx | |
| <span class="hljs-comment"># Create a new graph</span> | |
| G = nx.Graph() | |
| <span class="hljs-comment"># Add nodes and edges</span> | |
| <span class="hljs-keyword">for</span> el <span class="hljs-keyword">in</span> extracted_data: | |
| company_name = el[<span class="hljs-string">"Company"</span>][<span class="hljs-string">"Name"</span>] | |
| G.add_node(company_name, label=company_name, title=<span class="hljs-string">"Company"</span>) | |
| investors = el[<span class="hljs-string">"Funding"</span>][<span class="hljs-string">"Investors"</span>] | |
| <span class="hljs-keyword">for</span> investor <span class="hljs-keyword">in</span> investors: | |
| <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> G.has_node(investor): | |
| G.add_node(investor, label=investor, title=<span class="hljs-string">"Investor"</span>, color=<span class="hljs-string">"red"</span>) | |
| G.add_edge(company_name, investor)<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-91i8zd">Next, we use Pyvis to visualize the graph.</p> <p data-svelte-h="svelte-1qj01og"><a href="https://pyvis.readthedocs.io/en/latest/" rel="nofollow">Pyvis</a> is a Python package for interactive visualization of networks/graphs. It integrates nicely with NetworkX.</p> <div class="code-block relative"><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> pyvis.network <span class="hljs-keyword">import</span> Network | |
| <span class="hljs-keyword">from</span> IPython.display <span class="hljs-keyword">import</span> display, HTML | |
| net = Network(notebook=<span class="hljs-literal">True</span>, cdn_resources=<span class="hljs-string">"in_line"</span>) | |
| net.from_nx(G) | |
| net.show(<span class="hljs-string">"simple_graph.html"</span>) | |
| display(HTML(<span class="hljs-string">"simple_graph.html"</span>))<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-3t44yz"><img src="https://huggingface.co/datasets/huggingface/cookbook-images/resolve/main/haystack_graph.png" alt="graph visualization"></p> <p data-svelte-h="svelte-15k62qv">Looks like Andreessen Horowitz is quite present in the selected funding announcements 😊</p> <h2 class="relative group"><a id="conclusion-and-ideas" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#conclusion-and-ideas"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Conclusion and ideas</span></h2> <p data-svelte-h="svelte-1b9o2wt">In this notebook, we demonstrated how to set up an information extraction system using a small language model (NuExtract) and Haystack, a customizable orchestration framework for LLM applications.</p> <p data-svelte-h="svelte-1thq36n">How can we use the extracted data?</p> <p data-svelte-h="svelte-g53aii">Some ideas:</p> <ul data-svelte-h="svelte-xq94wl"><li>The extracted data can be added to the original documents stored in a <a href="https://docs.haystack.deepset.ai/docs/document-store?utm_campaign=developer-relations&utm_source=hf-cookbook" rel="nofollow">Document Store</a>. This allows for advanced search capabilities with <a href="https://docs.haystack.deepset.ai/docs/metadata-filtering?utm_campaign=developer-relations&utm_source=hf-cookbook" rel="nofollow">metadata filtering</a>.</li> <li>Expanding on the previous idea, you can do RAG (Retrieval Agumented Extraction) with metadata extraction from the query, as explained in <a href="https://haystack.deepset.ai/blog/extracting-metadata-filter?utm_campaign=developer-relations&utm_source=hf-cookbook" rel="nofollow">this blog post</a>.</li> <li>Store the documents and extracted data in a Knowledge Graph and perform Graph RAG (<a href="https://prosto.github.io/neo4j-haystack" rel="nofollow">Neo4j-Haystack integration</a>).</li></ul> <a class="!text-gray-400 !no-underline text-sm flex items-center not-prose mt-4" href="https://github.com/huggingface/cookbook/blob/main/notebooks/en/information_extraction_haystack_nuextract.md" target="_blank"><span data-svelte-h="svelte-1kd6by1"><</span> <span data-svelte-h="svelte-x0xyl0">></span> <span data-svelte-h="svelte-1dajgef"><span class="underline ml-1.5">Update</span> on GitHub</span></a> <p></p> | |
| <script> | |
| { | |
| __sveltekit_1l2350x = { | |
| assets: "/docs/cookbook/main/en", | |
| base: "/docs/cookbook/main/en", | |
| env: {} | |
| }; | |
| const element = document.currentScript.parentElement; | |
| const data = [null,null]; | |
| Promise.all([ | |
| import("/docs/cookbook/main/en/_app/immutable/entry/start.96b44205.js"), | |
| import("/docs/cookbook/main/en/_app/immutable/entry/app.e92a3d99.js") | |
| ]).then(([kit, app]) => { | |
| kit.start(app, element, { | |
| node_ids: [0, 26], | |
| data, | |
| form: null, | |
| error: null | |
| }); | |
| }); | |
| } | |
| </script> | |
Xet Storage Details
- Size:
- 143 kB
- Xet hash:
- 64e4f99eaf842ff5bc4894a3e23ecdda59d4f4157f3ffe705504d4c14bd61bc4
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.