解决在无网络环境下搭建GraphRAG时tiktoken的ConnectTimeout问题
在搭建GraphRAG时,如果在无网络环境下运行,可能会遇到ConnectTimeout错误。具体表现为在尝试加载cl100k_base.tiktoken文件时,由于无法连接到https://openaipublic.blob.core.windows.net/encodings/cl100k_base.tiktoken而失败。本文将详细介绍如何解决这一问题。
问题描述
在无网络环境下搭建GraphRAG时,执行过程中遇到了以下错误:
ConnectTimeout: HTTPSConnectionPool(host='openaipublic.blob.core.windows.net', port=443): Max retries exceeded with url: /encodings/cl100k_base.tiktoken (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x7f3bca330050>, 'Connection to openaipublic.blob.core.windows.net timed out. (connect timeout=None)'))
环境信息
- tiktoken版本: 0.9.0
尝试的解决方案
设置缓存目录
根据网上的一些解决方案,尝试通过设置TIKTOKEN_CACHE_DIR环境变量来指定自己的tiktoken缓存目录。虽然设置了环境变量,但在调用tiktoken.get_encoding("cl100k_base")时,仍然会尝试加载默认的https://openaipublic.blob.core.windows.net/encodings/cl100k_base.tiktoken文件,导致报错。🤯🤯🤯
read_file_cached源码分析
为了更好地理解问题,我们查看了tiktoken库中read_file_cached函数的源码:
def read_file_cached(blobpath: str, expected_hash: str | None = None) -> bytes:
user_specified_cache = True
print("TIKTOKEN_CACHE_DIR : ", os.environ.get("TIKTOKEN_CACHE_DIR", ""))
if "TIKTOKEN_CACHE_DIR" in os.environ:
cache_dir = os.environ["TIKTOKEN_CACHE_DIR"]
elif "DATA_GYM_CACHE_DIR" in os.environ:
cache_dir = os.environ["DATA_GYM_CACHE_DIR"]
else:
import tempfile
cache_dir = os.path.join(tempfile.gettempdir(), "data-gym-cache")
user_specified_cache = False
if cache_dir == "":
# disable caching
return read_file(blobpath)
cache_key = hashlib.sha1(blobpath.encode()).hexdigest()
cache_path = os.path.join(cache_dir, cache_key)
if os.path.exists(cache_path):
with open(cache_path, "rb") as f:
data = f.read()
if expected_hash is None or check_hash(data, expected_hash):
return data
# the cached file does not match the hash, remove it and re-fetch
try:
os.remove(cache_path)
except OSError:
pass
contents = read_file(blobpath)
if expected_hash and not check_hash(contents, expected_hash):
raise ValueError(
f"Hash mismatch for data downloaded from {blobpath} (expected {expected_hash}). "
f"This may indicate a corrupted download. Please try again."
)
import uuid
try:
os.makedirs(cache_dir, exist_ok=True)
tmp_filename = cache_path + "." + str(uuid.uuid4()) + ".tmp"
with open(tmp_filename, "wb") as f:
f.write(contents)
os.rename(tmp_filename, cache_path)
except OSError:
# don't raise if we can't write to the default cache, e.g. issue #75
if user_specified_cache:
raise
return contents
从源码中可以看出,即使设置了TIKTOKEN_CACHE_DIR,如果调用时未传入本地blobpath(如:tiktoken.get_encoding不支持传入本地路径),仍然会尝试从远程服务器下载文件。
解决方案
下载所需的文件
-
下载文件:首先,需要在有网络的环境下下载
cl100k_base.tiktoken文件:wget https://openaipublic.blob.core.windows.net/encodings/cl100k_base.tiktokentiktoken文件已上传,可按需下载 下载链接
-
创建目录:在本地创建一个目录来存放下载的文件。例如,创建一个名为
tiktoken的目录:mkdir -p /path/to/your/tiktoken -
移动文件:将下载的
cl100k_base.tiktoken文件移动到刚刚创建的目录中:mv cl100k_base.tiktoken /path/to/your/tiktoken/
修改源码
-
修改源码:找到
tiktoken库的安装路径,通常在虚拟环境的site-packages目录下。例如:/home/oss/miniforge3-py312/envs/rag/lib/python3.12/site-packages/tiktoken_ext/openai_public.py打开
openai_public函数所在的文件,修改cl100k_base函数的实现,使其直接读取本地文件而不是尝试从远程服务器下载。例如,可以将cl100k_base函数修改为:
def cl100k_base():
mergeable_ranks = load_tiktoken_bpe(
"/path/to/your/tiktoken/cl100k_base.tiktoken", # 修改此处为你的路径
expected_hash="223921b76ee99bde995b7ff738513eef100fb51d18c93597a113bcffe865b2a7",
)
special_tokens = {
ENDOFTEXT: 100257,
FIM_PREFIX: 100258,
FIM_MIDDLE: 100259,
FIM_SUFFIX: 100260,
ENDOFPROMPT: 100276,
}
return {
"name": "cl100k_base",
"pat_str": r"""'(?i:[sdmt]|ll|ve|re)|[^\r\n\p{L}\p{N}]?+\p{L}++|\p{N}{1,3}+| ?[^\s\p{L}\p{N}]++[\r\n]*+|\s++$|\s*[\r\n]|\s+(?!\S)|\s""",
"mergeable_ranks": mergeable_ranks,
"special_tokens": special_tokens,
}
保存并运行
-
保存修改:保存修改后的文件。
-
运行代码:重新运行你的代码,应该不会再出现
ConnectTimeout错误。
总结
通过上述步骤,我们成功地解决了在无网络环境下搭建GraphRAG时遇到的ConnectTimeout问题。通过下载所需的文件并修改源码,使得程序能够正确地从本地读取文件,避免了网络连接的问题。
&spm=1001.2101.3001.5002&articleId=148531156&d=1&t=3&u=b1883551c3ab44448a5e0f0b4602c0d0)
2915

被折叠的 条评论
为什么被折叠?



