华为Ascend NPU适配

Ascend Extension for PyTorch插件

简介

本项目开发了名为torch_npuAscend Extension for PyTorch插件,使昇腾NPU可以适配PyTorch框架,为使用PyTorch框架的开发者提供昇腾AI处理器的超强算力。

昇腾为基于华为昇腾处理器和软件的行业应用及服务提供全栈AI计算基础设施。您可以通过访问昇腾社区,了解关于昇腾的更多信息。

安装

使用二进制文件进行安装

我们为用户提供可以快速安装torch_npu的whl安装包。在安装torch_npu之前,您需要先安装CANN软件。昇腾辅助软件中有更多关于CANN的版本信息。请参考CANN安装指南获取CANN安装包。

  1. 安装PyTorch

通过 pip 安装 PyTorch。

aarch64:

pip3 install torch==2.1.0

x86:

pip3 install torch==2.1.0+cpu  --index-url https://download.pytorch.org/whl/cpu

若使用pip命令安装失败,请使用下载链接或进入PyTorch官方网站进行查询下载对应版本。

架构 Python版本 下载链接
x86 Python3.8 下载链接
x86 Python3.9 下载链接
x86 Python3.10 下载链接
aarch64 Python3.8 下载链接
aarch64 Python3.9 下载链接
aarch64 Python3.10 下载链接
  1. 安装torch_npu依赖

运行以下命令安装依赖。

pip3 install pyyaml
pip3 install setuptools
  1. 安装torch_npu
pip3 install torch-npu==2.1.0.post3

如需要保存安装日志,可在pip3 install命令后面加上参数 --log <PATH>,并对您指定的目录<PATH>做好权限管控。

使用源代码进行安装

某些特殊场景下,用户可能需要自行编译torch_npu。可以根据昇腾辅助软件表PyTorch与Python版本配套表选择合适的分支。推荐使用Docker镜像编译torch_npu,可以通过以下步骤获取(建议只挂载工作路径,并避开系统路径,以降低安全风险), 生成的.whl文件路径为./dist/:

  1. 克隆torch_npu代码仓

    git clone https://gitee.com/ascend/pytorch.git -b v2.1.0-6.0.rc1 --depth 1
    
  2. 构建镜像

    cd pytorch/ci/docker/{arch} # {arch} for X86 or ARM
    docker build -t manylinux-builder:v1 .
    
  3. 进入Docker容器

    docker run -it -v /{code_path}/pytorch:/home/pytorch manylinux-builder:v1 bash
    # {code_path} is the torch_npu source code path
    
  4. 编译torch_npu

    Python 3.8 为例。

    cd /home/pytorch
    bash ci/build.sh --python=3.8
    

卸载

Pytorch框架训练环境的卸载可以参考昇腾官方文档

torch_npu的卸载只需执行命令:

pip3 uninstall torch_npu

如需要保存卸载日志,可在pip3 uninstall命令后面加上参数 --log <PATH>,并对您指定的目录<PATH>做好权限管控。

入门

前提

运行以下命令初始化CANN环境变量。

# Default path, change it if needed.
source /usr/local/Ascend/ascend-toolkit/set_env.sh

快速验证

可以通过以下样例快速体验昇腾NPU

import torch
import torch_npu

x = torch.randn(2, 2).npu()
y = torch.randn(2, 2).npu()
z = x.mm(y)

print(z)

PyTorch与Python版本配套表

PyTorch版本 Python版本
PyTorch1.11.0 Python3.7.x(>=3.7.5), Python3.8.x, Python3.9.x, Python3.10.x
PyTorch2.1.0 Python3.8.x, Python3.9.x, Python3.10.x
PyTorch2.2.0 Python3.8.x, Python3.9.x, Python3.10.x

昇腾辅助软件

PyTorch Extension版本号采用{PyTorch版本}-{昇腾版本}命名规则,前者为PyTorch Extension匹配的PyTorch版本,后者用于匹配CANN版本,详细匹配如下:

