Skip to content

Commit

Permalink
Feature fix (#128)
Browse files Browse the repository at this point in the history
* Update README (#120)

* Update README_cn.md

* Update README_en.md

* docs: add Japanese README file

I created Japanese translated README.

* Update README.md

update roadmap

* Optimize tag detect rule and fix space clone url bug (#123)

* Add multi sync config (#124)

* Support multisync with gitlay git server (#126)

* Support multisync with gitlay git server

* Replace the gitea string

* auto build repo and runtime frameworks relation (#127)

Co-authored-by: Haihui.Wang <wanghh2000@163.com>

---------

Co-authored-by: rader <ld_leida@hotmail.com>
Co-authored-by: Ikko Eltociear Ashimine <eltociear@gmail.com>
Co-authored-by: SeanHH86 <154984842+SeanHH86@users.noreply.github.com>
Co-authored-by: Haihui.Wang <wanghh2000@163.com>
  • Loading branch information
5 people authored Sep 26, 2024
1 parent bc83b81 commit d9fec74
Show file tree
Hide file tree
Showing 70 changed files with 2,569 additions and 1,170 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*[English](README_en.md)[简体中文](README_cn.md)*
*[English](README_en.md)[简体中文](README_cn.md)[日本語](README_ja.md)*

`CSGHub Server` is a part of the open source and reliable large model assets management platform - [CSGHub](https://github.com/OpenCSGs/CSGHub/). It focuses on management of models、datasets and other LLM assets through REST API。

Expand Down Expand Up @@ -44,7 +44,7 @@ docker-compose -f docker-compose.yml up -d
- Enable content moderation on demand, and choose any third-party content moderation service.

## Roadmap
- [ ] Support more Git Servers: Currently supports Gitea, and plans to support mainstream Git repositories in the future.
- [x] Support more Git Servers: Currently supports Gitea, and plans to support mainstream Git repositories in the future.
- [x] Git LFS: Git LFS supports large files, and supports Git command operations and online download through the Web UI.
- [x] DataSet online viewer: Data set preview, supports the Top20/TopN loading preview of LFS format data sets.
- [x] Model/Dataset AutoTag: Supports custom metadata and automatic extraction of model/dataset tags.
Expand Down
4 changes: 2 additions & 2 deletions README_cn.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*[English](README_en.md)[简体中文](README_cn.md)*
*[English](README_en.md)[简体中文](README_cn.md)[日本語](README_ja.md)*

CSGHub Server是开源、可信的大模型资产管理平台[CSGHub](https://github.com/OpenCSGs/CSGHub/)的服务端部分开源项目,提供基于REST API的模型、数据集等大模型资产管理功能。

Expand Down Expand Up @@ -43,7 +43,7 @@ docker compose -f docker-compose.yml up -d
- 按需开启内容审核,选择任意第三方内容审核服务

## 技术规划
- [ ] 支持更多Git Server: 目前内置了对gitea的支持,未来计划实现对主流Git仓库的支持
- [x] 支持更多Git Server: 目前内置了对gitea的支持,未来计划实现对主流Git仓库的支持
- [x] 支持Git LFS: Git LFS支持超大文件, 支持git命令操作和Web UI在线下载
- [x] 数据集在线预览: 数据集预览,支持LFS格式数据集的Top20/TopN加载预览
- [x] 模型和数据集自动打标签::支持自定义元数据和自动化提取模型/数据集标签
Expand Down
2 changes: 1 addition & 1 deletion README_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ docker-compose -f docker-compose.yml up -d
- Enable content moderation on demand, and choose any third-party content moderation service.

## Roadmap
- [ ] Support more Git Servers: Currently supports Gitea, and plans to support mainstream Git repositories in the future.
- [x] Support more Git Servers: Currently supports Gitea, and plans to support mainstream Git repositories in the future.
- [x] Git LFS: Git LFS supports large files, and supports Git command operations and online download through the Web UI.
- [x] DataSet online viewer: Data set preview, supports the Top20/TopN loading preview of LFS format data sets.
- [x] Model/Dataset AutoTag: Supports custom metadata and automatic extraction of model/dataset tags.
Expand Down
75 changes: 75 additions & 0 deletions README_ja.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
*[English](README_en.md)[简体中文](README_cn.md)[日本語](README_ja.md)*

`CSGHub Server`は、オープンソースで信頼性の高い大規模モデル資産管理プラットフォーム - [CSGHub](https://github.com/OpenCSGs/CSGHub/)の一部です。REST APIを通じてモデル、データセット、その他のLLM資産の管理に焦点を当てています。

## 主な機能:
- ユーザーと組織の作成と管理
- モデルとデータセットのラベルの自動タグ付け
- ユーザー、組織、モデル、データの検索
- データセットファイルのオンラインプレビュー、例えば `.parquet` ファイル
- テキストと画像のコンテンツモデレーション
- 個々のファイルのダウンロード、LFSファイルを含む
- モデルとデータセットのアクティビティデータの追跡、ダウンロード数やいいね数など

## デモ
CSGHubの機能と使用方法を迅速に理解するために、デモビデオを録画しました。このビデオを視聴することで、プログラムの主な機能と操作手順を迅速に理解できます。
- CSGHubのデモビデオは以下の通りです。また、[YouTube](https://www.youtube.com/watch?v=SFDISpqowXs)[Bilibili](https://www.bilibili.com/video/BV12T4y187bv/)でもご覧いただけます。
<video width="658" height="432" src="https://github-production-user-asset-6210df.s3.amazonaws.com/3232817/296556812-205d07f2-de9d-4a7f-b3f5-83514a71453e.mp4"></video>

強力な管理機能を体験するには、[OpenCSGウェブサイト](https://portal.opencsg.com/models)をご覧ください。

## クイックスタート
> システムリソース要件: 4c CPU/8GBメモリ
Dockerをインストールしてください。このプロジェクトはUbuntu22環境でテストされています。

docker-composeを使用してローカライズされた`CSGHub Server`サービスを迅速にデプロイできます:
```shell
# APIトークンは少なくとも128文字の長さである必要があり、csghub-serverへのHTTPリクエストにはAPIトークンをBearerトークンとして送信して認証を行う必要があります。
export STARHUB_SERVER_API_TOKEN=<API token>
mkdir -m 777 gitea minio_data
curl -L https://raw.githubusercontent.com/OpenCSGs/csghub-server/main/docker-compose.yml -o docker-compose.yml
docker-compose -f docker-compose.yml up -d
```

## 技術アーキテクチャ
<div align=center>
<img src="docs/csghub_server-arch.png" alt="csghub-server architecture" width="800px">
</div>

### 拡張性とカスタマイズ性
- Gitea、GitLabなどの異なるGitサーバーをサポート
- LFSストレージシステムの柔軟な構成をサポートし、S3プロトコルに対応したローカルまたは任意のサードパーティクラウドストレージサービスを使用できます
- 必要に応じてコンテンツモデレーションを有効にし、任意のサードパーティコンテンツモデレーションサービスを選択できます

## ロードマップ
- [x] さらに多くのGitサーバーをサポート: 現在はGiteaをサポートしており、将来的には主流のGitリポジトリをサポートする予定です。
- [x] Git LFS: Git LFSは大きなファイルをサポートし、Gitコマンド操作とWeb UIを通じたオンラインダウンロードをサポートします。
- [x] データセットのオンラインビューア: データセットのプレビュー、LFS形式のデータセットのTop20/TopNの読み込みプレビューをサポートします。
- [x] モデル/データセットの自動タグ付け: カスタムメタデータとモデル/データセットタグの自動抽出をサポートします。
- [x] S3プロトコルのサポート: S3(MinIO)ストレージプロトコルをサポートし、より高い信頼性とストレージコスト効率を提供します。
- [ ] モデルフォーマットの変換: 主流のモデルフォーマットの変換。
- [x] モデルのワンクリックデプロイ: OpenCSG llm-inferenceとの統合をサポートし、ワンクリックでモデル推論を開始します。

## ライセンス
Apache 2.0ライセンスを使用しています。詳細は`LICENSE`ファイルをご覧ください。

## 貢献
貢献したい場合は、[貢献ガイドライン](docs/en/contributing.md)に従ってください。貢献を非常に楽しみにしています!

## 謝辞
このプロジェクトは、Gin、DuckDB、minio、Giteaなどのオープンソースプロジェクトに基づいています。これらのオープンソースの貢献に心から感謝します!

### お問い合わせ
使用中に問題が発生した場合は、以下のいずれかの方法でお問い合わせください:
1. GitHubでissueを発行する
2. WeChatヘルパーのQRコードをスキャンしてWeChatグループに参加する
3. 公式Discordチャンネルに参加する: [OpenCSG Discord Channel](https://discord.gg/bXnu4C9BkR)
4. Slackワークスペースに参加する: [OpenCSG Slack Channel](https://join.slack.com/t/opencsghq/shared_invite/zt-2fmtem7hs-s_RmMeoOIoF1qzslql2q~A)
<div style="display:inline-block">
<img src="https://github.com/OpenCSGs/csghub/blob/main/docs/images/wechat-assistant-new.png" width='200'>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<img src="https://github.com/OpenCSGs/csghub/blob/main/docs/images/discord-qrcode.png" width='200'>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<img src="https://github.com/OpenCSGs/csghub/blob/main/docs/images/slack-qrcode.png" width='200'>
</div>
187 changes: 187 additions & 0 deletions api/handler/runtime_architecture.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
package handler

import (
"fmt"
"log/slog"
"strconv"

"github.com/gin-gonic/gin"
"opencsg.com/csghub-server/api/httpbase"
"opencsg.com/csghub-server/common/config"
"opencsg.com/csghub-server/common/types"
"opencsg.com/csghub-server/component"
)

func NewRuntimeArchitectureHandler(config *config.Config) (*RuntimeArchitectureHandler, error) {
nrc, err := component.NewRepoComponent(config)
if err != nil {
return nil, fmt.Errorf("fail to create repo component, %w", err)
}
nrac, err := component.NewRuntimeArchitectureComponent(config)
if err != nil {
return nil, fmt.Errorf("fail to create runtime arch component, %w", err)
}

return &RuntimeArchitectureHandler{
rc: nrc,
rac: nrac,
}, nil
}

type RuntimeArchitectureHandler struct {
rc *component.RepoComponent
rac *component.RuntimeArchitectureComponent
}

// GetArchitectures godoc
// @Security ApiKey
// @Summary Get runtime framework architectures
// @Description get runtime framework architectures
// @Tags RuntimeFramework
// @Accept json
// @Produce json
// @Param id path int true "runtime framework id"
// @Success 200 {object} types.Response{} "OK"
// @Failure 400 {object} types.APIBadRequest "Bad request"
// @Failure 500 {object} types.APIInternalServerError "Internal server error"
// @Router /runtime_framework/{id}/architecture [get]
func (r *RuntimeArchitectureHandler) ListByRuntimeFrameworkID(ctx *gin.Context) {
strID := ctx.Param("id")
id, err := strconv.ParseInt(strID, 10, 64)
if err != nil {
slog.Error("invalid runtime framework ID", slog.Any("error", err))
httpbase.BadRequest(ctx, "invalid runtime framework ID format")
return
}
resp, err := r.rac.ListByRuntimeFrameworkID(ctx, id)
if err != nil {
slog.Error("fail to list runtime architectures", slog.Any("error", err))
httpbase.ServerError(ctx, err)
return
}
httpbase.OK(ctx, resp)
}

// UpdateArchitectures godoc
// @Security ApiKey
// @Summary Set runtime framework architectures
// @Description set runtime framework architectures
// @Tags RuntimeFramework
// @Accept json
// @Produce json
// @Param id path int true "runtime framework id"
// @Param body body types.RuntimeArchitecture true "body"
// @Success 200 {object} types.Response{} "OK"
// @Failure 400 {object} types.APIBadRequest "Bad request"
// @Failure 500 {object} types.APIInternalServerError "Internal server error"
// @Router /runtime_framework/{id}/architecture [put]
func (r *RuntimeArchitectureHandler) UpdateArchitecture(ctx *gin.Context) {
var req types.RuntimeArchitecture
if err := ctx.ShouldBindJSON(&req); err != nil {
slog.Error("Bad request format", "error", err)
httpbase.BadRequest(ctx, err.Error())
return
}

id, err := strconv.ParseInt(ctx.Param("id"), 10, 64)
if err != nil {
slog.Error("Bad request runtime framework id format", "error", err)
httpbase.BadRequest(ctx, err.Error())
return
}

res, err := r.rac.SetArchitectures(ctx, id, req.Architectures)
if err != nil {
slog.Error("Failed to set architectures", slog.Any("error", err))
httpbase.ServerError(ctx, err)
return
}

httpbase.OK(ctx, res)
}

// DeleteArchitectures godoc
// @Security ApiKey
// @Summary Delete runtime framework architectures
// @Description Delete runtime framework architectures
// @Tags RuntimeFramework
// @Accept json
// @Produce json
// @Param id path int true "runtime framework id"
// @Param body body types.RuntimeArchitecture true "body"
// @Success 200 {object} types.Response{} "OK"
// @Failure 400 {object} types.APIBadRequest "Bad request"
// @Failure 500 {object} types.APIInternalServerError "Internal server error"
// @Router /runtime_framework/{id}/architecture [delete]
func (r *RuntimeArchitectureHandler) DeleteArchitecture(ctx *gin.Context) {
var req types.RuntimeArchitecture
if err := ctx.ShouldBindJSON(&req); err != nil {
slog.Error("Bad request format", "error", err)
httpbase.BadRequest(ctx, err.Error())
return
}

id, err := strconv.ParseInt(ctx.Param("id"), 10, 64)
if err != nil {
slog.Error("Bad request runtime framework id format", "error", err)
httpbase.BadRequest(ctx, err.Error())
return
}

list, err := r.rac.DeleteArchitectures(ctx, id, req.Architectures)
if err != nil {
slog.Error("Failed to delete architectures", slog.Any("error", err))
httpbase.ServerError(ctx, err)
return
}

httpbase.OK(ctx, list)
}

// ScanArchitecture godoc
// @Security ApiKey
// @Summary Scan runtime architecture
// @Description Scan runtime architecture
// @Tags RuntimeFramework
// @Accept json
// @Produce json
// @Param id path int true "runtime framework id"
// @Param scan_type query int false "scan_type(0:all models, 1:new models, 2:old models)" Enums(0, 1, 2)
// @Param body body types.RuntimeFrameworkModels true "body"
// @Success 200 {object} types.Response{} "OK"
// @Failure 400 {object} types.APIBadRequest "Bad request"
// @Failure 500 {object} types.APIInternalServerError "Internal server error"
// @Router /runtime_framework/{id}/scan [post]
func (r *RuntimeArchitectureHandler) ScanArchitecture(ctx *gin.Context) {
id, err := strconv.ParseInt(ctx.Param("id"), 10, 64)
if err != nil {
slog.Error("Bad request runtime framework id format", "error", err)
httpbase.BadRequest(ctx, err.Error())
return
}

scanTypeStr := ctx.Query("scan_type")
if scanTypeStr == "" {
slog.Error("Bad request scan type")
httpbase.BadRequest(ctx, "bad request scan type")
return
}
scanType, err := strconv.Atoi(scanTypeStr)
if err != nil {
slog.Error("Bad request scan format", "error", err)
httpbase.BadRequest(ctx, err.Error())
return
}

var req types.RuntimeFrameworkModels
ctx.ShouldBindJSON(&req)

err = r.rac.ScanArchitecture(ctx, id, scanType, req.Models)
if err != nil {
slog.Error("Failed to scan architecture", slog.Any("error", err))
httpbase.ServerError(ctx, err)
return
}

httpbase.OK(ctx, nil)
}
2 changes: 1 addition & 1 deletion api/middleware/git_http_param.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func GetCurrentUserFromHeader() gin.HandlerFunc {
userStore := database.NewUserStore()
return func(c *gin.Context) {
authHeader := c.Request.Header.Get("Authorization")
if authHeader != "" {
if authHeader != "" && !strings.HasPrefix(authHeader, "X-OPENCSG-Sync-Token") {
authHeader = strings.TrimPrefix(authHeader, "Basic ")
authInfo, err := base64.StdEncoding.DecodeString(authHeader)
if err != nil {
Expand Down
15 changes: 12 additions & 3 deletions api/router/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,12 @@ func NewRouter(config *config.Config, enableSwagger bool) (*gin.Engine, error) {
event := apiGroup.Group("/events")
event.POST("", eventHandler.Create)

createRuntimeFrameworkRoutes(apiGroup, needAPIKey, modelHandler)
runtimeArchHandler, err := handler.NewRuntimeArchitectureHandler(config)
if err != nil {
return nil, fmt.Errorf("error creating runtime framework architecture handler:%w", err)
}

createRuntimeFrameworkRoutes(apiGroup, needAPIKey, modelHandler, runtimeArchHandler)

syncHandler, err := handler.NewSyncHandler(config)
if err != nil {
Expand Down Expand Up @@ -640,14 +645,19 @@ func createUserRoutes(apiGroup *gin.RouterGroup, needAPIKey gin.HandlerFunc, use
apiGroup.GET("/user/:username/run/serverless", needAPIKey, userHandler.GetRunServerless)
}

func createRuntimeFrameworkRoutes(apiGroup *gin.RouterGroup, needAPIKey gin.HandlerFunc, modelHandler *handler.ModelHandler) {
func createRuntimeFrameworkRoutes(apiGroup *gin.RouterGroup, needAPIKey gin.HandlerFunc, modelHandler *handler.ModelHandler, runtimeArchHandler *handler.RuntimeArchitectureHandler) {
runtimeFramework := apiGroup.Group("/runtime_framework")
{
runtimeFramework.GET("/:id/models", modelHandler.ListByRuntimeFrameworkID)
runtimeFramework.GET("", modelHandler.ListAllRuntimeFramework)
runtimeFramework.POST("/:id", needAPIKey, modelHandler.UpdateModelRuntimeFrameworks)
runtimeFramework.DELETE("/:id", needAPIKey, modelHandler.DeleteModelRuntimeFrameworks)
runtimeFramework.GET("/models", modelHandler.ListModelsOfRuntimeFrameworks)

runtimeFramework.GET("/:id/architecture", needAPIKey, runtimeArchHandler.ListByRuntimeFrameworkID)
runtimeFramework.PUT("/:id/architecture", needAPIKey, runtimeArchHandler.UpdateArchitecture)
runtimeFramework.DELETE("/:id/architecture", needAPIKey, runtimeArchHandler.DeleteArchitecture)
runtimeFramework.POST("/:id/scan", needAPIKey, runtimeArchHandler.ScanArchitecture)
}
}

Expand Down Expand Up @@ -691,7 +701,6 @@ func createHFRoutes(r *gin.Engine, hfdsHandler *handler.HFDatasetHandler, repoCo
}
}
}

}

func createDiscussionRoutes(apiGroup *gin.RouterGroup, needAPIKey gin.HandlerFunc, discussionHandler *handler.DiscussionHandler) {
Expand Down
5 changes: 3 additions & 2 deletions builder/git/gitserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import (
"opencsg.com/csghub-server/builder/git/gitserver/gitaly"
"opencsg.com/csghub-server/builder/git/gitserver/gitea"
"opencsg.com/csghub-server/common/config"
"opencsg.com/csghub-server/common/types"
)

func NewGitServer(config *config.Config) (gitserver.GitServer, error) {
if config.GitServer.Type == "gitea" {
if config.GitServer.Type == types.GitServerTypeGitea {
gitServer, err := gitea.NewClient(config)
return gitServer, err
} else if config.GitServer.Type == "gitaly" {
} else if config.GitServer.Type == types.GitServerTypeGitaly {
gitServer, err := gitaly.NewClient(config)
return gitServer, err
}
Expand Down
5 changes: 4 additions & 1 deletion builder/git/gitserver/gitaly/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package gitaly

import (
"context"
"errors"
"fmt"
"io"
"math"
Expand Down Expand Up @@ -142,7 +143,7 @@ func (c *Client) GetSingleCommit(ctx context.Context, req gitserver.GetRepoLastC
if err != nil {
return nil, err
}
if commitResp != nil {
if commitResp != nil && commitResp.Commit != nil {
commit = types.Commit{
ID: string(commitResp.Commit.Id),
CommitterName: string(commitResp.Commit.Committer.Name),
Expand All @@ -160,6 +161,8 @@ func (c *Client) GetSingleCommit(ctx context.Context, req gitserver.GetRepoLastC
})
}

} else {
return nil, errors.New("commit not found")
}
result = types.CommitResponse{
Commit: &commit,
Expand Down
Loading

0 comments on commit d9fec74

Please sign in to comment.