File size: 8,549 Bytes
2abfccb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
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)
## 数据过大无法上传,则需要分片上传
使用样例 [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 中提取。
## 以流的形式读取数据
```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
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>
``` |