CANN版本 支持的PyTorch版本 支持的Extension版本 Gitee分支 AscendHub镜像版本/名称(链接)
CANN 8.0.RC1 2.2.0 2.2.0 v2.2.0-6.0.rc1
2.1.0 2.1.0.post3 v2.1.0-6.0.rc1
1.11.0 1.11.0.post11 v1.11.0-6.0.rc1
CANN 7.0.0 2.1.0 2.1.0 v2.1.0-5.0.0
2.0.1 2.0.1.post1 v2.0.1-5.0.0
1.11.0 1.11.0.post8 v1.11.0-5.0.0
CANN 7.0.RC1 2.1.0 2.1.0.rc1 v2.1.0-5.0.rc3
2.0.1 2.0.1 v2.0.1-5.0.rc3
1.11.0 1.11.0.post4 v1.11.0-5.0.rc3
CANN 6.3.RC3.1 1.11.0 1.11.0.post3 v1.11.0-5.0.rc2.2
CANN 6.3.RC3 1.11.0 1.11.0.post2 v1.11.0-5.0.rc2.1
CANN 6.3.RC2 2.0.1 2.0.1.rc1 v2.0.1-5.0.rc2
1.11.0 1.11.0.post1 v1.11.0-5.0.rc2 23.0.RC1-1.11.0
1.8.1 1.8.1.post2 v1.8.1-5.0.rc2 23.0.RC1-1.8.1
CANN 6.3.RC1 1.11.0 1.11.0 v1.11.0-5.0.rc1
1.8.1 1.8.1.post1 v1.8.1-5.0.rc1
CANN 6.0.1 1.5.0 1.5.0.post8 v1.5.0-3.0.0 22.0.0
1.8.1 1.8.1 v1.8.1-3.0.0 22.0.0-1.8.1
1.11.0 1.11.0.rc2(beta) v1.11.0-3.0.0
CANN 6.0.RC1 1.5.0 1.5.0.post7 v1.5.0-3.0.rc3 22.0.RC3
1.8.1 1.8.1.rc3 v1.8.1-3.0.rc3 22.0.RC3-1.8.1
1.11.0 1.11.0.rc1(beta) v1.11.0-3.0.rc3
CANN 5.1.RC2 1.5.0 1.5.0.post6 v1.5.0-3.0.rc2 22.0.RC2
1.8.1 1.8.1.rc2 v1.8.1-3.0.rc2 22.0.RC2-1.8.1
CANN 5.1.RC1 1.5.0 1.5.0.post5 v1.5.0-3.0.rc1 22.0.RC1
1.8.1 1.8.1.rc1 v1.8.1-3.0.rc1
CANN 5.0.4 1.5.0 1.5.0.post4 2.0.4.tr5 21.0.4
CANN 5.0.3 1.8.1 1.5.0.post3 2.0.3.tr5 21.0.3
CANN 5.0.2 1.5.0 1.5.0.post2 2.0.2.tr5 21.0.2

建议与交流

欢迎大家为社区做贡献。如果有任何疑问或建议,请提交gitee Issues,我们会尽快回复。感谢您的支持。

分支维护策略

AscendPyTorch版本分支的维护阶段如下:

状态 时间 说明
计划 1—3 个月 计划特性
开发 3 个月 开发特性
维护 6-12 个月 合入所有已解决的问题并发布版本,针对不同的PyTorch版本采取不同的维护策略,常规版本和长期支持版本维护周期分别为6个月和12个月
无维护 0—3 个月 合入所有已解决的问题,无专职维护人员,无版本发布
生命周期终止(EOL) N/A 分支不再接受任何修改

PyTorch版本维护策略

PyTorch版本 维护策略 当前状态 发布时间 后续状态 EOL日期
2.2.0 常规版本 维护 2024/04/01 预计2024/10/15起无维护
2.1.0 长期支持 维护 2023/10/15 预计2024/10/15起无维护
2.0.1 常规版本 EOL 2023/7/19 2024/3/14
1.11.0 长期支持 维护 2023/4/19 预计2024/4/19起无维护
1.8.1 长期支持 EOL 2022/4/10 2023/4/10
1.5.0 长期支持 EOL 2021/7/29 2022/7/29

安全声明

Ascend Extension for PyTorch插件 安全声明

参考文档

有关安装指南、模型迁移和训练/推理教程和API列表等更多详细信息,请参考昇腾社区Ascend Extension for PyTorch

文档名称 文档链接
安装指南 参考链接
网络模型迁移和训练 参考链接
算子适配 参考链接
API清单(PyTorch原生接口与自定义接口) 参考链接

许可证

Ascend Extension for PyTorch插件使用BSD许可证。详见LICENSE文件。

GCP的免费金和免费服务的区别

CGP的spot vm,不支持使用free tair credits,吓我一跳

实际是庸人自扰,因为我把free tier和free credits混淆在了一起。

  • free tier指用户可以免费、限量、限品种的使用部分google的服务,例如地图、计算资源等
  • free credits指用户可以在注册成功后的90天内,免费获得300美金来购买google的各项服务。

重新创建GCP instance并安装

