mirror of
https://github.com/run-llama/llama_cloud_services.git
synced 2026-07-21 03:55:22 -04:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1541b29296 | |||
| a1d18d83da | |||
| 1ad881e9fc | |||
| 2de26be464 | |||
| 36f09543b2 | |||
| 393acf8557 | |||
| ab27f2ab79 | |||
| d13b5ea30a | |||
| 81843b9285 | |||
| b19f85234b | |||
| 9dee30a616 | |||
| 4489eb1291 | |||
| dde72e3800 | |||
| e49fca4b51 | |||
| 0411b08c07 | |||
| 6c490ab781 | |||
| 737884d297 | |||
| 00c63b046d | |||
| d04bf78335 | |||
| 7dbe12b893 | |||
| 4caa9cbc02 | |||
| af1f61186a | |||
| 13dea6ae1a | |||
| fa9698a681 | |||
| 4bed7c7895 |
+2
-1
@@ -1,3 +1,4 @@
|
||||
.git
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.pyc
|
||||
.DS_Store
|
||||
@@ -1,22 +1,30 @@
|
||||
# LlamaParse (Preview)
|
||||
# LlamaParse
|
||||
|
||||
LlamaParse is an API created by LlamaIndex to efficiently parse and represent files for efficient retrieval and context augmentation using LlamaIndex frameworks.
|
||||
|
||||
LlamaParse directly integrates with [LlamaIndex](https://github.com/run-llama/llama_index).
|
||||
|
||||
Currently available in preview mode for **free**. Try it out today!
|
||||
|
||||
**NOTE:** Currently, only PDF files are supported.
|
||||
Free plan is up to 1000 pages a day. Paid plan is free 7k pages per week + 0.3c per additional page.
|
||||
|
||||
## Getting Started
|
||||
|
||||
First, login and get an api-key from `https://cloud.llamaindex.ai`.
|
||||
|
||||
Install the package:
|
||||
Then, make sure you have the latest LlamaIndex version installed.
|
||||
|
||||
**NOTE:** If you are upgrading from v0.9.X, we recommend following our [migration guide](https://pretty-sodium-5e0.notion.site/v0-10-0-Migration-Guide-6ede431dcb8841b09ea171e7f133bd77), as well as uninstalling your previous version first.
|
||||
|
||||
```
|
||||
pip uninstall llama-index # run this if upgrading from v0.9.x or older
|
||||
pip install -U llama-index --upgrade --no-cache-dir --force-reinstall
|
||||
```
|
||||
|
||||
Lastly, install the package:
|
||||
|
||||
`pip install llama-parse`
|
||||
|
||||
Then, you can run the following to parse your first PDF file:
|
||||
Now you can run the following to parse your first PDF file:
|
||||
|
||||
```python
|
||||
import nest_asyncio
|
||||
@@ -28,7 +36,8 @@ parser = LlamaParse(
|
||||
api_key="llx-...", # can also be set in your env as LLAMA_CLOUD_API_KEY
|
||||
result_type="markdown", # "markdown" and "text" are available
|
||||
num_workers=4, # if multiple files passed, split in `num_workers` API calls
|
||||
verbose=True
|
||||
verbose=True,
|
||||
language="en" # Optionaly you can define a language, default=en
|
||||
)
|
||||
|
||||
# sync
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install llama-index\n",
|
||||
"!pip install llama-index-core==0.10.6.post1\n",
|
||||
"!pip install llama-index-core\n",
|
||||
"!pip install llama-index-embeddings-openai\n",
|
||||
"!pip install llama-index-postprocessor-flag-embedding-reranker\n",
|
||||
"!pip install git+https://github.com/FlagOpen/FlagEmbedding.git\n",
|
||||
@@ -489,7 +489,7 @@
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "llama-parse-aNC435Vv-py3.11",
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
@@ -503,10 +503,9 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.4"
|
||||
},
|
||||
"orig_nbformat": 4
|
||||
"version": "3.10.10"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,296 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Using llama-parse with AstraDB"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"In this notebook, we show a basic RAG-style example that uses `llama-parse` to parse a PDF document, store the corresponding document into a vector store (`AstraDB`) and finally, perform some basic queries against that store. The notebook is modeled after the quick start notebooks and hence is meant as a way of getting started with `llama-parse`, backed by a vector database."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Requirements"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# First, install the required dependencies\n",
|
||||
"!pip install --quiet llama-index llama-parse llama-index-vector-stores-astra-db llama-index-llms-openai"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Configuration"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import openai\n",
|
||||
"\n",
|
||||
"from getpass import getpass\n",
|
||||
"\n",
|
||||
"# Get all required API keys and parameters\n",
|
||||
"llama_cloud_api_key = getpass(\"Enter your Llama Index Cloud API Key: \")\n",
|
||||
"api_endpoint = input(\"Enter your Astra DB API Endpoint: \")\n",
|
||||
"token = getpass(\"Enter your Astra DB Token: \")\n",
|
||||
"namespace = input(\"Enter your Astra DB namespace (optional, must exist on Astra): \") or None\n",
|
||||
"openai_api_key = getpass(\"Enter your OpenAI API Key: \")\n",
|
||||
"\n",
|
||||
"os.environ[\"LLAMA_CLOUD_API_KEY\"] = llama_cloud_api_key\n",
|
||||
"openai.api_key = openai_api_key"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# llama-parse is async-first, running the sync code in a notebook requires the use of nest_asyncio\n",
|
||||
"import nest_asyncio\n",
|
||||
"\n",
|
||||
"nest_asyncio.apply()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Using llama-parse to parse a PDF"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Download complete.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Grab a PDF from Arxiv for indexing\n",
|
||||
"import requests \n",
|
||||
"\n",
|
||||
"# The URL of the file you want to download\n",
|
||||
"url = \"https://arxiv.org/pdf/1706.03762.pdf\"\n",
|
||||
"# The local path where you want to save the file\n",
|
||||
"file_path = \"./attention.pdf\"\n",
|
||||
"\n",
|
||||
"# Perform the HTTP request\n",
|
||||
"response = requests.get(url)\n",
|
||||
"\n",
|
||||
"# Check if the request was successful\n",
|
||||
"if response.status_code == 200:\n",
|
||||
" # Open the file in binary write mode and save the content\n",
|
||||
" with open(file_path, \"wb\") as file:\n",
|
||||
" file.write(response.content)\n",
|
||||
" print(\"Download complete.\")\n",
|
||||
"else:\n",
|
||||
" print(\"Error downloading the file.\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id ce3909a7-54cf-438b-849a-fe9a903b0c71\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_parse import LlamaParse\n",
|
||||
"\n",
|
||||
"documents = LlamaParse(result_type=\"text\").load_data(file_path)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'rmer - model architecture.\\nThe Transformer follows this overall architecture using stacked self-attention and point-wise, fully\\nconnected layers for both the encoder and decoder, shown in the left and right halves of Figure 1,\\nrespectively.\\n3.1 Encoder and Decoder Stacks\\nEncoder: The encoder is composed of a stack of N = 6 identical layers. Each layer has two\\nsub-layers. The first is a multi-head self-attention mechanism, and the second is a simple, position-\\nwise fully connected feed-forward network. We employ a residual connection [11] around each of\\nthe two sub-layers, followed by layer normalization [1]. That is, the output of each sub-layer is\\nLayerNorm(x + Sublayer(x)), where Sublayer(x) is the function implemented by the sub-layer\\nitself. To facilitate these residual connections, all sub-layers in the model, as well as the embedding\\nlayers, produce outputs of dimension dmodel = 512.\\nDecoder: The decoder is also composed of a stack of N = 6 identical layers. In addition '"
|
||||
]
|
||||
},
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Take a quick look at some of the parsed text from the document:\n",
|
||||
"documents[0].get_content()[10000:11000]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Storing into Astra DB"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.vector_stores.astra_db import AstraDBVectorStore\n",
|
||||
"\n",
|
||||
"astra_db_store = AstraDBVectorStore(\n",
|
||||
" token=token,\n",
|
||||
" api_endpoint=api_endpoint,\n",
|
||||
" namespace=namespace,\n",
|
||||
" collection_name=\"astra_v_table_llamaparse\",\n",
|
||||
" embedding_dimension=1536\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.node_parser import SimpleNodeParser\n",
|
||||
"\n",
|
||||
"node_parser = SimpleNodeParser()\n",
|
||||
"\n",
|
||||
"nodes = node_parser.get_nodes_from_documents(documents)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.embeddings.openai import OpenAIEmbedding\n",
|
||||
"from llama_index.core import VectorStoreIndex, StorageContext\n",
|
||||
"\n",
|
||||
"storage_context = StorageContext.from_defaults(vector_store=astra_db_store)\n",
|
||||
"\n",
|
||||
"index = VectorStoreIndex(\n",
|
||||
" nodes=nodes,\n",
|
||||
" storage_context=storage_context,\n",
|
||||
" embed_model=OpenAIEmbedding(api_key=openai_api_key),\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Simple RAG Example"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(similarity_top_k=15)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"***********New LlamaParse+ Basic Query Engine***********\n",
|
||||
"Multi-Head Attention is also known as multi-headed self-attention.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"query = \"What is Multi-Head Attention also known as?\"\n",
|
||||
"\n",
|
||||
"response_1 = query_engine.query(query)\n",
|
||||
"print(\"\\n***********New LlamaParse+ Basic Query Engine***********\")\n",
|
||||
"print(response_1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'We used beam search as described in the previous section, but no\\ncheckpoint averaging. We present these results in Table 3.\\nIn Table 3 rows (A), we vary the number of attention heads and the attention key and value dimensions,\\nkeeping the amount of computation constant, as described in Section 3.2.2. While single-head\\nattention is 0.9 BLEU worse than the best setting, quality also drops off with too many heads.\\nIn Table 3 rows (B), we observe that reducing the attention key size dk hurts model quality. This\\nsuggests that determining compatibility is not easy and that a more sophisticated compatibility\\nfunction than dot product may be beneficial. We further observe in rows (C) and (D) that, as expected,\\nbigger models are better, and dropout is very helpful in avoiding over-fitting. In row (E) we replace our\\nsinusoidal positional encoding with learned positional embeddings [9], and observe nearly identical\\nresults to the base model.\\n6.3 English Constituency Parsing\\nTo evaluate if the Transformer can generalize to other tasks we performed experiments on English\\nconstituency parsing. This task presents specific challenges: the output is subject to strong structural\\nconstraints and is significantly longer than the input. Furthermore, RNN sequence-to-sequence\\nmodels have not been able to attain state-of-the-art results in small-data regimes [37].\\nWe trained a 4-layer transformer with dmodel = 1024 on the Wall Street Journal (WSJ) portion of the\\nPenn Treebank [25], about 40K training sentences. We also trained it in a semi-supervised setting,\\nusing the larger high-confidence and BerkleyParser corpora from with approximately 17M sentences\\n[37]. We used a vocabulary of 16K tokens for the WSJ only setting and a vocabulary of 32K tokens\\nfor the semi-supervised setting.\\nWe performed only a small number of experiments to select the dropout, both attention and residual\\n(section 5.4), learning rates and beam size on the Section 22 development set, all other parameters\\nremained unchanged from the English-to-German base translation model. During inference, we\\n 9\\n---\\nTable 4: The Transformer generalizes well to English constituency parsing (Results are on Section 23\\nof WSJ)\\n Parser Training WSJ 23 F1\\n Vinyals & Kaiser el al. (2014) [37] WSJ only, discriminative 88.3\\n Petrov et al. (2006) [29] WSJ only, discriminative 90.4\\n Zhu et al. (2013) [40] WSJ only, discriminative 90.4\\n Dyer et al. (2016) [8] WSJ only, discriminative 91.7\\n Transformer (4 layers) WSJ only, discriminative 91.3\\n Zhu et al. (2013) [40] semi-supervised 91.3\\n Huang & Harper (2009) [14] semi-supervised 91.3\\n McClosky et al. (2006) [26] semi-supervised 92.1\\n Vinyals & Kaiser el al. (2014) [37] semi-supervised 92.1\\n Transformer (4 layers) semi-supervised 92.7\\n Luong et al. (2015) [23] multi-task 93.0\\n Dyer et al. (2016) [8] generative 93.3\\nincreased the maximum output length to input length + 300. We used a beam size of 21 and α = 0.3\\nfor both WSJ only and the semi-supervised setting.\\nOur results in Table 4 show that despite the lack of task-specific tuning our model performs sur-\\nprisingly well, yielding better results than all previously reported models with the exception of the\\nRecurrent Neural Network Grammar [8].\\nIn contrast to RNN sequence-to-sequence models [37], the Transformer outperforms the Berkeley-\\nParser [29] even when training only on the WSJ training set of 40K sentences.\\n7 Conclusion\\nIn this work, we presented the Transformer, the first sequence transduction model based entirely on\\nattention, replacing the recurrent layers most commonly used in encoder-decoder architectures with\\nmulti-headed self-attention.\\nFor translation tasks, the Transformer can be trained significantly faster than architectures based\\non recurrent or convolutional layers.'"
|
||||
]
|
||||
},
|
||||
"execution_count": 12,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Take a look at one of the source nodes from the response\n",
|
||||
"response_1.source_nodes[0].get_content()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
@@ -168,7 +168,7 @@
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "llama-parse-aNC435Vv-py3.11",
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
@@ -182,10 +182,10 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.5"
|
||||
"version": "3.10.12"
|
||||
},
|
||||
"orig_nbformat": 4
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
|
||||
@@ -0,0 +1,398 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "d27f1082-cd10-405e-9570-6f0e934bba8b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# LlamaParse JSON Mode + Multimodal RAG\n",
|
||||
"\n",
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_parse/blob/main/examples/demo_json.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>\n",
|
||||
"\n",
|
||||
"This notebook shows you how to use LlamaParse JSON mode with LlamaIndex to build a simple multimodal RAG pipeline.\n",
|
||||
"\n",
|
||||
"Using JSON mode gives you back a list of json dictionaries, which contains both text and images. You can then download these images and use a multimodal model to extract information and index them."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a004db48-8d3f-421c-915a-477692f71b90",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setup\n",
|
||||
"\n",
|
||||
"Define imports, env variables, global LLM/embedding models."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "bc6a7a4b-b568-4db5-bcba-62f5c517ff3a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install llama-index\n",
|
||||
"!pip install llama-index-core\n",
|
||||
"!pip install llama-index-llms-anthropic llama-index-multi-modal-llms-anthropic\n",
|
||||
"!pip install llama-index-embeddings-huggingface\n",
|
||||
"!pip install llama-parse"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "0879301c-ff91-4431-941a-6c0ef7cd8fe2",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# llama-parse is async-first, running the async code in a notebook requires the use of nest_asyncio\n",
|
||||
"import nest_asyncio\n",
|
||||
"nest_asyncio.apply()\n",
|
||||
"\n",
|
||||
"import os\n",
|
||||
"# API access to llama-cloud\n",
|
||||
"os.environ[\"LLAMA_CLOUD_API_KEY\"] = \"llx-\"\n",
|
||||
"\n",
|
||||
"# Using Anthropic API for embeddings/LLMs\n",
|
||||
"os.environ[\"ANTHROPIC_API_KEY\"] = \"sk-\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "391e2d95-5569-4d73-9f16-5b59d7326f8d",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.llms.anthropic import Anthropic\n",
|
||||
"\n",
|
||||
"llm = Anthropic(model=\"claude-3-opus-20240229\", temperature=0.0)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "700f48e8-8b52-41f3-90f9-144d5fdd5c52",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import Settings\n",
|
||||
"\n",
|
||||
"Settings.llm = llm\n",
|
||||
"Settings.embed_model = \"local:BAAI/bge-small-en-v1.5\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "b411d2ee-3e6b-45b0-b532-4a8e3abcdea0",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Load Data\n",
|
||||
"\n",
|
||||
"Let's load in the Uber 10Q report."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c39d408f-e885-4940-85c7-b09ca3bc7cb7",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/10q/uber_10q_march_2022.pdf' -O './uber_10q_march_2022.pdf'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c2f42af8-afb3-4b3b-82d3-6b332fb38aa4",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Using LlamaParse in JSON Mode for PDF Reading\n",
|
||||
"\n",
|
||||
"We show you how to run LlamaParse in JSON mode for PDF reading."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "9c9cd670-8229-4ad6-99a9-845bd82b7ec1",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id cf5a4f51-1af8-47f7-9b3d-80a905d06b89\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_parse import LlamaParse\n",
|
||||
"\n",
|
||||
"parser = LlamaParse(verbose=True)\n",
|
||||
"json_objs = parser.get_json_result(\"./uber_10q_march_2022.pdf\")\n",
|
||||
"json_list = json_objs[0][\"pages\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "b26d21d1-05b5-4f49-b937-c13106a84015",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.schema import TextNode\n",
|
||||
"from typing import List\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def get_text_nodes(json_list: List[dict]):\n",
|
||||
" text_nodes = []\n",
|
||||
" for idx, page in enumerate(json_list):\n",
|
||||
" text_node = TextNode(\n",
|
||||
" text=page[\"text\"],\n",
|
||||
" metadata={\n",
|
||||
" \"page\": page[\"page\"]\n",
|
||||
" }\n",
|
||||
" )\n",
|
||||
" text_nodes.append(text_node)\n",
|
||||
" return text_nodes"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "364a3276-d2db-4aee-9bc6-617ffd726d25",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"text_nodes = get_text_nodes(json_list)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "2fe2e911-0393-42e8-a233-65639cdbebc4",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Extract/Index images from image dicts\n",
|
||||
"\n",
|
||||
"Here we use a multimodal model to extract and index images from image dictionaries."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"id": "36012145-5521-4ddb-a53e-df9ebd1ca8dd",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"mkdir: llama2_images: File exists\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# call get_images on parser, convert to ImageDocuments\n",
|
||||
"!mkdir llama2_images\n",
|
||||
"\n",
|
||||
"from llama_index.core.schema import ImageDocument\n",
|
||||
"from llama_index.multi_modal_llms.anthropic import AnthropicMultiModal\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def get_image_text_nodes(json_objs: List[dict]):\n",
|
||||
" \"\"\"Extract out text from images using a multimodal model.\"\"\"\n",
|
||||
" anthropic_mm_llm = AnthropicMultiModal(max_tokens=300)\n",
|
||||
" image_dicts = parser.get_images(json_objs, download_path=\"llama2_images\")\n",
|
||||
" image_documents = []\n",
|
||||
" img_text_nodes = []\n",
|
||||
" for image_dict in image_dicts:\n",
|
||||
" image_doc = ImageDocument(image_path=image_dict[\"path\"])\n",
|
||||
" response = anthropic_mm_llm.complete(\n",
|
||||
" prompt=\"Describe the images as an alternative text\",\n",
|
||||
" image_documents=[image_doc],\n",
|
||||
" )\n",
|
||||
" text_node = TextNode(\n",
|
||||
" text=str(response),\n",
|
||||
" metadata={\"path\": image_dict[\"path\"]}\n",
|
||||
" )\n",
|
||||
" img_text_nodes.append(text_node)\n",
|
||||
" return img_text_nodes"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "38f25045-6102-4920-9cd0-42b0ae6c872f",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"image_text_nodes = get_image_text_nodes(json_objs)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 60,
|
||||
"id": "4683c97a-da06-408a-9fe9-7e3c0aceb77d",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'The image shows a bar graph titled \"Monthly Active Platform Consumers (in millions)\". The graph displays data from Q2 2020 to Q1 2022 over 8 quarters. The number of monthly active platform consumers starts at 55 million in Q2 2020 and steadily increases each quarter, reaching 115 million by Q1 2022. The graph illustrates consistent quarter-over-quarter growth in this metric over the nearly 2 year time period shown.'"
|
||||
]
|
||||
},
|
||||
"execution_count": 60,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"image_text_nodes[0].get_content()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "3cfdf6db-381c-4e53-a0fb-e7670f75e0d5",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Build Index across image and text nodes\n",
|
||||
"\n",
|
||||
"Here we build a vector index across both text nodes and text nodes extracted from images."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 68,
|
||||
"id": "939aec6c-064a-4319-b2dc-70cc4a304c06",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex\n",
|
||||
"\n",
|
||||
"index = VectorStoreIndex(text_nodes + image_text_nodes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 69,
|
||||
"id": "529340d5-9319-4cdf-8ee1-bbd01ed00226",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 71,
|
||||
"id": "81d7ff30-5a87-44da-880d-4b1f41434d90",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"The bar graph titled \"Monthly Active Platform Consumers (in millions)\" shows the number of monthly active consumers on Uber's platform over a period of 8 quarters from Q2 2020 to Q1 2022. \n",
|
||||
"\n",
|
||||
"The graph indicates steady quarter-over-quarter growth in this metric, starting at 55 million monthly active platform consumers in Q2 2020 and increasing each quarter to reach 115 million by Q1 2022. This represents consistent growth in Uber's user base on their platform over the nearly 2 year period shown in the graph.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# ask question over image! \n",
|
||||
"response = query_engine.query(\"What does the bar graph titled 'Monthly Active Platform Consumers' show?\") \n",
|
||||
"print(str(response)) "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 72,
|
||||
"id": "c4f14ad8-6bfd-49d9-b3d5-7215cf0e4ac1",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Based on the context provided, some of the main risk factors for Uber include:\n",
|
||||
"\n",
|
||||
"- A significant percentage of Uber's bookings come from large metropolitan areas, which could be negatively impacted by various economic, social, weather, regulatory and other conditions, including COVID-19.\n",
|
||||
"\n",
|
||||
"- Uber may fail to successfully offer autonomous vehicle technologies on its platform or these technologies may not perform as expected. \n",
|
||||
"\n",
|
||||
"- Retaining and attracting high-quality personnel is important for Uber's business and continued attrition could adversely impact the company.\n",
|
||||
"\n",
|
||||
"- Security breaches, data privacy issues, cyberattacks and unauthorized access to Uber's proprietary data and systems pose risks.\n",
|
||||
"\n",
|
||||
"- Uber is subject to climate change risks, both physical and transitional, that could adversely impact its business if not managed properly. \n",
|
||||
"\n",
|
||||
"- Uber relies on third parties for open marketplaces to distribute its platform and software, and interference from these third parties could harm its business.\n",
|
||||
"\n",
|
||||
"- Uber will require additional capital to support its growth and this capital may not be available on reasonable terms.\n",
|
||||
"\n",
|
||||
"- Acquisitions and integrations carry risks if Uber is unable to successfully identify and integrate suitable businesses.\n",
|
||||
"\n",
|
||||
"- Extensive government regulations around payments, financial services, data privacy and other areas pose compliance risks and challenges for Uber's business model in certain jurisdictions.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# ask question over text! \n",
|
||||
"response = query_engine.query(\"What are the main risk factors for Uber?\") \n",
|
||||
"print(str(response)) "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "82ea880b-a0c7-410c-94c7-8fb3ac96c30c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "llama_parse",
|
||||
"language": "python",
|
||||
"name": "llama_parse"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.8"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,481 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "28d15ea5-a3eb-4ee5-9d91-8dbd95e53129",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Multi-Language Support in LlamaParse\n",
|
||||
"\n",
|
||||
"LlamaParse supports users to specify a `language` parameter before uploading documents, giving users better OCR capabilities over non-English PDFs, parsing images into more accurate representations.\n",
|
||||
"\n",
|
||||
"You can specify 80+ different languages: see this file for a full list of supported languages: https://github.com/run-llama/llama_parse/blob/main/llama_parse/base.py.\n",
|
||||
"\n",
|
||||
"This notebook shows a demo of this in action. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "15539193-2f5c-4ecf-9ca4-9aee6f888468",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install llama-index llama-parse"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "87322210-c21c-43d6-b459-2e8a828ac576",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# llama-parse is async-first, running the sync code in a notebook requires the use of nest_asyncio\n",
|
||||
"import nest_asyncio\n",
|
||||
"\n",
|
||||
"nest_asyncio.apply()\n",
|
||||
"\n",
|
||||
"import os\n",
|
||||
"# os.environ[\"LLAMA_CLOUD_API_KEY\"] = \"llx-...\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "2b5cabdf-342a-42d2-8ad4-0ba7c46cdfb9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Load in a French PDF\n",
|
||||
"\n",
|
||||
"We load in the 2022 annual report from Agence France Tresor."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e81e0a08-3a99-42e6-adcc-00bb4ce1c3d4",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!wget \"https://www.dropbox.com/scl/fi/fxg17log5ydwoflhxmgrb/treasury_report.pdf?rlkey=mdintk0o2uuzkple26vc4v6fd&dl=1\" -O treasury_report.pdf"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "ecfc578c-3c7f-4ec1-aa06-51565c28632b",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id 476966e1-9e04-49e7-a5dc-952b053b8b94\n",
|
||||
"......"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_parse import LlamaParse\n",
|
||||
"\n",
|
||||
"parser = LlamaParse(\n",
|
||||
" result_type=\"text\",\n",
|
||||
" language=\"fr\"\n",
|
||||
")\n",
|
||||
"documents = parser.load_data(\"./treasury_report.pdf\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"id": "0c37db27-3496-4a59-918b-701c9ad7706d",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" ET GESTION DE LA DETTE DE L’ÉTAT\n",
|
||||
" P.56 FOCUS OAT VERTES\n",
|
||||
" P.60 CONTRÔLE DES RISQUES & POST-MARCHÉ\n",
|
||||
" Chiffres de l’exercice 2022 P.64 À 105\n",
|
||||
" P.65 ACTIVITÉ DE L’AFT\n",
|
||||
" P.84 RAPPORT STATISTIQUE\n",
|
||||
" FICHES TECHNIQUES GLOSSAIRES LISTE DES ABRÉVIATIONS\n",
|
||||
" P.106 P.118 P.122\n",
|
||||
" AGENCE FRANCE TRÉSOR - RAPPORT D’ACTIVITÉ 2022 3\n",
|
||||
"---\n",
|
||||
" Édito\n",
|
||||
" 111 Avec une croissance\n",
|
||||
" de +2,5 %, la France a illustré\n",
|
||||
" une nouvelle fois sa résilience\n",
|
||||
" économique face aux chocs.\n",
|
||||
"4 AGENCE FRANCE TRÉSOR - RAPPORT D’ACTIVITÉ 2022\n",
|
||||
"---\n",
|
||||
" L’économie française en 2022 :\n",
|
||||
" résilience face aux chocs géopolitiques\n",
|
||||
" et économiques\n",
|
||||
" sa résilience économique face aux lors du dernier trimestre de 2022.\n",
|
||||
"LE DÉBUT DE chocs. Cette croissance a été permise Malgré un climat des affaires impacté\n",
|
||||
"L’ANNÉE 2022 grâce à une forte demande intérieure par l’inflation, le soutien apporté\n",
|
||||
" alimentée par le dynamisme de aux TPE/PME leur a permis de faire\n",
|
||||
"SEMBLAIT l’investissement et, en dépit de face aux défis énergétiques tout en\n",
|
||||
" l’inflation, d’une résilience de la préservant l’emploi.\n",
|
||||
"ENGAGÉ DANS consommation des ménages sur une\n",
|
||||
" grande partie de l’année. Afin de combattre l’inflation qui a\n",
|
||||
"UNE DYNAMIQUE largement dépassé la cible de 2 %,\n",
|
||||
" Le taux d’inflation des prix à la la BCE, de concert avec les banques\n",
|
||||
"EFFICACE DE consommation français est resté l’un centrales des principales économies\n",
|
||||
"SORTIE DE CRISE des plus bas d’Europe avec +6,0 % développées, a adapté sa fonction de\n",
|
||||
" en 2022, s’appuyant, d’une part, sur réaction en mettant fin aux politiques\n",
|
||||
"PORTÉE PAR l’atout structurel que représente un d’assouplissement monétaire qu’elle\n",
|
||||
" mix énergétique parmi les moins menait depuis la crise financière de\n",
|
||||
"UNE REPRISE exposés à la Russie et, d’autre part, 2008. Ainsi, dès juillet 2022, et pour\n",
|
||||
" sur les politiques proactives du la première fois en 10 ans, la BCE a\n",
|
||||
"ÉCONOMIQUE gouvernement avec la mise en place augmenté ses taux directeurs. Les\n",
|
||||
" du bouclier tarifaire, de la remise taux d’emprunts de l’État à 10 ans se\n",
|
||||
"INÉDITE carburant et du chèque énergie. sont ainsi progressivement éloignés\n",
|
||||
"AMORCÉE Ces dispositifs, temporaires, ont de leur territoire négatif pour\n",
|
||||
" été progressivement supprimés : la atteindre 3,10 % en fin d’année.\n",
|
||||
"EN 2021. remise carburant, d’abord prolongée\n",
|
||||
" jusqu’à mi-novembre a pris fin Cette décision s’est également\n",
|
||||
"Le déclenchement de la guerre en en décembre 2022, tandis que le accompagnée de la fin du\n",
|
||||
"Ukraine par la Russie dès février a chèque énergie exceptionnel a pris programme d’achat d’urgence (PEPP)\n",
|
||||
"rebattu les cartes de cet équilibre, fin en mars 2023. mis en place pendant la pandémie,\n",
|
||||
"provoquant des bouleversements suivi de la réduction progressive de\n",
|
||||
"majeurs sur les plans géopolitiques et Le marché du travail français a par son bilan, à un rythme mensuel de 15\n",
|
||||
"économiques, avec le déploiement ailleurs montré toute sa robustesse, milliards d’euros par mois.\n",
|
||||
"de sanctions à l’encontre de la Russie la dynamique de reprise initiée en\n",
|
||||
"et une forte poussée inflationniste. 2021 ainsi que l’effet des réformes L’Agence France Trésor a fait face à ce\n",
|
||||
"Face à cette situation, les principales structurelles engagées les années contexte de grands bouleversements\n",
|
||||
"banques centrales mondiales, dont précédentes permettant au taux géopolitiques, économiques et\n",
|
||||
"la Banque centrale européenne d’emploi des Français âgés de 15 à 64 financiers en s’appuyant sur ses\n",
|
||||
"(BCE), ont engagé une politique de ans d’atteindre fin 2022 un niveau principes de régularité, de prévisibilité\n",
|
||||
"normalisation monétaire rapide de 68,1 %, un record depuis 1975. et de transparence. Cette stratégie\n",
|
||||
"pour lutter contre l’inflation. La reprise économique de début s’est de nouveau révélée robuste et,\n",
|
||||
"Parallèlement, le gouvernement d’année et les effets positifs du plan alliée à l’engagement et à l’efficacité\n",
|
||||
"français a mis en place des mesures France Relance ont permis la création de ses équipes, ainsi qu’à la qualité\n",
|
||||
"(à hauteur de 43,6 milliards d’euros de 337 100 emplois, essentiellement de crédit de la signature de la France,\n",
|
||||
"sur l’année 2022) pour protéger les dans le secteur salarié marchand. Ce lui a permis d’accomplir sa mission\n",
|
||||
"entreprises et les ménages. dynamisme a aussi conduit à la chute de financement de l’action publique\n",
|
||||
" du taux de chômage, atteignant son au bénéfice de tous.\n",
|
||||
"Avec une croissance de +2,5 %, la niveau le plus bas depuis mars 2008\n",
|
||||
"France a illustré une nouvelle fois avec 7,2 % de demandeurs d’emploi\n",
|
||||
" Emmanuel Moulin\n",
|
||||
" DIRECTEUR GÉNÉRAL DU TRÉSOR\n",
|
||||
" ET PRÉSIDENT DE L’AFT\n",
|
||||
" AGENCE FRANCE TRÉSOR - RAPPORT D’ACTIVITÉ 2022 5\n",
|
||||
"---\n",
|
||||
" du directeur général Le mot\n",
|
||||
" 011 En 2022, le choc d’inflation\n",
|
||||
" et la normalisation\n",
|
||||
" de la politique monétaire\n",
|
||||
" ont mis fin à une décennie\n",
|
||||
" de taux historiquement bas.\n",
|
||||
"6 AGENCE FRANCE TRÉSOR - RAPPORT D’ACTIVITÉ 2022\n",
|
||||
"---\n",
|
||||
" MALGRÉ UN CONTEXTE DE MARCHÉ MOUVEMENTÉ ET LES MESURES D’AMPLEUR\n",
|
||||
" PRISES POUR LIMITER L’IMPACT DE L’INFLATION SUR LES MÉNAGES ET\n",
|
||||
" LES ENTREPRISES, LE PROGRAMME DE FINANCEMENT À MOYEN ET LONG TERME\n",
|
||||
" EST DEMEURÉ INCHANGÉ À 260 MILLIARDS D’EUROS, STABLE PAR RAPPORT\n",
|
||||
" À 2021, ET LA DETTE DE COURT TERME A ÉTÉ RÉDUITE DE 7 MILLIARDS D’EUROS.\n",
|
||||
"En janvier 2022, la normalisation de d’obligations indexées sur l’inflation, la dette de court terme a été réduite\n",
|
||||
"la politique monétaire en zone euro sur lequel a été enregistré un de 7 milliards d’euros. En effet, le\n",
|
||||
"était une perspective de moyen supplément d’indexation supérieur dynamisme des recettes fiscales et\n",
|
||||
"terme. Quelques semaines plus tard, de 17 milliards d’euros à celui de la trésorerie levée lors de la crise\n",
|
||||
"l’invasion de l’Ukraine par la Russie l’année 2021. Il s’est également sanit\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(documents[0].get_content()[1000:10000])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "be161577-7b1e-4710-b721-f549feb8e6d0",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Download Chinese PDF"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 24,
|
||||
"id": "ac332ea3-cfff-4216-b292-62410a26c336",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"--2024-02-28 16:41:26-- https://www.dropbox.com/scl/fi/g5ojyzk4m44hl7neut6vc/chinese_pdf.pdf?rlkey=45reu51kjvdvic6zucr8v9sh3&dl=1\n",
|
||||
"Resolving www.dropbox.com (www.dropbox.com)... 162.125.13.18\n",
|
||||
"Connecting to www.dropbox.com (www.dropbox.com)|162.125.13.18|:443... connected.\n",
|
||||
"HTTP request sent, awaiting response... 302 Found\n",
|
||||
"Location: https://uc7a03fdb7d960dbedb23e9298ab.dl.dropboxusercontent.com/cd/0/inline/COJ69Wg2e7wH9S0ELzl4j4znoonRSQS-JJrH6mxy_vcrvY-KV7f10kMyQH6IYmtfMh_9xcDNOYnLkWkwMTYItwE1XQB5nqXbjmLJ4jLbDrMeu7-b49m796ctxevwnp7k1_U/file?dl=1# [following]\n",
|
||||
"--2024-02-28 16:41:27-- https://uc7a03fdb7d960dbedb23e9298ab.dl.dropboxusercontent.com/cd/0/inline/COJ69Wg2e7wH9S0ELzl4j4znoonRSQS-JJrH6mxy_vcrvY-KV7f10kMyQH6IYmtfMh_9xcDNOYnLkWkwMTYItwE1XQB5nqXbjmLJ4jLbDrMeu7-b49m796ctxevwnp7k1_U/file?dl=1\n",
|
||||
"Resolving uc7a03fdb7d960dbedb23e9298ab.dl.dropboxusercontent.com (uc7a03fdb7d960dbedb23e9298ab.dl.dropboxusercontent.com)... 162.125.13.15\n",
|
||||
"Connecting to uc7a03fdb7d960dbedb23e9298ab.dl.dropboxusercontent.com (uc7a03fdb7d960dbedb23e9298ab.dl.dropboxusercontent.com)|162.125.13.15|:443... connected.\n",
|
||||
"HTTP request sent, awaiting response... 302 Found\n",
|
||||
"Location: /cd/0/inline2/COKEp-d6ZqzrIIaPRlanov72wwnd7GX5eNSPnsxug0A8pOpek8hO6eFxp84cY3_NMBRsAqtX-IIVPpcfYHNoV__mpu1SsOV8wV8a68DwVKaVJRJriY_KV8lEFocvLgf7c7mhrREbIJ1UBN2fx6S_qWegwVIen1z1-pw-K7icMnA3EKJNqM9DFtqx9ct0FI4vdYGsv8ckLF26WgAhs96k1cHn-VRJle4SKstdYs8EmBxiuFLXZRCL3gljwAsLu3J6WRvis9v7VJ2zNhgrcT-ZnVujlpQGoGWLLPmREKffK608Xfz1XE35DzO28e_mm4SUPRfsP2mvIUrJUtUrhobR4siqQRGojxi0S7-da4Y7fpB4Tw/file?dl=1 [following]\n",
|
||||
"--2024-02-28 16:41:27-- https://uc7a03fdb7d960dbedb23e9298ab.dl.dropboxusercontent.com/cd/0/inline2/COKEp-d6ZqzrIIaPRlanov72wwnd7GX5eNSPnsxug0A8pOpek8hO6eFxp84cY3_NMBRsAqtX-IIVPpcfYHNoV__mpu1SsOV8wV8a68DwVKaVJRJriY_KV8lEFocvLgf7c7mhrREbIJ1UBN2fx6S_qWegwVIen1z1-pw-K7icMnA3EKJNqM9DFtqx9ct0FI4vdYGsv8ckLF26WgAhs96k1cHn-VRJle4SKstdYs8EmBxiuFLXZRCL3gljwAsLu3J6WRvis9v7VJ2zNhgrcT-ZnVujlpQGoGWLLPmREKffK608Xfz1XE35DzO28e_mm4SUPRfsP2mvIUrJUtUrhobR4siqQRGojxi0S7-da4Y7fpB4Tw/file?dl=1\n",
|
||||
"Reusing existing connection to uc7a03fdb7d960dbedb23e9298ab.dl.dropboxusercontent.com:443.\n",
|
||||
"HTTP request sent, awaiting response... 200 OK\n",
|
||||
"Length: 8074860 (7.7M) [application/binary]\n",
|
||||
"Saving to: ‘chinese_pdf.pdf’\n",
|
||||
"\n",
|
||||
"chinese_pdf.pdf 100%[===================>] 7.70M 37.9MB/s in 0.2s \n",
|
||||
"\n",
|
||||
"2024-02-28 16:41:28 (37.9 MB/s) - ‘chinese_pdf.pdf’ saved [8074860/8074860]\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"!wget \"https://www.dropbox.com/scl/fi/g5ojyzk4m44hl7neut6vc/chinese_pdf.pdf?rlkey=45reu51kjvdvic6zucr8v9sh3&dl=1\" -O chinese_pdf.pdf"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 25,
|
||||
"id": "45235b17-08f0-48f1-92aa-06711225860b",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id 0089f0b6-29ee-4e94-a8bf-49a137666f15\n",
|
||||
".........."
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_parse import LlamaParse\n",
|
||||
"\n",
|
||||
"parser = LlamaParse(\n",
|
||||
" result_type=\"text\",\n",
|
||||
" language=\"ch_sim\"\n",
|
||||
")\n",
|
||||
"documents = parser.load_data(\"./chinese_pdf.pdf\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 28,
|
||||
"id": "f0d546cc-6549-4cf5-8b37-0896f4e8d43d",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"中国投资有限责任公司2022年度报告 5\n",
|
||||
"---\n",
|
||||
"企业文化与核心价值观\n",
|
||||
"使命 核心价值观\n",
|
||||
" 致力于实现国家外汇资金多元化投资,在可接受风险范围内 责任 合力\n",
|
||||
" 实现股东权益最大化,以服务于国家经济发展和深化金融体\n",
|
||||
" 制改革的需要 忠于使命、勤勉尽责 立足大局、有效协同\n",
|
||||
" 是公司遵奉的核心价值取向 是实现公司可持续发展的关键\n",
|
||||
" 愿景 专业 进取\n",
|
||||
" 成为受人尊重的国际一流主权财富基金 坚持良好的专业精神和职业操守 求知进取、追求卓越\n",
|
||||
" 是公司成功的基石 是公司成功和发展壮大的内驱力\n",
|
||||
"---\n",
|
||||
"01 我们将一以贯之地践行全球发展倡议,充分维护投资东道国利益,\n",
|
||||
" 积极投身可持续投资,助力世界经济实现更高质量、更有韧性的发展。\n",
|
||||
" 致 辞\n",
|
||||
" 3 中国投资有限责任公司2022年度报告 中国投资有限责任公司2022年度报告 4\n",
|
||||
"---\n",
|
||||
" “行之力则知愈进,知之深则行愈达。”站在新的历史起点上,中投公司\n",
|
||||
" 将继续秉承精益求精、追求卓越的专业精神,与国内外合作伙伴一起深化\n",
|
||||
" 合作,共聚力量、共迎挑战、共享成果,开启打造世界一流主权财富基金\n",
|
||||
" 的新篇章,为助力全球经济发展作出新贡献! #Ave彭纯\n",
|
||||
" 董事长\n",
|
||||
" 2022年,是中投公司成立十五周年。\n",
|
||||
"董事长致辞 自2007年成立以来,中投公司坚守长期机构投资者定位,坚持国际化、市场化、专业化、负责任原则,搭\n",
|
||||
" 建起符合大型国际投资机构特点的治理架构,形成了系统完备的投资管理体系,经受住了国际金融危机、世纪\n",
|
||||
" 疫情等多个历史罕见的风险与挑战。如今,公司对外投资业务覆盖国际市场主要资产类别以及全球110多个国家\n",
|
||||
" 和地区,培养了一支高素质专业化的投资管理人才队伍,搭建了互利共赢的投资合作“朋友圈”,长期投资收\n",
|
||||
" 益超越董事会制定的考核目标,为促进国家外汇资产保值增值、服务国内国际双循环作出了积极贡献,在推动\n",
|
||||
" 全球投资合作、助力世界经济增长中贡献了中投力量,书写了中国主权财富基金不平凡的创业发展史。\n",
|
||||
"5 中国投资有限责任公司2022年度报告 中国投资有限责任公司2022年度报告 6\n",
|
||||
"---\n",
|
||||
" 2022年以来,全球地缘政治风险显著攀升,产业链供应链持续调整重构,美欧央行大幅加息,国际资本 我们守正创新,坚决践行双碳与可持续发展理念。更加包容、更加普惠、更有韧性的发展是全球\n",
|
||||
"市场剧烈震荡,MSCI全球股票指数、彭博全球债券指数一度自高点下跌超过22%、13%。面对风高浪急的国 可持续发展的关键。我们积极履行负责任投资者理念,制定《关于践行双碳目标和可持续投资行动的意见》,\n",
|
||||
"际环境和前所未有的巨大挑战,公司保持战略定力,发挥长期机构投资者优势,不断优化资产配置和投资策 积极开展气候变化、能源转型等主题投资。我们发布《运营碳中和行动计划》,明确时间表和路线图,全力实\n",
|
||||
"略,着力提升总组合韧性,加强重点领域风险防控,年度投资收益跑赢大市;截至2022年底,过去十年对外 现节能减排目标。我们探索以绿色资源引领乡村发展的新方法,在四个定点帮扶县持续推进巩固脱贫成果与乡\n",
|
||||
"投资年化净收益率按美元计算为6.43%,超出十年业绩目标26个基点;自成立以来累计年化国有资本增值率达 村振兴的有效衔接,助力民生保障与产业扶持,积极履行企业社会责任。\n",
|
||||
"到12.67%,圆满完成五年战略规划主要目标任务。 面向未来,我们坚信,发展与合作是破解全球性问题的“钥匙”。中投公司将一以贯之地践行全球发展倡\n",
|
||||
" 我们矢志不渝,积极打造世界一流主权财富基金。长期资本对于促进世界经济持续发展有着不 议,秉持互利共赢理念,以资本为纽带,促进国际产业交流合作,推动世界互联互通;充分维护投资东道国利\n",
|
||||
"可替代的作用。我们坚持国际化、市场化、专业化、负责任原则,快速恢复常态化对外交流交往,按照互利共 益,与东道国共创价值、共享价值;积极投身可持续投资,推动被投企业履行社会责任,助力世界经济实现更\n",
|
||||
"赢原则深化与国内外各类机构合作,持续为世界经济发展提供长期资本支持。我们积极创新对外投资方式,稳 高质量、更有韧性的发展。\n",
|
||||
"健运行多支新型双边基金,新设相关投资合作平台,深入推进中国市场价值创造,促进被投资公司拓展市场空\n",
|
||||
"间,助推国际投资与产业合作高质量发展。 经济全球化的潮流不可阻挡。我们呼吁各国携起手来,做多边主义的坚定维护者,打造更加开放有序的投\n",
|
||||
" 资环境,便利资本和资源要素在全球顺畅流动。我们尊重各方的利益关切,在开放中捕捉投资机遇,以务实合\n",
|
||||
" 我们直面挑战,着力加强自主投资能力建设。面对持续动荡的国际金融市场,我们锚定配置方 作应对共同挑战,并肩前进分享发展红利,推动世界经济平稳运行和持续增长。\n",
|
||||
"向,强化研究驱动,有序实施组合调整、策略优化,及时调整公开市场投资布局,质量并重推进非公开市场投\n",
|
||||
"资,完成另类资产投资占比50%的资产配置目标,对外投资总组合的韧性和质量不断提高。我们持续深化投资 “行之力则知愈进,知之深则行愈达。”过去的十五年,是中投人不惧挑战、接续奋斗的十五\n",
|
||||
"管理体制机制改革,统一非公开市场投资决策制度流程,配强投资决策专职委员并设立支持团队,投资管理科 年。 2023年是中投人落实新一轮战略规划的开局之年。上半年,在风高浪急的国际环境下,中投公司锚定战略目\n",
|
||||
"学化、专业化水平得到进一步提升。 标,统筹好发展和安全,取得了良好业绩,实现了良好开局。近期,公司部分董事更换,我们对离任董事在指导和支\n",
|
||||
" 持公司完善公司治理、深化投资管理体制机制改革、应对国际市场风险挑战等方面所作的贡献表示衷心感谢,对新\n",
|
||||
" 我们勇担使命,坚定走好中国特色金融发展之路。面对新征程新要求,我们坚持发挥“积极股 任董事表示热烈欢迎。站在新的历史起点上,中投公司将完整、准确、全面贯彻新发展理念,积极助力构建新发展格\n",
|
||||
"东”作用,督促控参股金融企业优化产品服务、加大资源倾斜力度,全力支持稳经济稳增长。我们积极创新完 局,牢牢把握高质量发展首要任务,继续秉承精益求精、追求卓越的专业精神,与国内外合作伙伴一起深化合作,共\n",
|
||||
"善“汇金模式”,推动优化国有金融资本布局,以市场化方式参与问题金融机构救助,助力金融市场稳定健康 聚力量、共迎挑战、共享成果,开启打造世界一流主权财富基金的新篇章,为助力全球经济发展作出新贡献!\n",
|
||||
"发展。我们主动适应新形势新要求,围绕国有金融资本管理体系建设等重大课题深入研究,压实派出董事自主\n",
|
||||
"履职责任,不断提升机构化履职能力。\n",
|
||||
" 我们坚守底线,持续夯实全面风险管理体系。面对风高浪急的国际环境,我们优化风险管理委员\n",
|
||||
"会设置,修订全面风险管理基本制度,增加风险类别的覆盖度,全面提升风险预见、应对、处置水平。在对外投\n",
|
||||
"资方面,我们严守法律合规底线,健全地缘政治、气候变化等非传统风险防控机制,突出抓好流动性管理,对外\n",
|
||||
"投资总组合风险保持在董事会规定的容忍度内。在国有金融资本受托管理方面,我们建立健全控参股金融企业风\n",
|
||||
"险监测体系,全面开展多维度风险画像,推动控参股金融企业风险减存量、控增量、防变量取得积极成效。\n",
|
||||
"7 中国投资有限责任公司2022年度报告 中国投资有限责任公司2022年度报告 8\n",
|
||||
"---\n",
|
||||
"02 中投公司的组建宗旨是实现国家外汇资金多元化投资,在可接受风\n",
|
||||
" 险范围内实现股东权益最大化,以服务于国家宏观经济发展和深化\n",
|
||||
" 公 司 介 绍 金融体制改革的需要。\n",
|
||||
" 9 中国投资有限责任公司2022年度报告 中国投资有限责任公司2022年度报告 10\n",
|
||||
"---\n",
|
||||
"公司概况中国投资有限责任公司(以下简称“中投公司”)依照《中华人民共和国公司法》(以下简称“《公司 公司治理 中投公司按照《公司法》及《中国投资有限责任公司章程》(以下简称“《中投公司章程》”)中的有关规\n",
|
||||
"法》”)于2007年9月成立,总部设在北京。中投公司的初始资本金为2000亿美元,由中国财政部发行1.55万 定,设立了董事会、监事会和执行委员会(以下简称“执委会”),三者之间权责明确、独立履职、有效制衡。\n",
|
||||
"亿元人民币特别国债募集。截至2022年底,公司总资产达1.24万亿美元。 2022年,中投公司健全完善董事会、监事会运行机制,强化下设专门委员会的职能发挥,持续提升公司治\n",
|
||||
" 中投公司的组建宗旨是实现国家外汇资金多元化投资,在可接受风险范围内实现股东权益最大化,以服务于 理效能。公司根据业务发展需要,优化调整投资管理架构,完善投资决策和投后管理制度机制,深化全面风险管\n",
|
||||
"国家宏观经济发展和深化金融体制改革的需要。 理体系建设,全面提升机构化投资能力。\n",
|
||||
" 中投公司开展境外投资业务与境内金融机构股权管理工作。其中,境外投资业务由下设子公司⸺中投国际\n",
|
||||
"有限责任公司(以下简称“中投国际”)和中投海外直接投资有限责任公司(以下简称“中投海外”)承担,业\n",
|
||||
"务范围包括公开市场股票和债券投资,对冲基金和多资产,泛行业私募股权和私募信用投资,房地产、基础设\n",
|
||||
"施、资源商品、农业等领域的基金投资与直接投资,以及多双边基金管理等。 组织架构图\n",
|
||||
" 中央汇金投资有限责任公司(以下简称“中央汇金”)作为中投公司的子公司,根据国务院授权,对国有重\n",
|
||||
"点金融企业进行股权投资,以出资额为限代表国家依法对国有重点金融企业行使出资人权利和履行出资人义务。 董事会 监事会\n",
|
||||
"中央汇金不开展商业性经营活动,不干预其控股的国有重点金融企业的日常经营活动。 提名与\n",
|
||||
" 薪酬委员会\n",
|
||||
" 中投国际和中投海外开展的境外业务与中央汇金开展的境内业务之间实行严格的“防火墙”政策和措施。\n",
|
||||
" 战略与\n",
|
||||
" 社会责任\n",
|
||||
" 委员会\n",
|
||||
" 风险管理 执行 国际咨询 监督 审计\n",
|
||||
" 委员会 委员会 委员会 委员会 委员会\n",
|
||||
" 境外投资 管理与支持 境内股权\n",
|
||||
" 业务部门 部门 管理部门\n",
|
||||
"11 中国投资有限责任公司2022年度报告 中国投资有限责任公司2022年度报告 12\n",
|
||||
"---\n",
|
||||
"董事会 沈如军\n",
|
||||
" 党委委员、执行董事、副总经理\n",
|
||||
" 中投公司董事会行使《公司法》和《中投公司章程》中规定的有限责任公司董事会的职权,主要包括:审核 1964年出生,管理学博士,高级会计师。历任中国工商银行计划财务部副总经理、\n",
|
||||
"和批准公司的发展战略、经营方针和投资计划;确定公司需向股东报告的重大事项;制定公司年度预决算方案; 北京市分行副行长、财务会计部总经理、山东省分行行长,交通银行执行董事、副\n",
|
||||
"任免公司高级管理人员;决定或授权批准设立内部管理机构等。 行长。现任本公司党委委员、执行董事、副总经理。\n",
|
||||
" 董事会由执行董事、非执行董事、独立董事以及职工董事构成。 丛亮\n",
|
||||
" 2022年,面对复杂严峻的国际经济形势,董事会加强对公司重大经营管理事项的指导和督促,及时听取投 非执行董事\n",
|
||||
"资形势、经营管理、风险防控等汇报,认真审议经营计划、财务预算和决算、业绩考核等重要议题,深入谋划中 1971年出生,经济学博士。历任国家发展和改革委员会国民经济综合司副司长、司\n",
|
||||
"投公司新一轮战略规划,明确发展目标、基本原则和重点举措,为公司下一阶段改革发展描绘新的蓝图。董事会 长,国家发展和改革委员会秘书长、新闻发言人,国家发展和改革委员会副主任,\n",
|
||||
"专门委员会根据授权,重点关注关系企业长远发展的重大事项,为董事会出谋划策,推动公司高质量发展迈上新 国家粮食和物资储备局局长。现任国家发展和改革委员会副主任,并兼任本公司非\n",
|
||||
"台阶。 执行董事。\n",
|
||||
" 许宏才\n",
|
||||
" 非执行董事\n",
|
||||
"董事会成员 1963年出生,经济学学士。历任财政部预算司副司长、司长,财政部部长助理,财\n",
|
||||
" 政部副部长。现任全国人大财政经济委员会副主任委员、全国人大常委会预算工作\n",
|
||||
" 彭 纯 \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(documents[0].get_content()[1000:10000])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "640f0679-7f7e-4b0a-a46d-b099ae382fe2",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# download another copy with a different name to avoid hitting pdf cache\n",
|
||||
"!wget \"https://www.dropbox.com/scl/fi/g5ojyzk4m44hl7neut6vc/chinese_pdf.pdf?rlkey=45reu51kjvdvic6zucr8v9sh3&dl=1\" -O chinese_pdf2.pdf"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 31,
|
||||
"id": "bfcacf90-ca67-4bfd-b023-be0af2cb18c5",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id 99538f59-24f7-4f1e-ab27-4081933fa5ee\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_parse import LlamaParse\n",
|
||||
"\n",
|
||||
"base_parser = LlamaParse(\n",
|
||||
" result_type=\"text\",\n",
|
||||
" language=\"en\"\n",
|
||||
")\n",
|
||||
"base_documents = parser.load_data(\"./chinese_pdf2.pdf\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "b264ed4e-647a-4f51-9f79-fdf82b76762a",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"print(base_documents[0].get_content()[1000:10000])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d9f02762-bb97-4e0e-8268-ccc00612a974",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "llama_parse",
|
||||
"language": "python",
|
||||
"name": "llama_parse"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.8"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,615 @@
|
||||
{
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"provenance": []
|
||||
},
|
||||
"kernelspec": {
|
||||
"name": "python3",
|
||||
"display_name": "Python 3"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "python"
|
||||
}
|
||||
},
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"# LlamaParse - Parsing comic books with parsing intructions\n",
|
||||
"Parsing intructions allow you to instruct our parsing model the same way you would instruct an LLM!\n",
|
||||
"\n",
|
||||
"They can be usefull to help the parser get better results on complex document layouts, to extract data in a specific format, or to transform the document in other ways.\n",
|
||||
"\n",
|
||||
"Using Parsing Instruction you will get better results out of LlamaParse on complicated documents, and also be able to simplify your application code."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "eld1dKaN7P8B"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Installation\n",
|
||||
"\n",
|
||||
"Parsing instructions are part of the llamaParse API. They can be accessed by directly specifying the parsing_instruction parameter in the API or by using the LlamaParse python module (which we will use for this tutorial).\n",
|
||||
"\n",
|
||||
"To install llama-parse, just get it from PIP:"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "goB1sV8zu_Xl"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"!pip install llama-parse"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "7Y3_BwQLu-qK",
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"outputId": "652f8957-ae7a-48e3-86ae-2e9e885c4e1e"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"Collecting llama-parse\n",
|
||||
" Downloading llama_parse-0.3.8-py3-none-any.whl (6.7 kB)\n",
|
||||
"Collecting llama-index-core>=0.10.7 (from llama-parse)\n",
|
||||
" Downloading llama_index_core-0.10.19-py3-none-any.whl (15.3 MB)\n",
|
||||
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m15.3/15.3 MB\u001b[0m \u001b[31m31.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
|
||||
"\u001b[?25hRequirement already satisfied: PyYAML>=6.0.1 in /usr/local/lib/python3.10/dist-packages (from llama-index-core>=0.10.7->llama-parse) (6.0.1)\n",
|
||||
"Requirement already satisfied: SQLAlchemy[asyncio]>=1.4.49 in /usr/local/lib/python3.10/dist-packages (from llama-index-core>=0.10.7->llama-parse) (2.0.28)\n",
|
||||
"Requirement already satisfied: aiohttp<4.0.0,>=3.8.6 in /usr/local/lib/python3.10/dist-packages (from llama-index-core>=0.10.7->llama-parse) (3.9.3)\n",
|
||||
"Collecting dataclasses-json (from llama-index-core>=0.10.7->llama-parse)\n",
|
||||
" Downloading dataclasses_json-0.6.4-py3-none-any.whl (28 kB)\n",
|
||||
"Collecting deprecated>=1.2.9.3 (from llama-index-core>=0.10.7->llama-parse)\n",
|
||||
" Downloading Deprecated-1.2.14-py2.py3-none-any.whl (9.6 kB)\n",
|
||||
"Collecting dirtyjson<2.0.0,>=1.0.8 (from llama-index-core>=0.10.7->llama-parse)\n",
|
||||
" Downloading dirtyjson-1.0.8-py3-none-any.whl (25 kB)\n",
|
||||
"Requirement already satisfied: fsspec>=2023.5.0 in /usr/local/lib/python3.10/dist-packages (from llama-index-core>=0.10.7->llama-parse) (2023.6.0)\n",
|
||||
"Collecting httpx (from llama-index-core>=0.10.7->llama-parse)\n",
|
||||
" Downloading httpx-0.27.0-py3-none-any.whl (75 kB)\n",
|
||||
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m75.6/75.6 kB\u001b[0m \u001b[31m6.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
|
||||
"\u001b[?25hCollecting llamaindex-py-client<0.2.0,>=0.1.13 (from llama-index-core>=0.10.7->llama-parse)\n",
|
||||
" Downloading llamaindex_py_client-0.1.13-py3-none-any.whl (107 kB)\n",
|
||||
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m108.0/108.0 kB\u001b[0m \u001b[31m10.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
|
||||
"\u001b[?25hRequirement already satisfied: nest-asyncio<2.0.0,>=1.5.8 in /usr/local/lib/python3.10/dist-packages (from llama-index-core>=0.10.7->llama-parse) (1.6.0)\n",
|
||||
"Requirement already satisfied: networkx>=3.0 in /usr/local/lib/python3.10/dist-packages (from llama-index-core>=0.10.7->llama-parse) (3.2.1)\n",
|
||||
"Requirement already satisfied: nltk<4.0.0,>=3.8.1 in /usr/local/lib/python3.10/dist-packages (from llama-index-core>=0.10.7->llama-parse) (3.8.1)\n",
|
||||
"Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (from llama-index-core>=0.10.7->llama-parse) (1.25.2)\n",
|
||||
"Collecting openai>=1.1.0 (from llama-index-core>=0.10.7->llama-parse)\n",
|
||||
" Downloading openai-1.13.3-py3-none-any.whl (227 kB)\n",
|
||||
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m227.4/227.4 kB\u001b[0m \u001b[31m16.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
|
||||
"\u001b[?25hRequirement already satisfied: pandas in /usr/local/lib/python3.10/dist-packages (from llama-index-core>=0.10.7->llama-parse) (1.5.3)\n",
|
||||
"Requirement already satisfied: pillow>=9.0.0 in /usr/local/lib/python3.10/dist-packages (from llama-index-core>=0.10.7->llama-parse) (9.4.0)\n",
|
||||
"Requirement already satisfied: requests>=2.31.0 in /usr/local/lib/python3.10/dist-packages (from llama-index-core>=0.10.7->llama-parse) (2.31.0)\n",
|
||||
"Requirement already satisfied: tenacity<9.0.0,>=8.2.0 in /usr/local/lib/python3.10/dist-packages (from llama-index-core>=0.10.7->llama-parse) (8.2.3)\n",
|
||||
"Collecting tiktoken>=0.3.3 (from llama-index-core>=0.10.7->llama-parse)\n",
|
||||
" Downloading tiktoken-0.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.8 MB)\n",
|
||||
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.8/1.8 MB\u001b[0m \u001b[31m43.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
|
||||
"\u001b[?25hRequirement already satisfied: tqdm<5.0.0,>=4.66.1 in /usr/local/lib/python3.10/dist-packages (from llama-index-core>=0.10.7->llama-parse) (4.66.2)\n",
|
||||
"Requirement already satisfied: typing-extensions>=4.5.0 in /usr/local/lib/python3.10/dist-packages (from llama-index-core>=0.10.7->llama-parse) (4.10.0)\n",
|
||||
"Collecting typing-inspect>=0.8.0 (from llama-index-core>=0.10.7->llama-parse)\n",
|
||||
" Downloading typing_inspect-0.9.0-py3-none-any.whl (8.8 kB)\n",
|
||||
"Requirement already satisfied: aiosignal>=1.1.2 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.6->llama-index-core>=0.10.7->llama-parse) (1.3.1)\n",
|
||||
"Requirement already satisfied: attrs>=17.3.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.6->llama-index-core>=0.10.7->llama-parse) (23.2.0)\n",
|
||||
"Requirement already satisfied: frozenlist>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.6->llama-index-core>=0.10.7->llama-parse) (1.4.1)\n",
|
||||
"Requirement already satisfied: multidict<7.0,>=4.5 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.6->llama-index-core>=0.10.7->llama-parse) (6.0.5)\n",
|
||||
"Requirement already satisfied: yarl<2.0,>=1.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.6->llama-index-core>=0.10.7->llama-parse) (1.9.4)\n",
|
||||
"Requirement already satisfied: async-timeout<5.0,>=4.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.6->llama-index-core>=0.10.7->llama-parse) (4.0.3)\n",
|
||||
"Requirement already satisfied: wrapt<2,>=1.10 in /usr/local/lib/python3.10/dist-packages (from deprecated>=1.2.9.3->llama-index-core>=0.10.7->llama-parse) (1.14.1)\n",
|
||||
"Requirement already satisfied: pydantic>=1.10 in /usr/local/lib/python3.10/dist-packages (from llamaindex-py-client<0.2.0,>=0.1.13->llama-index-core>=0.10.7->llama-parse) (2.6.3)\n",
|
||||
"Requirement already satisfied: anyio in /usr/local/lib/python3.10/dist-packages (from httpx->llama-index-core>=0.10.7->llama-parse) (3.7.1)\n",
|
||||
"Requirement already satisfied: certifi in /usr/local/lib/python3.10/dist-packages (from httpx->llama-index-core>=0.10.7->llama-parse) (2024.2.2)\n",
|
||||
"Collecting httpcore==1.* (from httpx->llama-index-core>=0.10.7->llama-parse)\n",
|
||||
" Downloading httpcore-1.0.4-py3-none-any.whl (77 kB)\n",
|
||||
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m77.8/77.8 kB\u001b[0m \u001b[31m8.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
|
||||
"\u001b[?25hRequirement already satisfied: idna in /usr/local/lib/python3.10/dist-packages (from httpx->llama-index-core>=0.10.7->llama-parse) (3.6)\n",
|
||||
"Requirement already satisfied: sniffio in /usr/local/lib/python3.10/dist-packages (from httpx->llama-index-core>=0.10.7->llama-parse) (1.3.1)\n",
|
||||
"Collecting h11<0.15,>=0.13 (from httpcore==1.*->httpx->llama-index-core>=0.10.7->llama-parse)\n",
|
||||
" Downloading h11-0.14.0-py3-none-any.whl (58 kB)\n",
|
||||
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m5.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
|
||||
"\u001b[?25hRequirement already satisfied: click in /usr/local/lib/python3.10/dist-packages (from nltk<4.0.0,>=3.8.1->llama-index-core>=0.10.7->llama-parse) (8.1.7)\n",
|
||||
"Requirement already satisfied: joblib in /usr/local/lib/python3.10/dist-packages (from nltk<4.0.0,>=3.8.1->llama-index-core>=0.10.7->llama-parse) (1.3.2)\n",
|
||||
"Requirement already satisfied: regex>=2021.8.3 in /usr/local/lib/python3.10/dist-packages (from nltk<4.0.0,>=3.8.1->llama-index-core>=0.10.7->llama-parse) (2023.12.25)\n",
|
||||
"Requirement already satisfied: distro<2,>=1.7.0 in /usr/lib/python3/dist-packages (from openai>=1.1.0->llama-index-core>=0.10.7->llama-parse) (1.7.0)\n",
|
||||
"Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests>=2.31.0->llama-index-core>=0.10.7->llama-parse) (3.3.2)\n",
|
||||
"Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests>=2.31.0->llama-index-core>=0.10.7->llama-parse) (2.0.7)\n",
|
||||
"Requirement already satisfied: greenlet!=0.4.17 in /usr/local/lib/python3.10/dist-packages (from SQLAlchemy[asyncio]>=1.4.49->llama-index-core>=0.10.7->llama-parse) (3.0.3)\n",
|
||||
"Collecting mypy-extensions>=0.3.0 (from typing-inspect>=0.8.0->llama-index-core>=0.10.7->llama-parse)\n",
|
||||
" Downloading mypy_extensions-1.0.0-py3-none-any.whl (4.7 kB)\n",
|
||||
"Collecting marshmallow<4.0.0,>=3.18.0 (from dataclasses-json->llama-index-core>=0.10.7->llama-parse)\n",
|
||||
" Downloading marshmallow-3.21.1-py3-none-any.whl (49 kB)\n",
|
||||
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.4/49.4 kB\u001b[0m \u001b[31m4.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
|
||||
"\u001b[?25hRequirement already satisfied: python-dateutil>=2.8.1 in /usr/local/lib/python3.10/dist-packages (from pandas->llama-index-core>=0.10.7->llama-parse) (2.8.2)\n",
|
||||
"Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas->llama-index-core>=0.10.7->llama-parse) (2023.4)\n",
|
||||
"Requirement already satisfied: exceptiongroup in /usr/local/lib/python3.10/dist-packages (from anyio->httpx->llama-index-core>=0.10.7->llama-parse) (1.2.0)\n",
|
||||
"Requirement already satisfied: packaging>=17.0 in /usr/local/lib/python3.10/dist-packages (from marshmallow<4.0.0,>=3.18.0->dataclasses-json->llama-index-core>=0.10.7->llama-parse) (23.2)\n",
|
||||
"Requirement already satisfied: annotated-types>=0.4.0 in /usr/local/lib/python3.10/dist-packages (from pydantic>=1.10->llamaindex-py-client<0.2.0,>=0.1.13->llama-index-core>=0.10.7->llama-parse) (0.6.0)\n",
|
||||
"Requirement already satisfied: pydantic-core==2.16.3 in /usr/local/lib/python3.10/dist-packages (from pydantic>=1.10->llamaindex-py-client<0.2.0,>=0.1.13->llama-index-core>=0.10.7->llama-parse) (2.16.3)\n",
|
||||
"Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/dist-packages (from python-dateutil>=2.8.1->pandas->llama-index-core>=0.10.7->llama-parse) (1.16.0)\n",
|
||||
"Installing collected packages: dirtyjson, mypy-extensions, marshmallow, h11, deprecated, typing-inspect, tiktoken, httpcore, httpx, dataclasses-json, openai, llamaindex-py-client, llama-index-core, llama-parse\n",
|
||||
"Successfully installed dataclasses-json-0.6.4 deprecated-1.2.14 dirtyjson-1.0.8 h11-0.14.0 httpcore-1.0.4 httpx-0.27.0 llama-index-core-0.10.19 llama-parse-0.3.8 llamaindex-py-client-0.1.13 marshmallow-3.21.1 mypy-extensions-1.0.0 openai-1.13.3 tiktoken-0.6.0 typing-inspect-0.9.0\n"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## API key\n",
|
||||
"\n",
|
||||
"The use of LlamaParse requires an API key which you can get here: https://cloud.llamaindex.ai/parse"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "i-Rg2D_Rvf2i"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "af6i2P1vuU-U"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"os.environ[\"LLAMA_CLOUD_API_KEY\"] = \"llx-...\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Async (Notebook only)\n",
|
||||
"llama-parse is async-first, so running the code in a notebook requires the use of nest_asyncio\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "p8Eq-aX-wAEo"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"import nest_asyncio\n",
|
||||
"\n",
|
||||
"nest_asyncio.apply()"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "4OB0BkTqv_0l"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Import the package"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "dz927ecMyYo_"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"from llama_parse import LlamaParse"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "nSW-6sEwyXwx"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Using llamaparse for getting better results (on Manga!)\n",
|
||||
"\n",
|
||||
"Sometimes the layout of a page is unusual and you will get sub-optimal reading order results with LlamaParse. For example, when parsing manga you expect the reading order to be right to left even if the content is in English!"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "l_D4YsAHwUSk"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"Let's download an extract of a great manga \"The manga guide to calculus\", by Hiroyuki Kojima (https://www.amazon.com/Manga-Guide-Calculus-Hiroyuki-Kojima/dp/1593271948)\n",
|
||||
"\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "SV4K2RivxzJG"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"! wget \"https://drive.usercontent.google.com/uc?id=1tZJhcpepLRdQFJFCFX50QIqLyLgqzZsY&export=download\" -O ./manga.pdf"
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "d3qeuiyawT0U",
|
||||
"outputId": "e6da0635-dea2-4f2b-ec03-d8db99a75e17"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"--2024-03-13 13:57:19-- https://drive.usercontent.google.com/uc?id=1tZJhcpepLRdQFJFCFX50QIqLyLgqzZsY&export=download\n",
|
||||
"Resolving drive.usercontent.google.com (drive.usercontent.google.com)... 173.194.211.132, 2607:f8b0:400c:c10::84\n",
|
||||
"Connecting to drive.usercontent.google.com (drive.usercontent.google.com)|173.194.211.132|:443... connected.\n",
|
||||
"HTTP request sent, awaiting response... 303 See Other\n",
|
||||
"Location: https://drive.usercontent.google.com/download?id=1tZJhcpepLRdQFJFCFX50QIqLyLgqzZsY&export=download [following]\n",
|
||||
"--2024-03-13 13:57:19-- https://drive.usercontent.google.com/download?id=1tZJhcpepLRdQFJFCFX50QIqLyLgqzZsY&export=download\n",
|
||||
"Reusing existing connection to drive.usercontent.google.com:443.\n",
|
||||
"HTTP request sent, awaiting response... 200 OK\n",
|
||||
"Length: 3041634 (2.9M) [application/octet-stream]\n",
|
||||
"Saving to: ‘./manga.pdf’\n",
|
||||
"\n",
|
||||
"./manga.pdf 100%[===================>] 2.90M --.-KB/s in 0.04s \n",
|
||||
"\n",
|
||||
"2024-03-13 13:57:20 (78.6 MB/s) - ‘./manga.pdf’ saved [3041634/3041634]\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### Without parsing instructions\n",
|
||||
"For the sake of comparison, let's first parse without any instructions."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "Gbr8RiHEyF3-"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"vanilaParsing = LlamaParse(result_type=\"markdown\").load_data(\"./manga.pdf\")"
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "3jKnXCuAyQ9_",
|
||||
"outputId": "8ab58d56-8c51-44de-8d34-0d94b1bb440f"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"Started parsing the file under job_id 25bf4202-78d8-4705-88cf-c616ae7c82af\n"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"As you can see below, LlamaParse is not doing a great job here. It is interpreting the grid of comic panels as a table, and trying to fit the dialogue into a table. It's very hard to follow."
|
||||
],
|
||||
"metadata": {
|
||||
"id": "p4GVOdWzzvYg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"print(vanilaParsing[0].text[100:1000])"
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "ZMhWfKrzzhgQ",
|
||||
"outputId": "5426c0cc-7e62-4836-9877-87258e1f0b6f"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"\n",
|
||||
"The Asagake Times Sanda-Cho Distributor\n",
|
||||
"\n",
|
||||
"A newspaper distributor? do I have the wrong map?\n",
|
||||
"\n",
|
||||
"You’re looking It’s next for the Sanda-cho door. branch office? Everybody mistakes us for the office because we are larger. What Is a Function? 3\n",
|
||||
"---\n",
|
||||
"## Calculating the Derivative of a Constant, Linear, or Quadratic Function\n",
|
||||
"\n",
|
||||
"|1.|Let’s find the derivative of constant function f(x) = α. The differential coefficient of f(x) at x = a is|\n",
|
||||
"|---|---|\n",
|
||||
"| |lim ε→0 (f(a + ε) - f(a)) / ε = lim ε→0 (α - α) = lim ε→0 0 = 0|\n",
|
||||
"| |Thus, the derivative of f(x) is f′(x) = 0. This makes sense, since our function is constant—the rate of change is 0.|\n",
|
||||
"\n",
|
||||
"Note: The differential coefficient of f(x) at x = a is often simply called the derivative of f(x) at x = a, or just f′(a).\n",
|
||||
"\n",
|
||||
"|2.|Let’s calculate the derivative of linear function f(x) = αx + β. The derivative of f(x) at x = α is|\n",
|
||||
"|---|---|\n",
|
||||
"| |lim ε→0 (f(α + ε) - f(a)) = \n"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### Using parsing instructions\n",
|
||||
"Let's try to parse the manga with custom instructions:\n",
|
||||
"\n",
|
||||
"\"The provided document is a manga comic book. Most pages do NOT have title. It does not contain tables. Try to reconstruct the dialogue happening in a cohesive way.\"\n",
|
||||
"\n",
|
||||
"To do so just pass the parsing instruction as a parameter to LlamaParse:"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "sUq6znUryiu0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"parsingInstructionManga = \"\"\"The provided document is a manga comic book, most page do NOT have title.\n",
|
||||
"It does not contain table.\n",
|
||||
"Try to reconstruct the dialog happening in a cohesive way.\"\"\"\n",
|
||||
"withInstructionParsing = LlamaParse(result_type=\"markdown\", parsing_instruction=parsingInstructionManga).load_data(\"./manga.pdf\")"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "dEX7Mv9V0UvM",
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"outputId": "184b77b7-7e3a-4991-f2c9-eb9105a35a7b"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"Started parsing the file under job_id 88ab273e-b2a7-4f84-8e72-e9367cf6b114\n",
|
||||
"."
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"Let's see how it compare with page 3! We encourage you to play with the target page and explore other pages. As you will see, the parsing instruction allowed LlamaParse to make sense of the document!\n",
|
||||
"\n",
|
||||
"<img src=\"https://drive.usercontent.google.com/download?id=1M87rXTIZE8d5v7aHmVZVW6gW3eDGq6ks&authuser=0\" />\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "-UQcA-YW2kjd"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"target_page=1\n",
|
||||
"print(vanilaParsing[0].text.split('\\n---\\n')[target_page])\n",
|
||||
"print(\"\\n\\n------------------------------------------------------------\\n\\n\")\n",
|
||||
"print(withInstructionParsing[0].text.split('\\n---\\n')[target_page])"
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "0oPHXg0F0yAS",
|
||||
"outputId": "38b729bc-b0b7-42f2-97e0-b4e9d7d459a1"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"The Asagake Times Sanda-Cho Distributor\n",
|
||||
"\n",
|
||||
"A newspaper distributor? do I have the wrong map?\n",
|
||||
"\n",
|
||||
"You’re looking It’s next for the Sanda-cho door. branch office? Everybody mistakes us for the office because we are larger. What Is a Function? 3\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"------------------------------------------------------------\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# The Asagake Times\n",
|
||||
"\n",
|
||||
"Sanda-Cho Distributor\n",
|
||||
"\n",
|
||||
"A newspaper distributor?\n",
|
||||
"\n",
|
||||
"Do I have the wrong map?\n",
|
||||
"\n",
|
||||
"You're looking for the Sanda-cho branch office?\n",
|
||||
"\n",
|
||||
"It's next door.\n",
|
||||
"\n",
|
||||
"Everybody mistakes us for the office because we are larger.\n",
|
||||
"\n",
|
||||
"What Is a Function? 3\n"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### Math - doing more with parsing instuction!\n",
|
||||
"\n",
|
||||
"But this manga is about math and full of equations, why not ask the parser to output them in **LaTeX**?\n",
|
||||
"\n",
|
||||
"<img src=\"https://drive.usercontent.google.com/download?id=1tze3xcQ7axVA-vC_iZeAj_GvYcyNuYDa&authuser=0\" />"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "yU_jyYWI5fMH"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"parsingInstructionMangaLatex = \"\"\"The provided document is a manga comic book, most page do NOT have title.\n",
|
||||
"It does not contain table. Do not output table.\n",
|
||||
"Try to reconstruct the dialog happening in a cohesive way.\n",
|
||||
"Output any math equation in LATEX markdown (between $$)\"\"\"\n",
|
||||
"withLatex = LlamaParse(result_type=\"markdown\", parsing_instruction=parsingInstructionMangaLatex).load_data(\"./manga.pdf\")"
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "FP_YdO2y5e5o",
|
||||
"outputId": "45171cdd-298a-4f1f-e67d-6be3cb1a1156"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"Started parsing the file under job_id 3a055e64-d91e-484e-b9b0-99a2e637c08d\n",
|
||||
"."
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"target_page=2\n",
|
||||
"print(\"\\n\\n[Without instruction]------------------------------------------------------------\\n\\n\")\n",
|
||||
"print(vanilaParsing[0].text.split('\\n---\\n')[target_page])\n",
|
||||
"print(\"\\n\\n[With instruction to output math in LATEX!]------------------------------------------------------------\\n\\n\")\n",
|
||||
"print(withLatex[0].text.split('\\n---\\n')[target_page])\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "TntdRRGp6Rui",
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"outputId": "e2e503fa-eb87-4f78-83d8-209fe7cebd9e"
|
||||
},
|
||||
"execution_count": null,
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"\n",
|
||||
"\n",
|
||||
"[Without instruction]------------------------------------------------------------\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"## Calculating the Derivative of a Constant, Linear, or Quadratic Function\n",
|
||||
"\n",
|
||||
"|1.|Let’s find the derivative of constant function f(x) = α. The differential coefficient of f(x) at x = a is|\n",
|
||||
"|---|---|\n",
|
||||
"| |lim ε→0 (f(a + ε) - f(a)) / ε = lim ε→0 (α - α) = lim ε→0 0 = 0|\n",
|
||||
"| |Thus, the derivative of f(x) is f′(x) = 0. This makes sense, since our function is constant—the rate of change is 0.|\n",
|
||||
"\n",
|
||||
"Note: The differential coefficient of f(x) at x = a is often simply called the derivative of f(x) at x = a, or just f′(a).\n",
|
||||
"\n",
|
||||
"|2.|Let’s calculate the derivative of linear function f(x) = αx + β. The derivative of f(x) at x = α is|\n",
|
||||
"|---|---|\n",
|
||||
"| |lim ε→0 (f(α + ε) - f(a)) = lim ε→0 (α(a + ε) + β - (αa + β)) = lim ε→0 α = α|\n",
|
||||
"| |Thus, the derivative of f(x) is f′(x) = α, a constant value. This result should also be intuitive—linear functions have a constant rate of change by definition.|\n",
|
||||
"\n",
|
||||
"|3.|Let’s find the derivative of f(x) = x^2, which appeared in the story. The differential coefficient of f(x) at x = a is|\n",
|
||||
"|---|---|\n",
|
||||
"| |lim ε→0 ((a + ε)^2 - a^2) / ε = lim (a^2 + 2aε + ε^2 - a^2) / ε = lim (2aε + ε^2) = lim (2a + ε) = 2a|\n",
|
||||
"| |Thus, the differential coefficient of f(x) at x = a is 2a, or f′(a) = 2a. Therefore, the derivative of f(x) is f′(x) = 2x.|\n",
|
||||
"\n",
|
||||
"## Summary\n",
|
||||
"\n",
|
||||
"- The calculation of a limit that appears in calculus is simply a formula calculating an error.\n",
|
||||
"- A limit is used to obtain a derivative.\n",
|
||||
"- The derivative is the slope of the tangent line at a given point.\n",
|
||||
"- The derivative is nothing but the rate of change.\n",
|
||||
"\n",
|
||||
"## Chapter 1 Let’s Differentiate a Function!\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"[With instruction to output math in LATEX!]------------------------------------------------------------\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Derivative of Constant, Linear, or Quadratic Function\n",
|
||||
"\n",
|
||||
"## Calculating the Derivative of a Constant, Linear, or Quadratic Function\n",
|
||||
"\n",
|
||||
"1. Let’s find the derivative of constant function f(x) = α. The differential coefficient of f(x) at x = a is\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"\\begin{align*}\n",
|
||||
"&\\lim_{{\\varepsilon \\to 0}} \\left( \\frac{f(a + \\varepsilon) - f(a)}{\\varepsilon} \\right) = \\lim_{{\\varepsilon \\to 0}} \\frac{\\alpha - \\alpha}{\\varepsilon} = \\lim_{{\\varepsilon \\to 0}} 0 = 0 \\\\\n",
|
||||
"\\end{align*}\n",
|
||||
"$$\n",
|
||||
"Thus, the derivative of f(x) is f′(x) = 0. This makes sense, since our function is constant—the rate of change is 0.\n",
|
||||
"\n",
|
||||
"Note: The differential coefficient of f(x) at x = a is often simply called the derivative of f(x) at x = a, or just f′(a).\n",
|
||||
"\n",
|
||||
"2. Let’s calculate the derivative of linear function f(x) = αx + β. The derivative of f(x) at x = α is\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"\\begin{align*}\n",
|
||||
"&\\lim_{{\\varepsilon \\to 0}} \\left( \\frac{f(\\alpha + \\varepsilon) - f(a)}{\\varepsilon} \\right) = \\lim_{{\\varepsilon \\to 0}} \\frac{\\alpha(a + \\varepsilon) + \\beta - (\\alpha a + \\beta)}{\\varepsilon} = \\lim_{{\\varepsilon \\to 0}} \\alpha = \\alpha \\\\\n",
|
||||
"\\end{align*}\n",
|
||||
"$$\n",
|
||||
"Thus, the derivative of f(x) is f′(x) = α, a constant value. This result should also be intuitive—linear functions have a constant rate of change by definition.\n",
|
||||
"\n",
|
||||
"3. Let’s find the derivative of f(x) = x2. The differential coefficient of f(x) at x = a is\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"\\begin{align*}\n",
|
||||
"&\\lim_{{\\varepsilon \\to 0}} \\left( \\frac{f(a + \\varepsilon) - f(a)}{\\varepsilon} \\right) = \\lim_{{\\varepsilon \\to 0}} \\left( (a + \\varepsilon)^2 - a^2 \\right) = \\lim_{{\\varepsilon \\to 0}} 2a\\varepsilon + \\varepsilon = \\lim_{{\\varepsilon \\to 0}} (2a + \\varepsilon) = 2a \\\\\n",
|
||||
"\\end{align*}\n",
|
||||
"$$\n",
|
||||
"Thus, the differential coefficient of f(x) at x = a is 2a, or f′(a) = 2a. Therefore, the derivative of f(x) is f′(x) = 2x.\n",
|
||||
"\n",
|
||||
"### Summary\n",
|
||||
"\n",
|
||||
"- The calculation of a limit that appears in calculus is simply a formula calculating an error.\n",
|
||||
"- A limit is used to obtain a derivative.\n",
|
||||
"- The derivative is the slope of the tangent line at a given point.\n",
|
||||
"- The derivative is nothing but the rate of change.\n"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"And here is the result as rendered by https://upmath.me/ .\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"<img src=\"https://drive.usercontent.google.com/download?id=1qGo5bMGYOiIC9MnprcgEByaYjU9YII2Q&authuser=0\" />\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Over this short notebook we saw how to use parsing instructions to increase the quality and accuracy of parsing with LLamaParse!"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "rfFdeWZKmmLW"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,391 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# RAG for Table Comparisons with LlamaParse + LlamaIndex\n",
|
||||
"\n",
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_parse/blob/main/examples/demo_table_comparisons.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>\n",
|
||||
"\n",
|
||||
"This notebook shows you how to do comparisons across both tabular and text data across multiple PDF documents.\n",
|
||||
"\n",
|
||||
"We load in multiple PDFs with embedded tables (2021 and 2020 10K filings for Apple) using LlamaParse, parse each into a hierarchy of tables/text objects, define a recursive retriever over each, and then compose both with a SubQuestionQueryEngine."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setup\n",
|
||||
"\n",
|
||||
"Install core packages, download files, parse documents."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install llama-index\n",
|
||||
"!pip install llama-index-core\n",
|
||||
"!pip install llama-index-embeddings-openai\n",
|
||||
"!pip install llama-index-question-gen-openai\n",
|
||||
"!pip install llama-index-postprocessor-flag-embedding-reranker\n",
|
||||
"!pip install git+https://github.com/FlagOpen/FlagEmbedding.git\n",
|
||||
"!pip install llama-parse"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!wget \"https://s2.q4cdn.com/470004039/files/doc_financials/2020/ar/_10-K-2020-(As-Filed).pdf\" -O apple_2020_10k.pdf\n",
|
||||
"!wget \"https://s2.q4cdn.com/470004039/files/doc_financials/2021/q4/_10-K-2021-(As-Filed).pdf\" -O apple_2021_10k.pdf"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Some OpenAI and LlamaParse details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# llama-parse is async-first, running the async code in a notebook requires the use of nest_asyncio\n",
|
||||
"import nest_asyncio\n",
|
||||
"nest_asyncio.apply()\n",
|
||||
"\n",
|
||||
"import os\n",
|
||||
"# API access to llama-cloud\n",
|
||||
"os.environ[\"LLAMA_CLOUD_API_KEY\"] = \"llx-\"\n",
|
||||
"\n",
|
||||
"# Using OpenAI API for embeddings/llms\n",
|
||||
"os.environ[\"OPENAI_API_KEY\"] = \"sk-\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.llms.openai import OpenAI\n",
|
||||
"from llama_index.embeddings.openai import OpenAIEmbedding\n",
|
||||
"from llama_index.core import VectorStoreIndex\n",
|
||||
"from llama_index.core import Settings\n",
|
||||
"\n",
|
||||
"embed_model=OpenAIEmbedding(model=\"text-embedding-3-small\")\n",
|
||||
"llm = OpenAI(model=\"gpt-3.5-turbo-0125\")\n",
|
||||
"\n",
|
||||
"Settings.llm = llm\n",
|
||||
"Settings.embed_model = embed_model\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Using brand new `LlamaParse` PDF reader for PDF Parsing\n",
|
||||
"\n",
|
||||
"we also compare two different retrieval/query engine strategies:\n",
|
||||
"1. Using raw Markdown text as nodes for building index and apply simple query engine for generating the results;\n",
|
||||
"2. Using `MarkdownElementNodeParser` for parsing the `LlamaParse` output Markdown results and building recursive retriever query engine for generation."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_parse import LlamaParse\n",
|
||||
"\n",
|
||||
"docs_2021 = LlamaParse(result_type=\"markdown\").load_data('./apple_2021_10k.pdf')\n",
|
||||
"docs_2020 = LlamaParse(result_type=\"markdown\").load_data('./apple_2020_10k.pdf')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Create Recursive Retriever over each Document\n",
|
||||
"\n",
|
||||
"We define a function to get a recursive retriever from each document. The steps are the following:\n",
|
||||
"- Hierarchically parse the document using our `MarkdownElementNodeParser`, which will embed/summarize embedded tables.\n",
|
||||
"- Load into a vector store. Under the hood we will automatically store links between nodes (e.g. table summary to table text).\n",
|
||||
"- Get a query engine over the vector store, which performs retrieval/synthesis. Under the hood we will automatically perform recursive retrieval if there are links."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 36,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.node_parser import MarkdownElementNodeParser\n",
|
||||
"\n",
|
||||
"node_parser = MarkdownElementNodeParser(llm=OpenAI(model=\"gpt-3.5-turbo-0125\"), num_workers=8)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 46,
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pickle\n",
|
||||
"from llama_index.postprocessor.flag_embedding_reranker import FlagEmbeddingReranker\n",
|
||||
"\n",
|
||||
"reranker = FlagEmbeddingReranker(\n",
|
||||
" top_n=5,\n",
|
||||
" model=\"BAAI/bge-reranker-large\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"def create_query_engine_over_doc(docs, nodes_save_path=None):\n",
|
||||
" \"\"\"Big function to go from document path -> recursive retriever.\"\"\"\n",
|
||||
" if nodes_save_path is not None and os.path.exists(nodes_save_path):\n",
|
||||
" raw_nodes = pickle.load(open(nodes_save_path, \"rb\"))\n",
|
||||
" else:\n",
|
||||
" raw_nodes = node_parser.get_nodes_from_documents(docs)\n",
|
||||
" if nodes_save_path is not None:\n",
|
||||
" pickle.dump(raw_nodes, open(nodes_save_path, \"wb\"))\n",
|
||||
"\n",
|
||||
" base_nodes, objects = node_parser.get_nodes_and_objects(\n",
|
||||
" raw_nodes\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" ### Construct Retrievers\n",
|
||||
" # construct top-level vector index + query engine\n",
|
||||
" vector_index = VectorStoreIndex(nodes=base_nodes+objects)\n",
|
||||
" query_engine = vector_index.as_query_engine(\n",
|
||||
" similarity_top_k=15,\n",
|
||||
" node_postprocessors=[reranker]\n",
|
||||
" )\n",
|
||||
" return query_engine, base_nodes"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_engine_2021, nodes_2021 = create_query_engine_over_doc(\n",
|
||||
" docs_2021, nodes_save_path=\"2021_nodes.pkl\"\n",
|
||||
")\n",
|
||||
"query_engine_2020, nodes_2020 = create_query_engine_over_doc(\n",
|
||||
" docs_2020, nodes_save_path=\"2020_nodes.pkl\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 38,
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.tools import QueryEngineTool, ToolMetadata\n",
|
||||
"from llama_index.core.query_engine import SubQuestionQueryEngine\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# setup base query engine as tool\n",
|
||||
"query_engine_tools = [\n",
|
||||
" QueryEngineTool(\n",
|
||||
" query_engine=query_engine_2021,\n",
|
||||
" metadata=ToolMetadata(\n",
|
||||
" name=\"apple_2021_10k\",\n",
|
||||
" description=(\n",
|
||||
" \"Provides information about Apple financials for year 2021\"\n",
|
||||
" ),\n",
|
||||
" ),\n",
|
||||
" ),\n",
|
||||
" QueryEngineTool(\n",
|
||||
" query_engine=query_engine_2020,\n",
|
||||
" metadata=ToolMetadata(\n",
|
||||
" name=\"apple_2020_10k\",\n",
|
||||
" description=(\n",
|
||||
" \"Provides information about Apple financials for year 2020\"\n",
|
||||
" ),\n",
|
||||
" ),\n",
|
||||
" ),\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"sub_query_engine = SubQuestionQueryEngine.from_defaults(\n",
|
||||
" query_engine_tools=query_engine_tools,\n",
|
||||
" llm=llm,\n",
|
||||
" use_async=True,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Try out Some Comparisons"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 41,
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Generated 4 sub questions.\n",
|
||||
"\u001b[1;3;38;2;237;90;200m[apple_2021_10k] Q: What are the deferred assets in 2021?\n",
|
||||
"\u001b[0m\u001b[1;3;38;2;90;149;237m[apple_2021_10k] Q: What are the deferred liabilities in 2021?\n",
|
||||
"\u001b[0m\u001b[1;3;38;2;11;159;203m[apple_2020_10k] Q: What are the deferred assets in 2020?\n",
|
||||
"\u001b[0m\u001b[1;3;38;2;155;135;227m[apple_2020_10k] Q: What are the deferred liabilities in 2020?\n",
|
||||
"\u001b[0m\u001b[1;3;38;2;90;149;237m[apple_2021_10k] A: $7,200\n",
|
||||
"\u001b[0m\u001b[1;3;38;2;155;135;227m[apple_2020_10k] A: $10,138\n",
|
||||
"\u001b[0m\u001b[1;3;38;2;237;90;200m[apple_2021_10k] A: $25,176 million\n",
|
||||
"\u001b[0m\u001b[1;3;38;2;11;159;203m[apple_2020_10k] A: $19,336\n",
|
||||
"\u001b[0m"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"response = sub_query_engine.query(\n",
|
||||
" \"Can you compare and contrast the deferred assets and liabilities in 2021 with 2020?\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 40,
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"In 2021, the deferred assets increased by $5,840 million compared to 2020, while the deferred liabilities decreased by $2,938 million in the same period.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(str(response))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 42,
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Generated 2 sub questions.\n",
|
||||
"\u001b[1;3;38;2;237;90;200m[apple_2021_10k] Q: What is the total number of RSUs in Apple's 2021 financials?\n",
|
||||
"\u001b[0m\u001b[1;3;38;2;90;149;237m[apple_2020_10k] Q: What is the total number of RSUs in Apple's 2020 financials?\n",
|
||||
"\u001b[0m\u001b[1;3;38;2;237;90;200m[apple_2021_10k] A: The total number of RSUs in Apple's 2021 financials is 240,427.\n",
|
||||
"\u001b[0m\u001b[1;3;38;2;90;149;237m[apple_2020_10k] A: The total number of RSUs in Apple's 2020 financials is 310,778.\n",
|
||||
"\u001b[0m"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"response = sub_query_engine.query(\n",
|
||||
" \"Can you compare and contrast the total number of RSUs in 2021 and 2020?\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 44,
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Generated 2 sub questions.\n",
|
||||
"\u001b[1;3;38;2;237;90;200m[apple_2021_10k] Q: What are the risk factors mentioned in the 2021 financial report of Apple?\n",
|
||||
"\u001b[0m\u001b[1;3;38;2;90;149;237m[apple_2020_10k] Q: What are the risk factors mentioned in the 2020 financial report of Apple?\n",
|
||||
"\u001b[0m\u001b[1;3;38;2;237;90;200m[apple_2021_10k] A: The risk factors mentioned in the 2021 financial report of Apple include risks related to COVID-19, macroeconomic and industry risks, political events, trade and international disputes, natural disasters, public health issues, industrial accidents, credit risk, fluctuations in foreign currency exchange rates, changes in tax rates and legislation, volatility in the price of the company's stock, and exposure to legal proceedings and claims.\n",
|
||||
"\u001b[0m\u001b[1;3;38;2;90;149;237m[apple_2020_10k] A: The risk factors mentioned in the 2020 financial report of Apple include the impact of the COVID-19 pandemic on the company's business operations, financial condition, and stock price; global and regional economic conditions affecting demand for products and services; competition in global markets with rapid technological changes; potential disruptions in the supply chain due to industrial accidents or public health issues; information technology system failures or network disruptions affecting business operations; risks associated with confidential information security and potential unauthorized access; fluctuations in quarterly net sales and operating results due to various factors; stock price volatility impacting investor confidence and employee retention; financial performance risks related to changes in foreign currency exchange rates affecting sales and earnings.\n",
|
||||
"\u001b[0m"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"response = sub_query_engine.query(\n",
|
||||
" \"Can you compare and contrast the risk factors in 2021 vs. 2020?\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 45,
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"The risk factors mentioned in the 2021 financial report of Apple include risks related to COVID-19, macroeconomic and industry risks, political events, trade and international disputes, natural disasters, public health issues, industrial accidents, credit risk, fluctuations in foreign currency exchange rates, changes in tax rates and legislation, volatility in the price of the company's stock, and exposure to legal proceedings and claims. In contrast, the risk factors mentioned in the 2020 financial report of Apple focused more on the impact of the COVID-19 pandemic on the company's business operations, financial condition, and stock price; global and regional economic conditions affecting demand for products and services; competition in global markets with rapid technological changes; potential disruptions in the supply chain due to industrial accidents or public health issues; information technology system failures or network disruptions affecting business operations; risks associated with confidential information security and potential unauthorized access; fluctuations in quarterly net sales and operating results due to various factors; stock price volatility impacting investor confidence and employee retention; financial performance risks related to changes in foreign currency exchange rates affecting sales and earnings.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(str(response))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "llama_parse",
|
||||
"language": "python",
|
||||
"name": "llama_parse"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.8"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
@@ -0,0 +1,405 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e0647976-5597-4899-8678-e9a73c19f18b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# LlamaParse over Powerpoint Files\n",
|
||||
"\n",
|
||||
"In this notebook we show you how to build a RAG pipeline over [our talk at PyData Global](https://docs.google.com/presentation/d/1rFQ0hPyYja3HKRdGEgjeDxr0MSE8wiQ2iu4mDtwR6fc/edit?usp=sharing) in 2023.\n",
|
||||
"\n",
|
||||
"We use LlamaParse to load in our slides in .pptx format, and use LlamaIndex to build a RAG pipeline over these files.\n",
|
||||
"\n",
|
||||
"**NOTE**: LlamaParse is capable of image extraction through JSON mode, in this notebook we stick with text."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "14cdcfaf-88b4-4489-9910-e362e0ccec53",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import nest_asyncio\n",
|
||||
"nest_asyncio.apply()\n",
|
||||
"\n",
|
||||
"from llama_parse import LlamaParse"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "6f5b5841-dd3e-4169-9bd4-6a672b5b34ee",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"os.environ[\"LLAMA_CLOUD_API_KEY\"] = \"llx-\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a2a619a1-fdd4-4ff0-85f8-94c125c275eb",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Download Data\n",
|
||||
"\n",
|
||||
"First, download the slides from https://docs.google.com/presentation/d/1rFQ0hPyYja3HKRdGEgjeDxr0MSE8wiQ2iu4mDtwR6fc/edit?usp=sharing and export in .pptx format, and put it in the folder that you're running this notebook.\n",
|
||||
"\n",
|
||||
"Name the file `pydata_global.pptx`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a7e697d9-4463-4be4-908c-0a3e9179a342",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## [Basic] Build a RAG Pipeline over Powerpoint Text\n",
|
||||
"\n",
|
||||
"In this example, we use LlamaParse in markdown mode to extract out text from the slides, and we build a top-k RAG pipeline over it.\n",
|
||||
"\n",
|
||||
"**Notes**: \n",
|
||||
"- This does not use our `MarkdownElementNodeParser`, which is tailored for documents with tables.\n",
|
||||
"- This also does not parse out images (we show that in the next section).\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "0dd0f860-8e92-43a7-9443-ad1a4fb9365c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"parser = LlamaParse(result_type=\"markdown\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "fd932bef-ba82-4449-b7a0-5c2a9b55089f",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id 9c687e37-4239-4c2f-b2a1-2564bfc98473\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"docs = parser.load_data(\"pydata_global.pptx\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "0f41c2bc-02cd-49b5-a98c-f986faa8fffc",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Let's take a look at a few slides."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "2a73e553-2194-4ac9-9764-0edab0d6fdce",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"# Building and Productionizing RAG\n",
|
||||
"\n",
|
||||
"Jerry Liu, LlamaIndex co-founder/CEO\n",
|
||||
"---\n",
|
||||
"|Content|Page Number|\n",
|
||||
"|---|---|\n",
|
||||
"|Document Processing| |\n",
|
||||
"|Tagging & Extraction| |\n",
|
||||
"|Knowledge Base| |\n",
|
||||
"|Knowledge Search & QA| |\n",
|
||||
"|Workflow:| |\n",
|
||||
"|Read latest messages from user A| |\n",
|
||||
"|Send email suggesting next-steps| |\n",
|
||||
"|Document| |\n",
|
||||
"|Human:| |\n",
|
||||
"|Agent:| |\n",
|
||||
"|Topic:| |\n",
|
||||
"|Summary:| |\n",
|
||||
"|Author:| |\n",
|
||||
"|Conversational Agent| |\n",
|
||||
"|Workflow Automation| |\n",
|
||||
"---\n",
|
||||
"Context\n",
|
||||
"\n",
|
||||
"- LLMs are a phenomenal piece of technology for knowledge generation and reasoning. They are pre-trained on large amounts of publicly available data.\n",
|
||||
"\n",
|
||||
"Use Cases\n",
|
||||
"\n",
|
||||
"- Question-Answering\n",
|
||||
"- Text Generation\n",
|
||||
"- Summarization\n",
|
||||
"- Planning\n",
|
||||
"\n",
|
||||
"# LLM’s\n",
|
||||
"---\n",
|
||||
"|Context|\n",
|
||||
"|---|\n",
|
||||
"|How do we best augment LLMs with our own private data?|\n",
|
||||
"|Raw Files|API’s|\n",
|
||||
"| |salesforce|?|\n",
|
||||
"| | |Use Cases|\n",
|
||||
"| | |Question-Answering|\n",
|
||||
"| | |Text Generation|\n",
|
||||
"| | |Summarization|\n",
|
||||
"|Vector Stores|SQL DB’s|\n",
|
||||
"| | |Planning|\n",
|
||||
"| |LLM’s|\n",
|
||||
"| |Milvus|\n",
|
||||
"---\n",
|
||||
"Paradigms for inserting knowledge\n",
|
||||
"\n",
|
||||
"Retrieval Augmentation - Fix pe model, put context into pe prompt\n",
|
||||
"Before college pe two main pings I worked on, outside of school, were writing and programming. I didn't write essays. I wrote what beginning writers were supposed to write pen, and probably still are: short stories. My stories were awful. They had hardly any plot, just characters wip strong feelings, which I imagined made pem deep...\n",
|
||||
"\n",
|
||||
"Input Prompt\n",
|
||||
"\n",
|
||||
"Here is the context:\n",
|
||||
"\n",
|
||||
"Before college the two main things...\n",
|
||||
"\n",
|
||||
"Given the context, answer the following question:\n",
|
||||
"\n",
|
||||
"{query_str} LLM\n",
|
||||
"---\n",
|
||||
"Paradigms for inserting knowledge\n",
|
||||
"\n",
|
||||
"Fine-tuning - baking knowledge into pe weights of pe network\n",
|
||||
"Before college pe two main pings I worked on, outside of school, were writing and programming. I didn't write essays. I wrote what beginning writers were supposed to write pen, and probably still are: short stories. My stories were awful. They had hardly any plot, just characters wip strong feelings, which I imagined made pem deep... LLM RLHF, Adam, SGD, etc.\n",
|
||||
"---\n",
|
||||
"## LlamaIndex: A data framework for LLM applications\n",
|
||||
"\n",
|
||||
"|Data Ingestion (LlamaHub 🦙)|Data Structures|Queries|\n",
|
||||
"|---|---|---|\n",
|
||||
"|Connect your existing data sources and data formats (API’s, PDF’s, docs, SQL, etc.)|Store and index your data for different use cases. Integrate with different db’s (vector db, graph db, kv db)|Retrieve and query over data. Includes: QA, Summarization, Agents, and more|\n",
|
||||
"---\n",
|
||||
"# quickstart py\n",
|
||||
"\n",
|
||||
"from Llama_index import VectorStoreIndex, SimpleDirectoryReader\n",
|
||||
"\n",
|
||||
"SimpleDirectoryReader( ' data' ) . Load_datal)\n",
|
||||
"\n",
|
||||
"documents\n",
|
||||
"\n",
|
||||
"VectorStoreIndex.from_documents\n",
|
||||
"\n",
|
||||
"indexdocuments_\n",
|
||||
"\n",
|
||||
"index.as_query_engine()\n",
|
||||
"\n",
|
||||
"query_engine\n",
|
||||
"\n",
|
||||
"query_engine.query ( \"What did the authordo growingup?\" )\n",
|
||||
"\n",
|
||||
"response\n",
|
||||
"\n",
|
||||
"print(str(response) )Codelmage\n",
|
||||
"---\n",
|
||||
"NO_CONTENT_HERE\n",
|
||||
"---\n",
|
||||
"|Data Ingestion / Parsing|Data Querying|\n",
|
||||
"|---|---|\n",
|
||||
"|Chunk| |\n",
|
||||
"|Chunk| |\n",
|
||||
"|Doc|Chunk|\n",
|
||||
"|Chunk|Chunk|\n",
|
||||
"| |Vector|Chunk|LLM|\n",
|
||||
"| | |Database|\n",
|
||||
"|Chunk| |\n",
|
||||
"| |5 Lines of Code in LlamaIndex!|\n",
|
||||
"---\n",
|
||||
"|Current RAG Stack (Data Ingestion/Parsing)|Process:|\n",
|
||||
"|---|---|\n",
|
||||
"|● Split up document(s) into even chunks.| |\n",
|
||||
"|● Each chunk is a piece of raw text.| |\n",
|
||||
"|Chunk|● Generate embedding for each chunk (e.g. OpenAI embeddings, sentence_transformer)|\n",
|
||||
"|Chunk|● Store each chunk into a vector database|\n",
|
||||
"|Doc|Chunk|\n",
|
||||
"|Chunk|Vector Database|\n",
|
||||
"|Chunk| |\n",
|
||||
"---\n",
|
||||
"|Current RAG Stack (Querying)|\n",
|
||||
"|---|\n",
|
||||
"|Process:|\n",
|
||||
"|● Find top-k most similar chunks from vector database collection|\n",
|
||||
"|● Plug into LLM response synthesis module|\n",
|
||||
"|Chunk|Chunk|LLM|\n",
|
||||
"|Vector|Chunk| |\n",
|
||||
"|Database|\n",
|
||||
"---\n",
|
||||
"|Current RAG Stack (Querying)|\n",
|
||||
"|---|\n",
|
||||
"|Process:|\n",
|
||||
"|● Find top-k most similar chunks from vector database collection|\n",
|
||||
"|● Plug into LLM response synthesis module|\n",
|
||||
"|Chunk|LLM|\n",
|
||||
"|Chunk|\n",
|
||||
"|Vector|\n",
|
||||
"|Database|\n",
|
||||
"|Retrieval|Synthesis|\n",
|
||||
"---\n",
|
||||
"|Query|Nodel|Response|Nodez|\n",
|
||||
"|---|---|---|---|\n",
|
||||
"|Create and Refine|Intermediate| | |\n",
|
||||
"| | |Final|Response|\n",
|
||||
"---\n",
|
||||
"|Query|Node1|Node2|Node3|Node4|\n",
|
||||
"|---|---|---|---|---|\n",
|
||||
"|Tree Summarize| | | | |\n",
|
||||
"---\n",
|
||||
"Quickstart\n",
|
||||
"\n",
|
||||
"Link to Google Colab\n",
|
||||
"---\n",
|
||||
"NO_CONTENT_HERE\n",
|
||||
"---\n",
|
||||
"# Challenges with Naive RAG\n",
|
||||
"\n",
|
||||
"- Failure Modes\n",
|
||||
"- Quality-Related (Hallucination, Accuracy)\n",
|
||||
"- Non-Quality-Related (Latency, Cost, Syncing)\n",
|
||||
"---\n",
|
||||
"## Challenges with Naive RAG (Response Quality)\n",
|
||||
"\n",
|
||||
"|Bad Retrieval|Low Precision: Not all chunks in retrieved set are relevant|Hallucination + Lost in the Middle Problems|\n",
|
||||
"|---|---|---|\n",
|
||||
"| |Low Recall: Now all relevant chunks are retrieved.|Lacks enough context for LLM to synthesize an answer|\n",
|
||||
"| |Outdated information: The data is redundant or out of date.| |\n",
|
||||
"---\n",
|
||||
"## Challenges with Naive RAG (Response Quality)\n",
|
||||
"\n",
|
||||
"|Bad Retrieval|Low Precision: Not all chunks in retrieved set are relevant|Hallucination + Lost in the Middle Problems|\n",
|
||||
"|---|---|---|\n",
|
||||
"| |Low Recall: Now all relevant chunks are retrieved.|Lacks enough context for LLM to synthesize an answer|\n",
|
||||
"| |Outdated information: The data is redundant or out of date.| |\n",
|
||||
"|Bad Response Generation|Hallucination: Model makes up an answer that isn’t in the context.| |\n",
|
||||
"| |Irrelevance: Model makes up an answer that doesn’t answer the question.| |\n",
|
||||
"| |Toxicity/Bias: Model makes up an answer t\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(docs[0].get_content()[:5000])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c2fa0a1a-1ed8-4a5a-a0c1-5792fe32634b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Build a RAG pipeline over these documents\n",
|
||||
"\n",
|
||||
"We now use LlamaIndex to build a RAG pipeline over these powerpoint slides."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"id": "c779547f-e4f7-4c84-9786-2b6b749827ab",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"id": "68b3a95e-ce19-4df1-9fdd-e6efb2fc423a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"index = VectorStoreIndex.from_documents(docs)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"id": "a2ae28f6-4b3a-4130-8e65-0921b7678739",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"id": "232091ee-aa22-4f51-838c-410024acc344",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"response = query_engine.query(\"What are some response quality challenges with naive RAG?\") "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"id": "75f32aa7-c308-4221-af60-779822cfdba1",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Some response quality challenges with naive RAG include issues related to bad retrieval, such as low precision where not all retrieved chunks are relevant, leading to problems like hallucination and being lost in the middle. Additionally, low recall can occur when not all relevant chunks are retrieved, resulting in a lack of sufficient context for the language model to synthesize an answer. Outdated information in the retrieved data can also pose a challenge. On the response generation side, challenges include hallucination where the model generates an answer not present in the context, irrelevance where the answer does not address the question, and toxicity/bias where the answer is harmful or offensive.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(str(response))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d309d8fb-750a-4393-a1b2-67b14b7c121f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "llama_parse",
|
||||
"language": "python",
|
||||
"name": "llama_parse"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.8"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,422 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "eld1dKaN7P8B"
|
||||
},
|
||||
"source": [
|
||||
"# LlamaParse - Parsing Financial Powerpoints 📊\n",
|
||||
"\n",
|
||||
"In this cookbook we show you how to use LlamaParse to parse a financial powerpoint."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "goB1sV8zu_Xl"
|
||||
},
|
||||
"source": [
|
||||
"## Installation\n",
|
||||
"\n",
|
||||
"Parsing instruction are part of the LlamaParse API. They can be access by directly specifying the parsing_instruction parameter in the API or by using LlamaParse python module (which we will use for this tutorial).\n",
|
||||
"\n",
|
||||
"To install llama-parse, just get it from `pip`:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "7Y3_BwQLu-qK",
|
||||
"outputId": "b1129c52-7a70-44cc-ad03-1f8d3a8c794a"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install llama-index\n",
|
||||
"!pip install llama-parse\n",
|
||||
"!pip install torch transformers python-pptx Pillow"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "i-Rg2D_Rvf2i"
|
||||
},
|
||||
"source": [
|
||||
"## API Key\n",
|
||||
"\n",
|
||||
"The use of LlamaParse requires an API key which you can get here: https://cloud.llamaindex.ai/parse"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "af6i2P1vuU-U"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"os.environ[\"LLAMA_CLOUD_API_KEY\"] = \"llx-...\"\n",
|
||||
"os.environ[\"OPENAI_API_KEY\"] = \"sk-...\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "p8Eq-aX-wAEo"
|
||||
},
|
||||
"source": [
|
||||
"**NOTE**: Since LlamaParse is natively async, running the sync code in a notebook requires the use of nest_asyncio.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {
|
||||
"id": "4OB0BkTqv_0l",
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import nest_asyncio\n",
|
||||
"\n",
|
||||
"nest_asyncio.apply()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dz927ecMyYo_"
|
||||
},
|
||||
"source": [
|
||||
"## Importing the package\n",
|
||||
"\n",
|
||||
"To import llama_parse simply do:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "nSW-6sEwyXwx",
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_parse import LlamaParse"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "l_D4YsAHwUSk"
|
||||
},
|
||||
"source": [
|
||||
"## Using LlamaParse to Parse Presentations\n",
|
||||
"\n",
|
||||
"Like Powerpoints, presentations are often hard to extract for RAG. With LlamaParse we can now parse them and unclock their content of presentations for RAG.\n",
|
||||
"\n",
|
||||
"Let's download a financial report from the World Meteorological Association."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "d3qeuiyawT0U",
|
||||
"outputId": "cec0ea0a-be8b-49b6-9376-797c91f63be7",
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! mkdir data; wget \"https://meetings.wmo.int/Cg-19/PublishingImages/SitePages/FINAC-43/7%20-%20EC-77-Doc%205%20Financial%20Statements%20for%202022%20(FINAC).pptx\" -O data/presentation.pptx"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "Gbr8RiHEyF3-"
|
||||
},
|
||||
"source": [
|
||||
"### Parsing the presentation\n",
|
||||
"\n",
|
||||
"Now let's parse it into Markdown with LlamaParse and the default LlamaIndex parser.\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "osocsofoJ42S"
|
||||
},
|
||||
"source": [
|
||||
"#### Llama Index default"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "PTVy5XCNJwW-",
|
||||
"outputId": "d0e2cc4b-1407-45a9-b5e6-d06f91a533b4",
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import SimpleDirectoryReader\n",
|
||||
"\n",
|
||||
"vanilla_documents = SimpleDirectoryReader(\"./data/\").load_data()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "oucbsciZJwxt"
|
||||
},
|
||||
"source": [
|
||||
"#### Llama Parse"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "3jKnXCuAyQ9_",
|
||||
"outputId": "1f668f17-1e20-46e5-fbab-9a55e4b28891",
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id 56724c0d-e45a-4e30-ae8c-e416173c608a\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"llama_parse_documents = LlamaParse(result_type=\"markdown\").load_data(\"./data/presentation.pptx\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Let's take a look at the parsed output from an example slide (see image below).\n",
|
||||
"\n",
|
||||
"As we can see the table is faithfully extracted!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 27,
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"ation and mitigation\n",
|
||||
"---\n",
|
||||
"|Item|31 Dec 2022|31 Dec 2021|Change|\n",
|
||||
"|---|---|---|---|\n",
|
||||
"|Payables and accruals|4,685|4,066|619|\n",
|
||||
"|Employee benefits|127,215|84,676|42,539|\n",
|
||||
"|Contributions received in advance|6,975|10,192|(3,217)|\n",
|
||||
"|Unearned revenue from exchange transactions|20|651|(631)|\n",
|
||||
"|Deferred Revenue|71,301|55,737|15,564|\n",
|
||||
"|Borrowings|28,229|29,002|(773)|\n",
|
||||
"|Funds held in trust|30,373|29,014|1,359|\n",
|
||||
"|Provisions|1,706|1,910|(204)|\n",
|
||||
"|Total Liabilities|270,504|215,248|55,256|\n",
|
||||
"---\n",
|
||||
"## Liabilities\n",
|
||||
"\n",
|
||||
"Employee Ben\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(llama_parse_documents[0].get_content()[-2800:-2300])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"Compared against the original slide image.\n",
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "p4GVOdWzzvYg"
|
||||
},
|
||||
"source": [
|
||||
"## Comparing the two for RAG\n",
|
||||
"\n",
|
||||
"The main difference between LlamaParse and the previous directory reader approach, it that LlamaParse will extract the document in a structured format, allowing better RAG."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "oVcdGus5NDxi"
|
||||
},
|
||||
"source": [
|
||||
"### Query Engine on SimpleDirectoryReader results"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"metadata": {
|
||||
"id": "DqXYsLCWNg9_",
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex, SimpleDirectoryReader\n",
|
||||
"\n",
|
||||
"vanilla_index = VectorStoreIndex.from_documents(vanilla_documents)\n",
|
||||
"vanilla_query_engine = vanilla_index.as_query_engine()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "ZLkHt9l2Nbxx"
|
||||
},
|
||||
"source": [
|
||||
"### Query Engine on LlamaParse Results\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"metadata": {
|
||||
"id": "ZllaDcfRNLv3",
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"llama_parse_index = VectorStoreIndex.from_documents(llama_parse_documents)\n",
|
||||
"llama_parse_query_engine = llama_parse_index.as_query_engine()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "0dY_0_1bNg0X",
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"### Liability provision\n",
|
||||
"What was the liability provision as of Dec 31 2021?\n",
|
||||
"\n",
|
||||
"<!-- <img src=\"https://drive.usercontent.google.com/download?id=184jVq0QyspDnmCyRfV0ebmJJxmAOJHba&authuser=0\" /> -->"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 21,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "Tmn-qNTEN-cb",
|
||||
"outputId": "a9bffc00-9cfc-43d8-b159-596a6c1aca64",
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"The liability provision as of December 31, 2021, included Employee Benefit Liabilities, Contributions received in advance (assessed contributions), and Deferred revenue.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"vanilla_response = vanilla_query_engine.query(\"What was the liability provision as of Dec 31 2021?\")\n",
|
||||
"print(vanilla_response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "4EZ_uqlROP7R",
|
||||
"outputId": "0645a159-06c6-411e-d1f6-79ea95d32b42",
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"The liability provision as of December 31, 2021, was 1,910 CHF.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"llama_parse_response = llama_parse_query_engine.query(\"What was the liability provision as of Dec 31 2021?\")\n",
|
||||
"print(llama_parse_response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"provenance": []
|
||||
},
|
||||
"kernelspec": {
|
||||
"display_name": "llama_parse",
|
||||
"language": "python",
|
||||
"name": "llama_parse"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.8"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
+256
-57
@@ -4,6 +4,7 @@ import httpx
|
||||
import mimetypes
|
||||
import time
|
||||
from enum import Enum
|
||||
from pathlib import Path
|
||||
from typing import List, Optional, Union
|
||||
|
||||
from llama_index.core.async_utils import run_jobs
|
||||
@@ -12,15 +13,113 @@ from llama_index.core.constants import DEFAULT_BASE_URL
|
||||
from llama_index.core.readers.base import BasePydanticReader
|
||||
from llama_index.core.schema import Document
|
||||
|
||||
|
||||
nest_asyncio_err = "cannot be called from a running event loop"
|
||||
nest_asyncio_msg = "The event loop is already running. Add `import nest_asyncio; nest_asyncio.apply()` to your code to fix this issue."
|
||||
|
||||
class ResultType(str, Enum):
|
||||
"""The result type for the parser."""
|
||||
|
||||
TXT = "text"
|
||||
MD = "markdown"
|
||||
|
||||
class Language(str, Enum):
|
||||
BAZA = "abq"
|
||||
ADYGHE = "ady"
|
||||
AFRIKAANS = "af"
|
||||
ANGIKA = "ang"
|
||||
ARABIC = "ar"
|
||||
ASSAMESE = "as"
|
||||
AVAR = "ava"
|
||||
AZERBAIJANI = "az"
|
||||
BELARUSIAN = "be"
|
||||
BULGARIAN = "bg"
|
||||
BIHARI = "bh"
|
||||
BHOJPURI = "bho"
|
||||
BENGALI = "bn"
|
||||
BOSNIAN = "bs"
|
||||
SIMPLIFIED_CHINESE = "ch_sim"
|
||||
TRADITIONAL_CHINESE = "ch_tra"
|
||||
CHECHEN = "che"
|
||||
CZECH = "cs"
|
||||
WELSH = "cy"
|
||||
DANISH = "da"
|
||||
DARGWA = "dar"
|
||||
GERMAN = "de"
|
||||
ENGLISH = "en"
|
||||
SPANISH = "es"
|
||||
ESTONIAN = "et"
|
||||
PERSIAN_FARSI = "fa"
|
||||
FRENCH = "fr"
|
||||
IRISH = "ga"
|
||||
GOAN_KONKANI = "gom"
|
||||
HINDI = "hi"
|
||||
CROATIAN = "hr"
|
||||
HUNGARIAN = "hu"
|
||||
INDONESIAN = "id"
|
||||
INGUSH = "inh"
|
||||
ICELANDIC = "is"
|
||||
ITALIAN = "it"
|
||||
JAPANESE = "ja"
|
||||
KABARDIAN = "kbd"
|
||||
KANNADA = "kn"
|
||||
KOREAN = "ko"
|
||||
KURDISH = "ku"
|
||||
LATIN = "la"
|
||||
LAK = "lbe"
|
||||
LEZGHIAN = "lez"
|
||||
LITHUANIAN = "lt"
|
||||
LATVIAN = "lv"
|
||||
MAGAHI = "mah"
|
||||
MAITHILI = "mai"
|
||||
MAORI = "mi"
|
||||
MONGOLIAN = "mn"
|
||||
MARATHI = "mr"
|
||||
MALAY = "ms"
|
||||
MALTESE = "mt"
|
||||
NEPALI = "ne"
|
||||
NEWARI = "new"
|
||||
DUTCH = "nl"
|
||||
NORWEGIAN = "no"
|
||||
OCCITAN = "oc"
|
||||
PALI = "pi"
|
||||
POLISH = "pl"
|
||||
PORTUGUESE = "pt"
|
||||
ROMANIAN = "ro"
|
||||
RUSSIAN = "ru"
|
||||
SERBIAN_CYRILLIC = "rs_cyrillic"
|
||||
SERBIAN_LATIN = "rs_latin"
|
||||
NAGPURI = "sck"
|
||||
SLOVAK = "sk"
|
||||
SLOVENIAN = "sl"
|
||||
ALBANIAN = "sq"
|
||||
SWEDISH = "sv"
|
||||
SWAHILI = "sw"
|
||||
TAMIL = "ta"
|
||||
TABASSARAN = "tab"
|
||||
TELUGU = "te"
|
||||
THAI = "th"
|
||||
TAJIK = "tjk"
|
||||
TAGALOG = "tl"
|
||||
TURKISH = "tr"
|
||||
UYGHUR = "ug"
|
||||
UKRANIAN = "uk"
|
||||
URDU = "ur"
|
||||
UZBEK = "uz"
|
||||
VIETNAMESE = "vi"
|
||||
|
||||
|
||||
SUPPORTED_FILE_TYPES = [
|
||||
".pdf",
|
||||
".xml"
|
||||
".doc",
|
||||
".docx",
|
||||
".pptx",
|
||||
".rtf",
|
||||
".pages",
|
||||
".key",
|
||||
".epub"
|
||||
]
|
||||
|
||||
|
||||
class LlamaParse(BasePydanticReader):
|
||||
"""A smart-parser for files."""
|
||||
@@ -50,6 +149,13 @@ class LlamaParse(BasePydanticReader):
|
||||
verbose: bool = Field(
|
||||
default=True, description="Whether to print the progress of the parsing."
|
||||
)
|
||||
language: Language = Field(
|
||||
default=Language.ENGLISH, description="The language of the text to parse."
|
||||
)
|
||||
parsing_instruction: Optional[str] = Field(
|
||||
default="",
|
||||
description="The parsing instruction for the parser."
|
||||
)
|
||||
|
||||
@validator("api_key", pre=True, always=True)
|
||||
def validate_api_key(cls, v: str) -> str:
|
||||
@@ -69,73 +175,91 @@ class LlamaParse(BasePydanticReader):
|
||||
url = os.getenv("LLAMA_CLOUD_BASE_URL", None)
|
||||
return url or v or DEFAULT_BASE_URL
|
||||
|
||||
# upload a document and get back a job_id
|
||||
async def _create_job(self, file_path: str, extra_info: Optional[dict] = None) -> str:
|
||||
file_path = str(file_path)
|
||||
file_ext = os.path.splitext(file_path)[1]
|
||||
if file_ext not in SUPPORTED_FILE_TYPES:
|
||||
raise Exception(
|
||||
f"Currently, only the following file types are supported: {SUPPORTED_FILE_TYPES}\n"
|
||||
f"Current file type: {file_ext}"
|
||||
)
|
||||
|
||||
extra_info = extra_info or {}
|
||||
extra_info["file_path"] = file_path
|
||||
|
||||
headers = {"Authorization": f"Bearer {self.api_key}"}
|
||||
|
||||
# load data, set the mime type
|
||||
with open(file_path, "rb") as f:
|
||||
mime_type = mimetypes.guess_type(file_path)[0]
|
||||
files = {"file": (f.name, f, mime_type)}
|
||||
|
||||
# send the request, start job
|
||||
url = f"{self.base_url}/api/parsing/upload"
|
||||
async with httpx.AsyncClient(timeout=self.max_timeout) as client:
|
||||
response = await client.post(url, files=files, headers=headers, data={"language": self.language.value, "parsing_instruction": self.parsing_instruction})
|
||||
if not response.is_success:
|
||||
raise Exception(f"Failed to parse the file: {response.text}")
|
||||
|
||||
# check the status of the job, return when done
|
||||
job_id = response.json()["id"]
|
||||
return job_id
|
||||
|
||||
async def _get_job_result(self, job_id: str, result_type: str) -> dict:
|
||||
result_url = f"{self.base_url}/api/parsing/job/{job_id}/result/{result_type}"
|
||||
headers = {"Authorization": f"Bearer {self.api_key}"}
|
||||
|
||||
start = time.time()
|
||||
tries = 0
|
||||
while True:
|
||||
await asyncio.sleep(self.check_interval)
|
||||
async with httpx.AsyncClient(timeout=self.max_timeout) as client:
|
||||
tries += 1
|
||||
|
||||
result = await client.get(result_url, headers=headers)
|
||||
|
||||
if result.status_code == 404:
|
||||
end = time.time()
|
||||
if end - start > self.max_timeout:
|
||||
raise Exception(
|
||||
f"Timeout while parsing the file: {job_id}"
|
||||
)
|
||||
if self.verbose and tries % 10 == 0:
|
||||
print(".", end="", flush=True)
|
||||
continue
|
||||
|
||||
if result.status_code == 400:
|
||||
detail = result.json().get("detail", "Unknown error")
|
||||
raise Exception(f"Failed to parse the file: {detail}")
|
||||
|
||||
return result.json()
|
||||
|
||||
async def _aload_data(self, file_path: str, extra_info: Optional[dict] = None) -> List[Document]:
|
||||
"""Load data from the input path."""
|
||||
try:
|
||||
file_path = str(file_path)
|
||||
if not file_path.endswith(".pdf"):
|
||||
raise Exception("Currently, only PDF files are supported.")
|
||||
|
||||
extra_info = extra_info or {}
|
||||
extra_info["file_path"] = file_path
|
||||
|
||||
headers = {"Authorization": f"Bearer {self.api_key}"}
|
||||
|
||||
# load data, set the mime type
|
||||
with open(file_path, "rb") as f:
|
||||
mime_type = mimetypes.guess_type(file_path)[0]
|
||||
files = {"file": (f.name, f, mime_type)}
|
||||
|
||||
# send the request, start job
|
||||
url = f"{self.base_url}/api/parsing/upload"
|
||||
async with httpx.AsyncClient(timeout=self.max_timeout) as client:
|
||||
response = await client.post(url, files=files, headers=headers)
|
||||
if not response.is_success:
|
||||
raise Exception(f"Failed to parse the PDF file: {response.text}")
|
||||
|
||||
# check the status of the job, return when done
|
||||
job_id = response.json()["id"]
|
||||
job_id = await self._create_job(file_path, extra_info=extra_info)
|
||||
if self.verbose:
|
||||
print("Started parsing the file under job_id %s" % job_id)
|
||||
|
||||
result_url = f"{self.base_url}/api/parsing/job/{job_id}/result/{self.result_type.value}"
|
||||
result = await self._get_job_result(job_id, self.result_type.value)
|
||||
|
||||
start = time.time()
|
||||
tries = 0
|
||||
while True:
|
||||
await asyncio.sleep(self.check_interval)
|
||||
async with httpx.AsyncClient(timeout=self.max_timeout) as client:
|
||||
tries += 1
|
||||
|
||||
result = await client.get(result_url, headers=headers)
|
||||
|
||||
if result.status_code == 404:
|
||||
end = time.time()
|
||||
if end - start > self.max_timeout:
|
||||
raise Exception(
|
||||
f"Timeout while parsing the PDF file: {response.text}"
|
||||
)
|
||||
if self.verbose and tries % 10 == 0:
|
||||
print(".", end="", flush=True)
|
||||
continue
|
||||
|
||||
if result.status_code == 400:
|
||||
detail = result.json().get("detail", "Unknown error")
|
||||
raise Exception(f"Failed to parse the PDF file: {detail}")
|
||||
|
||||
return [
|
||||
Document(
|
||||
text=result.json()[self.result_type.value],
|
||||
metadata=extra_info,
|
||||
)
|
||||
]
|
||||
return [
|
||||
Document(
|
||||
text=result[self.result_type.value],
|
||||
metadata=extra_info or {},
|
||||
)
|
||||
]
|
||||
|
||||
except Exception as e:
|
||||
print("Error while parsing the PDF file: ", e)
|
||||
print(f"Error while parsing the file '{file_path}':", e)
|
||||
raise e
|
||||
return []
|
||||
|
||||
|
||||
async def aload_data(self, file_path: Union[List[str], str], extra_info: Optional[dict] = None) -> List[Document]:
|
||||
"""Load data from the input path."""
|
||||
if isinstance(file_path, str):
|
||||
if isinstance(file_path, (str, Path)):
|
||||
return await self._aload_data(file_path, extra_info=extra_info)
|
||||
elif isinstance(file_path, list):
|
||||
jobs = [self._aload_data(f, extra_info=extra_info) for f in file_path]
|
||||
@@ -160,4 +284,79 @@ class LlamaParse(BasePydanticReader):
|
||||
if nest_asyncio_err in str(e):
|
||||
raise RuntimeError(nest_asyncio_msg)
|
||||
else:
|
||||
raise e
|
||||
raise e
|
||||
|
||||
|
||||
async def _aget_json(self, file_path: str, extra_info: Optional[dict] = None) -> List[dict]:
|
||||
"""Load data from the input path."""
|
||||
try:
|
||||
job_id = await self._create_job(file_path, extra_info=extra_info)
|
||||
if self.verbose:
|
||||
print("Started parsing the file under job_id %s" % job_id)
|
||||
|
||||
result = await self._get_job_result(job_id, "json")
|
||||
result["job_id"] = job_id
|
||||
result["file_path"] = file_path
|
||||
return [result]
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error while parsing the file '{file_path}':", e)
|
||||
raise e
|
||||
|
||||
|
||||
|
||||
async def aget_json(self, file_path: Union[List[str], str], extra_info: Optional[dict] = None) -> List[dict]:
|
||||
"""Load data from the input path."""
|
||||
if isinstance(file_path, (str, Path)):
|
||||
return await self._aget_json(file_path, extra_info=extra_info)
|
||||
elif isinstance(file_path, list):
|
||||
jobs = [self._aget_json(f, extra_info=extra_info) for f in file_path]
|
||||
try:
|
||||
results = await run_jobs(jobs, workers=self.num_workers)
|
||||
|
||||
# return flattened results
|
||||
return [item for sublist in results for item in sublist]
|
||||
except RuntimeError as e:
|
||||
if nest_asyncio_err in str(e):
|
||||
raise RuntimeError(nest_asyncio_msg)
|
||||
else:
|
||||
raise e
|
||||
else:
|
||||
raise ValueError("The input file_path must be a string or a list of strings.")
|
||||
|
||||
|
||||
def get_json_result(self, file_path: Union[List[str], str], extra_info: Optional[dict] = None) -> List[dict]:
|
||||
"""Parse the input path."""
|
||||
try:
|
||||
return asyncio.run(self.aget_json(file_path, extra_info))
|
||||
except RuntimeError as e:
|
||||
if nest_asyncio_err in str(e):
|
||||
raise RuntimeError(nest_asyncio_msg)
|
||||
else:
|
||||
raise e
|
||||
|
||||
def get_images(self, json_result: list[dict], download_path: str) -> List[dict]:
|
||||
"""Download images from the parsed result."""
|
||||
headers = {"Authorization": f"Bearer {self.api_key}"}
|
||||
try:
|
||||
images = []
|
||||
for result in json_result:
|
||||
job_id = result["job_id"]
|
||||
for page in result["pages"]:
|
||||
if self.verbose:
|
||||
print(f"> Image for page {page['page']}: {page['images']}")
|
||||
for image in page["images"]:
|
||||
image_name = image["name"]
|
||||
image_path = os.path.join(download_path, f"{job_id}-{image_name}")
|
||||
image["path"]=image_path
|
||||
image["job_id"]=job_id
|
||||
image["original_pdf_path"]=result["file_path"]
|
||||
image["page_number"]=page["page"]
|
||||
with open(image_path, "wb") as f:
|
||||
image_url = f"{self.base_url}/api/parsing/job/{job_id}/result/image/{image_name}"
|
||||
f.write(httpx.get(image_url, headers=headers).content)
|
||||
images.append(image)
|
||||
return images
|
||||
except Exception as e:
|
||||
print(f"Error while downloading images from the parsed result:", e)
|
||||
return []
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "llama-parse"
|
||||
version = "0.3.3"
|
||||
version = "0.3.9"
|
||||
description = "Parse files into RAG-Optimized formats."
|
||||
authors = ["Logan Markewich <logan@llamaindex.ai>"]
|
||||
license = "MIT"
|
||||
|
||||
Reference in New Issue
Block a user