初试牛刀,问题乍现

“insert代码看完之后,我们代码跑起来先。”小胖坐在他那有些凌乱但舒适的办公桌前,自言自语道。今天,他要处理从某财整理的一些研报数据,用来测试模型效果。这些数据集将帮助他验证最近修改的模型参数是否有效。

研报.png

按照官方example中的指导,小胖精心调整了模型的相关参数,编写了一段代码,通过for循环逐一写入研报数据。“这段代码按理来说是没有毛病的,”他一边想着,一边敲下了最后一行代码。

from fast_graphrag import GraphRAG
import os
from fast_graphrag._llm import OpenAIEmbeddingService, OpenAILLMService
import openai
import instructor


dir_name = "./研报txt"

DOMAIN = "从研报信息里面提取出信息."
ENTITY_TYPES = ["Company", "Person", "Stock", "Object", "Activity", "Event", "Industry", "Strategy", "Policy", "Market", "Economy", "Technology", "Environment", "Health", "Education", "Culture", "Sports", "Entertainment", "Other"]

grag = GraphRAG(
    working_dir="./yanb_example",
    domain=DOMAIN,
    example_queries="",
    entity_types=ENTITY_TYPES,
    n_checkpoints=3,
    config=GraphRAG.Config(
    llm_service=OpenAILLMService(
        model="gpt-3.5-turbo", base_url=os.getenv("OPENAI_API_BASE"), api_key=os.getenv("OPENAI_API_KEY"),
        mode=instructor.Mode.JSON
    ),
    embedding_service=OpenAIEmbeddingService(
            model="text-embedding-ada-002",
            base_url=os.getenv("OPENAI_API_BASE"),
            api_key=os.getenv("OPENAI_API_KEY"),
            embedding_dim=1536
        ),
    ),
)
filenames = os.listdir(dir_name)
filenames.sort()

for i, filename in enumerate(filenames):
    with open(os.path.join(dir_name, filename), "r") as f:
        data = f.read()
        res = grag.insert(data)
        print(res)

然而,经过一番耐心等待后,结果却出乎意料。“啊?这生成的数据文件才几百k?”小胖惊讶地叫了出来,用pickle包打开pkl文件和pklz文件后,发现里面竟然只有最后一篇研报的数据。他的心情一下子从期待跌落到了谷底,“我跑了2个小时,100多万的token,就这样没了?”

错误结果.png

抽丝剥茧,找到症结

面对突如其来的挫折,乐观的小胖并没有气馁。他知道,每一次失败都是成长的机会。于是,他开始仔细检查代码,终于发现了问题所在——原来是n_checkpoints=3​这个参数惹的祸。如果不加上这个参数,这样的写法是正常的;一旦加上,就必须在for循环里实例化GraphRAG​。

from fast_graphrag import GraphRAG
import os
from fast_graphrag._llm import OpenAIEmbeddingService, OpenAILLMService
import openai
import instructor


dir_name = "./研报txt"

DOMAIN = "从研报信息里面提取出信息."
ENTITY_TYPES = ["Company", "Person", "Stock", "Object", "Activity", "Event", "Industry", "Strategy", "Policy", "Market", "Economy", "Technology", "Environment", "Health", "Education", "Culture", "Sports", "Entertainment", "Other"]


filenames = os.listdir(dir_name)
filenames.sort()

for i, filename in enumerate(filenames):
	grag = GraphRAG(
	    working_dir="./yanb_example",
	    domain=DOMAIN,
	    example_queries="",
	    entity_types=ENTITY_TYPES,
	    n_checkpoints=3,
	    config=GraphRAG.Config(
	    llm_service=OpenAILLMService(
	        model="gpt-3.5-turbo", base_url=os.getenv("OPENAI_API_BASE"), api_key=os.getenv("OPENAI_API_KEY"),
	        mode=instructor.Mode.JSON
	    ),
	    embedding_service=OpenAIEmbeddingService(
	            model="text-embedding-ada-002",
	            base_url=os.getenv("OPENAI_API_BASE"),
	            api_key=os.getenv("OPENAI_API_KEY"),
	            embedding_dim=1536
	        ),
	    ),
	)
    with open(os.path.join(dir_name, filename), "r") as f:
        data = f.read()
        res = grag.insert(data)
        print(res)

修改.png

“okok,这样也行吧~”小胖笑着说道,似乎已经习惯了这种小插曲。他决定尝试另一种方法:直接把数据整到一个list里面,再一次性插入,而不是使用for循环逐条插入。这样做不仅简化了代码逻辑,还让整个过程看起来更加整洁高效。

意外并发,峰回路转

就在小胖以为一切顺利的时候,新的挑战又出现了。本地部署的模型中转服务突然挂掉,超时了。查看日志后,他发现是因为并发量过高导致的。“并发16??”小胖皱起了眉头,意识到自己本地的模型只支持3个并发。

为了不让这次的努力再次付诸东流,小胖迅速行动起来。他定位到了问题所在——fast_graphrag._services._information_extraction.DefaultInformationExtractionService.extract​这段代码使用了asyncio.create_task​来开启并发,但却没有限制并发数。

没有并发限制.png

小胖很快想到了解决方案:使用asyncio.Semaphore来限制并发数,确保服务稳定运行。

限制并发.png

最终,经过一系列努力,小胖成功解决了所有问题。看着平稳运行的程序,他露出了欣慰的笑容。这一刻,所有的辛苦都变得值得。

欢迎大家关注我的公众号,公众号后台回复 fast-graphrag研报 获取本篇代码及文件~

Snipaste_2024-12-07_11-05-00.png