夭折的GCP instance

  • 因为不知道什么原因,我在google cloud上的第一个instance(20240215,春节期间申请)被停机了,无法重启,官方给出的说明如下:
  • 分析:是在设置vpn network的firewall rule时,按照eve安装文档要求,新增了定制的egress流量(outband),其中tcp协议是全部端口(0-65535),来源ip是所有范围(ipv4,0.0.0.0/0),所以造成instance运行没两天,就被强制停机。
  • 没办法,我一方面发邮件给google cloud的support发了邮件,同时也思考解决方案。邮件很快有回复
    这并没有什么卵用,我除了礼貌感谢外,没有其他办法。
  • 还好这是云啊,直接删除instance,重新安装部署(可怜短短几天,85加币就没有了)

重新创建GCP的instance

  • 按照eve要求,重新创建具有vmx功能的虚拟机,也就是nested套娃虚拟机;
  • 这次特地选择了vm是spot vm,是所有vm中的丐中丐,价格据说off 60%,代价是随时会被停机,下面是介绍
This page describes Spot VMs: virtual machine (VM) instances that are excess Compute Engine capacity. Spot VMs have significant discounts, but Compute Engine might preemptively stop or delete (preempt) Spot VMs to reclaim the capacity at any time. Spot VMs are the latest version of preemptible VMs.

The provisioning model of a VM affects its discounts and availability; Compute Engine VMs can use either the standard provisioning model (standard VMs) (default) or the spot provisioning model (Spot VMs). In contrast to standard VMs, Spot VMs are available at much lower prices but have lower availability because they are subject to preemption. Use Spot VMs to reduce costs for fault-tolerant workloads.

To learn more about Compute Engine VMs in general, read the Virtual machine instances documentation. To learn how to create Spot VMs, read Create and use Spot VMs.

What are Spot VMs?

Spot VMs are available at much lower prices—60-91% discounts for most machine types and GPUs as well as smaller discounts for local SSDs and A3 VMs—compared to the on-demand price for standard VMs. However, Compute Engine might preempt Spot VMs at any time, such as when it needs the resources for other tasks. At this uncertain preemption time, Compute Engine either stops (default) or deletes your Spot VMs depending on your specified termination action for each Spot VM. Spot VMs are excess Compute Engine capacity, so their availability varies based on Compute Engine usage. Spot VMs do not have a minimum or maximum runtime unless you specifically limit the runtime.

If your workloads are fault-tolerant and can withstand possible VM preemption, Spot VMs can reduce your Compute Engine costs significantly. For example, batch processing jobs can run on Spot VMs. If some of those VMs stop during processing, the job slows but does not completely stop. Spot VMs complete your batch processing tasks without placing additional load on your existing VMs and without requiring you to pay full price for additional standard VMs.

  • 我们可以看到,在spot模式下,google vm可以便宜到0.01美元每小时
    *

  • 下面是我的选择

  • 还可以更加丧心病狂,因为spot停机后是不收费的(硬盘和静态ip需要收费),那么我们再来一个定期停机,一切就完美了。
    当完成定期计划来启停机器时,会出现如下告警

Compute Engine System service account service-111462968063@compute-system.iam.gserviceaccount.com needs to have [compute.instances.start] permissions applied in order to perform this operation.

参考下面的方案就能解决
Solution:

  • Login to the Google Cloud Console
  • To to IAM & Admin
  • Select IAM in the left panel
  • Click the box Include Google-provided role grants on the right side of the window. This enables showing Google-managed service accounts.
  • Locate the service account. Press CTRL-F5 to open a search box. Enter the text compute-system.
  • Click the pencil icon to edit the service account.
  • Click ADD ANOTHER ROLE
  • In the role filter enter Compute. Select Compute Instance Admin (v1).
  • Click SAVE

Wait a few minutes before trying to use the new permissions.

  • 完成后上传交换机的os文件(见下面章节)
  • 安装eve,并启动
  • eve界面启动后,添加node,启动switch都正常,但是telnet无法工作(ssh正常)
    • firewall rule添加ingress,tcp 23,无效
    • firewall rule添加egress,tcp 23,无效
    • firewall rule添加ingress,tcp 0-65535,ip 0.0.0.0/0,telnet成功!

