tiktoken离线环境使用(解决在无网络环境下搭建GraphRAG时的ConnectTimeout问题)

解决在无网络环境下搭建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不支持传入本地路径),仍然会尝试从远程服务器下载文件。

解决方案

下载所需的文件

  1. 下载文件:首先,需要在有网络的环境下下载cl100k_base.tiktoken文件:

    wget https://openaipublic.blob.core.windows.net/encodings/cl100k_base.tiktoken
    

    tiktoken文件已上传,可按需下载 下载链接

  2. 创建目录:在本地创建一个目录来存放下载的文件。例如,创建一个名为tiktoken的目录:

    mkdir -p /path/to/your/tiktoken
    
  3. 移动文件:将下载的cl100k_base.tiktoken文件移动到刚刚创建的目录中:

    mv cl100k_base.tiktoken /path/to/your/tiktoken/
    

修改源码

  1. 修改源码:找到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,
    }

保存并运行

  1. 保存修改:保存修改后的文件。

  2. 运行代码:重新运行你的代码,应该不会再出现ConnectTimeout错误。

总结

通过上述步骤,我们成功地解决了在无网络环境下搭建GraphRAG时遇到的ConnectTimeout问题。通过下载所需的文件并修改源码,使得程序能够正确地从本地读取文件,避免了网络连接的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值