Weiyun1025's picture
Upload folder using huggingface_hub
2abfccb verified
|
raw
history blame
9.54 kB
Petrel OSS SDK 2.0
===
注意:该版本SDK需要python3.6环境
若之前安装过旧版本,请先运行
```bash
$ pip uninstall pycephs3client
$ rm -rf ~/.local/lib/python3.6/site-packages/petrel_client
```
## 建议在安装之前先升级 pip
```bash
source /mnt/lustre/share/platform/env/<pat... or pt...> # 请根据实际情况确定是否需要 source
python3 -m pip install --upgrade pip # 请根据实际情况确定是否需要 `sudo` 或添加 `--user` 参数
```
## 训练集群环境上安装
```bash
$ source /mnt/lustre/share/platform/env/<pat... or pt...>
$ python setup.py sdist
$ pip install --user dist/*
```
## 通过修改 PYTHONPATH 安装
```bash
$ source /mnt/lustre/share/platform/env/<pat... or pt...>
# 安装SDK依赖
$ python setup.py egg_info
$ pip install -r *.egg-info/requires.txt
# 将SDK编译到 ./build 目录
$ python setup.py build
# 修改 PYTHONPATH 环境变量
$ export PYTHONPATH=<path_to_sdk>/build/lib:$PYTHONPATH
```
## venv环境上安装
```bash
$ python3 -m venv your_venv_name # 若已创建venv环境则无需执行
$ source your_venv_name/bin/active
$ python setup.py sdist
$ pip install dist/*
```
## 系统环境上安装
```bash
$ python3 setup.py sdist
$ python3 -m pip install dist/* # 请根据实际情况确定是否需要 `sudo` 或添加 `--user` 参数
```
## 使用
SDK 提供 `get``put` 接口,使用方式为
```python
data = client.get(url) # 默认情况由配置文件决定是否使用 MC
data = client.get(url, no_cache=True) # 本次 get 直接从 ceph 读取
data = client.get(url, update_cache=True) # 本次 get 直接从 ceph 读取,并将数据缓存至 MC
```
```python
client.put(url, data) # 默认 put 不会更新 MC
client.put(url, data, update_cache=True) # 本次 put 将数据存入 ceph 之后并更新 MC
```
``注意:``若配置文件中没有启用 `MC` ,则 `no_cache` 和 `update_cache` 参数将被忽略
以下为使用 SDK 读取图片、进行图片处理后并保存图片的简单例子
```python
import cv2
import numpy as np
from os.path import splitext
from petrel_client.client import Client
conf_path = '~/petreloss.conf'
client = Client(conf_path) # 若不指定 conf_path ,则从 '~/petreloss.conf' 读取配置文件
img_url = 's3://bucket1/image.jpeg'
img_gray_url = 's3://bucket1/image_gray.jpeg'
img_ext = splitext(img_gray_url)[-1]
# 图片读取
img_bytes = client.get(img_url)
assert(img_bytes is not None)
img_mem_view = memoryview(img_bytes)
img_array = np.frombuffer(img_mem_view, np.uint8)
img = cv2.imdecode(img_array, cv2.IMREAD_COLOR)
# 图片处理
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 图片存储
success, img_gray_array = cv2.imencode(img_ext, img_gray)
assert(success)
img_gray_bytes = img_gray_array.tostring()
client.put(img_gray_url, img_gray_bytes)
```
配置文件请参考 [petreloss.conf](./conf/petreloss.conf)
``请注意:配置文件中 `key = value` 的 key 前面不能有空格,否则该行视为上一行配置项 value 的一部分``
使用样例请参考 [multi_cluster_test.py](./tests/multi_cluster_test.py)
## `Tensor` 和 `Json` 数据保存与读取
使用样例 [tensor_json_test.py](./tests/tensor_json_test.py)
## `Pillow Image` 数据保存与读取
使用样例 [pillow_image_test.py](./tests/pillow_image_test.py)
## 数据过大无法上传,则需要分片上传
使用样例 [multipart_test.py](./tests/multipart_test.py)
## 创建 Bucket
```python
client.create_bucket('s3://mybucket')
```
## 顺序的读取某个前缀的数据
```python
cluster = 'cluster1'
files = client.get_file_iterator('cluster1:s3://lili1.test2/test3')
for p, k in files
key = '{0}:s3://{1}'.format(cluster, p)
data = client.get(key)
```
## 使用 anonymous 账户访问数据
若在配置文件中不设置 `access_key``secret_key`,将以 `anonymous` 账户访问数据。
## McKeySizeExceed 错误
默认情况下,`MC` 所支持 `key` 的最大长度为250个字节。如果路径过长,将会出现 `McKeySizeExceed` 错误。
此时需要用户定义 `key` 的转换规则来避免该错误。
``注意:``中文字符对应多个字节。
例如:
```python
def trim_key(key):
if isinstance(key, str):
key = key.encode('utf-8')
else:
assert isinstance(key, bytes)
return key[-249:]
client = Client('~/petreloss.conf', mc_key_cb=trim_key)
```
此外,可使用内置函数 `md5``sha256` 等,例如:
```python
client = Client('~/petreloss.conf', mc_key_cb='sha256')
```
或在配置文件中指定:
```conf
[mc]
mc_key_cb = sha512
```
``请注意``
- 用户需要保证转换规则结果的唯一性,内置转换函数也有可能发生哈希碰撞。
- 如果 `key``str` 类型且其中出现中文字符,请务必用 `encode('utf-8')` 对其进行编码。
## 使用伪客户端
在对应客户端添加如下配置:
```conf
fake = True
```
配置文件请参考 [fake_client.conf](./conf/fake_client.conf)
使用样例请参考 [fake_client_test.py](./tests/fake_client_test.py)
## 强制更新MC
使用 `get_and_update` 接口或在 `get` 中传入 `update_cache=True` 参数将直接从存储系统读取数据并更新MC。
## IO 统计信息
IO 统计信息可通过以下三种方式修改其`log`输出频度:
- 由环境变量 `count_disp` 设置
- 由配置文件 `count_disp` 设置 (若已设置环境变量,则该方式无效)
- 调用 `client.set_count_disp(count_disp)` (该方式将覆盖上述两种方式),但限于`parrots``pytorch`的运行机制,在某些使用场景下可能无法有效修改。
`count_disp``0` ,则将关闭 IO 统计信息打印。
若需要在 `console` 中打印 IO 统计信息,则需要设置 `console_log_level``INFO` 或更低级别,且 `count_disp` 需大于 `0`
## DataLoader
`SDK` 提供的 `DataLoader` 额外支持如下参数:
- `prefetch_factor`,默认2。每个 `worker` 预读 `batch` 数目。
- `persistent_workers`,默认 `False`。如果为 `True`,则每轮 `epoch` 迭代完毕后 `worker` 进程将不会关闭,下轮 `epoch` 将复用该 `worker` 进程。
用例:
```python
from petrel_client.utils.data import DataLoader
dataloader = DataLoader(dataset=xxx, ..., prefetch_factor=4, persistent_workers=True)
```
## SSL 验证
使用 `https` 协议时默认不会对 `SSL` 进行验证。若需要开启验证,请在配置文件中进行如下设置
```conf
verify_ssl = True
```
## Presigned URL,生成签名链接
```python
presigned_url = client.generate_presigned_url(url, client_method ='get_object', expires_in=3600)
```
`client_method` 取值为 `get_object` (默认值) 或 `put_object`
`expires_in` 单位为秒,默认值为 3600
## Presigned POST,生成签名 POST
```python
presigned_post = client.generate_presigned_post(url, fields=None, conditions=None, expires_in=3600)
```
参数及返回值详见 [generate_presigned_post](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.Client.generate_presigned_post),其中参数 bucket 和 key 从 url 中提取。
## Range 读取
range 的形式有如下几种
- '`first_byte_pos`-':读取`first_byte_pos`及后续的所有数据
- '`first_byte_pos`-`last_byte_pos`':读取`first_byte_pos``last_byte_pos`(包含)的数据
- '-`suffix_length`':读取最后`suffix_length`字节的数据
具体详见 HTTP 中 Range 的定义:https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35 ,但ceph目前不支持多个 Range 读取。
```python
# 假设数据长度为 10000 字节
# 读取第一段 500 字节数据
data1 = client.get(url, range='0-499')
# 读取第二段 500 字节数据
data2 = client.get(url, range='500-999')
# 读取最后 500 字节数据
data_last = client.get(url, range='-500')
# 或
data_last = client.get(url, range='9500-')
```
## 以流的形式读取数据
```python
stream = client.get(url, enable_stream=True)
```
返回的 `stream``StreamingBody`,使用方法详见
https://botocore.amazonaws.com/v1/documentation/api/latest/reference/response.html
## 判断对象是否存在
```python
exists = client.contains(url)
```
## 查询对象大小
```python
size = client.size(url)
```
若对象不存在,产生 `NoSuchKeyError` 异常
## 删除对象
```python
client.delete(url)
```
## 列出当前路径包含的对象或目录
```python
contents = client.list(url)
for content in contents:
if content.endswith('/'):
print('directory:', content)
else:
print('object:', content)
```
## 判断目录是否存在
```python
client.isdir(url)
```
注意:`Ceph`中没有目录的概念,本函数返回`True`时代表存在以该`url`作为前缀的对象,其他情况返回`False`
## 使用 `/mnt/cache` 目录下的 `Python` 环境
相对于 `/mnt/lustre` 目录,在 `/mnt/cache` 目录执行 `Python` 有一定的性能提升。
使用方式如下:
- `source` `/mnt/cache` 目录下的 `Python` 环境
```bash
### 例如 pt1.3v1
source /mnt/cache/share/platform/env/pt1.3v1
### 或 s0.3.3
source /mnt/cache/share/spring/s0.3.3
```
- 检查 `Python` 路径是否正确
```bash
which python
### 结果应为 /mnt/cache/...
```
- 设定 `PYTHONUSERBASE` 环境变量
```bash
export PYTHONUSERBASE=/mnt/cache/<username>/.local
```
- 重新安装相关依赖库(仅需首次使用时执行)
```
python -m pip install --user <packages>
```