上传交换机和路由器的系统文件

  1. Cisco的iol/ios镜像文件

    1. 把iol文件,后缀是bin,上传到目录:/opt/unetlab/addons/iol/bin/
    2. 使用如下命令来修改权限(切记)
    /opt/unetlab/wrappers/unl_wrapper -a fixpermissions
    
    1. 运行授权文件No need to fix the permission of the license file as we will run this file using the python program. Run command
    python3     CiscoIOUKeygen3f.py
    
    1. 使用如下命令来测试iou/ios文件是否安装成功
    cd /opt/unetlab/addons/iol/bin
    touch NETMAP
    LD_LIBRARY_PATH=/opt/unetlab/addons/iol/lib /opt/unetlab/addons/iol/bin/<iosname.bin> 1
    
    ***************************************************************
    IOS On Unix - Cisco Systems confidential, internal use only
    Under no circumstances is this software to be provided to any
    non Cisco staff or customers.  To do so is likely to result
    in disciplinary action. Please refer to the IOU Usage policy at
    wwwin-iou.cisco.com for more information.
    ***************************************************************
    
                  Restricted Rights Legend
    
    Use, duplication, or disclosure by the Government is
    subject to restrictions as set forth in subparagraph
    (c) of the Commercial Computer Software - Restricted
    Rights clause at FAR sec. 52.227-19 and subparagraph
    (c) (1) (ii) of the Rights in Technical Data and Computer
    Software clause at DFARS sec. 252.227-7013.
    
               cisco Systems, Inc.
               170 West Tasman Drive
               San Jose, California 95134-1706
    
  2. Cisco的其他镜像文件
    1.

  3. 华为的镜像文件
    1.

  4. 华三的镜像文件
    1.

oracle cloud and google cloud

春节在家,一直到初五都没闲着,这几天主要是在折腾eve-ng,装了2台mac电脑,还有一个google cloud,用下来还是gcp给力,毕竟300美金不是闹着玩的。

oracle cloud

说google cloud的之前,得先唠叨下我去年申请的oracle cloud,号称永久免费的云,虽然配置不怎么地,胜在免费,用下来挺不错,唯一不爽的是一直要登录oracle的shell,今天突然发现,使用token的方式,与ssh密码登录是不矛盾的,只能怪自己学艺不精吧

vi /etc/ssh/sshd.conf

在上面的配置文件里,修改两个地方

  • PasswordAuthentication yes
  • Passwordlogin yes

然后重新启动ssh服务

systemctl restart sshd

就可以实现ssh登录了

google cloud

为什么要折腾google cloud呢?按理说我自己的目标是在aws找一个网工的职业,在苦寒之地可以不用洗盘子和在超市搬货。所以在我寻找eve-ng这个软件的部署方式时,突然发现原来是可以在云主机上部署的,唯一的特殊要求是,需要支持nested,也就是在虚拟机套娃(在一台虚拟机里,再安装一台虚拟机),这个时候就要用到一个比较特殊的技术,vmx,也就是允许虚拟机把硬件资源开放出来,让套娃虚拟机继续使用,和我们搞gpu的passthrough很类似,很可惜,国内的阿里云是不支持这样做的,目测下来只有google cloud支持的比较好。

所以早晨抓紧时间,利用目前google的优惠政策,申请了一台3个月的免费主机,算下来,3个月我也能在网络技术方面小有所成了。

下面是这次的几个心得

  1. 申请ecs的时候,选4个vcpu,16g内存,因为eve可能要支持100个node,每个node也许就要部署一个1G的镜像包 ,性能太差就玩不起来;
  2. 硬盘可以选的差一点,我直接用了standard,而不是ssd,每个月50G可以省7美金,用下来觉得自己真是会精打细算;
  3. cpu架构一定要选intel的cascade或skylake,一方面便宜,另外对vmx支持比较好
  4. 3个月biling大概350加币,马上就要突破300美金了,有一点点紧迫的感觉
  5. 云主机创建完成,会发现ssh的环境和cloud shell的环境不同,ssh上的是ubuntu20的环境,这就是套娃虚拟机的系统,是用eve官网给的命令安装的;而google cloud的环境是debian的系统,内核版本很高,关于这两个环境不不同的原因我还没有搞的很清楚,毕竟整个ecs创建的过程中,没有让我选择os啊?

20G disk space is not mounted!

今天打算在阿里云上安装eve-ng,感觉磁盘空间可能不足,打开控制台,发现还有一个20G的数据盘,觉得勉强够用,就直接在终端上通过lsblk查看

