### Install Nano-GraphRAG from Source Source: https://github.com/gusye1234/nano-graphrag/blob/main/readme.md Install the library by cloning the repository and using pip in editable mode. This is the recommended installation method. ```shell cd nano-graphrag pip install -e . ``` -------------------------------- ### Install nano-graphrag Source: https://context7.com/gusye1234/nano-graphrag/llms.txt Install nano-graphrag from source or PyPI. Recommended to install from source for development. ```bash # From source (recommended) git clone https://github.com/gusye1234/nano-graphrag cd nano-graphrag pip install -e . # From PyPI pip install nano-graphrag ``` -------------------------------- ### Display First 5 Examples Source: https://github.com/gusye1234/nano-graphrag/blob/main/examples/generate_entity_relationship_dspy.ipynb Shows the first 5 examples from the 'devset' dataset, each containing 'input_text', 'entities', and 'relationships'. This is useful for inspecting the data structure. ```python devset[:5] ``` -------------------------------- ### Display First Two Relationships in Development Set Example Source: https://github.com/gusye1234/nano-graphrag/blob/main/examples/finetune_entity_relationship_dspy.ipynb Shows the first two relationships from the first example in the development dataset. This allows for a quick inspection of the development data structure. ```python devset[0].relationships[:2] ``` -------------------------------- ### Install Nano-GraphRAG from PyPI Source: https://github.com/gusye1234/nano-graphrag/blob/main/readme.md Install the library directly from the Python Package Index using pip. ```shell pip install nano-graphrag ``` -------------------------------- ### Display First 5 Examples of Training Set Source: https://github.com/gusye1234/nano-graphrag/blob/main/examples/generate_entity_relationship_dspy.ipynb Retrieves and displays the first 5 examples from the generated training dataset, showing the structure of the input text, entities, and relationships. ```python trainset[:5] ``` -------------------------------- ### Install Dependencies Source: https://github.com/gusye1234/nano-graphrag/blob/main/examples/benchmarks/eval_naive_graphrag_on_multi_hop.ipynb Installs necessary libraries for RAG evaluation, including ragas and nest_asyncio. ```python !pip install ragas nest_asyncio datasets ``` -------------------------------- ### Display First Two Relationships in Training Set Example Source: https://github.com/gusye1234/nano-graphrag/blob/main/examples/finetune_entity_relationship_dspy.ipynb Shows the first two relationships from the first example in the training dataset. This provides a quick look at the structure of relationship data. ```python trainset[0].relationships[:2] ``` -------------------------------- ### Example Data Structure Source: https://github.com/gusye1234/nano-graphrag/blob/main/examples/generate_entity_relationship_dspy.ipynb Illustrates the structure of a single example, including the input text and extracted entities and relationships. This format is used by the DSPy framework. ```python Example({'input_text': "As students from Marjory Stoneman Douglas High School confront lawmakers with demands to restrict sales of assault rifles, there were warnings by the president of the Florida school administration association that schools in the state were vulnerable to such an attack.\nHighlights\n“Nikolas Cruz was able to purchase an assault rifle before he was able to buy a beer,” said Stoneman Douglas student Laurenzo Prado, referring to a Florida law that allows people as young as 18 to buy assault weapons. Students galvanized by the deadly mass shooting at the Florida high school confronted lawmakers with demands to restrict sales of assault rifles, while President Donald Trump suggested arming teachers as a way to stop more U.S. rampages.\nTwo weeks before a gunman fatally shot 17 people at a Florida high school, Bill Lee, the president of the state’s school administrators association, warned that Florida’s schools were vulnerable to just such an attack. “It’s not a matter of if, but when,” he wrote in the Orlando Sentinel on Jan. 29, calling on legislators to increase school security spending after two January school shootings in other states.\nWorld\nU.S. players pose for a photo as they celebrate their victory over Canada. REUTERS/Grigory Dukor She’s practiced the ‘Oops, I did it again’ thousands of times in training, and her signature trick was worth its weight in Olympic gold as American Jocelyne Lamoureux-Davidson’s shootout winner broke a Canadian 16-year stranglehold on the women’s ice hockey title. It was the perfect jaw-dropping finale to a game that was billed as a grudge match but swiftly developed into a classic for the ages at the Pyeongchang Winter Games.\nWarplanes pounded the last rebel enclave near the Syrian capital for a fifth straight day, as the United Nations pleaded for a truce to halt one of the fiercest air assaults of the seven-year civil war and prevent a “massacre” .\nBangladesh is racing to turn an uninhabited and muddy Bay of Bengal island into home for 100,000 Rohingya Muslims who have fled a military crackdown in Myanmar , amid conflicting signals from top Bangladeshi officials about whether the refugees would end up being stranded there.\nCommentary\nNorth Korea’s participation in the 2018 Winter Olympics has created an opening for renewed dialogue with the United States and South Korea, writes Peter App s. “By taking part so visibly alongside South Korea, Pyongyang has been able to present itself as a credible global and regional power in a way that has eluded North Korean leaders since the war that divided the peninsula. The real strategic winner, however, is the South Korean government, which has shrewdly used the games to reshape the diplomatic landscape.”\nBusiness\nLast March, executives at General Electric's power-plant business gave Wall Street a surprisingly bullish forecast for the year. Despite flat demand for new natural gas power plants, they said, GE Power’s revenue and profit would rise. ``` -------------------------------- ### MIPROv2 Trial Completion and Next Trial Setup Source: https://github.com/gusye1234/nano-graphrag/blob/main/examples/finetune_entity_relationship_dspy.ipynb This log entry marks the completion of trial 17 with its score and parameters, and indicates the start of trial 18 with specific instruction and demo indices. ```log Average Metric: 0.9375 / 1 (93.8): 100%|██████████| 1/1 [00:00<00:00, 2083.61it/s] INFO:dspy.evaluate.evaluate:[2m2024-09-20T23:33:00.038879Z[0m [[32m[1minfo [0m] [1mAverage Metric: 0.9375 / 1 (93.8%)[0m [[0m[1m[34mdspy.evaluate.evaluate[0m][0m [36mfilename[0m=[35mevaluate.py[0m [36mlineno[0m=[35m218[0m [I 2024-09-20 19:33:00,045] Trial 17 finished with value: 87.8 and parameters: {'0_predictor_instruction': 4, '0_predictor_demos': 1}. Best is trial 16 with value: 89.69. INFO:root:Starting trial num: 18 INFO:root:instruction_idx 0 INFO:root:demos_idx 1 ``` -------------------------------- ### Configure Working Directories and Logging Source: https://github.com/gusye1234/nano-graphrag/blob/main/examples/finetune_entity_relationship_dspy.ipynb Sets up the working directories for caching and examples, loads environment variables, and configures logging levels for the nano-graphrag module. ```python WORKING_DIR = "./nano_graphrag_cache_finetune_entity_relationship_dspy" EXAMPLES_DIR = "./nano_graphrag_cache_generate_dspy_examples" load_dotenv() logging.basicConfig(level=logging.WARNING) logging.getLogger("nano-graphrag").setLevel(logging.DEBUG) np.random.seed(1337) ``` -------------------------------- ### Display First 5 Examples of Generated Dataset Source: https://github.com/gusye1234/nano-graphrag/blob/main/examples/generate_entity_relationship_dspy.ipynb This code snippet shows how to display the first 5 examples from the generated entity relationship dataset. This is useful for inspecting the output and verifying the dataset's structure. ```python valset[:5] ``` -------------------------------- ### Using Ollama as LLM Source: https://github.com/gusye1234/nano-graphrag/blob/main/readme.md Provides a link to an example demonstrating the use of Ollama as the LLM model. ```python # You can refer to this [example](./examples/using_ollama_as_llm.py) that use [`ollama`](https://github.com/ollama/ollama) as the LLM model ``` -------------------------------- ### Log Saved Examples Source: https://github.com/gusye1234/nano-graphrag/blob/main/examples/generate_entity_relationship_dspy.ipynb This log message indicates the number of examples saved and filtered by the nano-graphrag tool, along with their keys. ```text INFO:nano-graphrag:Saved 197 examples with keys: ['input_text', 'entities', 'relationships'], filtered 3 examples ``` -------------------------------- ### Bootstrapping Full Traces (Round 0, Example 1) Source: https://github.com/gusye1234/nano-graphrag/blob/main/examples/finetune_entity_relationship_dspy.ipynb Indicates the successful bootstrapping of 3 full traces after processing 4 examples in round 0. This is part of an iterative learning or data generation process. ```text Output: Bootstrapped 3 full traces after 4 examples in round 0. ``` -------------------------------- ### Display First Two Relationships in Validation Set Example Source: https://github.com/gusye1234/nano-graphrag/blob/main/examples/finetune_entity_relationship_dspy.ipynb Displays the first two relationships from the first example in the validation dataset. This is useful for comparing validation data structure with training data. ```python valset[0].relationships[:2] ``` -------------------------------- ### Bootstrapping Full Traces (Round 0, Example 2) Source: https://github.com/gusye1234/nano-graphrag/blob/main/examples/finetune_entity_relationship_dspy.ipynb Indicates the successful bootstrapping of 2 full traces after processing 3 examples in round 0. This is part of an iterative learning or data generation process. ```text Output: Bootstrapped 2 full traces after 3 examples in round 0. ``` -------------------------------- ### Using Deepseek as LLM Source: https://github.com/gusye1234/nano-graphrag/blob/main/readme.md Provides a link to an example demonstrating the use of Deepseek Chat as the LLM model. ```python # You can refer to this [example](./examples/using_deepseek_as_llm.py) that use [`deepseek-chat`](https://platform.deepseek.com/api-docs/) as the LLM model ``` -------------------------------- ### Bootstrapping Full Traces (Round 0, Example 3) Source: https://github.com/gusye1234/nano-graphrag/blob/main/examples/finetune_entity_relationship_dspy.ipynb Indicates the successful bootstrapping of 1 full trace after processing 2 examples in round 0. This is part of an iterative learning or data generation process. ```text Output: Bootstrapped 1 full traces after 2 examples in round 0. ``` -------------------------------- ### MIPROv2 Evaluation Initialization Source: https://github.com/gusye1234/nano-graphrag/blob/main/examples/finetune_entity_relationship_dspy.ipynb This snippet shows the initialization of the MIPROv2 evaluation process, including API calls and the start of the progress bar. It is useful for observing the beginning of the evaluation. ```text 0%| | 0/20 [00:00 " + field.json_schema_extra["prefix"] + " " + completion[name] for name, field in signature.output_fields.items() ), lm_explain=try_i + 1 < self.max_retries, ) if errors: ``` -------------------------------- ### Generate Example for Type Source: https://github.com/gusye1234/nano-graphrag/blob/main/examples/finetune_entity_relationship_dspy.ipynb Generates a valid JSON example for a given Pydantic model type. This is cached by DSPy for efficiency. If a valid example cannot be generated, an empty string is returned. ```python def _make_example(self, type_) -> str: # Note: DSPy will cache this call so we only pay the first time TypedPredictor is called. schema = json.dumps(type_.model_json_schema()) if self.wrap_json: schema = "```json\n" + schema + "\n```\n" json_object = dspy.Predict( make_signature( "json_schema -> json_object", "Make a very succinct json object that validates with the following schema", ), )(json_schema=schema).json_object # We use the model_validate_json method to make sure the example is valid try: type_.model_validate_json(_unwrap_json(json_object, type_.model_validate_json)) except (pydantic.ValidationError, ValueError): return "" # Unable to make an example return json_object ``` -------------------------------- ### Import Libraries and Setup Source: https://github.com/gusye1234/nano-graphrag/blob/main/examples/benchmarks/eval_naive_graphrag_on_multi_hop.ipynb Imports essential Python libraries for RAG, sets up OpenAI API key (optional), applies nest_asyncio for async operations, and configures logging. ```python import os # os.environ["OPENAI_API_KEY"] = "YOUR_API_KEY" import json import sys sys.path.append("../..") import nest_asyncio nest_asyncio.apply() import logging logging.basicConfig(level=logging.WARNING) logging.getLogger("nano-graphrag").setLevel(logging.INFO) from nano_graphrag import GraphRAG, QueryParam from datasets import Dataset from ragas import evaluate from ragas.metrics import ( answer_correctness, answer_similarity, ) ``` -------------------------------- ### Progress and Logging Output Example Source: https://github.com/gusye1234/nano-graphrag/blob/main/examples/finetune_entity_relationship_dspy.ipynb This snippet displays typical progress and logging information during a fine-tuning or evaluation process, showing HTTP requests and metric updates. It indicates the status of the operations and the performance metrics being tracked. ```text 0%| | 0/25 [00:00 str` ### Parameters #### `insert` Parameters - **documents** (Union[str, List[str]]) - Required - A string containing the document content or a list of strings, each representing a document. #### `query` Parameters - **question** (str) - Required - The natural language question to ask the knowledge graph. - **param** (QueryParam) - Optional - An instance of `QueryParam` to configure the query behavior, such as search mode, context retrieval, and LLM hints. ### Request Example (insert) ```python import os from nano_graphrag import GraphRAG os.environ["OPENAI_API_KEY"] = "sk-..." rag = GraphRAG(working_dir="./my_graph") with open("book.txt") as f: rag.insert(f.read()) rag.insert(["Document one content.", "Document two content."]) ``` ### Request Example (query - global) ```python answer = rag.query("What are the top themes in this story?") print(answer) ``` ### Request Example (query - local) ```python from nano_graphrag import QueryParam answer = rag.query("Describe the key characters.", param=QueryParam(mode="local")) print(answer) ``` ### Response (query) - **answer** (str) - The synthesized answer to the query, or raw context if `only_need_context` is True in `QueryParam`. ``` -------------------------------- ### Example Input Text for Entity Relationship Extraction Source: https://github.com/gusye1234/nano-graphrag/blob/main/examples/finetune_entity_relationship_dspy.ipynb Provides an example of input text used for entity and relationship extraction tasks, focusing on a sports news article. ```text task_demos Input Text: (CNN)Roger Federer thinks the professional tennis circuit won't return for a while due to the coronavirus pandemic but, when the time does come, the Swiss superstar said he would find it difficult to play without fans. While European football's Bundesliga resurfaced last week behind closed doors and Spain's La Liga is set to resume the middle of next month, the last official word from tennis authorities essentially saw all action suspended through July. The hiatus began in March, with Federer already sidelined since he was recuperating from knee surgery. Sunday would have marked the first day of the French Open in its usual spot on the tennis calendar -- in March, though, it was rescheduled for September -- and another grand slam, Wimbledon in July, was called off. "I'm not training at the moment because I don't see a reason for that to be honest," Federer told three-time French Open champion Gustavo Kuerten -- who is raising funds for coronavirus relief efforts in his native Brazil -- in a video interview reported by Tennis.com.Read More"I am happy with my body now and I still believe that the return of the tour is a long way off," continued the 38-year-old. "And I think it's important mentally to enjoy this break, having played so much tennis. "When I'm getting towards returning and have a goal to train for, I think I will be super motivated."We should be sliding into @rolandgarros right now, thinking of our mates in Paris 👋 pic.twitter.com/0PLKryyIjj— #AusOpen (@AustralianOpen) May 24, 2020 Federer is arguably tennis' best supported player ever, and the prospect of competing without spectators doesn't appeal to him. "Most of the time when we are training, there is no one," said the men's record 20-time grand slam champion. "For us, of course, it is possible to play if there are no fans. But on the other hand, I really hope that the circuit can return as it normally is. "And hold off till the time is appropriate, minimum a third of the stadium or half full. But, for me, completely empty when playing big tournaments is very difficult."Federer has been active on social media during the lockdown, sparking a public discussion on the merging of the men's and women's tours with a tweet last month and embarking on a funny Instagram Live with tennis rival Rafael Nadal.Nadal, unlike Federer, has started practicing, though only very recently. The Spaniard would have been favored to win a 20th major and tie Federer had the French Open been played as usual given he has collected a record 12 titles at Roland Garros. Here I am, the first pictures I am posting for you on court. This is my practice earlier today at @rnadalacademy #BackOnCourt #BabolatFamily 🎾👍🏻💪🏻😉 pic.twitter.com/x7tzgLj9pc— Rafa Nadal (@RafaelNadal) May 22, 2020 The next grand slam is scheduled to ``` -------------------------------- ### Desired LLM Response Format Example Source: https://github.com/gusye1234/nano-graphrag/blob/main/docs/FAQ.md This is an example of the expected output format from the LLM when extracting entities and relations. Ensure your LLM's responses adhere to this structure. ```text ("entity"<|>"Cruz"<|>"person"<|>"Cruz is associated with a vision of control and order, influencing the dynamics among other characters.") ``` -------------------------------- ### Initialize and Compile MIPROv2 Optimizer Source: https://github.com/gusye1234/nano-graphrag/blob/main/examples/finetune_entity_relationship_dspy.ipynb Initializes the MIPROv2 optimizer with specified models and metrics, then compiles it with training and validation datasets. This prepares the model for fine-tuning and evaluation. ```python optimizer = MIPROv2( prompt_model=deepseek, task_model=qwen2, metric=entity_recall_metric, init_temperature=1.4, num_candidates=10, verbose=False ) kwargs = dict(num_threads=os.cpu_count(), display_progress=True, display_table=0) miprov2_model = optimizer.compile( model, trainset=trainset[:50], valset=valset[:20], requires_permission_to_run=False, num_batches=20, max_labeled_demos=5, max_bootstrapped_demos=3, eval_kwargs=kwargs ) miprov2_model ``` -------------------------------- ### Initialize and Use GraphRAG (Sync) Source: https://context7.com/gusye1234/nano-graphrag/llms.txt Initialize the GraphRAG object with configuration, insert documents, and perform queries. Supports global and local search modes. ```python import os from nano_graphrag import GraphRAG, QueryParam os.environ["OPENAI_API_KEY"] = "sk-..." # Download sample text # curl https://raw.githubusercontent.com/gusye1234/nano-graphrag/main/tests/mock_data.txt > book.txt rag = GraphRAG( working_dir="./my_graph", # persisted storage directory enable_local=True, # enable local-mode queries enable_naive_rag=False, # set True to also enable naive queries chunk_token_size=1200, # tokens per chunk chunk_overlap_token_size=100, # overlap between chunks enable_llm_cache=True, # cache LLM responses to disk ) # Index a document (idempotent — duplicate content is skipped) with open("book.txt") as f: rag.insert(f.read()) # Batch insert rag.insert(["Document one content.", "Document two content."]) # Global search: synthesises community reports across the whole graph answer = rag.query("What are the top themes in this story?") print(answer) # Local search: entity-centric retrieval with neighbourhood context answer = rag.query( "Describe the key characters.", param=QueryParam(mode="local"), ) print(answer) ``` -------------------------------- ### Configure DSPy Language Models Source: https://github.com/gusye1234/nano-graphrag/blob/main/examples/finetune_entity_relationship_dspy.ipynb Sets up two language models, DeepSeek Chat and Qwen2 (OllamaLocal), with specific configurations including API keys, base URLs, system prompts, and temperatures. It then configures DSPy to use DeepSeek Chat as the default language model. ```python system_prompt = """ You are a world-class AI system, capable of complex reasoning and reflection. Reason through the query, and then provide your final response. If you detect that you made a mistake in your reasoning at any point, correct yourself. Think carefully. """ deepseek = dspy.OpenAI( model="deepseek-chat", model_type="chat", api_key=os.environ["DEEPSEEK_API_KEY"], base_url=os.environ["DEEPSEEK_BASE_URL"], system_prompt=system_prompt, temperature=1.0, max_tokens=8192 ) qwen2 = dspy.OllamaLocal( model="qwen2", system=system_prompt, temperature=1.0, max_tokens=4096, num_ctx=32000, format="json", timeout_s=240, ) dspy.settings.configure(lm=deepseek, experimental=True) ``` -------------------------------- ### Define Output File Paths Source: https://github.com/gusye1234/nano-graphrag/blob/main/examples/generate_entity_relationship_dspy.ipynb Creates the working directory if it doesn't exist and defines the file paths for saving the generated training, validation, and development datasets as pickle files. ```python os.makedirs(WORKING_DIR, exist_ok=True) entity_relationship_trainset_path = os.path.join(WORKING_DIR, "entity_relationship_extraction_news_trainset.pkl") entity_relationship_valset_path = os.path.join(WORKING_DIR, "entity_relationship_extraction_news_valset.pkl") entity_relationship_devset_path = os.path.join(WORKING_DIR, "entity_relationship_extraction_news_devset.pkl") ```