From d8a85234f02646d6da54a24dd7668fca9392f4d3 Mon Sep 17 00:00:00 2001 From: whiskymeow <1051950160@qq.com> Date: Tue, 25 Feb 2025 10:46:07 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=AD=E8=8B=B1=E6=96=87?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E5=9B=BE=E7=89=87=E4=B8=8D=E4=B8=80=E8=87=B4?= =?UTF-8?q?=E7=9A=84=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: whiskymeow <1051950160@qq.com> --- docs/en/api_reference/error.md | 16 ++-- docs/en/api_reference/om_file_system.md | 71 +++++++-------- docs/en/api_reference/upload_api.md | 6 +- .../en/basic_tutorial/third-party_platform.md | 26 +++--- docs/en/basic_tutorial/upload.md | 16 ++-- .../figures/certificate download 1.png | Bin 8571 -> 0 bytes .../figures/certificate download 2.png | Bin 11139 -> 0 bytes .../figures/certificate download 3.png | Bin 16283 -> 0 bytes .../figures/certificate_download_1.png | Bin 8571 -> 14733 bytes .../figures/certificate_download_2.png | Bin 11139 -> 15225 bytes .../en/developer_tutorial/trouble_shooting.md | 10 +-- docs/en/install.md | 50 +++++++---- docs/en/overview.md | 4 +- docs/en/quick_start.md | 12 +-- docs/en/release_note.md | 82 ++++++++++-------- 15 files changed, 154 insertions(+), 139 deletions(-) delete mode 100644 docs/en/developer_tutorial/figures/certificate download 1.png delete mode 100644 docs/en/developer_tutorial/figures/certificate download 2.png delete mode 100644 docs/en/developer_tutorial/figures/certificate download 3.png diff --git a/docs/en/api_reference/error.md b/docs/en/api_reference/error.md index 1506f10..f087905 100644 --- a/docs/en/api_reference/error.md +++ b/docs/en/api_reference/error.md @@ -1,29 +1,29 @@ # Public Errors -## openmind_hub.utils.OMValidationError +## openmind_hub.OMValidationError Parameter validation failed. -## openmind_hub.utils.EntryNotFoundError +## openmind_hub.EntryNotFoundError The file does not exist. -## openmind_hub.utils.RepositoryNotFoundError +## openmind_hub.RepositoryNotFoundError The repository does not exist. -## openmind_hub.utils.RevisionNotFoundError +## openmind_hub.RevisionNotFoundError The branch or committed version does not exist. -## openmind_hub.utils.GatedRepoError +## openmind_hub.GatedRepoError Access to the repository is restricted. -## openmind_hub.utils.LocalEntryNotFoundError +## openmind_hub.LocalEntryNotFoundError The local file does not exist. -## openmind_hub.utils.OmHubHTTPError +## openmind_hub.OmHubHTTPError -Parent class of all HTTP exceptions in the openMind Hub Client. +Parent class of all HTTP exceptions in openMind Hub Client. diff --git a/docs/en/api_reference/om_file_system.md b/docs/en/api_reference/om_file_system.md index 88c8e85..69955d1 100644 --- a/docs/en/api_reference/om_file_system.md +++ b/docs/en/api_reference/om_file_system.md @@ -20,7 +20,7 @@ Parameter description: | Name | Description | Type | Default Value | |-----------------|-------------|-----|-------------| -| endpoint | Destination address | str | None, pointing to the default domain name| +| endpoint | Destination address | str | None| | token | Access token | str | None | | storage_options | Variable that passes storage options| None | None | @@ -34,11 +34,6 @@ fs = OmFileSystem() **Class-related methods:** -> Many class methods use the `path` parameter, whose structure is `{repo_type}s/owner/repo@revision/path/in/repo`. `owner/repo` must specify a repository, and other arguments are optional. By default, `repo_type` is a model, `revision` is the main branch, and `path/in/repo` is the root path of a repository. -> - Example 1: `path="PyTorch-NPU/t5_small"` indicates the root path of the PyTorch-NPU/t5_small model. -> - Example 2: `path="modles/PyTorch-NPU/t5_small/README.md`indicates the **README.md** file of the PyTorch-NPU/t5_small model. -> - Example 3: `path="datasets/AI_Connect/glue@other/ax/test-00000-of-00001.parquet"` indicates the **ax/test-00000-of-00001.parquet** file of the "other" branch of the AI_Connect/glue dataset. - - **resolve_path()**: resolved path. ```python @@ -49,7 +44,7 @@ fs = OmFileSystem() | Name | Description | Type | Default Value | |----------|-----------|-----|----------------| - | path | Repository or path in a repository| str | None | + | path | Repository path| str | None | | revision | Branch | str | None (main)| Example: @@ -58,22 +53,22 @@ fs = OmFileSystem() from openmind_hub import OmFileSystem fs = OmFileSystem() - path = "models/PyTorch-NPU/t5_small/README.md" - resolve_path = fs.resolve_path(path) - # resolve_path: OmFileSystemResolvedPath(repo_type='model', repo_id='PyTorch-NPU/t5_small', revision='main', path_in_repo='README.md') + path = "models/PyTorch-NPU/t5_small" + resolve_path = fs.resolve_path(path=path) + # resolve_path: OmFileSystemResolvedPath(repo_type='model', repo_id='PyTorch-NPU/t5_small', revision='main', path_in_repo='') ``` -- **invalidate_cache()**: clears file system caches. **ls ()** can be called to obtain the file information in a repository, and the information is stored in caches. When **ls ()** or **info ()** is called again to obtain the queried file information, the information is directly read from caches. Therefore, this method may be used when a file is changed during the life cycle of an OmFileSystem instance. +- **invalidate_cache()**: clears file system caches. ```python - def invalidate_cache(self, path: Optional[str] = None) -> None + def invalidate_cache(self, path: Optional[str] = None) -> None: ``` Parameter description: | Name | Description | Type | Default Value| |------|-----------|-----|-----| - | path | Repository or path in a repository| str | None | + | path | Repository path| str | None | Example: @@ -82,7 +77,7 @@ fs = OmFileSystem() fs = OmFileSystem() path = "models/PyTorch-NPU/t5_small" - fs.invalidate_cache(path) + fs.invalidate_cache(path=path) ``` - **rm()**: deletes a file from a repository. @@ -114,12 +109,8 @@ fs = OmFileSystem() from openmind_hub import OmFileSystem fs = OmFileSystem(token="xxx") - # Delete a file in a repository. - path = "models/owner/repo/file_to_delete" - fs.rm(path) - # Recursively deletes all files in a directory in a repository (that is, deletes a directory). - path = "models/owner/repo/folder/*" - fs.rm(path) + path = "my-username/my-model/pytorch_model.bin" + fs.rm(path=path) ``` - **ls()**: lists the names or more details of all files and directories in a specified path. @@ -166,7 +157,7 @@ fs = OmFileSystem() | Name | Description | Type | Default Value| |--------|----------------|------|-----| - | path | Repository or path in a repository | str | None | + | path | Repository path | str | None | | kwargs | Branch information contained in **revision**| dict | None | Example: @@ -175,9 +166,9 @@ fs = OmFileSystem() from openmind_hub import OmFileSystem fs = OmFileSystem() - path = "models/PyTorch-NPU/t5_small/**/*.md" - files = fs.glob(path) - # Obtain all MD files in the repository: ['models/PyTorch-NPU/t5_small/README.md'] + path = "models/PyTorch-NPU/t5_small/" + glob_out = fs.glob(path=path) + # glob_out: ['models/PyTorch-NPU/t5_small'] ``` - **find()**: searches for files recursively in a specified directory and returns related information. @@ -187,7 +178,6 @@ fs = OmFileSystem() self, path: str, maxdepth: Optional[int] = None, - detail: bool = False, withdirs: bool = False, refresh: bool = False, revision: Optional[str] = None, @@ -200,8 +190,7 @@ fs = OmFileSystem() | Name | Description | Type | Default Value | |----------|----------------------------------|------|-------| | path | Path of the file to be listed | str | None | - | maxdepth | Number of recursion layers. If the value is 0 or None, all directories are recursively searched. If the value is 1, only the current directory is searched.| int | None | - | detail | Whether to list file details | bool | False | + | maxdepth | Maximum depth | int | None | | withdirs | Whether to contain folders | bool | False | | refresh | Whether to forcibly refresh or re-obtain path content | bool | False | | revision | Branch | str | None | @@ -214,7 +203,7 @@ fs = OmFileSystem() fs = OmFileSystem() path = "models/PyTorch-NPU/t5_small/examples" - out = fs.find(path) + out = fs.find(path=path) # out: {'models/PyTorch-NPU/t5_small/examples/inference.py': {'name': 'models/PyTorch-NPU/t5_small/examples/inference.py', 'size': 1339, 'type': 'file', 'blob_id': '5afee089d8a4222a90881ec09e914406dc51085e', 'lfs': None, 'last_commit': LastCommitInfo(oid='e46308f04bef49c9bde77abb6f685d7ea089ffb1', title='update examples\n', date=datetime.datetime(2024, 7, 26, 11, 42, 50))}, 'models/PyTorch-NPU/t5_small/examples/requirements.txt': {'name': 'models/PyTorch-NPU/t5_small/examples/requirements.txt', 'size': 58, 'type': 'file', 'blob_id': '26c7f4164062d89a177cd386cc297e8802e1e6dc', 'lfs': None, 'last_commit': LastCommitInfo(oid='e46308f04bef49c9bde77abb6f685d7ea089ffb1', title='update examples\n', date=datetime.datetime(2024, 7, 26, 11, 42, 50))}} ``` @@ -228,7 +217,7 @@ fs = OmFileSystem() | Name | Description | Type | Default Value| |--------|---------------|-----|-----| - | path | Repository or path in a repository | str | None | + | path | Repository path | str | None | | kwargs | For compatibility only| None | None | Example: @@ -238,7 +227,7 @@ fs = OmFileSystem() fs = OmFileSystem() path = "models/PyTorch-NPU/t5_small" - out = fs.modified(path) + out = fs.modified(path=path) # out: 2024-07-26 11:42:50 ``` @@ -259,7 +248,7 @@ fs = OmFileSystem() | Name | Description | Type | Default Value | |----------|----------------------------------|------|-------| | path | Path of the file to be listed | str | None | - | refresh | Whether to update the path information stored in the cache. If the path information exists in the cache, the path information is directly returned.| bool | False | + | refresh | Whether to update the path information stored in the cache. | bool | False | | revision | Branch | str | None | | kwargs | For compatibility only | None | None | @@ -269,8 +258,8 @@ fs = OmFileSystem() from openmind_hub import OmFileSystem fs = OmFileSystem() - path = "models/PyTorch-NPU/t5_small" - out = fs.info(path) + path = "models/PyTorch-NPU/t5_small/" + out = fs.info(path=path) # out: {'name': 'models/PyTorch-NPU/t5_small', 'size': 0, 'type': 'directory', 'last_commit': LastCommitInfo(oid='e46308f04bef49c9bde77abb6f685d7ea089ffb1', title='update examples\n', date=datetime.datetime(2024, 7, 26, 11, 42, 50))} ``` @@ -284,7 +273,7 @@ fs = OmFileSystem() | Name | Description | Type | Default Value| |--------|---------------|-----|-----| - | path | Repository or path in a repository | str | None | + | path | Repository path | str | None | | kwargs | For compatibility only| None | None | Example: @@ -293,8 +282,8 @@ fs = OmFileSystem() from openmind_hub import OmFileSystem fs = OmFileSystem() - path = "models/PyTorch-NPU/t5_small/README.md" - out = fs.exists(path) + path = "models/PyTorch-NPU/t5_small/" + out = fs.exists(path=path) # out: True ``` @@ -308,7 +297,7 @@ fs = OmFileSystem() | Name | Description | Type | Default Value| |------|-----------|-----|-----| - | path | Repository or path in a repository| str | None | + | path | Repository path | str | None | Example: @@ -317,7 +306,7 @@ fs = OmFileSystem() fs = OmFileSystem() path = "models/PyTorch-NPU/t5_small" - out = fs.isdir(path) + out = fs.isdir(path=path) # out: True ``` @@ -331,7 +320,7 @@ fs = OmFileSystem() | Name | Description | Type | Default Value| |------|-----------|-----|-----| - | path | Repository or path in a repository| str | None | + | path | Repository path | str | None | Example: @@ -340,7 +329,7 @@ fs = OmFileSystem() fs = OmFileSystem() path = "models/PyTorch-NPU/t5_small" - out = fs.isfile(path) + out = fs.isfile(path=path) # out: False ``` @@ -354,7 +343,7 @@ fs = OmFileSystem() | Name | Description | Type | Default Value| |------|-----------|-----|-----| - | path | Repository or path in a repository| str | None | + | path | Repository path | str | None | Example: diff --git a/docs/en/api_reference/upload_api.md b/docs/en/api_reference/upload_api.md index 6aebf7f..a49993d 100644 --- a/docs/en/api_reference/upload_api.md +++ b/docs/en/api_reference/upload_api.md @@ -22,7 +22,7 @@ upload_file( + **path_in_repo** (`str`): path for uploading files to the repository. + **repo_id** (`str`): target repository, in the format of *username*/*repository name*. For the username and repository name, letters, digits, dots (.), underscores (_), and hyphens (-) are allowed. + **token** (`str`, *optional*): access token that has the write permission on the target repository. This parameter is required when this method is used separately. -+ **revision** (`str`, *optional*): branch to be uploaded. Letters, digits, underscores (_), and hyphens (-) are allowed. The default value is **main**. ++ **revision** (`str`, *optional*): branch to be uploaded. Letters, digits, underscores (_), and hyphens (-) are allowed. The default value is **None**. + **commit_message** (`str`, *optional*): commit message of the upload. The default value is **Upload {path_in_repo} with openMind hub**. + **commit_description** (`str`, *optional*): description of this commit. + **kwargs**: required only for compatibility with third-party components. @@ -54,7 +54,7 @@ upload_folder( + **commit_message** (`str`, *optional*): commit message of the upload. The default message is **Upload folder using openMind hub**. + **commit_description** (`str`, *optional*): description of this commit. + **token** (`str`, *optional*): access token that has the write permission on the target repository. This parameter is required when this method is used separately. -+ **revision** (`str`, *optional*): branch to be uploaded. Letters, digits, underscores (_), and hyphens (-) are allowed. The default value is **main**. ++ **revision** (`str`, *optional*): branch to be uploaded. Letters, digits, underscores (_), and hyphens (-) are allowed. The default value is **None**. + **allow_patterns** (`List[str]` or `str`, *optional*): only certain types of files can be uploaded. For example, `allow_patterns="*.bin, *.py"` indicates that only .bin and .py files can be uploaded. + **ignore_patterns** (`List[str]` or `str`, *optional*): Ignore the upload of a certain type of files. For example, `ignore_patterns="*.log"` indicates that all log files are ignored. + **num_threads** (`int`, *optional*): number of threads used for uploading. The default value is **5**. @@ -88,6 +88,6 @@ create_commit( + **commit_message** (`str`): commit message of the upload. + **commit_description** (`str`, *optional*): description of this commit. + **token** (`str`, *optional*): access token that has the write permission on the target repository. This parameter is required when this method is used separately. -+ **revision** (`str`, *optional*): branch to be uploaded. Letters, digits, underscores (_), and hyphens (-) are allowed. The default value is **main**. ++ **revision** (`str`, *optional*): branch to be uploaded. Letters, digits, underscores (_), and hyphens (-) are allowed. The default value is **None**. + **num_threads** (`int`, *optional*): number of threads used for uploading. The default value is **5**. + **kwargs**: required only for compatibility with third-party components. diff --git a/docs/en/basic_tutorial/third-party_platform.md b/docs/en/basic_tutorial/third-party_platform.md index 6204a46..71cd70b 100644 --- a/docs/en/basic_tutorial/third-party_platform.md +++ b/docs/en/basic_tutorial/third-party_platform.md @@ -1,25 +1,23 @@ # Interconnection with Third-party Communities -The openMind Hub Client can connect to multiple communities so that you can upload and download files in different communities. Currently, the following communities are interconnected: +openMind Hub Client can connect to multiple communities so that you can upload and download files in different communities. Currently, the following communities are interconnected: -+ [openMind community](https://telecom.openmind.cn): By default, this community is connected. All open interfaces are supported. ++ [Modelers community](https://modelers.cn): This community is connected by default. All open interfaces are supported. + [Openl community](https://openi.pcl.ac.cn): Only some interfaces are supported, covering repository creation and file upload and download. ## Example -The following uses the Openl community as an example to describe how to connect a third-party community. - ### Installation ```shell pip install openmind_hub[openi] ``` -For details, see [*Installation Guide*](../install.md). +For details, see [Installation Guide](../install.md). ### Specifying a Community -You can specify a community in any of the following ways: +You can specify a community using any of the following ways: + Using `set_platform()`: @@ -42,30 +40,30 @@ You can specify a community in any of the following ways: ```python import os - # Environment variables must be set before **openmind_hub** is imported. + # Environment variables must be set before openmind_hub is imported. os.environ["platform"] = "openi" from openmind_hub import * om_hub_download(repo_id="FoundationModel/ChatGLM2-6B", filename="config.json", local_dir=".") ``` -Use case: +Use the three methods together: ```python from openmind_hub import set_platform, create_repo, upload_folder, snapshot_download token = "token_in_openi" -# Download the **openmind/baichuan2_7b_chat_ms** model in the openMind community to the **./baichuan2_7b_chat_ms** directory. -snapshot_download(repo_id="openmind/baichuan2_7b_chat_ms", local_dir="./baichuan2_7b_chat_ms") -# Download the **FoundationModel/ChatGLM2-6B** model in the Openl community to the **./ChatGLM2-6B** directory. +# Download the PyTorch-NPU/t5_small model in the Modelers community to the ./t5_small directory. +snapshot_download(repo_id="PyTorch-NPU/t5_small", local_dir="./t5_small") +# Download the FoundationModel/ChatGLM2-6B model in the specified community to the ./ChatGLM2-6B directory. # snapshot_download(repo_id="FoundationModel/ChatGLM2-6B", local_dir="./ChatGLM2-6B", platform="openi") -# Set the default community to Openl community. +# Set the default community. set_platform("openi") -# Create an **owner/cool-model** project and a **cool-model** in the Openl community. (Use the actual user name and repository name.) +# Create owner/cool-model and cool-model in the specified community. (Use the actual user name and repository name.) create_repo(repo_id="owner/cool-model", token=token) -# Upload files to the **cool-model** of the **owner/cool-model** project. +# Upload files to cool-model under owner/cool-model. upload_folder(repo_id="owner/cool-model", folder_path="./baichuan2_7b_chat_ms", token=token) ``` diff --git a/docs/en/basic_tutorial/upload.md b/docs/en/basic_tutorial/upload.md index 5950caa..c3d45e3 100644 --- a/docs/en/basic_tutorial/upload.md +++ b/docs/en/basic_tutorial/upload.md @@ -1,14 +1,14 @@ # Uploading Files -[Access tokens](../quick_start.md# access token) are required to upload files to a repository. +[Access tokens](../quick_start.md#access-token) are required to upload files to a repository. -The openMind Hub Client controls file upload paths through blocklist and trustlist. The absolute path of a file cannot start with a path in the blocklist (except the default cache path ~/.cache/openmind) and must be in the trustlist. The blocklist includes `["/etc", "/var", "/bin", "/boot", "/lib", "~/."]`, and the trustlist is defaulted as `["/tmp,"~/"]` in Linux and `["~/", "D:", "E:", "F:"]` in Windows. You can also configure the environment variable `HUB_WHITE_LIST_PATHS` (separate each path by commas) to configure the trustlist. In addition, the priority of the blocklist permission is higher than that of the trustlist permission. +openMind Hub Client controls file upload paths through blocklist and trustlist. The absolute path of a file cannot start with a path in the blocklist (except the default cache path `~/.cache/openmind`) and must be in the trustlist. The blocklist includes `["/etc", "/var", "/bin", "/boot", "/lib", "~/."]`, and the trustlist is defaulted as `["/tmp,"~/"]` in Linux and `["~/", "D:", "E:", "F:"]` in Windows. You can also configure the environment variable `HUB_WHITE_LIST_PATHS` (separate each path by commas) to configure the trustlist. In addition, the priority of the blocklist permission is higher than that of the trustlist permission. **Note**: Due to the diversity of model files, you can upload files in any format to the server theoretically. The model size could range from several MB to hundreds of GB. Therefore, openMind Hub Client does not restrict the type and size of files to be uploaded. But you need to pay attention to the sensitivity of files, to prevent sensitive information from being uploaded to the server. ## Uploading a Folder -[upload_folder](../api_reference/upload_api.md#upload_folder) can be used to upload folders to a repository. The following is an example. Obtain the detailed parameters from the API document. +[upload_folder](../api_reference/upload_api.md#upload_folder) can be used to upload folders to a repository. The following is an example. You can oObtain the detailed parameters from the API document. ```py from openmind_hub import upload_folder @@ -24,8 +24,7 @@ upload_folder( + `folder_path` (required): path of the local folder to be uploaded. + `repo_id` (required): target repository. -If you want to filter the types of files to be uploaded, use `allow_patterns` and `ignore_patterns`. -For details, see [upload_folder](../api_reference/upload_api.md#upload_folder). +If you want to filter the types of files to be uploaded, use `allow_patterns` and `ignore_patterns`. For details, see [upload_folder](../api_reference/upload_api.md#upload_folder). ## Uploading Files Using Git @@ -56,3 +55,10 @@ This part does not describe how to use [Git](https://git-scm.com/) to manage rep git commit -m 'commit message' git push ``` + +When you clone a private repository or submit a push request, the following account and password verification procedure is displayed in the command line. In this case, you need to [create an access token](https://modelers.cn/my/tokens). **password** specifies the access token. If the repository involves **lfs** files, multiple verification is required. + +```shell +Username for 'https://modelers.cn': username +Password for 'https://username@modelers.cn': Access token +``` diff --git a/docs/en/developer_tutorial/figures/certificate download 1.png b/docs/en/developer_tutorial/figures/certificate download 1.png deleted file mode 100644 index 28f7d94357e2e3a41c051bb27cddeec676142dee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8571 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 diff --git a/docs/en/developer_tutorial/figures/certificate download 2.png b/docs/en/developer_tutorial/figures/certificate download 2.png deleted file mode 100644 index a608a2ec18f14c063394e0f1be5c95508a9a0fdf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11139 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 diff --git a/docs/en/developer_tutorial/figures/certificate download 3.png b/docs/en/developer_tutorial/figures/certificate download 3.png deleted file mode 100644 index 849e39819853f204bb28c85d5d78b32046007937..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16283 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 diff --git a/docs/en/developer_tutorial/figures/certificate_download_1.png b/docs/en/developer_tutorial/figures/certificate_download_1.png index 28f7d94357e2e3a41c051bb27cddeec676142dee..854cff7de291d3eb00962e5bec6114d60b8ba810 100644 GIT binary patch literal 14733 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 literal 8571 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 diff --git a/docs/en/developer_tutorial/figures/certificate_download_2.png b/docs/en/developer_tutorial/figures/certificate_download_2.png index a608a2ec18f14c063394e0f1be5c95508a9a0fdf..d71bd54c9983345d258d32f6c9e03b445c6e9881 100644 GIT binary patch literal 15225 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 q(9jCKYfyY6gW)A{m8(@gC56G_;C~1sr70A literal 11139 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 diff --git a/docs/en/developer_tutorial/trouble_shooting.md b/docs/en/developer_tutorial/trouble_shooting.md index e6c05df..1114d4a 100644 --- a/docs/en/developer_tutorial/trouble_shooting.md +++ b/docs/en/developer_tutorial/trouble_shooting.md @@ -1,10 +1,10 @@ # Troubleshooting -When using openMind Hub Client, you may encounter some problems. This document collects some common problems and their solutions. We will continue to update this document to help you troubleshoot faults. +When using openMind Hub Client, you may encounter some issues. This document collects some common issues and their solutions. We will continue to update this document to help you troubleshoot faults. ## Certificate Verification Failure: CERTIFICATE_VERIFY_FAILED -There are multiple causes for certificate verification failures. The following lists the solutions to different errors. +There are multiple causes for certificate verification failures. The following lists the solutions to different issues. Solution 1: If the Python root CA certificate does not match the requests library version, use either of the following methods to locate the fault. @@ -46,11 +46,11 @@ Solution 2: Manually configure the certificate of the Modelers community. SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate (_ssl.c:1131)') ``` -1. Download the certificate from Modelers Community. The following describes the procedure for downloading the certificate using Google Chrome. The procedure for downloading the certificate using other browsers is similar. In Windows, double-click the certificate to install it. In Linux, refer to the following procedure. +1. Download the certificate from the Modelers community. The following describes the procedure for downloading the certificate using Google Chrome. The procedure for downloading the certificate using other browsers is similar. In Windows, double-click the certificate to install it. In Linux, refer to the following procedure. - ![img.png](figures/certificate download 1.png) ![img_1.png](figures/certificate download 2.png) + ![img.png](figures/certificate_download_1.png) ![img_1.png](figures/certificate_download_2.png) - ![img_2.png](figures/certificate download 3.png) + ![img_2.png](figures/certificate_download_3.png) 2. Move the downloaded certificate to the `/usr/local/share/ca-certificates/` directory. 3. Run `update-ca-certificates`. diff --git a/docs/en/install.md b/docs/en/install.md index e28abba..1ced7d7 100644 --- a/docs/en/install.md +++ b/docs/en/install.md @@ -1,36 +1,50 @@ -# openMind Hub Client Installation +# Installing openMind Hub Client -Before the installation, you need to configure the local environment. The openMind Hub Client supports Python 3.8, 3.9, and 3.10. For details, see [Installation Description](https://docs.python.org/3/using/index.html). Compatibility with other versions is not guaranteed. +Before the installation, you need to configure the local environment. openMind Hub Client supports Python 3.8, 3.9, and 3.10. For details, see [Installation Description](https://docs.python.org/3/using/index.html). Compatibility with other versions is not guaranteed. ## Installation Guide -To avoid compatibility issues between dependencies in different projects, Python and conda virtual environments are recommended. For details about how to install and manage the virtual environments, see [Python virtual environment](https://docs.python.org/3/library/venv.html) and [conda virtual environment](https://conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html). This document only describes how to create and enable the virtual environments. +To avoid compatibility issues between dependencies in different projects, Python and conda virtual environments are recommended. For details about how to install and manage the virtual environments, see [Python virtual environment](https://docs.python.org/3/library/venv.html) and [conda virtual environment](https://conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html). This section only describes how to create and enable the virtual environments. 1. Create and activate virtual environments. - - Create and activate the Python virtual environment. + - Create and activate a Python virtual environment. ```shell - # Create a Python virtual environment named **your_venv_name**. + # Create a Python virtual environment named your_venv_name. python3 -m venv /path/to/your_venv_name - # Activate the **your_venv_name** virtual environment. + # Activate the your_venv_name virtual environment. source /path/to/your_venv_name/bin/activate ``` - - Create and activate the conda virtual environment. + - Create and activate a conda virtual environment. ```shell - # Create a Python 3.8 virtual environment named **your_venv_name**. + # Create a Python 3.8 virtual environment named your_venv_name. conda create -n your_venv_name python=3.8 - # Activate the **your_venv_name** virtual environment. + # Activate the your_venv_name virtual environment. conda activate your_venv_name ``` -2. Install openMind Hub Client from the .whl package. +2. Install openMind Hub Client in pip mode as required. - ```shell - pip install openmind_hub-x.x-py3-none-any.whl - ``` + - Use the default installation mode, which can interact with the Modelers community. + + ```shell + pip install openmind_hub + ``` + + - Install modules of all adapted third-party communities for interactions. For details, see [Interconnection with Third-Party Communities](./basic_tutorial/third-party_platform.md). + + ```shell + pip install openmind_hub-x.x-py3-none-any.whl[all] + ``` + + - Install a specified module that can interact with Modelers or a specified community. + + ```shell + pip install openmind_hub-x.x-py3-none-any.whl[openi] + ``` ## Verifying the Installation @@ -42,19 +56,19 @@ python -c "from openmind_hub import repo_info; print(repo_info('openmind/baichua The detailed information about the baichuan2_13b_base_pt model will be displayed in the command output. -## Uninstallation Guide +## Uninstalling openMind Hub Client -Uninstall openMind Hub Client: +Run the following command to uninstall openMind Hub Client: ```shell pip uninstall openmind_hub ``` -**Tips** +**Notes** -You can run the following commands to record logs about the installation and uninstallation of openMind Hub Client. **LOG_FILE** indicates the log path or log file name specified by the user. +You can run the following commands to record logs about the installation and uninstallation of openMind Hub Client. **LOG_FILE** indicates the user-defined log path or log file name. -[Note] Installation or uninstallation logs are not dumped. Pay attention to the remaining drive space before recording the logs. +Note that installation or uninstallation logs are not dumped. Pay attention to the remaining drive space before recording the logs. ```shell # Record logs during openMind Hub Client installation. diff --git a/docs/en/overview.md b/docs/en/overview.md index 0c1504c..ec4f767 100644 --- a/docs/en/overview.md +++ b/docs/en/overview.md @@ -1,5 +1,3 @@ # Overview -[openMind](https://telecom.openmind.cn) is a Git-based platform for storing models, covering various fields such as audio, vision, natural language processing, and multimodal. You can search for, use, and contribute to the most advanced models. - -The openMind Hub Client helps you interact with models without leaving the development environment. For details, see [Quick Start](./quick_start.md). +openMind Hub Client allows you to interact with the Modelers community without leaving the development environment, such as uploading and downloading files. Click [here](./quick_start.md) to view more details. diff --git a/docs/en/quick_start.md b/docs/en/quick_start.md index 799ad62..8459649 100644 --- a/docs/en/quick_start.md +++ b/docs/en/quick_start.md @@ -2,17 +2,17 @@ ## Installation -Install openMind Hub Client from the .whl package. +Install openMind Hub Client using pip. ```shell pip install openmind_hub-0.6-py3-none-any.whl ``` -For details, see [*openMind Hub Client Installation*](install.md). +For details, see [openMind Hub Client Installation](install.md). ## Downloading Files -For example, to download the [t5_small](https://telecom.openmind.cn/models/PyTorch-NPU/t5_small/) configuration file, run the following commands: +For example, to download the [t5_small](https://modelers.cn/models/PyTorch-NPU/t5_small/) configuration file, run the following commands: ```py from openmind_hub import om_hub_download @@ -24,7 +24,7 @@ For details, see [Downloading Files](basic_tutorial/download.md). ## Access Token -Access tokens are required when you interact with openMind Models, such as accessing private repository resources, creating repositories, and uploading files. Register or log in to [openMind](https://telecom.openmind.cn/my/tokens) to create an access token and keep it secure. The token is displayed only when it is created. +Access tokens are required when you interact with the community, such as accessing private repository resources, creating repositories, and uploading files. [Create an access token](https://modelers.cn/my/tokens) and keep it secure. The token is displayed only when it is created. ## Uploading Files @@ -42,13 +42,13 @@ upload_folder( + `token` (required): access token that has the write permission on the target repository. + `repo_id` (required): repository to which files are uploaded. -+ `folder_path` (required): path of the directory to be uploaded. The content to be uploaded does not contain the directory itself. Character string or the Path type is supported, for example, `"./folder"` or `Path("./folder")`. ++ `folder_path` (required): path of the folder to be uploaded. The content to be uploaded does not contain the folder itself. Character string or the Path type is supported, for example, `"./folder"` or `Path("./folder")`. For details, see [Uploading Files](./basic_tutorial/upload.md). ## Advanced Use -The openMind Hub Client provides you with a simple way to interact with the openMind model repositories using Python. To learn more about how to manage files and model repositories on openMind, refer to the following: +openMind Hub Client provides you with a simple way to interact with the community using Python. To learn more about how to manage files and repositories in the community, refer to the following documents: + [Download](./basic_tutorial/download.md) files from a repository. + [Upload](./basic_tutorial/upload.md) files to a repository. diff --git a/docs/en/release_note.md b/docs/en/release_note.md index 15a6c56..9b35d7f 100644 --- a/docs/en/release_note.md +++ b/docs/en/release_note.md @@ -1,20 +1,30 @@ -# Change History +# Release Notes -Description of openMind Hub Client V0.7.1 +## Description of openMind Hub Client V0.7.1 -## New Features +## Version Updates -### Interconnection with Third-party Communities +### Update -The openMind Hub Client connects to the Openl community and allows users to upload and download model files in the Openl community. +Changed the default domain name of the Modelers community to . -## Previous Features +### Resolved Issue + +Resolved the issue that `requests.exceptions.ChunkedEncodingError` occasionally occurs during download. + +## Description of openMind Hub Client V0.7.0 + +### New Features + +- openMind Hub Client supports interconnection with multiple communities and provides unified standard APIs. Currently, the function of uploading and downloading model files is verified based on third-party communities. + +### Previous Features ### Repository Management -Users can manage repositories on the openMind platform, including creating and deleting repositories of various types, creating and deleting branches, and searching for and filtering repositories. +You can manage repositories on the openMind platform, including creating and deleting repositories of various types, creating and deleting branches, and searching for and filtering repositories. -+ Universal APIs +- Universal APIs | API/Class | Description | |----------------|------------------------| @@ -25,62 +35,62 @@ Users can manage repositories on the openMind platform, including creating and d | create_branch | Creates a branch. | | delete_branch | Deletes a branch. | | OmFileSystem | Accesses files in a remote repository as if they were local. | - | Repository | Encapsulates a series of Git commands and uses them to manage repositories. | + | Repository | Encapsulates a series of Git commands and uses them to manage repositories.| -+ Model-related APIs +- Model-related APIs | API/Class | Description | |-----------------------|---------------| | model_info | Obtains information about a model. | | list_models | Searches for a model. | - | ModelFilter | Encapsulates filter criteria available for model search. | + | ModelFilter | Encapsulates filter criteria available for model search.| -+ Dataset-related APIs +- Dataset-related APIs | API/Class | Description | |-----------------|-----------| | dataset_info | Obtains information about a dataset. | | list_datasets | Searches for a dataset. | | DatasetInfo | Encapsulates dataset information. | - | DatasetCard | Encapsulates dataset card information. | - | DatasetCardData | Encapsulates dataset card information. | + | DatasetCard | Encapsulates dataset card information.| + | DatasetCardData | Encapsulates dataset card information.| -+ Space-related APIs +- Space-related APIs | API | Description | |---------------|-----------| | space_info | Obtains information about a space. | | list_spaces | Searches for a space. | - | restart_space | Restarts a space app. | + | restart_space | Restarts a space app.| -### File Uploading and Downloading +### File Upload and Download -Users can upload and download files on the openMind platform. +You can upload and download files on the openMind platform. -+ Upload APIs +- Upload APIs | API/Class | Description | |-----------------------|-------------| | upload_file | Uploads a file. | - | upload_folder | Uploads files in a directory. | + | upload_folder | Uploads files in a folder. | | create_commit | Uploads or deletes a file. | - | CommitOperationAdd | Encapsulates information about the file to be uploaded. | - | CommitOperationDelete | Encapsulates information about the file to be deleted. | + | CommitOperationAdd | Encapsulates information about the file to be uploaded.| + | CommitOperationDelete | Encapsulates information about the file to be deleted.| -+ Download APIs +- Download APIs | API | Description | |------------------------|-------------| | om_hub_download | Downloads a single file. | | snapshot_download | Downloads files from a repository. | | get_om_file_metadata | Obtains file information. | - | om_hub_url | URL for downloading the concatenated file. | + | om_hub_url | Concatenates the file download URL. | | http_get | Bottom-layer API for downloading a file. | - | try_to_load_from_cache | Searches for the path of a file in the cache. | + | try_to_load_from_cache | Searches for the path of a file in the cache.| ### Interconnection Between openMind Toolchain and openMind Platform -Provides public APIs, classes, and constants to enable the openMind toolchain or other user software to connect to the openMind platform. In addition to the preceding repository management API and upload/download APIs, other APIs such as public errors and constants are also included. +Provides public APIs, classes, and constants to enable the openMind toolchain or other user software to connect to the openMind platform. In addition to the preceding repository management APIs and upload/download APIs, other APIs such as public errors and constants are also provided. | API/Class/Constant | Description | |-------------------------|-----------------| @@ -93,15 +103,15 @@ Provides public APIs, classes, and constants to enable the openMind toolchain or | whoami | Obtains user information. | | get_full_repo_name | Obtains the complete repository name. | | metadata_update | Updates a repository card. | - | om_raise_for_status | Throws an exception based on the status code of the response body. | + | om_raise_for_status | Throws an exception based on the status code of the response body.| | build_om_headers | Constructs a request header. | - | OMValidationError | Verification failed. | - | EntryNotFoundError | The file does not exist. | - | RepositoryNotFoundError | The repository does not exist. | - | RevisionNotFoundError | The branch does not exist. | - | GatedRepoError | Access to the repository is restricted. | + | OMValidationError | Verification error. | + | EntryNotFoundError | File not exist. | + | RepositoryNotFoundError | Repository not exist. | + | RevisionNotFoundError | Branch not exist. | + | GatedRepoError | Restricted access to a repository. | | OmHubHTTPError | Network request error. | - | LocalEntryNotFoundError | The local file does not exist. | + | LocalEntryNotFoundError | Local file not exist. | ### Document Development @@ -109,6 +119,6 @@ Includes quick start, basic tutorials, developer tutorials, and API reference. Y ## Resolved Issues -1. Resolved the issue that the resumable download function of `snapshot_download` is unavailable. -2. Resolved the issue that `local_files_only` of `snapshot_download` is abnormal. -3. Resolved the issue that a repository can be downloaded even if `repo_id` and `repo_type` are different from the actual repository name and type. +- Resolved the issue that the resumable download function of `snapshot_download` is unavailable. +- Resolved the issue that `local_files_only` of `snapshot_download` is abnormal. +- Resolved the issue that a repository can be downloaded even if `repo_id` and `repo_type` are different from the actual repository name and type. -- Gitee