[MDaliyun ~]# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
loop0    7:0    0 63.5M  1 loop /snap/core20/2015
loop2    7:2    0 40.4M  1 loop /snap/snapd/20671
loop3    7:3    0 11.9M  1 loop /snap/kubectl/3164
loop4    7:4    0 63.9M  1 loop /snap/core20/2105
loop5    7:5    0 40.9M  1 loop /snap/snapd/20290
loop6    7:6    0 11.9M  1 loop /snap/kubectl/3149
vda    252:0    0   40G  0 disk 
└─vda1 252:1    0   40G  0 part /
vdb    252:16   0   20G  0 disk 

好家伙,这一看不要紧,发现vdb这块盘虽然启动2年了,但是一直没有挂载,就这么白白浪费了2年!
马上格式化,挂载,把它用起来,为了省事,直接让chatgpt出马:

The output /dev/vdb: data from the file -s /dev/vdb command indicates that the /dev/vdb block device does not have a recognizable filesystem or partition table. This typically means that the disk is either unformatted or contains raw data that is not structured in a manner recognized by the file command.

Given this situation, if you intend to use /dev/vdb for storage, the next steps would involve creating a filesystem on it. Here's how you can do it:

Create a Filesystem on /dev/vdb
Choose a Filesystem Type: Decide on the type of filesystem you want to create. Common choices include ext4 for general use, xfs for high-performance environments, and btrfs for systems requiring advanced features like snapshotting.
Create the Filesystem: Use the mkfs command to create a filesystem. For example, to create an ext4 filesystem on /dev/vdb, you would use:
bash
Copy code
mkfs.ext4 /dev/vdb
Replace ext4 with your filesystem of choice if different.
Mount the Filesystem
After creating the filesystem, you can mount it to make the storage available for use:

Create a Mount Point: This is the directory where the disk's contents will be accessible. For example, to create a mount point at /mnt/data, use:
bash
Copy code
mkdir /mnt/data
Mount the Disk: Mount the newly formatted disk to the mount point:
bash
Copy code
mount /dev/vdb /mnt/data
Ensure Persistent Mounting Across Reboots
To automatically mount the disk after a reboot, you'll need to add an entry to the /etc/fstab file:

Find the UUID of /dev/vdb: The UUID is a unique identifier for the disk, which is preferable to use in the /etc/fstab file instead of the device name (/dev/vdb) since it won't change between reboots.
bash
Copy code
blkid /dev/vdb
Edit /etc/fstab: Add a line to this file with the disk's UUID and mount information. Open the file in a text editor (like nano or vi), and add a line similar to:
plaintext
Copy code
UUID=<your-uuid> /mnt/data ext4 defaults 0 2
Replace <your-uuid> with the actual UUID you obtained from the blkid command.

使用mkfs.ext4这个命令,作为通用存储,结果如下:

[MDaliyun ~]# mkfs.ext4 /dev/vdb
mke2fs 1.45.5 (07-Jan-2020)
Creating filesystem with 5242880 4k blocks and 1310720 inodes
Filesystem UUID: 811e4057-5c8b-45e2-8fb9-40e023ec72cc
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
        4096000

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done   

然后挂在在data下面:

[MDaliyun /]# mkdir /mnt/data
/
[MDaliyun /]# file -s /dev/vdb  
/dev/vdb: Linux rev 1.0 ext4 filesystem data, UUID=811e4057-5c8b-45e2-8fb9-40e023ec72cc (extents) (64bit) (large files) (huge files)
[MDaliyun /]# mount /dev/vdb /mnt/data
[MDaliyun /]# blkid /dev/vdb
/dev/vdb: UUID="811e4057-5c8b-45e2-8fb9-40e023ec72cc" TYPE="ext4"

再使用lsblk看看,成功了

不过正事还没有完,eve-ng是虚拟机,没法在已经虚拟化的机器上安装(阿里云不支持vmx,也就是硬件已经使用了一次kvm的vmx,虚拟机里就无法支持二次的vmx了),但是我的本地电脑也没有空间继续安装vmware,如何是好?

https://zhuanlan.zhihu.com/p/548997684
我们知道,在Intel处理器上,KVM使用Intel的vmx(virtul machine eXtensions)来提高虚拟机性能, 即硬件辅助虚拟化技术, 现在如果我们需要测试一个openstack集群,又或者单纯的需要多台具备"vmx"支持的主机, 但是又没有太多物理服务器可使用, 如果我们的虚拟机能够和物理机一样支持"vmx",那么问题就解决了,而正常情况下,一台虚拟机无法使自己成为一个hypervisors并在其上再次安装虚拟机,因为这些虚拟机并不支持"vmx"

嵌套式虚拟nested是一个可通过内核参数来启用的功能。它能够使一台虚拟机具有物理机CPU特性,支持vmx或者svm(AMD)硬件虚拟化。

