feat(cli): add 'list' subcommand to display supported models with optional JSON output
This commit is contained in:
+57
@@ -254,6 +254,63 @@ aha delete --model qwen3vl-2b
|
|||||||
- Shows "Model not found" message if the model directory doesn't exist
|
- Shows "Model not found" message if the model directory doesn't exist
|
||||||
- Shows "Model deleted successfully" message after completion
|
- Shows "Model deleted successfully" message after completion
|
||||||
|
|
||||||
|
### list - List all supported models
|
||||||
|
|
||||||
|
List all supported models with their ModelScope IDs.
|
||||||
|
|
||||||
|
**Syntax:**
|
||||||
|
```bash
|
||||||
|
aha list [OPTIONS]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Options:**
|
||||||
|
|
||||||
|
| Option | Description | Default |
|
||||||
|
|--------|-------------|---------|
|
||||||
|
| `-j, --json` | Output in JSON format (includes name, model_id, and type fields) | false |
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# List models in table format (default)
|
||||||
|
aha list
|
||||||
|
|
||||||
|
# List models in JSON format
|
||||||
|
aha list --json
|
||||||
|
|
||||||
|
# Short form
|
||||||
|
aha list -j
|
||||||
|
```
|
||||||
|
|
||||||
|
**JSON Output Format:**
|
||||||
|
|
||||||
|
When using `--json`, the output includes:
|
||||||
|
- `name`: Model identifier used with `-m` flag
|
||||||
|
- `model_id`: Full ModelScope model ID
|
||||||
|
- `type`: Model category (`llm`, `ocr`, `asr`, or `image`)
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "qwen3vl-2b",
|
||||||
|
"model_id": "Qwen/Qwen3-VL-2B-Instruct",
|
||||||
|
"type": "llm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deepseek-ocr",
|
||||||
|
"model_id": "deepseek-ai/DeepSeek-OCR",
|
||||||
|
"type": "ocr"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Model Types:**
|
||||||
|
- `llm`: Language models (text generation, chat, etc.)
|
||||||
|
- `ocr`: Optical Character Recognition models
|
||||||
|
- `asr`: Automatic Speech Recognition models
|
||||||
|
- `image`: Image processing models
|
||||||
|
|
||||||
## Supported Models
|
## Supported Models
|
||||||
|
|
||||||
| Model ID | Model Name | Description |
|
| Model ID | Model Name | Description |
|
||||||
|
|||||||
@@ -254,6 +254,63 @@ aha delete --model qwen3vl-2b
|
|||||||
- 如果模型目录不存在,显示"模型未找到"消息
|
- 如果模型目录不存在,显示"模型未找到"消息
|
||||||
- 删除完成后显示"删除成功"消息
|
- 删除完成后显示"删除成功"消息
|
||||||
|
|
||||||
|
### list - 列出所有支持的模型
|
||||||
|
|
||||||
|
列出所有支持的模型及其 ModelScope ID。
|
||||||
|
|
||||||
|
**语法:**
|
||||||
|
```bash
|
||||||
|
aha list [OPTIONS]
|
||||||
|
```
|
||||||
|
|
||||||
|
**选项:**
|
||||||
|
|
||||||
|
| 选项 | 说明 | 默认值 |
|
||||||
|
|------|------|--------|
|
||||||
|
| `-j, --json` | 以 JSON 格式输出(包含 name、model_id 和 type 字段) | false |
|
||||||
|
|
||||||
|
**示例:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 以表格格式列出模型(默认)
|
||||||
|
aha list
|
||||||
|
|
||||||
|
# 以 JSON 格式列出模型
|
||||||
|
aha list --json
|
||||||
|
|
||||||
|
# 简写形式
|
||||||
|
aha list -j
|
||||||
|
```
|
||||||
|
|
||||||
|
**JSON 输出格式:**
|
||||||
|
|
||||||
|
使用 `--json` 时,输出包含:
|
||||||
|
- `name`:与 `-m` 参数一起使用的模型标识符
|
||||||
|
- `model_id`:完整的 ModelScope 模型 ID
|
||||||
|
- `type`:模型类别(`llm`、`ocr`、`asr` 或 `image`)
|
||||||
|
|
||||||
|
示例:
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "qwen3vl-2b",
|
||||||
|
"model_id": "Qwen/Qwen3-VL-2B-Instruct",
|
||||||
|
"type": "llm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deepseek-ocr",
|
||||||
|
"model_id": "deepseek-ai/DeepSeek-OCR",
|
||||||
|
"type": "ocr"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
**模型类型:**
|
||||||
|
- `llm`:语言模型(文本生成、对话等)
|
||||||
|
- `ocr`:光学字符识别模型
|
||||||
|
- `asr`:自动语音识别模型
|
||||||
|
- `image`:图像处理模型
|
||||||
|
|
||||||
## 支持的模型
|
## 支持的模型
|
||||||
|
|
||||||
| 模型标识 | 模型名称 | 说明 |
|
| 模型标识 | 模型名称 | 说明 |
|
||||||
|
|||||||
+45
-12
@@ -6,6 +6,8 @@ use aha::{
|
|||||||
utils::{download_model, get_default_save_dir},
|
utils::{download_model, get_default_save_dir},
|
||||||
};
|
};
|
||||||
use clap::{Args, Parser, Subcommand, ValueEnum};
|
use clap::{Args, Parser, Subcommand, ValueEnum};
|
||||||
|
use serde::Serialize;
|
||||||
|
use serde_json;
|
||||||
use rocket::{
|
use rocket::{
|
||||||
Config,
|
Config,
|
||||||
data::{ByteUnit, Limits},
|
data::{ByteUnit, Limits},
|
||||||
@@ -63,7 +65,7 @@ enum Commands {
|
|||||||
/// Run model inference directly
|
/// Run model inference directly
|
||||||
Run(RunArgs),
|
Run(RunArgs),
|
||||||
/// List all supported models
|
/// List all supported models
|
||||||
List,
|
List(ListArgs),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Common/shared arguments for server operations
|
/// Common/shared arguments for server operations
|
||||||
@@ -168,6 +170,14 @@ struct DeleteArgs {
|
|||||||
model: WhichModel,
|
model: WhichModel,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Arguments for the 'list' subcommand (list all supported models)
|
||||||
|
#[derive(Args, Debug)]
|
||||||
|
struct ListArgs {
|
||||||
|
/// Output models in JSON format (includes name, model_id, and type fields)
|
||||||
|
#[arg(short, long)]
|
||||||
|
json: bool,
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the default weight path for a given model
|
/// Get the default weight path for a given model
|
||||||
/// Returns ~/.aha/{model_id} e.g., ~/.aha/OpenBMB/VoxCPM1.5
|
/// Returns ~/.aha/{model_id} e.g., ~/.aha/OpenBMB/VoxCPM1.5
|
||||||
fn get_default_weight_path(model: WhichModel) -> String {
|
fn get_default_weight_path(model: WhichModel) -> String {
|
||||||
@@ -176,8 +186,17 @@ fn get_default_weight_path(model: WhichModel) -> String {
|
|||||||
format!("{}/{}", save_dir, model_id)
|
format!("{}/{}", save_dir, model_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Model information for JSON output
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct ModelInfo {
|
||||||
|
name: String,
|
||||||
|
model_id: String,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
model_type: String,
|
||||||
|
}
|
||||||
|
|
||||||
/// List all supported models
|
/// List all supported models
|
||||||
fn run_list() -> anyhow::Result<()> {
|
fn run_list(args: ListArgs) -> anyhow::Result<()> {
|
||||||
let models = [
|
let models = [
|
||||||
WhichModel::MiniCPM4_0_5B,
|
WhichModel::MiniCPM4_0_5B,
|
||||||
WhichModel::Qwen2_5vl3B,
|
WhichModel::Qwen2_5vl3B,
|
||||||
@@ -199,15 +218,29 @@ fn run_list() -> anyhow::Result<()> {
|
|||||||
WhichModel::FunASRNano2512,
|
WhichModel::FunASRNano2512,
|
||||||
];
|
];
|
||||||
|
|
||||||
println!("Available models:");
|
if args.json {
|
||||||
println!();
|
// JSON output
|
||||||
println!("{:<30} ModelScope ID", "Model Name");
|
let model_infos: Vec<ModelInfo> = models.iter().map(|model| {
|
||||||
println!("{}", "-".repeat(80));
|
let possible_value = model.to_possible_value().unwrap();
|
||||||
for model in models {
|
ModelInfo {
|
||||||
let possible_value = model.to_possible_value().unwrap();
|
name: possible_value.get_name().to_string(),
|
||||||
let name = possible_value.get_name();
|
model_id: model.model_id().to_string(),
|
||||||
let id = model.model_id();
|
model_type: model.model_type().to_string(),
|
||||||
println!("{:<30} {}", name, id);
|
}
|
||||||
|
}).collect();
|
||||||
|
println!("{}", serde_json::to_string_pretty(&model_infos)?);
|
||||||
|
} else {
|
||||||
|
// Table output (default)
|
||||||
|
println!("Available models:");
|
||||||
|
println!();
|
||||||
|
println!("{:<30} ModelScope ID", "Model Name");
|
||||||
|
println!("{}", "-".repeat(80));
|
||||||
|
for model in models {
|
||||||
|
let possible_value = model.to_possible_value().unwrap();
|
||||||
|
let name = possible_value.get_name();
|
||||||
|
let id = model.model_id();
|
||||||
|
println!("{:<30} {}", name, id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -517,7 +550,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
Some(Commands::Delete(args)) => run_delete(args),
|
Some(Commands::Delete(args)) => run_delete(args),
|
||||||
Some(Commands::Download(args)) => run_download(args).await,
|
Some(Commands::Download(args)) => run_download(args).await,
|
||||||
Some(Commands::Run(args)) => run_run(args),
|
Some(Commands::Run(args)) => run_run(args),
|
||||||
Some(Commands::List) => run_list(),
|
Some(Commands::List(args)) => run_list(args),
|
||||||
None => {
|
None => {
|
||||||
// Backward compatibility: when no subcommand is provided, use 'cli' behavior
|
// Backward compatibility: when no subcommand is provided, use 'cli' behavior
|
||||||
let model = cli.model.expect("Model is required (use -m or --model)");
|
let model = cli.model.expect("Model is required (use -m or --model)");
|
||||||
|
|||||||
Reference in New Issue
Block a user