untitled

The curly brackets {} in Python have different meanings depending on the context. Here are some common uses of {} in Python:

Dictionary literals:

A dictionary is a data structure that stores key-value pairs. You can create a dictionary by using curly brackets and separating the keys and values by colons. For example, person = {"name": "Alice", "age": 25} creates a dictionary with two keys: “name” and “age”, and their corresponding values: “Alice” and 25.

Set literals:

A set is a data structure that stores unique and unordered elements. You can create a set by using curly brackets and separating the elements by commas. For example, colors = {"red", "green", "blue"} creates a set with three elements: “red”, “green”, and “blue”.

String formatting:

You can use curly brackets as placeholders for variables or expressions in a string. You can then use the format() method to replace the placeholders with the desired values. For example, print("Hello, {}!".format("world")) prints “Hello, world!” to the console. You can also use numbers or keywords inside the curly brackets to specify the order or name of the arguments. For example, print("The area of a circle with radius {r} is {a:.2f}".format(r=5, a=3.14*5**2)) prints “The area of a circle with radius 5 is 78.50” to the console.

Nginx反向代理服务器配置

Nginx 可以作为非常强大的反向代理服务器,下面是一个简单的 Nginx 反向代理的配置示例以及对应的详细解释:

nginx
Copy code
http {
    upstream backend {
        server backend1.example.com;
        server backend2.example.com;
    }

    server {
        listen 80;
        server_name www.example.com;

        location / {
            proxy_pass http://backend;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
}

配置解释

http 块:

这是 Nginx 配置中的顶级块,用于包含 HTTP 服务器的配置。
upstream backend 块:
这个块定义了一个名为 backend 的服务器组,可以包含一个或多个服务器。
server backend1.example.com; 和 server backend2.example.com; 行指定了组成这个服务器组的后端服务器的地址。这些服务器可以是其他 Nginx 服务器,也可以是任何能够处理 HTTP 请求的服务器。

server 块:

这个块定义了一个虚拟服务器,用于处理进入的 HTTP 请求。
listen 80; 行告诉 Nginx 在端口 80 上监听请求,这是 HTTP 的默认端口。
server_name www.example.com; 行定义了服务器的域名。

location / 块:

location 块用于定义当请求匹配特定模式时应如何处理这些请求。在这个例子中,/ 指的是匹配所有请求。
proxy_pass http://backend; 行指定将请求转发到名为 backend 的上游服务器组。这意味着所有到达此 Nginx 服务器的 HTTP 请求都会被转发到 backend1.example.com 或 backend2.example.com。

proxy_set_header 指令:

这些指令用于修改或添加传递给后端服务器的 HTTP 请求头。
Host $host; 将请求头中的 Host 设置为客户端请求中的 Host 值。
X-Real-IP $remote_addr; 添加了一个自定义请求头,包含客户端的 IP 地址。
X-Forwarded-For $proxy_add_x_forwarded_for; 添加了一个请求头,包含原始请求的 IP 地址链。这对于在后端服务器上记录正确的客户端 IP 地址很重要。
X-Forwarded-Proto $scheme; 添加了一个请求头,标明了客户端是使用 HTTP 还是 HTTPS 协议。

通过上述配置,Nginx 会将所有到达 www.example.com 的请求转发到两个后端服务器之一,并保持客户端的原始 IP 地址和其它相关信息,使得后端服务器能够获取到正确的客户端信息。

从国内访问chatgpt

方案一

下面是在 Linux 服务器上配置 OpenVPN 客户端、设置路由以及保证应用通过 VPN 隧道访问 ChatGPT API 的一般步骤和命令。请注意,在进行以下操作之前,请确保您拥有阿里云服务器的 root 权限或 sudo 权限,以及加拿大 OpenVPN 服务器的必要配置文件。

步骤 1: 安装 OpenVPN 客户端
在您的阿里云服务器上安装 OpenVPN 客户端:

sudo apt-get update  # 如果是基于 Debian 的系统
sudo apt-get install openvpn

或者

sudo yum update  # 如果是基于 RHEL 的系统
sudo yum install openvpn

步骤 2: 配置 OpenVPN 客户端
将从加拿大 OpenVPN 服务器获取的配置文件(通常是 .ovpn 文件)传输到阿里云服务器。
启动 OpenVPN 客户端,连接到服务器:

sudo openvpn --config /path/to/your/vpnconfig.ovpn

确保将 /path/to/your/vpnconfig.ovpn 替换为您的实际配置文件路径。这条命令将启动 OpenVPN 并尝试连接到您的加拿大 VPN 服务器。

步骤 3: 路由设置
修改 OpenVPN 配置文件以添加路由。打开 .ovpn 文件,添加类似以下行来指定路由:

route ChatGPT_API_IP 255.255.255.255 vpn_gateway

将 ChatGPT_API_IP 替换为 ChatGPT API 的实际 IP 地址,vpn_gateway 通常会自动设置为通过 VPN 连接的默认网关。

或者,您也可以在 OpenVPN 连接后通过命令行手动添加路由:

sudo ip route add ChatGPT_API_IP/32 via VPN_GATEWAY_IP dev tun0

将 ChatGPT_API_IP 替换为 ChatGPT API 的 IP 地址,VPN_GATEWAY_IP 替换为您 VPN 的网关 IP,tun0 是 OpenVPN 使用的默认网络接口,如果您的配置不同,请相应调整。

步骤 4: 验证连接
一旦 OpenVPN 客户端启动并且路由设置完成,您可以使用 ping 命令或类似的网络工具来测试 VPN 连接和路由是否正确:

ping ChatGPT_API_IP

也可以查看路由表确保新路由已经设置:

ip route show

步骤 5: 应用配置
确保您的应用在发起到 ChatGPT API 的请求时,不需要任何特别的配置,因为操作系统的路由表已经指示了通过 VPN 隧道转发到 ChatGPT API 的流量。

步骤 6: 持久化 VPN 连接
为了确保 VPN 连接在服务器重启后自动启动,您可以将 OpenVPN 连接命令添加到系统的启动脚本中,如 rc.local 或使用系统的服务管理器(如 systemd)创建一个服务。

这里的步骤和命令提供了一般的指南,具体的命令可能会根据您的 Linux 发行版和 OpenVPN 配置有所不同。此外,确保您具有连接到 OpenVPN 服务器所需的所有凭据和权限。

方案二

要设置加拿大服务器作为反向代理服务器并转发请求到 ChatGPT API,你可以使用 Nginx 或 Apache。下面以 Nginx 为例,提供详细的配置步骤和命令。

Nginx 反向代理配置
步骤 1: 安装 Nginx

在加拿大的服务器上安装 Nginx:

sudo apt update  # 对于 Debian/Ubuntu 系统
sudo apt install nginx

或者对于 RHEL/CentOS 系统

sudo yum update
sudo yum install nginx

步骤 2: 配置 Nginx 作为反向代理

创建一个新的 Nginx 配置文件或编辑现有的站点配置文件:

sudo nano /etc/nginx/sites-available/chatgpt-proxy

在配置文件中添加以下内容:

server {
    listen 80;
    server_name your-canadian-server.com;  # 替换为你加拿大服务器的域名或IP

    location / {
        proxy_pass https://api.openai.com/v1/;  # ChatGPT API 的 URL
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

启用配置并测试:

sudo ln -s /etc/nginx/sites-available/chatgpt-proxy /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

步骤 3: 配置 SSL/TLS

使用 Let’s Encrypt 提供的 certbot 工具来自动获取和安装 SSL 证书:

sudo apt install certbot python3-certbot-nginx  # 对于 Debian/Ubuntu 系统

或者

sudo yum install certbot python3-certbot-nginx  # 对于 RHEL/CentOS 系统

sudo certbot --nginx -d your-canadian-server.com  # 用实际域名替换
Certbot 会自动处理证书的获取和安装,并修改 Nginx 配置以启用 HTTPS。

步骤 4: (可选) 设置 API 认证

如果需要,你可以在 Nginx 配置中添加基本认证:

location / {
    # ...其他配置保持不变...

    auth_basic "Restricted Content";
    auth_basic_user_file /etc/nginx/.htpasswd;  # 路径到密码文件
}

创建密码文件并设置用户和密码:

sudo apt-get install apache2-utils  # 安装 htpasswd 工具
sudo htpasswd -c /etc/nginx/.htpasswd username  # 用实际用户名替换

步骤 5: 修改阿里云应用配置

在阿里云服务器上的应用中,你需要将所有指向 ChatGPT API 的请求修改为通过你的加拿大服务器反向代理的 URL。

例如,如果你的加拿大服务器域名是 your-canadian-server.com,应用中的 API 请求 URL 应更改为:

https://your-canadian-server.com/v1/...  # 具体路径根据实际请求调整

注意事项
确保在配置 Nginx 或应用时替换所有的占位符(如 your-canadian-server.com 和 username)为实际的值。
使用 SSL/TLS 时,确保你的域名已正确解析到加拿大服务器的 IP 地址,并且端口 80 和 443 在服务器上是开放的。
测试配置更改后的应用以确保它可以通过加拿大服务器正确访问 ChatGPT API

方案三

要通过 SSH 隧道来转发请求到 ChatGPT API,你需要在阿里云服务器上执行以下步骤:

步骤 1: 建立 SSH 隧道
在阿里云服务器上,使用 SSH 命令建立一个隧道。这个隧道将本地端口转发到加拿大服务器上的端口,然后由加拿大服务器转发到 ChatGPT API。

执行以下命令以建立隧道:

ssh -L [本地端口]:api.openai.com:443 [用户]@[加拿大服务器IP] -N -f

[本地端口]:这是阿里云服务器上的本地端口号,选择一个未被使用的端口,例如 8080。
api.openai.com:443:这是 ChatGPT API 的域名和端口。
[用户]:这是你在加拿大服务器上的用户名。
[加拿大服务器IP]:这是加拿大服务器的公网 IP 地址。
-N 告诉 SSH 客户端不执行远程命令,只进行端口转发。
-f 告诉 SSH 客户端在后台运行。
例如:

ssh -L 8080:api.openai.com:443 myuser@198.51.100.0 -N -f

这条命令将在后台创建一个 SSH 隧道,把阿里云服务器上的 8080 端口的流量转发到 api.openai.com 的 443 端口上。
步骤 2: 测试端口转发
测试本地端口转发是否工作正常:

curl -v https://localhost:8080/v1/engines -H "Authorization: Bearer YOUR_OPENAI_API_KEY"

这个命令应该返回 ChatGPT API 的响应。确保将 YOUR_OPENAI_API_KEY 替换为你的实际 OpenAI API 密钥。

步骤 3: 修改应用配置
修改你在阿里云服务器上的应用配置,把所有指向 ChatGPT API 的请求改为通过本地端口:

https://localhost:8080/v1/...

这样,当你的应用尝试连接到 ChatGPT API 时,实际上它将通过 SSH 隧道发送请求。

注意事项
请确保你的阿里云服务器上的防火墙配置允许本地端口(例如 8080)的流量。
你可能需要在加拿大服务器上配置 SSH 以允许端口转发。
在生产环境中使用 SSH 隧道时,可能需要考虑使用更稳健的方法来保持隧道的持续运行,如使用 autossh。
由于使用了 -f 参数,SSH 命令会在后台运行。如果需要终止隧道,你可以找到对应的 SSH 进程并杀掉它,或者关闭监听本地端口的 SSH 隧道。

langchain的sdk也升级了

前两天升级openai后,这两天一直在解决下面的错误,openai的error属性缺失

File /usr/local/lib/python3.11/site-packages/langchain/chat_models/openai.py:77, in _create_retry_decorator(llm, run_manager)
     68 def _create_retry_decorator(
     69     llm: ChatOpenAI,
     70     run_manager: Optional[
     71         Union[AsyncCallbackManagerForLLMRun, CallbackManagerForLLMRun]
     72     ] = None,
     73 ) -> Callable[[Any], Any]:
     74     import openai
     76     errors = [
---> 77         openai.error.Timeout,
     78         openai.error.APIError,
     79         openai.error.APIConnectionError,
     80         openai.error.RateLimitError,
     81         openai.error.ServiceUnavailableError,
     82     ]
     83     return create_base_retry_decorator(
     84         error_types=errors, max_retries=llm.max_retries, run_manager=run_manager
     85     )

AttributeError: module 'openai' has no attribute 'error'

开始有点着急,毕竟openai已经是最新版本了,不想降级,然后就开始把openai.py里的相关code都注释掉,这下可好,压下葫芦起了瓢,各种稀奇古怪的问题都跑出来,
不得已检查各种包的版本

pip3 list --outdated

发现langchain也要升级了,最后一招制敌。

pip3 install --upgrade langchain

升级到新版本后,问题解决了

pip3 show langchain       
Name: langchain
Version: 0.0.352
Summary: Building applications with LLMs through composability
Home-page: https://github.com/langchain-ai/langchain
Author: 
Author-email: 
License: MIT
Location: /usr/local/lib/python3.11/site-packages
Requires: aiohttp, dataclasses-json, jsonpatch, langchain-community, langchain-core, langsmith, numpy, pydantic, PyYAML, requests, SQLAlchemy, tenacity

如果按照网上的建议,非得降级才能解决,这不是自断手脚嘛。

pip install openai==0.28.1
pip install langchain==0.0.330