Compare commits

..

10 Commits

Author SHA1 Message Date
Docker7530 5b32d919f3 1774877281 2026-03-30 21:28:03 +08:00
Docker7530 78804225bd 1774789246 2026-03-29 21:00:48 +08:00
Docker7530 d34d77c34d 1774789119 2026-03-29 20:58:42 +08:00
Docker7530 10b7d60a86 1774773887 2026-03-29 16:44:49 +08:00
Docker7530 6b9ac80177 1774767884 2026-03-29 15:04:47 +08:00
Docker7530 798019bbbf 1774707388 2026-03-28 22:16:30 +08:00
Docker7530 d17550351d 1774673562 2026-03-28 12:52:49 +08:00
Docker7530 e4a339bd77 1774597379 2026-03-27 15:43:03 +08:00
Docker7530 ab0cbad418 1774315861 2026-03-24 09:31:04 +08:00
Docker7530 7ab924d668 1774110743 2026-03-22 00:32:26 +08:00
102 changed files with 4144 additions and 2053 deletions
+1 -3
View File
@@ -22,7 +22,5 @@
"showIndentGuide": false, "showIndentGuide": false,
"spellcheck": false, "spellcheck": false,
"foldIndent": false, "foldIndent": false,
"userIgnoreFilters": [ "userIgnoreFilters": null
"attachment/"
]
} }
+1 -3
View File
@@ -1,7 +1,5 @@
{ {
"enabledCssSnippets": [ "enabledCssSnippets": [],
"myTheme"
],
"monospaceFontFamily": "JetBrainsMono Nerd Font Mono", "monospaceFontFamily": "JetBrainsMono Nerd Font Mono",
"textFontFamily": "思源黑体", "textFontFamily": "思源黑体",
"interfaceFontFamily": "JetBrainsMono Nerd Font Mono", "interfaceFontFamily": "JetBrainsMono Nerd Font Mono",
-6
View File
@@ -5,12 +5,6 @@
"ctime": 1736742940138, "ctime": 1736742940138,
"path": "work/移动杭研/业务梳理/接口收纳.md" "path": "work/移动杭研/业务梳理/接口收纳.md"
}, },
{
"type": "file",
"ctime": 1768964533760,
"path": "work/移动杭研/开发记录/7.18.0/开发笔记.md",
"title": "7.18.0 开发笔记"
},
{ {
"type": "file", "type": "file",
"ctime": 1772680366639, "ctime": 1772680366639,
-1
View File
@@ -2,7 +2,6 @@
"pinned": [ "pinned": [
"file-explorer:reveal-active-file", "file-explorer:reveal-active-file",
"file-explorer:move-file", "file-explorer:move-file",
"open-with-default-app:show",
"app:reload" "app:reload"
] ]
} }
-3
View File
@@ -1,9 +1,6 @@
[ [
"obsidian-paste-image-rename",
"update-relative-links", "update-relative-links",
"quickadd",
"calendar", "calendar",
"recent-files-obsidian",
"oz-clear-unused-images", "oz-clear-unused-images",
"obsidian-excalidraw-plugin", "obsidian-excalidraw-plugin",
"templater-obsidian", "templater-obsidian",
+1 -1
View File
@@ -1,5 +1,5 @@
{ {
"folder": "calendar/diary", "folder": "calendar/diary",
"template": "attachment/templates/日记模板", "template": "attachment/templates/日常记录-日记模板",
"autorun": false "autorun": false
} }
+7 -22
View File
@@ -1,4 +1,5 @@
{ {
"app:open-help": [],
"workspace:goto-tab-1": [], "workspace:goto-tab-1": [],
"workspace:goto-tab-2": [], "workspace:goto-tab-2": [],
"workspace:goto-tab-3": [], "workspace:goto-tab-3": [],
@@ -7,45 +8,29 @@
"workspace:goto-tab-6": [], "workspace:goto-tab-6": [],
"workspace:goto-tab-7": [], "workspace:goto-tab-7": [],
"workspace:goto-tab-8": [], "workspace:goto-tab-8": [],
"workspace:goto-last-tab": [],
"editor:set-heading-1": [ "editor:set-heading-1": [
{ {
"modifiers": [ "modifiers": ["Mod"],
"Mod"
],
"key": "1" "key": "1"
} }
], ],
"editor:set-heading-2": [ "editor:set-heading-2": [
{ {
"modifiers": [ "modifiers": ["Mod"],
"Mod"
],
"key": "2" "key": "2"
} }
], ],
"editor:set-heading-3": [ "editor:set-heading-3": [
{ {
"modifiers": [ "modifiers": ["Mod"],
"Mod"
],
"key": "3" "key": "3"
} }
], ],
"workspace:goto-last-tab": [], "templater-obsidian:create-attachment/templates/日常记录-闪念笔记.md": [
"app:open-help": [],
"app:open-settings": [],
"obsidian-memos:show-thino-editor": [
{ {
"modifiers": [], "modifiers": [],
"key": "F1" "key": "F1"
} }
], ]
"editor:toggle-comments": [],
"quickadd:runQuickAdd": [
{
"modifiers": [],
"key": "F1"
}
],
"workspace:close-window": []
} }
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"id": "obsidian-excalidraw-plugin", "id": "obsidian-excalidraw-plugin",
"name": "Excalidraw", "name": "Excalidraw",
"version": "2.21.0", "version": "2.21.2",
"minAppVersion": "1.5.7", "minAppVersion": "1.5.7",
"description": "Sketch Your Mind. An Obsidian plugin to edit and view Excalidraw drawings. Enter the world of 4D Visual PKM.", "description": "Sketch Your Mind. An Obsidian plugin to edit and view Excalidraw drawings. Enter the world of 4D Visual PKM.",
"author": "Zsolt Viczian", "author": "Zsolt Viczian",
File diff suppressed because one or more lines are too long
-10
View File
@@ -1,10 +0,0 @@
{
"imageNamePattern": "image-{{DATE:YYYYMMDDHHmmssSSS}}",
"dupNumberAtStart": false,
"dupNumberDelimiter": "-",
"dupNumberAlways": false,
"autoRename": true,
"handleAllAttachments": false,
"excludeExtensionPattern": "",
"disableRenameNotice": true
}
-942
View File
@@ -1,942 +0,0 @@
/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD */
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// package.json
var require_package = __commonJS({
"package.json"(exports, module2) {
module2.exports = {
name: "obsidian-paste-image-rename",
version: "1.6.1",
main: "main.js",
scripts: {
start: "node esbuild.config.mjs",
build: "tsc -noEmit -skipLibCheck && BUILD_ENV=production node esbuild.config.mjs && cp manifest.json build",
version: "node version-bump.mjs && git add manifest.json versions.json",
release: "npm run build && gh release create ${npm_package_version} build/*"
},
keywords: [],
author: "Reorx",
license: "MIT",
devDependencies: {
"@types/node": "^18.11.18",
"@typescript-eslint/eslint-plugin": "^5.49.0",
"@typescript-eslint/parser": "^5.49.0",
"builtin-modules": "^3.3.0",
esbuild: "0.16.17",
obsidian: "^1.1.1",
tslib: "2.5.0",
typescript: "4.9.4"
},
dependencies: {
"cash-dom": "^8.1.2"
}
};
}
});
// src/main.ts
var main_exports = {};
__export(main_exports, {
default: () => PasteImageRenamePlugin
});
module.exports = __toCommonJS(main_exports);
var import_obsidian2 = require("obsidian");
// src/batch.ts
var import_obsidian = require("obsidian");
// src/utils.ts
var DEBUG = false;
if (DEBUG)
console.log("DEBUG is enabled");
function debugLog(...args) {
if (DEBUG) {
console.log(new Date().toISOString().slice(11, 23), ...args);
}
}
function createElementTree(rootEl, opts) {
const result = {
el: rootEl.createEl(opts.tag, opts),
children: []
};
const children = opts.children || [];
for (const child of children) {
result.children.push(createElementTree(result.el, child));
}
return result;
}
var path = {
// Credit: @creationix/path.js
join(...partSegments) {
let parts = [];
for (let i = 0, l = partSegments.length; i < l; i++) {
parts = parts.concat(partSegments[i].split("/"));
}
const newParts = [];
for (let i = 0, l = parts.length; i < l; i++) {
const part = parts[i];
if (!part || part === ".")
continue;
else
newParts.push(part);
}
if (parts[0] === "")
newParts.unshift("");
return newParts.join("/");
},
// returns the last part of a path, e.g. 'foo.jpg'
basename(fullpath) {
const sp = fullpath.split("/");
return sp[sp.length - 1];
},
// return extension without dot, e.g. 'jpg'
extension(fullpath) {
const positions = [...fullpath.matchAll(new RegExp("\\.", "gi"))].map((a) => a.index);
return fullpath.slice(positions[positions.length - 1] + 1);
}
};
var filenameNotAllowedChars = /[^\p{L}0-9~`!@$&*()\-_=+{};'",<.>? ]/ug;
var sanitizer = {
filename(s) {
return s.replace(filenameNotAllowedChars, "").trim();
},
delimiter(s) {
s = this.filename(s);
if (!s)
s = "-";
return s;
}
};
function escapeRegExp(s) {
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
function lockInputMethodComposition(el) {
const state = {
lock: false
};
el.addEventListener("compositionstart", () => {
state.lock = true;
});
el.addEventListener("compositionend", () => {
state.lock = false;
});
return state;
}
// src/batch.ts
var ImageBatchRenameModal = class extends import_obsidian.Modal {
constructor(app, activeFile, renameFunc, onClose) {
super(app);
this.activeFile = activeFile;
this.renameFunc = renameFunc;
this.onCloseExtra = onClose;
this.state = {
namePattern: "",
extPattern: "",
nameReplace: "",
renameTasks: []
};
}
onOpen() {
this.containerEl.addClass("image-rename-modal");
const { contentEl, titleEl } = this;
titleEl.setText("Batch rename embeded files");
const namePatternSetting = new import_obsidian.Setting(contentEl).setName("Name pattern").setDesc("Please input the name pattern to match files (regex)").addText((text) => text.setValue(this.state.namePattern).onChange(
(value) => __async(this, null, function* () {
this.state.namePattern = value;
})
));
const npInputEl = namePatternSetting.controlEl.children[0];
npInputEl.focus();
const npInputState = lockInputMethodComposition(npInputEl);
npInputEl.addEventListener("keydown", (e) => __async(this, null, function* () {
if (e.key === "Enter" && !npInputState.lock) {
e.preventDefault();
if (!this.state.namePattern) {
errorEl.innerText = 'Error: "Name pattern" could not be empty';
errorEl.style.display = "block";
return;
}
this.matchImageNames(tbodyEl);
}
}));
const extPatternSetting = new import_obsidian.Setting(contentEl).setName("Extension pattern").setDesc("Please input the extension pattern to match files (regex)").addText((text) => text.setValue(this.state.extPattern).onChange(
(value) => __async(this, null, function* () {
this.state.extPattern = value;
})
));
const extInputEl = extPatternSetting.controlEl.children[0];
extInputEl.addEventListener("keydown", (e) => __async(this, null, function* () {
if (e.key === "Enter") {
e.preventDefault();
this.matchImageNames(tbodyEl);
}
}));
const nameReplaceSetting = new import_obsidian.Setting(contentEl).setName("Name replace").setDesc("Please input the string to replace the matched name (use $1, $2 for regex groups)").addText((text) => text.setValue(this.state.nameReplace).onChange(
(value) => __async(this, null, function* () {
this.state.nameReplace = value;
})
));
const nrInputEl = nameReplaceSetting.controlEl.children[0];
const nrInputState = lockInputMethodComposition(nrInputEl);
nrInputEl.addEventListener("keydown", (e) => __async(this, null, function* () {
if (e.key === "Enter" && !nrInputState.lock) {
e.preventDefault();
this.matchImageNames(tbodyEl);
}
}));
const matchedContainer = contentEl.createDiv({
cls: "matched-container"
});
const tableET = createElementTree(matchedContainer, {
tag: "table",
children: [
{
tag: "thead",
children: [
{
tag: "tr",
children: [
{
tag: "td",
text: "Original path"
},
{
tag: "td",
text: "Renamed Name"
}
]
}
]
},
{
tag: "tbody"
}
]
});
const tbodyEl = tableET.children[1].el;
const errorEl = contentEl.createDiv({
cls: "error",
attr: {
style: "display: none;"
}
});
new import_obsidian.Setting(contentEl).addButton((button) => {
button.setButtonText("Rename all").setClass("mod-cta").onClick(() => {
new ConfirmModal(
this.app,
"Confirm rename all",
`Are you sure? This will rename all the ${this.state.renameTasks.length} images matched the pattern.`,
() => {
this.renameAll();
this.close();
}
).open();
});
}).addButton((button) => {
button.setButtonText("Cancel").onClick(() => {
this.close();
});
});
}
onClose() {
const { contentEl } = this;
contentEl.empty();
this.onCloseExtra();
}
renameAll() {
return __async(this, null, function* () {
debugLog("renameAll", this.state);
for (const task of this.state.renameTasks) {
yield this.renameFunc(task.file, task.name);
}
});
}
matchImageNames(tbodyEl) {
const { state } = this;
const renameTasks = [];
tbodyEl.empty();
const fileCache = this.app.metadataCache.getFileCache(this.activeFile);
if (!fileCache || !fileCache.embeds)
return;
const namePatternRegex = new RegExp(state.namePattern, "g");
const extPatternRegex = new RegExp(state.extPattern);
fileCache.embeds.forEach((embed) => {
const file = this.app.metadataCache.getFirstLinkpathDest(embed.link, this.activeFile.path);
if (!file) {
console.warn("file not found", embed.link);
return;
}
if (state.extPattern) {
const m0 = extPatternRegex.exec(file.extension);
if (!m0)
return;
}
const stem = file.basename;
namePatternRegex.lastIndex = 0;
const m1 = namePatternRegex.exec(stem);
if (!m1)
return;
let renamedName = file.name;
if (state.nameReplace) {
namePatternRegex.lastIndex = 0;
renamedName = stem.replace(namePatternRegex, state.nameReplace);
renamedName = `${renamedName}.${file.extension}`;
}
renameTasks.push({
file,
name: renamedName
});
createElementTree(tbodyEl, {
tag: "tr",
children: [
{
tag: "td",
children: [
{
tag: "span",
text: file.name
},
{
tag: "div",
text: file.path,
attr: {
class: "file-path"
}
}
]
},
{
tag: "td",
children: [
{
tag: "span",
text: renamedName
},
{
tag: "div",
text: path.join(file.parent.path, renamedName),
attr: {
class: "file-path"
}
}
]
}
]
});
});
debugLog("new renameTasks", renameTasks);
state.renameTasks = renameTasks;
}
};
var ConfirmModal = class extends import_obsidian.Modal {
constructor(app, title, message, onConfirm) {
super(app);
this.title = title;
this.message = message;
this.onConfirm = onConfirm;
}
onOpen() {
const { contentEl, titleEl } = this;
titleEl.setText(this.title);
contentEl.createEl("p", {
text: this.message
});
new import_obsidian.Setting(contentEl).addButton((button) => {
button.setButtonText("Yes").setClass("mod-warning").onClick(() => {
this.onConfirm();
this.close();
});
}).addButton((button) => {
button.setButtonText("No").onClick(() => {
this.close();
});
});
}
};
// src/template.ts
var dateTmplRegex = /{{DATE:([^}]+)}}/gm;
var frontmatterTmplRegex = /{{frontmatter:([^}]+)}}/gm;
var replaceDateVar = (s, date) => {
const m = dateTmplRegex.exec(s);
if (!m)
return s;
return s.replace(m[0], date.format(m[1]));
};
var replaceFrontmatterVar = (s, frontmatter) => {
if (!frontmatter)
return s;
const m = frontmatterTmplRegex.exec(s);
if (!m)
return s;
return s.replace(m[0], frontmatter[m[1]] || "");
};
var renderTemplate = (tmpl, data, frontmatter) => {
const now = window.moment();
let text = tmpl;
let newtext;
while ((newtext = replaceDateVar(text, now)) != text) {
text = newtext;
}
while ((newtext = replaceFrontmatterVar(text, frontmatter)) != text) {
text = newtext;
}
text = text.replace(/{{imageNameKey}}/gm, data.imageNameKey).replace(/{{fileName}}/gm, data.fileName).replace(/{{dirName}}/gm, data.dirName).replace(/{{firstHeading}}/gm, data.firstHeading);
return text;
};
// src/main.ts
var DEFAULT_SETTINGS = {
imageNamePattern: "{{fileName}}",
dupNumberAtStart: false,
dupNumberDelimiter: "-",
dupNumberAlways: false,
autoRename: false,
handleAllAttachments: false,
excludeExtensionPattern: "",
disableRenameNotice: false
};
var PASTED_IMAGE_PREFIX = "Pasted image ";
var PasteImageRenamePlugin = class extends import_obsidian2.Plugin {
constructor() {
super(...arguments);
this.modals = [];
}
onload() {
return __async(this, null, function* () {
const pkg = require_package();
console.log(`Plugin loading: ${pkg.name} ${pkg.version} BUILD_ENV=${"production"}`);
yield this.loadSettings();
this.registerEvent(
this.app.vault.on("create", (file) => {
if (!(file instanceof import_obsidian2.TFile))
return;
const timeGapMs = new Date().getTime() - file.stat.ctime;
if (timeGapMs > 1e3)
return;
if (isMarkdownFile(file))
return;
if (isPastedImage(file)) {
debugLog("pasted image created", file);
this.startRenameProcess(file, this.settings.autoRename);
} else {
if (this.settings.handleAllAttachments) {
debugLog("handleAllAttachments for file", file);
if (this.testExcludeExtension(file)) {
debugLog("excluded file by ext", file);
return;
}
this.startRenameProcess(file, this.settings.autoRename);
}
}
})
);
const startBatchRenameProcess = () => {
this.openBatchRenameModal();
};
this.addCommand({
id: "batch-rename-embeded-files",
name: "Batch rename embeded files (in the current file)",
callback: startBatchRenameProcess
});
if (DEBUG) {
this.addRibbonIcon("wand-glyph", "Batch rename embeded files", startBatchRenameProcess);
}
const batchRenameAllImages = () => {
this.batchRenameAllImages();
};
this.addCommand({
id: "batch-rename-all-images",
name: "Batch rename all images instantly (in the current file)",
callback: batchRenameAllImages
});
if (DEBUG) {
this.addRibbonIcon("wand-glyph", "Batch rename all images instantly (in the current file)", batchRenameAllImages);
}
this.addSettingTab(new SettingTab(this.app, this));
});
}
startRenameProcess(file, autoRename = false) {
return __async(this, null, function* () {
const activeFile = this.getActiveFile();
if (!activeFile) {
new import_obsidian2.Notice("Error: No active file found.");
return;
}
const { stem, newName, isMeaningful } = this.generateNewName(file, activeFile);
debugLog("generated newName:", newName, isMeaningful);
if (!isMeaningful || !autoRename) {
this.openRenameModal(file, isMeaningful ? stem : "", activeFile.path);
return;
}
this.renameFile(file, newName, activeFile.path, true);
});
}
renameFile(file, inputNewName, sourcePath, replaceCurrentLine) {
return __async(this, null, function* () {
const { name: newName } = yield this.deduplicateNewName(inputNewName, file);
debugLog("deduplicated newName:", newName);
const originName = file.name;
const linkText = this.app.fileManager.generateMarkdownLink(file, sourcePath);
const newPath = path.join(file.parent.path, newName);
try {
yield this.app.fileManager.renameFile(file, newPath);
} catch (err) {
new import_obsidian2.Notice(`Failed to rename ${newName}: ${err}`);
throw err;
}
if (!replaceCurrentLine) {
return;
}
const newLinkText = this.app.fileManager.generateMarkdownLink(file, sourcePath);
debugLog("replace text", linkText, newLinkText);
const editor = this.getActiveEditor();
if (!editor) {
new import_obsidian2.Notice(`Failed to rename ${newName}: no active editor`);
return;
}
const cursor = editor.getCursor();
const line = editor.getLine(cursor.line);
const replacedLine = line.replace(linkText, newLinkText);
debugLog("current line -> replaced line", line, replacedLine);
editor.transaction({
changes: [
{
from: __spreadProps(__spreadValues({}, cursor), { ch: 0 }),
to: __spreadProps(__spreadValues({}, cursor), { ch: line.length }),
text: replacedLine
}
]
});
if (!this.settings.disableRenameNotice) {
new import_obsidian2.Notice(`Renamed ${originName} to ${newName}`);
}
});
}
openRenameModal(file, newName, sourcePath) {
const modal = new ImageRenameModal(
this.app,
file,
newName,
(confirmedName) => {
debugLog("confirmedName:", confirmedName);
this.renameFile(file, confirmedName, sourcePath, true);
},
() => {
this.modals.splice(this.modals.indexOf(modal), 1);
}
);
this.modals.push(modal);
modal.open();
debugLog("modals count", this.modals.length);
}
openBatchRenameModal() {
const activeFile = this.getActiveFile();
const modal = new ImageBatchRenameModal(
this.app,
activeFile,
(file, name) => __async(this, null, function* () {
yield this.renameFile(file, name, activeFile.path);
}),
() => {
this.modals.splice(this.modals.indexOf(modal), 1);
}
);
this.modals.push(modal);
modal.open();
}
batchRenameAllImages() {
return __async(this, null, function* () {
const activeFile = this.getActiveFile();
const fileCache = this.app.metadataCache.getFileCache(activeFile);
if (!fileCache || !fileCache.embeds)
return;
const extPatternRegex = /jpe?g|png|gif|tiff|webp/i;
for (const embed of fileCache.embeds) {
const file = this.app.metadataCache.getFirstLinkpathDest(embed.link, activeFile.path);
if (!file) {
console.warn("file not found", embed.link);
return;
}
const m0 = extPatternRegex.exec(file.extension);
if (!m0)
return;
const { newName, isMeaningful } = this.generateNewName(file, activeFile);
debugLog("generated newName:", newName, isMeaningful);
if (!isMeaningful) {
new import_obsidian2.Notice("Failed to batch rename images: the generated name is not meaningful");
break;
}
yield this.renameFile(file, newName, activeFile.path, false);
}
});
}
// returns a new name for the input file, with extension
generateNewName(file, activeFile) {
let imageNameKey = "";
let firstHeading = "";
let frontmatter;
const fileCache = this.app.metadataCache.getFileCache(activeFile);
if (fileCache) {
debugLog("frontmatter", fileCache.frontmatter);
frontmatter = fileCache.frontmatter;
imageNameKey = (frontmatter == null ? void 0 : frontmatter.imageNameKey) || "";
firstHeading = getFirstHeading(fileCache.headings);
} else {
console.warn("could not get file cache from active file", activeFile.name);
}
const stem = renderTemplate(
this.settings.imageNamePattern,
{
imageNameKey,
fileName: activeFile.basename,
dirName: activeFile.parent.name,
firstHeading
},
frontmatter
);
const meaninglessRegex = new RegExp(`[${this.settings.dupNumberDelimiter}\\s]`, "gm");
return {
stem,
newName: stem + "." + file.extension,
isMeaningful: stem.replace(meaninglessRegex, "") !== ""
};
}
// newName: foo.ext
deduplicateNewName(newName, file) {
return __async(this, null, function* () {
const dir = file.parent.path;
const listed = yield this.app.vault.adapter.list(dir);
debugLog("sibling files", listed);
const newNameExt = path.extension(newName), newNameStem = newName.slice(0, newName.length - newNameExt.length - 1), newNameStemEscaped = escapeRegExp(newNameStem), delimiter = this.settings.dupNumberDelimiter, delimiterEscaped = escapeRegExp(delimiter);
let dupNameRegex;
if (this.settings.dupNumberAtStart) {
dupNameRegex = new RegExp(
`^(?<number>\\d+)${delimiterEscaped}(?<name>${newNameStemEscaped})\\.${newNameExt}$`
);
} else {
dupNameRegex = new RegExp(
`^(?<name>${newNameStemEscaped})${delimiterEscaped}(?<number>\\d+)\\.${newNameExt}$`
);
}
debugLog("dupNameRegex", dupNameRegex);
const dupNameNumbers = [];
let isNewNameExist = false;
for (let sibling of listed.files) {
sibling = path.basename(sibling);
if (sibling == newName) {
isNewNameExist = true;
continue;
}
const m = dupNameRegex.exec(sibling);
if (!m)
continue;
dupNameNumbers.push(parseInt(m.groups.number));
}
if (isNewNameExist || this.settings.dupNumberAlways) {
const newNumber = dupNameNumbers.length > 0 ? Math.max(...dupNameNumbers) + 1 : 1;
if (this.settings.dupNumberAtStart) {
newName = `${newNumber}${delimiter}${newNameStem}.${newNameExt}`;
} else {
newName = `${newNameStem}${delimiter}${newNumber}.${newNameExt}`;
}
}
return {
name: newName,
stem: newName.slice(0, newName.length - newNameExt.length - 1),
extension: newNameExt
};
});
}
getActiveFile() {
const view = this.app.workspace.getActiveViewOfType(import_obsidian2.MarkdownView);
const file = view == null ? void 0 : view.file;
debugLog("active file", file == null ? void 0 : file.path);
return file;
}
getActiveEditor() {
const view = this.app.workspace.getActiveViewOfType(import_obsidian2.MarkdownView);
return view == null ? void 0 : view.editor;
}
onunload() {
this.modals.map((modal) => modal.close());
}
testExcludeExtension(file) {
const pattern = this.settings.excludeExtensionPattern;
if (!pattern)
return false;
return new RegExp(pattern).test(file.extension);
}
loadSettings() {
return __async(this, null, function* () {
this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData());
});
}
saveSettings() {
return __async(this, null, function* () {
yield this.saveData(this.settings);
});
}
};
function getFirstHeading(headings) {
if (headings && headings.length > 0) {
for (const heading of headings) {
if (heading.level === 1) {
return heading.heading;
}
}
}
return "";
}
function isPastedImage(file) {
if (file instanceof import_obsidian2.TFile) {
if (file.name.startsWith(PASTED_IMAGE_PREFIX)) {
return true;
}
}
return false;
}
function isMarkdownFile(file) {
if (file instanceof import_obsidian2.TFile) {
if (file.extension === "md") {
return true;
}
}
return false;
}
var ImageRenameModal = class extends import_obsidian2.Modal {
constructor(app, src, stem, renameFunc, onClose) {
super(app);
this.src = src;
this.stem = stem;
this.renameFunc = renameFunc;
this.onCloseExtra = onClose;
}
onOpen() {
this.containerEl.addClass("image-rename-modal");
const { contentEl, titleEl } = this;
titleEl.setText("Rename image");
const imageContainer = contentEl.createDiv({
cls: "image-container"
});
imageContainer.createEl("img", {
attr: {
src: this.app.vault.getResourcePath(this.src)
}
});
let stem = this.stem;
const ext = this.src.extension;
const getNewName = (stem2) => stem2 + "." + ext;
const getNewPath = (stem2) => path.join(this.src.parent.path, getNewName(stem2));
const infoET = createElementTree(contentEl, {
tag: "ul",
cls: "info",
children: [
{
tag: "li",
children: [
{
tag: "span",
text: "Origin path"
},
{
tag: "span",
text: this.src.path
}
]
},
{
tag: "li",
children: [
{
tag: "span",
text: "New path"
},
{
tag: "span",
text: getNewPath(stem)
}
]
}
]
});
const doRename = () => __async(this, null, function* () {
debugLog("doRename", `stem=${stem}`);
this.renameFunc(getNewName(stem));
});
const nameSetting = new import_obsidian2.Setting(contentEl).setName("New name").setDesc("Please input the new name for the image (without extension)").addText((text) => text.setValue(stem).onChange(
(value) => __async(this, null, function* () {
stem = sanitizer.filename(value);
infoET.children[1].children[1].el.innerText = getNewPath(stem);
})
));
const nameInputEl = nameSetting.controlEl.children[0];
nameInputEl.focus();
const nameInputState = lockInputMethodComposition(nameInputEl);
nameInputEl.addEventListener("keydown", (e) => __async(this, null, function* () {
if (e.key === "Enter" && !nameInputState.lock) {
e.preventDefault();
if (!stem) {
errorEl.innerText = 'Error: "New name" could not be empty';
errorEl.style.display = "block";
return;
}
doRename();
this.close();
}
}));
const errorEl = contentEl.createDiv({
cls: "error",
attr: {
style: "display: none;"
}
});
new import_obsidian2.Setting(contentEl).addButton((button) => {
button.setButtonText("Rename").onClick(() => {
doRename();
this.close();
});
}).addButton((button) => {
button.setButtonText("Cancel").onClick(() => {
this.close();
});
});
}
onClose() {
const { contentEl } = this;
contentEl.empty();
this.onCloseExtra();
}
};
var imageNamePatternDesc = `
The pattern indicates how the new name should be generated.
Available variables:
- {{fileName}}: name of the active file, without ".md" extension.
- {{imageNameKey}}: this variable is read from the markdown file's frontmatter, from the same key "imageNameKey".
- {{DATE:$FORMAT}}: use "$FORMAT" to format the current date, "$FORMAT" must be a Moment.js format string, e.g. {{DATE:YYYY-MM-DD}}.
Here are some examples from pattern to image names (repeat in sequence), variables: fileName = "My note", imageNameKey = "foo":
- {{fileName}}: My note, My note-1, My note-2
- {{imageNameKey}}: foo, foo-1, foo-2
- {{imageNameKey}}-{{DATE:YYYYMMDD}}: foo-20220408, foo-20220408-1, foo-20220408-2
`;
var SettingTab = class extends import_obsidian2.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.plugin = plugin;
}
display() {
const { containerEl } = this;
containerEl.empty();
new import_obsidian2.Setting(containerEl).setName("Image name pattern").setDesc(imageNamePatternDesc).setClass("long-description-setting-item").addText((text) => text.setPlaceholder("{{imageNameKey}}").setValue(this.plugin.settings.imageNamePattern).onChange(
(value) => __async(this, null, function* () {
this.plugin.settings.imageNamePattern = value;
yield this.plugin.saveSettings();
})
));
new import_obsidian2.Setting(containerEl).setName("Duplicate number at start (or end)").setDesc(`If enabled, duplicate number will be added at the start as prefix for the image name, otherwise it will be added at the end as suffix for the image name.`).addToggle((toggle) => toggle.setValue(this.plugin.settings.dupNumberAtStart).onChange(
(value) => __async(this, null, function* () {
this.plugin.settings.dupNumberAtStart = value;
yield this.plugin.saveSettings();
})
));
new import_obsidian2.Setting(containerEl).setName("Duplicate number delimiter").setDesc(`The delimiter to generate the number prefix/suffix for duplicated names. For example, if the value is "-", the suffix will be like "-1", "-2", "-3", and the prefix will be like "1-", "2-", "3-". Only characters that are valid in file names are allowed.`).addText((text) => text.setValue(this.plugin.settings.dupNumberDelimiter).onChange(
(value) => __async(this, null, function* () {
this.plugin.settings.dupNumberDelimiter = sanitizer.delimiter(value);
yield this.plugin.saveSettings();
})
));
new import_obsidian2.Setting(containerEl).setName("Always add duplicate number").setDesc(`If enabled, duplicate number will always be added to the image name. Otherwise, it will only be added when the name is duplicated.`).addToggle((toggle) => toggle.setValue(this.plugin.settings.dupNumberAlways).onChange(
(value) => __async(this, null, function* () {
this.plugin.settings.dupNumberAlways = value;
yield this.plugin.saveSettings();
})
));
new import_obsidian2.Setting(containerEl).setName("Auto rename").setDesc(`By default, the rename modal will always be shown to confirm before renaming, if this option is set, the image will be auto renamed after pasting.`).addToggle((toggle) => toggle.setValue(this.plugin.settings.autoRename).onChange(
(value) => __async(this, null, function* () {
this.plugin.settings.autoRename = value;
yield this.plugin.saveSettings();
})
));
new import_obsidian2.Setting(containerEl).setName("Handle all attachments").setDesc(`By default, the plugin only handles images that starts with "Pasted image " in name,
which is the prefix Obsidian uses to create images from pasted content.
If this option is set, the plugin will handle all attachments that are created in the vault.`).addToggle((toggle) => toggle.setValue(this.plugin.settings.handleAllAttachments).onChange(
(value) => __async(this, null, function* () {
this.plugin.settings.handleAllAttachments = value;
yield this.plugin.saveSettings();
})
));
new import_obsidian2.Setting(containerEl).setName("Exclude extension pattern").setDesc(`This option is only useful when "Handle all attachments" is enabled.
Write a Regex pattern to exclude certain extensions from being handled. Only the first line will be used.`).setClass("single-line-textarea").addTextArea((text) => text.setPlaceholder("docx?|xlsx?|pptx?|zip|rar").setValue(this.plugin.settings.excludeExtensionPattern).onChange(
(value) => __async(this, null, function* () {
this.plugin.settings.excludeExtensionPattern = value;
yield this.plugin.saveSettings();
})
));
new import_obsidian2.Setting(containerEl).setName("Disable rename notice").setDesc(`Turn off this option if you don't want to see the notice when renaming images.
Note that Obsidian may display a notice when a link has changed, this option cannot disable that.`).addToggle((toggle) => toggle.setValue(this.plugin.settings.disableRenameNotice).onChange(
(value) => __async(this, null, function* () {
this.plugin.settings.disableRenameNotice = value;
yield this.plugin.saveSettings();
})
));
}
};
@@ -1,10 +0,0 @@
{
"id": "obsidian-paste-image-rename",
"name": "Paste image rename",
"version": "1.6.1",
"minAppVersion": "0.12.0",
"description": "Rename pasted images and all the other attchments added to the vault",
"author": "Reorx",
"authorUrl": "https://github.com/reorx",
"isDesktopOnly": false
}
@@ -1,79 +0,0 @@
/* src/styles.css */
:root {
--shadow-color: 0deg 0% 0%;
--shadow-elevation-medium:
0.5px 0.5px 0.7px hsl(var(--shadow-color) / 0.14),
1.1px 1.1px 1.5px -0.9px hsl(var(--shadow-color) / 0.12),
2.4px 2.5px 3.3px -1.8px hsl(var(--shadow-color) / 0.1),
5.3px 5.6px 7.3px -2.7px hsl(var(--shadow-color) / 0.09),
11px 11.4px 15.1px -3.6px hsl(var(--shadow-color) / 0.07);
}
.image-rename-modal .modal {
width: 65%;
min-width: 600px;
}
.image-rename-modal .modal-content {
padding: 10px 5px;
}
.image-rename-modal .image-container {
display: flex;
justify-content: center;
}
.image-rename-modal .info {
padding: 10px 0;
color: var(--text-muted);
user-select: text;
}
.image-rename-modal .info li > span:nth-of-type(1) {
display: inline-block;
width: 6em;
margin-right: .5em;
}
.image-rename-modal .info li > span:nth-of-type(1):after {
content: ":";
float: right;
}
.image-rename-modal .image-container img {
display: block;
max-height: 300px;
box-shadow: var(--shadow-elevation-medium);
}
.image-rename-modal .setting-item-control input {
min-width: 300px;
}
.image-rename-modal .error {
border: 1px solid rgb(201, 90, 90);
color: rgb(134, 22, 22);
padding: 10px;
}
.image-rename-modal table {
font-size: .9em;
line-height: 1.8;
margin-bottom: 1.5em;
user-select: text;
}
.image-rename-modal table td {
padding-right: 1em;
}
.image-rename-modal table thead td {
font-weight: 700;
}
.image-rename-modal table tbody td .file-path {
font-size: .8em;
color: var(--text-faint);
line-height: 1;
}
.long-description-setting-item {
flex-wrap: wrap;
}
.long-description-setting-item .setting-item-description {
white-space: pre-wrap;
line-height: 1.3em;
}
.long-description-setting-item .setting-item-control {
padding-top: 10px;
}
.long-description-setting-item .setting-item-control input {
min-width: 300px;
width: 50%;
}
-214
View File
@@ -1,214 +0,0 @@
{
"choices": [
{
"id": "0462f0ba-4349-4531-b1a0-6634e5fc146f",
"name": "日常记录-闪念笔记",
"type": "Template",
"command": false,
"templatePath": "attachment/templates/时间戳笔记.md",
"fileNameFormat": {
"enabled": true,
"format": "{{DATE:YYYYMMDDHHmmSS}}"
},
"folder": {
"enabled": true,
"folders": [
"000-Inbox"
],
"chooseWhenCreatingNote": false,
"createInSameFolderAsActiveFile": false,
"chooseFromSubfolders": false
},
"appendLink": false,
"openFileInNewTab": {
"enabled": true,
"direction": "vertical",
"focus": true
},
"openFile": true,
"openFileInMode": "default",
"fileExistsMode": "Increment the file name",
"setFileExistsBehavior": false,
"fileOpening": {
"location": "tab",
"direction": "vertical",
"focus": true,
"mode": "default"
}
},
{
"id": "eccc9792-8b8b-42bd-a20d-8c061ece98cf",
"name": "移动杭研-问题记录",
"type": "Template",
"command": false,
"templatePath": "attachment/templates/移动杭研-问题记录.md",
"fileNameFormat": {
"enabled": true,
"format": "{{DATE:MMDD}}-{{value}}"
},
"folder": {
"enabled": true,
"folders": [
"000-Inbox"
],
"chooseWhenCreatingNote": false,
"createInSameFolderAsActiveFile": false,
"chooseFromSubfolders": false
},
"appendLink": false,
"openFileInNewTab": {
"enabled": true,
"direction": "vertical",
"focus": true
},
"openFile": true,
"openFileInMode": "default",
"fileExistsMode": "Increment the file name",
"setFileExistsBehavior": false,
"fileOpening": {
"location": "split",
"direction": "vertical",
"focus": true,
"mode": "default"
}
},
{
"id": "4ad23b51-d9fd-445e-aed8-f332e99f2350",
"name": "移动杭研-开发笔记",
"type": "Template",
"command": false,
"templatePath": "attachment/templates/移动杭研-开发笔记.md",
"fileNameFormat": {
"enabled": true,
"format": "开发笔记"
},
"folder": {
"enabled": true,
"folders": [
"000-Inbox"
],
"chooseWhenCreatingNote": false,
"createInSameFolderAsActiveFile": false,
"chooseFromSubfolders": false
},
"appendLink": false,
"openFileInNewTab": {
"enabled": true,
"direction": "vertical",
"focus": true
},
"openFile": true,
"openFileInMode": "default",
"fileExistsMode": "Nothing",
"setFileExistsBehavior": true,
"fileOpening": {
"location": "split",
"direction": "vertical",
"focus": true,
"mode": "default"
}
},
{
"id": "83f6f73d-a391-4096-b07f-a9626f10980e",
"name": "openTerminal",
"type": "Macro",
"command": false,
"runOnStartup": false,
"macro": {
"name": "openTerminal",
"id": "2417c310-3ca2-4a95-9962-761529241e84",
"commands": [
{
"name": "openTerminal",
"type": "UserScript",
"id": "22516ce4-03d7-4f5b-b210-b15dd82340e5",
"path": "resource/工具/obsidian/scripts/openTerminal.js",
"settings": {}
}
]
}
}
],
"inputPrompt": "multi-line",
"persistInputPromptDrafts": true,
"useSelectionAsCaptureValue": true,
"devMode": false,
"templateFolderPath": "attachment/templates",
"announceUpdates": "all",
"version": "2.12.0",
"globalVariables": {},
"onePageInputEnabled": false,
"disableOnlineFeatures": true,
"enableRibbonIcon": false,
"showCaptureNotification": true,
"showInputCancellationNotification": false,
"enableTemplatePropertyTypes": false,
"dateAliases": {
"t": "today",
"tm": "tomorrow",
"yd": "yesterday",
"nw": "next week",
"nm": "next month",
"ny": "next year",
"lw": "last week",
"lm": "last month",
"ly": "last year"
},
"ai": {
"defaultModel": "Ask me",
"defaultSystemPrompt": "As an AI assistant within Obsidian, your primary goal is to help users manage their ideas and knowledge more effectively. Format your responses using Markdown syntax. Please use the [[Obsidian]] link format. You can write aliases for the links by writing [[Obsidian|the alias after the pipe symbol]]. To use mathematical notation, use LaTeX syntax. LaTeX syntax for larger equations should be on separate lines, surrounded with double dollar signs ($$). You can also inline math expressions by wrapping it in $ symbols. For example, use $$w_{ij}^{\text{new}}:=w_{ij}^{\text{current}}+etacdotdelta_jcdot x_{ij}$$ on a separate line, but you can write \"($eta$ = learning rate, $delta_j$ = error term, $x_{ij}$ = input)\" inline.",
"promptTemplatesFolderPath": "",
"showAssistant": true,
"providers": [
{
"name": "OpenAI",
"endpoint": "https://api.openai.com/v1",
"apiKey": "",
"models": [
{
"name": "gpt-3.5-turbo",
"maxTokens": 4096
},
{
"name": "gpt-3.5-turbo-16k",
"maxTokens": 16384
},
{
"name": "gpt-3.5-turbo-1106",
"maxTokens": 16385
},
{
"name": "gpt-4",
"maxTokens": 8192
},
{
"name": "gpt-4-32k",
"maxTokens": 32768
},
{
"name": "gpt-4-1106-preview",
"maxTokens": 128000
},
{
"name": "text-davinci-003",
"maxTokens": 4096
}
],
"modelSource": "auto"
}
]
},
"migrations": {
"migrateToMacroIDFromEmbeddedMacro": true,
"useQuickAddTemplateFolder": true,
"incrementFileNameSettingMoveToDefaultBehavior": true,
"mutualExclusionInsertAfterAndWriteToBottomOfFile": true,
"setVersionAfterUpdateModalRelease": true,
"addDefaultAIProviders": true,
"removeMacroIndirection": true,
"migrateFileOpeningSettings": true,
"setProviderModelDiscoveryMode": true,
"backfillFileOpeningDefaults": true,
"migrateProviderApiKeysToSecretStorage": true
}
}
File diff suppressed because one or more lines are too long
-12
View File
@@ -1,12 +0,0 @@
{
"id": "quickadd",
"name": "QuickAdd",
"version": "2.12.0",
"minAppVersion": "1.11.4",
"description": "Quickly add new pages or content to your vault.",
"author": "Christian B. B. Houmann",
"authorUrl": "https://bagerbach.com",
"fundingUrl": "https://www.buymeacoffee.com/chhoumann",
"helpUrl": "https://quickadd.obsidian.guide/docs/",
"isDesktopOnly": false
}
File diff suppressed because one or more lines are too long
-212
View File
@@ -1,212 +0,0 @@
{
"recentFiles": [
{
"basename": "tg-bot",
"path": "000-inbox/tg-bot.md"
},
{
"basename": "Redis 安装",
"path": "000-inbox/Redis 安装.md"
},
{
"basename": "杭州服务器-AI",
"path": "000-inbox/杭州服务器-AI.md"
},
{
"basename": "常用命令",
"path": "resource/常用命令.md"
},
{
"basename": "20260316213546",
"path": "000-Inbox/20260316213546.md"
},
{
"basename": "IBS 智能体具体落实技术方案",
"path": "work/移动杭研/AI 项目/IBS 智能体具体落实技术方案.md"
},
{
"basename": "20260316160264",
"path": "000-Inbox/20260316160264.md"
},
{
"basename": "20260316102936",
"path": "000-Inbox/20260316102936.md"
},
{
"basename": "20260316105203",
"path": "000-Inbox/20260316105203.md"
},
{
"basename": "0316-配管任务限流问题",
"path": "work/移动杭研/问题处理/2026-03/0316-配管任务限流问题.md"
},
{
"basename": "0316-配管任务限流问题",
"path": "000-Inbox/0316-配管任务限流问题.md"
},
{
"basename": "1107-试用单删除问题",
"path": "work/移动杭研/问题处理/2025-11/1107-试用单删除问题.md"
},
{
"basename": "20260313151563",
"path": "000-Inbox/20260313151563.md"
},
{
"basename": "Prompt 02 COSMIC 功能过程",
"path": "resource/ai/prompts/cosmic/Prompt 02 COSMIC 功能过程.md"
},
{
"basename": "Prompt 03 COSMIC 子过程",
"path": "resource/ai/prompts/cosmic/Prompt 03 COSMIC 子过程.md"
},
{
"basename": "Prompt 01 COSMIC 需求扩写",
"path": "resource/ai/prompts/cosmic/Prompt 01 COSMIC 需求扩写.md"
},
{
"basename": "Prompt 06 COSMIC 锐评",
"path": "resource/ai/prompts/cosmic/Prompt 06 COSMIC 锐评.md"
},
{
"basename": "Prompt 05 COSMIC 时序图",
"path": "resource/ai/prompts/cosmic/Prompt 05 COSMIC 时序图.md"
},
{
"basename": "Prompt 04 COSMIC PRD 文档",
"path": "resource/ai/prompts/cosmic/Prompt 04 COSMIC PRD 文档.md"
},
{
"basename": "Prompt 00 COSMIC v1",
"path": "resource/ai/prompts/cosmic/Prompt 00 COSMIC v1.md"
},
{
"basename": "BUSI_REQUIREMENT_COSMIC",
"path": "resource/ai/prompts/cosmic 业务版本/BUSI_REQUIREMENT_COSMIC.md"
},
{
"basename": "BUSI_REQUIREMENT_FLOWCHART",
"path": "resource/ai/prompts/cosmic 业务版本/BUSI_REQUIREMENT_FLOWCHART.md"
},
{
"basename": "Prompt 高级彩虹屁",
"path": "resource/ai/prompts/Prompt 高级彩虹屁.md"
},
{
"basename": "Prompt 考勤数据规整助手 小杨",
"path": "resource/ai/prompts/Prompt 考勤数据规整助手 小杨.md"
},
{
"basename": "RAG Flow",
"path": "work/移动杭研/AI 项目/RAG Flow.md"
},
{
"basename": "ibs-ai 项目梳理",
"path": "work/移动杭研/AI 项目/ibs-ai 项目梳理.md"
},
{
"basename": "开发备注",
"path": "work/移动杭研/AI 项目/开发备注.md"
},
{
"basename": "CLAUDE.md",
"path": "work/移动杭研/AI 项目/CLAUDE.md.md"
},
{
"basename": "RAG Flow 部署",
"path": "work/移动杭研/AI 项目/RAG Flow 部署.md"
},
{
"basename": "settings.local.json",
"path": "work/移动杭研/AI 项目/settings.local.json.md"
},
{
"basename": "Prompt 公司智能体",
"path": "resource/ai/prompts/临时/Prompt 公司智能体.md"
},
{
"basename": "Prompt 需求-考勤转换-小杨",
"path": "resource/ai/prompts/临时/Prompt 需求-考勤转换-小杨.md"
},
{
"basename": "Prompt 专家模板",
"path": "resource/ai/prompts/Prompt 专家模板.md"
},
{
"basename": "Prompt ChatBI 查询规划器",
"path": "resource/ai/prompts/Prompt ChatBI 查询规划器.md"
},
{
"basename": "Prompt Linus",
"path": "resource/ai/prompts/Prompt Linus.md"
},
{
"basename": "Prompt Lisp 语言",
"path": "resource/ai/prompts/Prompt Lisp 语言.md"
},
{
"basename": "Prompt PPT 大纲制作专家",
"path": "resource/ai/prompts/Prompt PPT 大纲制作专家.md"
},
{
"basename": "Prompt PPT 逐字稿编写专家",
"path": "resource/ai/prompts/Prompt PPT 逐字稿编写专家.md"
},
{
"basename": "开发笔记",
"path": "work/移动杭研/开发记录/7.19.0/开发笔记.md"
},
{
"basename": "20260312105716",
"path": "000-Inbox/20260312105716.md"
},
{
"basename": "服务器-香港",
"path": "personal/服务器-香港.md"
},
{
"basename": "20260311142461",
"path": "000-Inbox/20260311142461.md"
},
{
"basename": "K-V 功能",
"path": "work/移动杭研/项目备忘/K-V 功能.md"
},
{
"basename": "IBS NG 日志模板",
"path": "work/移动杭研/项目备忘/IBS NG 日志模板.md"
},
{
"basename": "项目杂记",
"path": "work/移动杭研/项目备忘/项目杂记.md"
},
{
"basename": "数据库信息",
"path": "work/移动杭研/项目备忘/数据库信息.md"
},
{
"basename": "获取企业 token 脚本",
"path": "work/移动杭研/项目备忘/获取企业 token 脚本.md"
},
{
"basename": "环境账号",
"path": "work/移动杭研/项目备忘/环境账号.md"
},
{
"basename": "工作账号",
"path": "work/移动杭研/项目备忘/工作账号.md"
},
{
"basename": "20260311083458",
"path": "000-Inbox/20260311083458.md"
}
],
"omittedPaths": [
"^attachment/",
"^calendar/"
],
"omittedTags": [],
"updateOn": "file-open",
"omitBookmarks": false,
"maxLength": null
}
File diff suppressed because one or more lines are too long
-16
View File
@@ -1,16 +0,0 @@
{
"id": "recent-files-obsidian",
"name": "Recent Files",
"version": "1.7.6",
"minAppVersion": "0.16.3",
"description": "List files by most recently opened",
"author": "Tony Grosinger",
"authorUrl": "https://grosinger.net",
"isDesktopOnly": false,
"fundingUrl": {
"Github Sponsor": "https://github.com/sponsors/tgrosinger",
"Buy me a Coffee": "https://buymeacoffee.com/tgrosinger",
"Paypal": "https://paypal.me/tgrosinger"
},
"donation": "https://buymeacoffee.com/tgrosinger"
}
-34
View File
@@ -1,34 +0,0 @@
.recent-files-file {
.tree-item-spacer {
flex-grow: 1;
}
}
.recent-files-title {
justify-content: flex-start;
align-items: unset;
}
.recent-files-file-delete {
justify-content: right;
display: none;
}
.recent-files-title:hover .recent-files-file-delete {
display: flex;
cursor: var(--cursor);
}
.recent-files-file-delete:hover {
color: var(--nav-item-color-hover);
}
.recent-files-donation {
width: 70%;
margin: 0 auto;
text-align: center;
}
.recent-files-donate-button {
margin: 10px;
}
+3 -1
View File
@@ -23,7 +23,9 @@
], ],
"syntax_highlighting": true, "syntax_highlighting": true,
"syntax_highlighting_mobile": false, "syntax_highlighting_mobile": false,
"enabled_templates_hotkeys": [], "enabled_templates_hotkeys": [
"attachment/templates/日常记录-闪念笔记.md"
],
"startup_templates": [], "startup_templates": [],
"intellisense_render": 1, "intellisense_render": 1,
"enable_ribbon_icon": true "enable_ribbon_icon": true
-25
View File
@@ -1,25 +0,0 @@
/* === 颜色变量 === */
:root {
--h1-color: #172a4f;
--h2-color: #4a5c7a;
--h3-color: #6b7280;
--bold-color: var(--h1-color);
}
/* === 标题样式 === */
h1 {
color: var(--h1-color);
}
h2 {
color: var(--h2-color);
}
h3 {
color: var(--h3-color);
}
/* === 粗体样式 === */
div.cm-line span.cm-strong,
div p strong {
color: var(--bold-color) !important;
}
+84 -83
View File
@@ -4,20 +4,41 @@
"type": "split", "type": "split",
"children": [ "children": [
{ {
"id": "b29f1eccf46b0980", "id": "0a4507548b25ff58",
"type": "tabs", "type": "tabs",
"children": [ "children": [
{ {
"id": "431eb252187a1635", "id": "1184ee15ec1fc896",
"type": "leaf", "type": "leaf",
"state": { "state": {
"type": "empty", "type": "markdown",
"state": {}, "state": {
"file": "personal/服务器-香港.md",
"mode": "source",
"source": false,
"backlinks": false
},
"icon": "lucide-file", "icon": "lucide-file",
"title": "新标签页" "title": "服务器-香港"
}
},
{
"id": "c3b31f156a70117f",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "000-inbox/2026-03-29_16-52-52.md",
"mode": "source",
"source": false,
"backlinks": false
},
"icon": "lucide-file",
"title": "2026-03-29_16-52-52"
} }
} }
] ],
"currentTab": 1
} }
], ],
"direction": "vertical" "direction": "vertical"
@@ -29,7 +50,6 @@
{ {
"id": "6836caf2765d7139", "id": "6836caf2765d7139",
"type": "tabs", "type": "tabs",
"dimension": 69.27016645326505,
"children": [ "children": [
{ {
"id": "c8718c0c63702202", "id": "c8718c0c63702202",
@@ -50,7 +70,7 @@
"state": { "state": {
"type": "search", "type": "search",
"state": { "state": {
"query": "培训", "query": "file:香港",
"matchingCase": false, "matchingCase": false,
"explainSearch": true, "explainSearch": true,
"collapseAll": false, "collapseAll": false,
@@ -72,27 +92,10 @@
} }
} }
] ]
},
{
"id": "729e97c586d5eaa9",
"type": "tabs",
"dimension": 30.72983354673495,
"children": [
{
"id": "4c0b938080320781",
"type": "leaf",
"state": {
"type": "recent-files",
"state": {},
"icon": "clock",
"title": "Recent Files"
}
}
]
} }
], ],
"direction": "horizontal", "direction": "horizontal",
"width": 222.5 "width": 255.5
}, },
"right": { "right": {
"id": "ca733f6d5936ae40", "id": "ca733f6d5936ae40",
@@ -101,7 +104,7 @@
{ {
"id": "1f21045435bfa327", "id": "1f21045435bfa327",
"type": "tabs", "type": "tabs",
"dimension": 57.8883495145631, "dimension": 57.03883495145632,
"children": [ "children": [
{ {
"id": "43a2e8e1d9201229", "id": "43a2e8e1d9201229",
@@ -109,12 +112,13 @@
"state": { "state": {
"type": "outline", "type": "outline",
"state": { "state": {
"file": "000-inbox/2026-03-29_16-52-52.md",
"followCursor": true, "followCursor": true,
"showSearch": false, "showSearch": false,
"searchQuery": "" "searchQuery": ""
}, },
"icon": "lucide-list", "icon": "lucide-list",
"title": "大纲" "title": "2026-03-29_16-52-52 的大纲"
} }
}, },
{ {
@@ -123,7 +127,7 @@
"state": { "state": {
"type": "backlink", "type": "backlink",
"state": { "state": {
"file": "000-Inbox/20260305103657.md", "file": "attachment/templates/查找未引用图片.md",
"collapseAll": false, "collapseAll": false,
"extraContext": false, "extraContext": false,
"sortOrder": "alphabetical", "sortOrder": "alphabetical",
@@ -133,7 +137,7 @@
"unlinkedCollapsed": false "unlinkedCollapsed": false
}, },
"icon": "links-coming-in", "icon": "links-coming-in",
"title": "20260305103657 的反向链接列表" "title": "查找未引用图片 的反向链接列表"
} }
}, },
{ {
@@ -142,12 +146,11 @@
"state": { "state": {
"type": "outgoing-link", "type": "outgoing-link",
"state": { "state": {
"file": "000-Inbox/20260305103657.md",
"linksCollapsed": false, "linksCollapsed": false,
"unlinkedCollapsed": true "unlinkedCollapsed": true
}, },
"icon": "links-going-out", "icon": "links-going-out",
"title": "20260305103657 的出链列表" "title": "出链"
} }
}, },
{ {
@@ -184,9 +187,7 @@
"type": "leaf", "type": "leaf",
"state": { "state": {
"type": "footnotes", "type": "footnotes",
"state": { "state": {},
"file": "000-Inbox/20260305103657.md"
},
"icon": "lucide-file-signature", "icon": "lucide-file-signature",
"title": "脚注" "title": "脚注"
} }
@@ -194,12 +195,12 @@
] ]
}, },
{ {
"id": "ea8a40d57ef90e62", "id": "e2c44b9c5d0747bb",
"type": "tabs", "type": "tabs",
"dimension": 42.1116504854369, "dimension": 42.96116504854368,
"children": [ "children": [
{ {
"id": "499dbd491c6fb256", "id": "736f0891b55bede0",
"type": "leaf", "type": "leaf",
"state": { "state": {
"type": "calendar", "type": "calendar",
@@ -212,7 +213,7 @@
} }
], ],
"direction": "horizontal", "direction": "horizontal",
"width": 287.5 "width": 281.5
}, },
"left-ribbon": { "left-ribbon": {
"hiddenItems": { "hiddenItems": {
@@ -222,58 +223,58 @@
"daily-notes:打开/创建今天的日记": false, "daily-notes:打开/创建今天的日记": false,
"canvas:新建白板": false, "canvas:新建白板": false,
"bases:新建数据库": false, "bases:新建数据库": false,
"templater-obsidian:Templater": true, "obsidian-excalidraw-plugin:New drawing": false,
"obsidian-excalidraw-plugin:New drawing": false "templater-obsidian:Templater": false
} }
}, },
"active": "c8718c0c63702202", "active": "c3b31f156a70117f",
"lastOpenFiles": [ "lastOpenFiles": [
"calendar/diary/2026-03-17.md", "000-inbox/2026-03-29_16-51-46.md",
"calendar/diary/2026-03-16.md", "personal/服务器-香港.md",
"000-inbox/tg-bot.md", "000-inbox/2026-03-30_20-38-38.md",
"000-inbox/Redis 安装.md", "resource/系统/ubuntu.md",
"000-inbox/杭州服务器-AI.md", "resource/ai/大模型安装笔记/关于模型思考问题.md",
"000-inbox/20260316213546.md", "000-inbox/n8n 安装.md",
"resource/常用命令.md", "000-inbox/2026-03-29_16-55-23.md",
"000-Inbox/20260316213546.md", "000-inbox/2026-03-29_22-08-03.md",
"work/移动杭研/AI 项目/IBS 智能体具体落实技术方案.md", "000-inbox/2026-03-29_16-52-52.md",
"000-Inbox/20260316160264.md", "attachment/Pasted image 20260329165253.png",
"000-inbox/20260316105203.md", "000-inbox/2026-03-291.md",
"000-Inbox/20260316102936.md", "000-inbox/2026-03-291111111111111111111.md",
"000-Inbox/20260316105203.md", "000-inbox/2026-03-2911.md",
"calendar/diary/2026-03-13.md", "000-inbox/202603292037501.md",
"calendar/diary/2026-03-15.md", "attachment/templates/time.md",
"calendar/weeks/2026-W11.md", "000-inbox/2026-03-29_19-37-09.md",
"calendar/diary/2026-03-14.md", "000-inbox/2026-03-29_17-01-36.md",
"calendar/diary/2026-03-12.md", "attachment/Pasted image 20260329170137.png",
"calendar/diary/2026-03-11.md", "attachment/Pasted image 20260329165321.png",
"calendar/diary/2026-03-10.md", "attachment/Pasted image 20260329165301.png",
"calendar/diary/2026-03-09.md", "attachment/templates/日常记录-闪念笔记.md",
"work/移动杭研/问题处理/2026-03/0316-配管任务限流问题.md", "resource/go/待总结/010 Go 语言 IO 流.md",
"attachment/images-paste/image-20230226203841579.png",
"attachment/templates/打开控制台.md",
"attachment/templates/移动杭研-开发笔记.md",
"attachment/templates/移动杭研-问题记录.md",
"calendar/diary/2026-03-29.md",
"attachment/templates/查找未引用图片.md",
"calendar/diary/2026-03-28.md",
"calendar/diary/2026-03-27.md",
"000-inbox/Untitled 2.md",
"attachment/Pasted image 20260329133947.png",
"attachment/jsscripts/openTerminal.js",
"attachment/jsscripts/新建文本文档.txt",
"attachment/jsscripts",
"attachment/images-paste/image-20260325102650978.png",
"attachment/images-paste/image-20260325224014579.png",
"attachment/images-paste/image-20260325224132102.png",
"attachment/images-paste/image-20260325224152205.png",
"resource/ai/大模型安装笔记",
"work/移动杭研/问题处理/2026-03", "work/移动杭研/问题处理/2026-03",
"000-inbox/20260313151563.md",
"000-Inbox/0316-配管任务限流问题.md",
"work/移动杭研/问题处理/2025-11/1107-试用单删除问题.md",
"000-Inbox/20260313151563.md",
"resource/ai/prompts/cosmic 业务版本", "resource/ai/prompts/cosmic 业务版本",
"resource/ai/prompts/cosmic", "resource/ai/prompts/cosmic",
"resource/ai/prompts/临时", "resource/ai/prompts/临时",
"resource/工具/rime", "resource/工具/rime",
"attachment/images-paste/image-20260304153545122.png",
"work/移动杭研/开发记录/7.19.0", "work/移动杭研/开发记录/7.19.0",
"work/移动杭研/AI 项目", "000-inbox/未命名.canvas"
"resource/前端",
"resource/英语",
"attachment/images-paste/image-20260305082403915.png",
"attachment/image-20260305103708566.png",
"attachment/Pasted image 20260305103645.png",
"attachment/Pasted image 20260305103633.png",
"000-inbox/未命名.canvas",
"attachment/images-uuid/dd32291e71724c52a904aa80ce1fc59a.png",
"attachment/images-uuid/e9d6d33cd6a44bd0ab62b5999e04c7be.png",
"attachment/image-20260302225213302.png",
"attachment/Pasted image 20260302225154.png",
"resource/mermaid",
"attachment/images-uuid/1b6c8b1c84064481ac7c72347ba8e259.png"
] ]
} }
+9
View File
@@ -0,0 +1,9 @@
![](../attachment/Pasted%20image%2020260329165253.png)
![](../attachment/Pasted%20image%2020260329165301.png)
![](../attachment/Pasted%20image%2020260329165321.png)
```
MPLkv5dlbyKh_q0DdvH5ECxaUHVr5BVg0Ogf5AOH
```
+3
View File
@@ -0,0 +1,3 @@
![](../attachment/Pasted%20image%2020260329170137.png)
2026-01-13 21:46
View File
@@ -0,0 +1,123 @@
# 🐳 Docker 核心知识与实战笔记
## 一、 Docker 核心工作流与常用命令速查表
### 1. 自定义镜像与分享工作流
- **流程**:下载镜像 -> 启动容器 -> 修改页面/配置 -> 保存镜像 (`commit`) -> 导出镜像 (`save`) -> 分享/加载 (`load`)
- `docker commit`:将修改后的容器提交为新的本地镜像。
- `docker save`:将镜像保存为 tar 归档文件(用于离线传输)。
- `docker load`:从 tar 归档文件中加载镜像。
### 2. 常用命令分类速查 (Cheat Sheet)
| 分类 | 命令示例 | 功能说明 |
| :--- | :--- | :--- |
| **镜像 (Image)** | `docker search` | 检索 Docker Hub 上的镜像 |
| | `docker pull` | 下载镜像到本地 |
| | `docker images` | 列出本地所有镜像 |
| | `docker rmi` | 删除本地镜像 |
| **容器 (Container)**| `docker run` | 创建并运行一个新容器 |
| | `docker ps` | 查看当前正在运行的容器 (`-a` 查看所有) |
| | `docker stop` / `start`| 停止 / 启动 容器 |
| | `docker restart` | 重启容器 |
| | `docker stats` | 查看容器资源实时使用状态 |
| | `docker logs` | 查看容器内部日志(排错必备) |
| | `docker exec` | 进入正在运行的容器内部执行命令 |
| | `docker rm` | 删除已停止的容器 |
| **分享与管理** | `docker login` | 登录 Docker 镜像仓库 |
| | `docker tag` | 给镜像打标签(重命名,准备推送) |
| | `docker push` | 将镜像推送到远程仓库 |
---
## 二、 数据持久化:目录挂载 vs 卷映射
Docker 提供了两种主要的数据持久化方式,通过 `-v` 参数实现:
### 1. 目录挂载 (Bind Mounts)
将宿主机的**绝对路径**直接挂载到容器内。
- **语法**`-v /宿主机绝对路径:/容器内路径`
- **示例**`-v /app/nghtml:/usr/share/nginx/html`
- **特点**:路径完全由用户掌控,适合挂载需要频繁修改的代码或配置文件。
### 2. 卷映射 (Named Volumes)
由 Docker 自动管理宿主机的存储目录,只需提供一个“卷名”。
- **语法**`-v 卷名:/容器内路径`
- **示例**`-v ngconf:/etc/nginx`
- **底层路径**:Docker 默认会将命名卷存放在宿主机的 `/var/lib/docker/volumes/<volume-name>/_data` 目录下。
- **特点**:Docker 统一管理,不用担心宿主机路径权限问题,适合持久化数据库数据等。
### 3. Volume 常用管理命令
- `docker volume ls`:列出所有由 Docker 管理的卷。
- `docker volume create <卷名>`:提前创建一个数据卷。
- `docker volume inspect <卷名>`:查看卷的详细信息(包含具体的 `Mountpoint` 宿主机物理路径)。
> ⚠️ **排错注意**:在挂载配置文件(如 nginx.conf)时,如果宿主机对应路径下没有该文件,直接挂载会导致容器内部找不到配置文件而启动失败(如截图中 `Exited (1)` 且日志报错 `open() "/etc/nginx/nginx.conf" failed`)。
---
## 三、 容器网络机制与自定义网络
### 1. 默认网络 (`docker0`) 的局限性
- Docker 会为每个容器分配一个唯一的内网 IP。
- **痛点**:由于容器重启等原因,**容器的 IP 是动态变化的**。默认的 `docker0` 桥接网络**不支持通过容器名(域名)进行内部互相解析**。
### 2. 解决方案:创建自定义网络
- **核心优势**:在自定义网络(如命名为 `mynet`)中,**容器名就是稳定的域名**。即使 IP 变了,容器之间依然可以通过容器名互相访问。
### 3. 实战案例:Redis 主从同步集群(通过容器名通信)
使用自定义网络,让从节点通过主节点的**容器名**进行连接,实现读写分离。
- **Master (主节点 - redis01)**:
- 宿主机端口: `6379`
- 环境变量: `REDIS_REPLICATION_MODE=master`, `REDIS_PASSWORD=123456`
- **Slave (从节点 - redis02)**:
- 宿主机端口: `6380`
- 环境变量:
- `REDIS_REPLICATION_MODE=slave`
- `REDIS_MASTER_HOST=redis01` (**重点:直接使用主节点的容器名**)
- `REDIS_MASTER_PORT_NUMBER=6379` (主节点内部端口)
- `REDIS_MASTER_PASSWORD=123456`
- `REDIS_PASSWORD=123456`
---
## 四、 Docker Compose 容器编排
当项目包含多个容器(如 App + MySQL + Redis)时,单个单个 `run` 非常繁琐,此时需要使用 Docker Compose。
### 1. 核心概念
通过一个 `compose.yaml` (或 `docker-compose.yml`) 声明式文件,一键管理整个项目的多个服务。
### 2. 常用操作命令
- `docker compose up -d`:**上线**(解析 yaml,创建网络/数据卷,后台启动所有容器)。
- `docker compose down`:**下线**(停止并删除 yaml 中定义的所有容器、网络)。
- `docker compose start [服务名1 服务名2]`:单独启动定义好的服务。
- `docker compose stop [服务名1 服务名2]`:单独停止服务。
- *(扩展)* `docker compose scale <服务名>=<数量>`:对某个服务进行扩缩容(注:新版语法多推荐使用 `up --scale`)。
### 3. `compose.yaml` 顶级元素构成
编写 yaml 文件时,主要包含以下几个顶级块(Top-level elements):
- `name`:项目名称
- `services`:**【核心】** 定义各个服务(如 web, db, cache),每个服务包含镜像、端口映射、环境变量等。
- `networks`:定义项目使用的自定义网络。
- `volumes`:定义项目使用的数据卷。
- `configs`:定义配置信息。
- `secrets`:定义敏感信息(如密码密钥)。
**官方参考文档查阅地址**
`https://docs.docker.com/compose/compose-file/` (编写 yaml 遇到属性不会写时,随时查阅 Reference 官方文档)。
+3
View File
@@ -0,0 +1,3 @@
```
{% if not add_generation_prompt is defined %}{% set add_generation_prompt = false %}{% endif %}{% set ns = namespace(is_first=false, is_tool=false, is_output_first=true, system_prompt='') %}{%- for message in messages %}{%- if message['role'] == 'system' %}{% set ns.system_prompt = message['content'] %}{%- endif %}{%- endfor %}{{bos_token}}{{ns.system_prompt}}{%- for message in messages %}{%- if message['role'] == 'user' %}{%- set ns.is_tool = false -%}{{'<User>' + message['content']}}{%- endif %}{%- if message['role'] == 'assistant' and message['content'] is none %}{%- set ns.is_tool = false -%}{%- for tool in message['tool_calls']%}{%- if not ns.is_first %}{{'<Assistant><tool▁calls▁begin><tool▁call▁begin>' + tool['type'] + '<tool▁sep>' + tool['function']['name'] + '\\n' + '```json' + '\\n' + tool['function']['arguments'] + '\\n' + '```' + '<tool▁call▁end>'}}{%- set ns.is_first = true -%}{%- else %}{{'\\n' + '<tool▁call▁begin>' + tool['type'] + '<tool▁sep>' + tool['function']['name'] + '\\n' + '```json' + '\\n' + tool['function']['arguments'] + '\\n' + '```' + '<tool▁call▁end>'}}{{'<tool▁calls▁end><end▁of▁sentence>'}}{%- endif %}{%- endfor %}{%- endif %}{%- if message['role'] == 'assistant' and message['content'] is not none %}{%- if ns.is_tool %}{{'<tool▁outputs▁end>' + message['content'] + '<end▁of▁sentence>'}}{%- set ns.is_tool = false -%}{%- else %}{% set content = message['content'] %}{% if '</think>' in content %}{% set content = message['content'].replace('</think>', '').split('<think>')[-1] %}{% endif %}{{'<Assistant>' + content + '<end▁of▁sentence>'}}{%- endif %}{%- endif %}{%- if message['role'] == 'tool' %}{%- set ns.is_tool = true -%}{%- if ns.is_output_first %}{{'<tool▁outputs▁begin><tool▁output▁begin>' + message['content'] + '<tool▁output▁end>'}}{%- set ns.is_output_first = false %}{%- else %}{{'\\n<tool▁output▁begin>' + message['content'] + '<tool▁output▁end>'}}{%- endif %}{%- endif %}{%- endfor -%}{% if ns.is_tool %}{{'<tool▁outputs▁end>'}}{% endif %}{% if add_generation_prompt and not ns.is_tool %}{{'<Assistant>'}}{% endif %}
```
+37
View File
@@ -0,0 +1,37 @@
```
services:
n8n:
image: ${N8N_IMAGE}
container_name: rebuild-n8n
restart: unless-stopped
ports:
- "127.0.0.1:5678:5678"
environment:
TZ: ${TZ}
GENERIC_TIMEZONE: ${GENERIC_TIMEZONE}
N8N_HOST: ${N8N_HOST}
N8N_PORT: 5678
N8N_PROTOCOL: https
WEBHOOK_URL: ${WEBHOOK_URL}
N8N_EDITOR_BASE_URL: ${N8N_EDITOR_BASE_URL}
N8N_PROXY_HOPS: 1
N8N_DEFAULT_LOCALE: zh
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: "true"
N8N_RUNNERS_ENABLED: "true"
volumes:
- /opt/docker/data/n8n:/home/node/.n8n
```
```
N8N_IMAGE=ghcr.io/aliveranme/n8n:2.12.2
N8N_HOST=n8n.excalicode.org
WEBHOOK_URL=https://n8n.excalicode.org/
N8N_EDITOR_BASE_URL=https://n8n.excalicode.org/
TZ=Asia/Shanghai
GENERIC_TIMEZONE=Asia/Shanghai
N8N_ENCRYPTION_KEY=3moa87LB!RMDuf
```
-20
View File
@@ -1,20 +0,0 @@
```
测试云主机信息 172.21.30.23 用户名:root 密码:Melo@3023
测试mysql 172.21.33.224 用户名:cosmic_ai 密码:Cosmic@3306
测试redis: 172.21.43.68:6379 密码:chRdw@redis
1.DeepSeek-671B http://36.137.208.165:5020/v1/chat/completions
2.Qwen3-8B http://172.21.9.104:31554/v1/chat/completions
redis-cli -h 127.0.0.1 -p 6379 -a '5sTb7fHFbsYl6KmI6pvC^XMw!7Y^Pbc1'
```
| 项目 | 配置 |
| --- | ------------------ |
| 系统 | Anolis OS 8.6 |
| 内核 | 4.18 |
| CPU | Intel Xeon Skylake |
| 核心 | **8 vCPU** |
| 主频 | 2.2 GHz |
| 虚拟化 | KVM |
| 架构 | x86_64 |
+44
View File
@@ -0,0 +1,44 @@
```
http://dev.p.cdn.10086.cn:8080
/statistics/getHitRatio
?cpId=*
&product=*
&affectAreas=
&domainNames=
&provider=*
&startTime=2026-03-27%2010:25
&endTime=2026-03-27%2010:25
&productId=
&isps=
&granular=0
&_=1774580169469
```
com.cmcc.cdn.platform.selfservice.controller.StatisticsController#getHitRatio
给我梳理下这个接口的功能,输出一个 markdown 文档到项目的根目录。
主要是用到哪些参数,有哪些校验,有没有参数转换和默认值。掉了哪些三方接口,调了接口后做了哪些事情。尽量清晰。注意细节。
---
com.cmcc.cdn.platform.selfservice.controller.StatisticsController#getHitRatio
getHitRatio接口分析.md 是我 getHitRatio 命中率接口的梳理,是在跑的业务。我现在给你安排一个艰巨的任务。
因为我们有一个 MCP 注册中心。我要接入进去。接入我们只需要提供标准的 http 接口就行了。所以按照这个接口做 3 个新接口出来:
1. 请求数
2. 命中请求数
3. 计算命中率(命中率 = 命中请求数 / 总请求数)的接口。
controller 在 ibs-portal\cdn-web\src\main\java\com\cmcc\cdn\platform 下建一个 mcp 文件夹写。
service 在 ibs-portal\cdn-service\src\main\java\com\cmcc\cdn\platform 下建一个 mcp 文件夹写。
因为是新接口代码一定要标准易读清晰,不要用原来的垃圾逻辑。
再帮我额外提供一个接口。可以实现比如 AI 获取 请求数 然后获取 命中请求数 。然后可以计算他们两个得出命中率的工具接口。方便我测试是调用一次计算命中率比较好,还是调用 请求数 然后调用 命中请求数 然后调用计算工具计算合适。
Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

+7
View File
@@ -0,0 +1,7 @@
<%*
const vaultPath = tp.app.vault.adapter.basePath;
const command = `wt -d "${vaultPath}"`;
const { exec } = require("node:child_process");
exec(command);
return "";
-%>
@@ -0,0 +1,11 @@
<%*
const name = tp.date.now("YYYY-MM-DD_HH-mm-ss");
await tp.file.rename(name);
setTimeout(() => {
const editor = app.workspace.activeEditor?.editor;
if (editor) {
editor.setCursor(0, 0);
editor.focus();
}
}, 150);
-%>
-1
View File
@@ -1 +0,0 @@
<% tp.file.cursor() %>
@@ -1,4 +1,7 @@
# 需求1 <%*
await tp.file.rename("开发笔记");
-%>
# 需求 1
## 需求评审 ## 需求评审
@@ -12,7 +15,7 @@
# 需求2 # 需求 2
## 需求评审 ## 需求评审
@@ -1,3 +1,10 @@
<%*
const monthDay = tp.date.now("MMDD");
const name = await tp.system.prompt("笔记名称", "");
if (name) {
await tp.file.rename(monthDay + "-" + name);
}
-%>
--- ---
日期: <% tp.date.now("YYYY-MM-DD HH:mm") %> 日期: <% tp.date.now("YYYY-MM-DD HH:mm") %>
来源: 来源:
+2
View File
@@ -11,7 +11,9 @@
寅杰说需要配管反向提交资料,确认下提交什么。 寅杰说需要配管反向提交资料,确认下提交什么。
3.8 系统提示优化 - 信安错误提醒优化(5 天) 3.8 系统提示优化 - 信安错误提醒优化(5 天)
4.1 政企侧用户体验优化(2 天) 4.1 政企侧用户体验优化(2 天)
5.5 试商用客户峰值带宽增加引入省份信息(2 天) 5.5 试商用客户峰值带宽增加引入省份信息(2 天)
# 总结 # 总结
-4
View File
@@ -24,10 +24,6 @@ excalicode-ai 是我之前的一个大项目,其中包含各种模块和功能
11:融合 1 平面 11:融合 1 平面
cli_a9381b92c0b8dbd8
KySVktr83JyJGaQR9GnJDesxLx5z3Gw2
OpenClaw: access not configured. OpenClaw: access not configured.
Your Feishu user id: ou_5c0794859a5a52712cbfb49aaa334b70 Your Feishu user id: ou_5c0794859a5a52712cbfb49aaa334b70
+32 -2
View File
@@ -1,8 +1,38 @@
# 任务 # 任务
- [ ] 开发:参加 IBS 项目晨会,同步昨日问题跟进事项。(李春良 0.5) - [x] 开发:参加 IBS 项目晨会,同步昨日问题跟进事项。(李春良 0.5)
- [ ] 开发:开发 IBS V7.19.0 需求。(新业务平面引入与系统集成实施 50% 李春良 5 - [x] 开发:开发 IBS V7.19.0 需求。(新业务平面引入与系统集成实施 70% 李春良 7
- [x] 客响:周一的信安信息邮件未发送。
# 日志 # 日志
```
[1Panel 2026-03-17 10:07:10 install Log]: =================感谢您的耐心等待,安装已完成==================
[1Panel 2026-03-17 10:07:10 install Log]:
[1Panel 2026-03-17 10:07:10 install Log]: 请使用您的浏览器访问面板:
[1Panel 2026-03-17 10:07:10 install Log]: 外部地址: http://182.255.32.64:22448/e506222c7e
[1Panel 2026-03-17 10:07:10 install Log]: 内部地址: http://192.168.126.129:22448/e506222c7e
[1Panel 2026-03-17 10:07:10 install Log]: 面板用户: fcee1b68c9
[1Panel 2026-03-17 10:07:10 install Log]: 面板密码: 2692d0bd2c
[1Panel 2026-03-17 10:07:10 install Log]:
[1Panel 2026-03-17 10:07:10 install Log]: 官方网站:https://1panel.cn
[1Panel 2026-03-17 10:07:10 install Log]: 项目文档:https://1panel.cn/docs
[1Panel 2026-03-17 10:07:10 install Log]: 代码仓库:https://github.com/1Panel-dev/1Panel
[1Panel 2026-03-17 10:07:10 install Log]: 前往 1Panel 官方论坛获取帮助:https://bbs.fit2cloud.com/c/1p/7
[1Panel 2026-03-17 10:07:10 install Log]:
[1Panel 2026-03-17 10:07:10 install Log]: 如果您使用的是云服务器,请在安全组中打开端口 22448
[1Panel 2026-03-17 10:07:10 install Log]:
[1Panel 2026-03-17 10:07:10 install Log]: 为了您的服务器安全,离开此屏幕后您将无法再次看到您的密码,请记住您的密码。
[1Panel 2026-03-17 10:07:10 install Log]:
[1Panel 2026-03-17 10:07:10 install Log]: ================================================================
```
# 总结 # 总结
```
更新方式也究极无敌简单,你直接把这段话,发给你的Agent就行,无论是Claude code、OpenClaw、OpenCode等等等等:https://github.com/anthropics/skills/tree/main/skills/skill-creator,这个skills更新了,帮我更新到最新版本  
```
调研了 Dify,今天小杨下班比较早。
晚上割接,自己页放开了。
+12
View File
@@ -0,0 +1,12 @@
# 任务
- [x] 开发:参加 IBS 项目晨会,同步昨日问题跟进事项。(李春良 0.5)
- [x] 开发:开发 IBS V7.19.0 需求。(新业务平面引入与系统集成实施 代发完成 李春良 7)
# 日志
# 总结
今天发现了在 Java 枚举类中可以使用 spring context 获取已经注册的 service,并从而实现枚举的业务过滤,从而简化了大部分的代码,是一个很好的技巧
下班时,李虎和我讨论了关于 rag 的实现,能为他的材料提供一些功能。我发现沟通是成长最好的途径,因为在沟通中,你可以知道每个人擅长的和了解的领域进行知识交换,从而发现每个人对从功能上到,就是整个对相同的事情有不同的学习领域、学习方式以及了解程度和多多维度的知识扩展
+23
View File
@@ -0,0 +1,23 @@
# 任务
- [x] 开发:参加 IBS 项目晨会,同步昨日问题跟进事项。(李春良 0.5)
- [x] 开发:自测 IBS V7.19.0 需求。(新业务平面引入与系统集成实施 代发完成 李春良 5)
- [x] 测试:IBS 7.19.0 测试用例评审。(961-570-648 郑子雯 2.5
# 日志
130623200701082153
tianhao123@
---
511725200605244415
wang8023941@
---
# 总结
早晨帮田昊强了四六级。8 点准时拿下。
+14
View File
@@ -0,0 +1,14 @@
# 任务
- [x] 开发:参加 IBS 项目晨会,同步昨日问题跟进事项。(李春良 0.5)
- [x] 开发:自测 IBS V7.19.0 需求。(新业务平面引入与系统集成实施 自测完成 李春良 7)
# 日志
# 总结
最近自己心态变化了一些,这次提测也没那么紧张了。
和志龙走用例。
下班带田宝去剪头发。二月二龙抬头。
+11
View File
@@ -0,0 +1,11 @@
# 任务
# 日志
# 总结
早晨起来收拾了一下屋子,上午去小寨大集吃东西。中午叫张泽过来吃饭。
下午去了全季酒店。
晚上回来带田宝去公园玩儿了会儿。
+17
View File
@@ -0,0 +1,17 @@
# 任务
# 日志
# 总结
今天早晨起来之后,我们打算带田宝去白浮泉公园玩。
我们先去了上次那个有攀爬项目的一侧。发现田宝其实比较胆小,他在看到一些比较危险的东西后,是不会去做任何尝试的。我感觉这其实非常好,对他这个年龄段来说,这种性格能起到很好的保护作用。
后面我们去玩了滑梯。白浮泉这个滑梯有一个很大的问题,就是大人不能快速地上下看护小孩。看到好多老人自己带孩子,在那儿就很无力,因为小朋友从滑梯滑下去后,老人再下去会非常费劲。不过今天在外边吹风感觉很舒服,白浮泉那边的整体环境也要好很多。
中午 12 点左右,我们回家去肯德基吃了一个冰淇淋。田宝吃完饭之后就去睡觉了。
下午起床后,我看了一些 React 的课程,田宝则去公园找他的好朋友瑞瑞和凯凯玩。他们一直疯狂地跑到 7 点钟才回家,吃完饭后明显感觉他今天累坏了。
晚上我跟着 React 课程完成了那个“井字棋”的游戏。我感觉这个 React 课程真的让我眼前一亮,老师经常能预料到学习者会遇到什么问题以及如何去解决,没有站在高位者的姿态去讲课。
+75
View File
@@ -0,0 +1,75 @@
# 任务
- [x] 开发:参加 IBS 项目晨会,同步昨日问题跟进事项。明确外协人员 AI 代码提交规范。(李春良 0.5)
- [x] 开发:支撑 IBS V7.19.0 版本测试。新业务平面引入与系统集成实施。运营管理/统计分析/数据统计,全部的其他五个选项分别选择后查询,可以得出结论数据来源于新增平面(李春良 1)
- [x] 客响:每周一信安信息更新通知未发送。Mail rejected because email has 钓鱼网站2(张鹏豪 3)
- [x] 项目:外协日报通报问题。2026.03.01-2026.03.22 这段时间一直在做 IBS 7.19.0 需求梳理、开发、自测,还有 IBS 智能体方案调研,工作内容连续性比较强。有些内容写得比较像,所以被判定为重复雷同。后面我会按每天实际完成的工作分别写明白,尽量写清当天处理了什么、进展到哪一步,避免再出现类似情况。(张鹏豪 1)
- [x] 项目:IBS 7.19.0 能力引入。NRWLXT-30741 BYOC 接口幂等核心代码能力输出,实现接口调用的稳定性和可重复执行能力。NRWLXT-30742 BYOC 文件管理核心代码能力输出,支持文件上传、下载、存储及访问全流程管理。NRWLXT-30743 BYOC 报表导出核心代码能力输出,实现报表数据高效生成、格式化与导出,支持多种格式和大数据量处理。(李春良 1)
- [x] 项目:BIS 7.19.0 AI 代码。Add NRWLXT-30729 BYAC CSPID-2026-00AQ1M AI 优化 新业务平面引入与系统集成实施。Add NRWLXT-30729 BYRC CLID-00ABRP 代码复用 新业务平面引入与系统集成实施。(李春良 0.5)
- [x] 项目:CDN 智能体技术研讨。关于语义路由是否需要通过 mcp 去决定方向。(张鹏豪 1)
# 日志
[关注点分离](https://zh.wikipedia.org/wiki/%E5%85%B3%E6%B3%A8%E7%82%B9%E5%88%86%E7%A6%BB)
[一次且仅一次](https://zh.wikipedia.org/wiki/%E4%B8%80%E6%AC%A1%E4%B8%94%E4%BB%85%E4%B8%80%E6%AC%A1)
每个需求必须有一次提交。
由于连续多天进行测试,所以出现XX天日报重复的情况
问题:2026-03-01至2026-03-22日存在10条日报异常记录
导向:
```
提醒:外协如有持续一段时间进行相同测试或者开发工作,请通知外协,日报中不要复制黏贴,会造成异常。有重复的工作,请每天展开描述一下,具体的工作内容和进展,降低重复率。如已经造成异常了,请在台账上备案,并确保下不为例
```
表格:
![](../../attachment/images-paste/image-20260323102328859.png)
序号 外协姓名 直属上级 自查问题分类 日报时间 原因说明 附件(截图) 备注
例 张三 李四 格式不规范/缺少归档路径/出现外链/重复雷同 2025.03.01-2025.03.05 由于连续多天进行测试,所以出现XX天日报重复的情况 截图
日报:
2026-03-16 的 归档地址 归档地址问题我写了。根据我的日报给我一份:重复雷同。原因说明。
这段时间一直在做 IBS 7.19.0 需求梳理、开发、自测,还有 IBS 智能体方案调研,工作内容连续性比较强。有些内容写得比较像,所以被判定为重复雷同。后面我会按每天实际完成的工作分别写明白,尽量写清当天处理了什么、进展到哪一步,避免再出现类似情况。
```
Add NRWLXT-30741 BYOC 接口幂等核心代码能力输出,实现接口调用的稳定性和可重复执行能力。
Add NRWLXT-30742 BYOC 文件管理核心代码能力输出,支持文件上传、下载、存储及访问全流程管理。
Add NRWLXT-30743 BYOC 报表导出核心代码能力输出,实现报表数据高效生成、格式化与导出,支持多种格式和大数据量处理。
```
```
Add NRWLXT-30729 BYAC CSPID-2026-00AQ1M AI 优化 新业务平面引入与系统集成实施
CSPID-2026-00AQ1M
Add NRWLXT-30729 BYRC CLID-00ABRP 代码复用 新业务平面引入与系统集成实施
```
```
ps -ef | grep xinan
1983 2025-12-08 18:13:12 root kill -9 25856
1984 2025-12-08 18:13:15 root nohup java -jar xinan-ibs-mock.jar > xinan.log &
```
# 总结
日报有问题。了解了一些概念。
+10
View File
@@ -0,0 +1,10 @@
# 任务
- [x] 开发:参加 IBS 项目晨会,同步昨日问题跟进事项。追踪信安信息邮件问题。(李春良 0.5)
- [x] 开发:支撑 IBS V7.19.0 版本测试。新业务平面引入与系统集成实施。合作服务商 显示问题。(李英浩 1)
# 日志
# 总结
张雪峰去世了。
+33
View File
@@ -0,0 +1,33 @@
# 任务
- [x] 开发:参加 IBS 项目晨会,同步昨日问题跟进事项。(李春良 0.5)
- [x] 开发:支撑 IBS V7.19.0 版本测试。新业务平面引入与系统集成实施。接口确认(郑子雯 1)
- [x] 项目:IBS 智能体调研,简化 MCP 接口逻辑。(张鹏豪 6.5)
# 日志
杭州是满血大概只有 8K。
咋们的蒸馏大概只有 4K。
1. vllm 可以控制请求时间么?
2. 是否开启思考是否可以控制?
3. vllm 启动有哪些可以控制。
deepseek-reasoner
DeepSeek-V3.2
(思考模式)
可以控制是否思考?
| 参数 | 不传默认值 | 传什么 | 作用 | 影响什么 |
| --------------------------- | ----------- | ----------------------------------------------------------------------- | ----------------- | -------------------------------------------------- |
| `--enable-auto-tool-choice` | 默认关闭(False | 传 `--enable-auto-tool-choice` 开启;或显式传 `--no-enable-auto-tool-choice` 关闭 | 允许模型自己决定是否调用工具 | 不开时,模型通常不会主动发起 tool call;开了后,模型可根据问题自动选择 MCP/tool |
| `--tool-call-parser` | 默认无(None) | 传一个解析器名字,比如 `openai``llama3_json``hermes``mistral``qwen3_xml` 等 | 指定如何解析模型输出的工具调用格式 | 不传时,即使模型输出了工具调用内容,也可能无法被正确识别;传错了会导致 tool call 解析失败 |
![](../../attachment/images-paste/image-20260325141838198.png)
# 总结
这两天在自己部署模型。想了解一些模型的概念。
+22
View File
@@ -0,0 +1,22 @@
# 任务
- [x] 开发:参加 IBS 项目晨会,同步昨日问题跟进事项。(李春良 0.5)
- [x] 开发:支撑 IBS V7.19.0 版本测试。新业务平面引入与系统集成实施。确认 2.7查询某域名具体配置信息(基础+高级配置)为什么无法触发平面。(郑子雯 1)
- [x] 客响:直播控制台无法导出。(后台时间过长)(李春良 0.5)
- [x] 前端:企业白名单、cache+二级域名白名单问题。(白寰宇 0.5)
- [x] 项目:IBS 智能体调研讨论,模型功能方向。(田卓 5.5)
# 日志
CoT 思考链
1. 到底是不是想要的。
2. 组件选型。
# 总结
这两天仔细了解了一下模型的安装部署,性能,以及工具调用协议等等。
首先感觉脑子里清晰了很多。
我发现我现在一个毛病,我想过多的了解更多的内容,导致我其实有个很大的问题,我总会挖的过深。然后脑子里积压过多的东西。然后当我瞬间轻松下来脑子里又一股脑的都出来了。笔记工具是我一个巨大的助力和习惯,让我有的追溯。
+46
View File
@@ -0,0 +1,46 @@
# 任务
- [x] 开发:参加 IBS 项目晨会,同步昨日问题跟进事项。(李春良 0.5)
- [x] 项目:内容网络IBS系统研发项目_IBS子项目3月任务清单。(李春良 1.5)
- [x] 开发:MCP统计接口服务实现,请求命中率计算问题。(张鹏豪 6)
# 日志
同步两个我个人的想法你们可以看看
DeepSeek-R1-Distill-Qwen-32B 接口似乎不支持 Tool Calling 和 Function Calling,虽然能靠底座 Qwen 的能力绕过,但接口标准是否一致还需本地验证。现在测试一直是用的官方的 API,别到最后咋们这边不适配就很难受。
128G 卡跑 32B,如果追求效果用 16bit 加大上下文比如顶满 128K ,剩下的显存留给 KV Cache 根本撑不住几个并发;如果为了高并发切到 8bit 量化加 8K 上下文,工具调用能力大概率会直线下降。所以这个资源和模型最好能快些定下来,用自己的资源测试,就会有一些实际的体感。
模型牛,人就轻松;模型弱,调试提示词和工具就要好久好久时间。
总是用官方满血测试就有一种啥啥都好的错觉。
实际效果我不知道,但我感觉涉及工具调用决策等等应该更看模型能力了。
评估具体实现方案,分为四大模块处理:
1. 运营数据
2. 话单
3. CDN集中运管平台接口规范扩展
4. BPM对接接口规范扩展
完成数据统计、实时监控、内容中心、用量查询、统计报表、运营指标导出、业务运维/配置管理、全站加速控制台/统计分析/数据统计、直播控制台/域名管理、冲突域名管理等页面开发。
完成计费对账、自有业务中间话单统计等页面开发。
完成以下接口适配创建/修改加速域名信息、域名配置回调接口(接口方向:CDN集中运维平台->IBS平台)、启用/停用加速域名、查询平面分发的所有加速域名列表、查询加速域名列表(基础配置)、查询某域名具体配置信息(基础+高级配置)、增加/修改域名高级配置、内容预热、内容刷新、内容分发、Url封禁/解禁。
完成以下接口适配IBS通用运维任务创建接口(IBS->BPM)、通用任务状态回传接口(BPM->IBS)、业务适配工单验收反馈接口(BPM->IBS)、业务适配工单阶段反馈接口(BPM->IBS)、域名平面同步接口(BPM->IBS
完成运营数据需求开发自测,具备联调条件
完成话单需求开发自测,具备联调条件
完成CDN集中运管平台接口规范扩展需求开发自测,具备联调条件
完成BPM对接接口规范扩展需求开发自测,具备联调条件
# 总结
早晨思考了一些关于 LLM 性能的问题,更新了 OpenClaw,下午写了两个接口,感觉最近集赞了很多东西没有消化了。
+7
View File
@@ -0,0 +1,7 @@
# 任务
# 日志
# 总结
修脚,下午睡了会儿觉,最近田宝和另一个瑞瑞玩儿的很不错。
+7
View File
@@ -0,0 +1,7 @@
# 任务
# 日志
# 总结
上午去医院。去了昌平线程的国泰,给团团买了一个小金豆子。
+1
View File
@@ -0,0 +1 @@
cosmic ai 工具部署、Dify、割接、Java 枚举问题、李虎 rag、四六级、龙抬头、小寨、张泽、全季、白浮泉、react
+2 -14
View File
@@ -4,11 +4,7 @@
``` ```
https://t.me/tgcnx【Telegram 中文社群】 https://t.me/tgcnx【Telegram 中文社群】
https://t.me/jisou2【极搜大船团】
https://t.me/animation_cn_chat【小乔国产动漫交流】
https://t.me/gmjlq【动漫交流群 Anime Group】 https://t.me/gmjlq【动漫交流群 Anime Group】
https://t.me/IPTV6789【IPTV📺軟件&直播源】
https://t.me/se_talk【SE-索引社群】
https://t.me/pixelexperiencechat_chn【Pixel Experience China】 https://t.me/pixelexperiencechat_chn【Pixel Experience China】
https://t.me/simpreadgroup【简悦 - SimpRead】 https://t.me/simpreadgroup【简悦 - SimpRead】
https://t.me/eryidebiji【二一交流群】 https://t.me/eryidebiji【二一交流群】
@@ -22,8 +18,6 @@ https://t.me/BinanceChinese【币安官方中文群】
https://t.me/OKXGroup_CN【欧易OKX官方中文群】 https://t.me/OKXGroup_CN【欧易OKX官方中文群】
https://t.me/ChinaPumpNow【中国密码鲸公司 WHALE CHINESE 🇨🇳🐳🚀🌖】 https://t.me/ChinaPumpNow【中国密码鲸公司 WHALE CHINESE 🇨🇳🐳🚀🌖】
https://t.me/airdrop_newer【币圈 小白 撸 空投】 https://t.me/airdrop_newer【币圈 小白 撸 空投】
https://t.me/SZ399001【A股🚀股票炒股投资📈】
https://t.me/anyplus【A股@炒股笔记 股票 股市 股吧】
https://t.me/tonkeeper_chinese_chat【Tonkeeper中文频道 Chat】 https://t.me/tonkeeper_chinese_chat【Tonkeeper中文频道 Chat】
https://t.me/InvestSoftGroup【InvestSoft】 https://t.me/InvestSoftGroup【InvestSoft】
``` ```
@@ -33,31 +27,24 @@ https://t.me/InvestSoftGroup【InvestSoft】
``` ```
https://t.me/haitunspeed【🐬海豚测速|公益EMBY|后端招募】 https://t.me/haitunspeed【🐬海豚测速|公益EMBY|后端招募】
https://t.me/ShadowrocketApp【Shadowrocket】 https://t.me/ShadowrocketApp【Shadowrocket】
https://t.me/SURGEPRO【SURGE PRO】
https://t.me/Loon0x00【Loon-0x00】 https://t.me/Loon0x00【Loon-0x00】
https://t.me/projectXray【Project X】 https://t.me/projectXray【Project X】
https://t.me/jichang_user【机场交流群|吃瓜群众】
https://t.me/v2rayN【v2rayN&G】 https://t.me/v2rayN【v2rayN&G】
https://t.me/Clashclient【Clash 交流群】 https://t.me/Clashclient【Clash 交流群】
https://t.me/qichiyuchat【七尺宇交流群】
https://t.me/airport_chat【离港[̲̅V̲̅I̲̅P̅]候机室|机场交流🅥】 https://t.me/airport_chat【离港[̲̅V̲̅I̲̅P̅]候机室|机场交流🅥】
https://t.me/qichiyu_bot【七尺宇私聊】
``` ```
## 技术 ## 技术
``` ```
https://t.me/gekugou2【iOS破解软件交流】 https://t.me/gekugou2【iOS破解软件交流】
https://t.me/gpt_user【ChatGPT AI】
https://t.me/BotTalk【Telegram Bot Talk】 https://t.me/BotTalk【Telegram Bot Talk】
https://t.me/JavaBotsApi【Telegram Bots】 https://t.me/JavaBotsApi【Telegram Bots】
https://t.me/linux_home【Linux窝】
``` ```
## 业务 ## 业务
``` ```
https://t.me/SVIP334179【开户 话费 电费 油卡 Q币 E卡7折优惠 赚钱项目】
https://t.me/hezu1【[合租社群]Netflix|YouTube|Spotify |office365|Hbo|Surge|美剧|等音乐影视聊天机场电影盒子软路由】 https://t.me/hezu1【[合租社群]Netflix|YouTube|Spotify |office365|Hbo|Surge|美剧|等音乐影视聊天机场电影盒子软路由】
https://t.me/voicebygoogle【Google Voice 中文群】 https://t.me/voicebygoogle【Google Voice 中文群】
``` ```
@@ -66,7 +53,6 @@ https://t.me/voicebygoogle【Google Voice 中文群】
``` ```
https://t.me/Deno333【Denis D】备注:mt4 插件。 https://t.me/Deno333【Denis D】备注:mt4 插件。
https://t.me/ycmjdev【KennelGPT 拼车】
https://t.me/xinchent【似水流年】 https://t.me/xinchent【似水流年】
https://t.me/Cococeo【奇迹】 https://t.me/Cococeo【奇迹】
``` ```
@@ -74,11 +60,13 @@ https://t.me/Cococeo【奇迹】
## 机器人 ## 机器人
``` ```
https://t.me/jisou【极搜🔍资源搜索@JISOU
https://t.me/OkayPayBot【Okpay💰】 https://t.me/OkayPayBot【Okpay💰】
https://t.me/freenodeshare_bot【免费节点自动分享】 https://t.me/freenodeshare_bot【免费节点自动分享】
https://t.me/SpamBot【Spam Info Bot】 https://t.me/SpamBot【Spam Info Bot】
https://t.me/aaooVbot【退押中·Kvmidc海外服务器🧑‍💻负责人】 https://t.me/aaooVbot【退押中·Kvmidc海外服务器🧑‍💻负责人】
https://t.me/dmssrobot【动漫搜索 Bot】 https://t.me/dmssrobot【动漫搜索 Bot】
https://t.me/qichiyu_bot【七尺宇私聊】
``` ```
# Google Voice 选购清单 # Google Voice 选购清单
+81 -95
View File
@@ -4,6 +4,8 @@
# 1Panel【域名】 # 1Panel【域名】
## 1)安装面板
[1Panel 服务器运维管理面板](https://1panel.cn/) [1Panel 服务器运维管理面板](https://1panel.cn/)
``` ```
@@ -13,106 +15,44 @@
面板密码: 6cd500f202 面板密码: 6cd500f202
``` ```
Cloudflare DNS 账户 ## 2)申请面板证书
DNS 账户 Cloudflare
``` ```
MPLkv5dlbyKh_q0DdvH5ECxaUHVr5BVg0Ogf5AOH MPLkv5dlbyKh_q0DdvH5ECxaUHVr5BVg0Ogf5AOH
``` ```
为 1panel.excalicode.org 申请证书
## 3)面板设置
1. 面板设置 - 安全 里关掉安全入口,对绑定域名后用域名访问面板友好
2. 面板设置 - 安全 里 开启面板 SSL
3. 在系统 - SSH 管理修改链接端口、关闭密码认证、开启密钥认证、授权密钥
4. 配置终端,方便后续操作
```
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBfW4LWZ/HxIHdQcT+bnUUa5Tqbbag5otkv+y6OkDa9I
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP87fXzm4HSwkS3XaJHGTsEeiu4o9lLlu+ZEwHGuSbzS github-actions
```
## 4CF 设置
1. cloudflare DNS 添加记录 1. cloudflare DNS 添加记录
2. 在 面板设置 - 安全 里关掉安全入口,对绑定域名后用域名访问面板友好 2. 在 Cloudflare 中先设定好 Origin Rules 以准备将面板域名请求自动重写到 1Panel 端口,目标端口: 选择 重写到 面板端口号
3. 为 1panel.excalicode.org 申请证书
4. 在 Cloudflare 中先设定好 Origin Rules 以准备将面板域名请求自动重写到 1Panel 端口,目标端口: 选择 重写到 面板端口号
5. 在 1Panel 设置 SSL、绑定域名
6. 在面板中设置 ssh 管理,增加安全性
一些建议设置 CF 小技巧:
``` 1. 在 Cloudflare 的侧栏点击 SSL/TLS,选择**完全(严格)**
在 Cloudflare 中将 SSL/TLS 加密模式改为完全(严格),并修改一些其他设置 2. 在侧栏点击**边缘证书**,开启下列选项:
在 Cloudflare 的侧栏点击 SSL/TLS - 始终使用 HTTPS
选择 完全(严格) - 随机加密
在侧栏点击 边缘证书 - TLS 1.3
开启下列选项 - 自动 HTTPS 重写
始终使用 HTTPS - 证书透明度监视
随机加密
TLS 1.3
自动 HTTPS 重写
证书透明度监视
```
--- ## 5)安装 Openresty
# OpenClaw【域名】
```
r5hzczwdpd2bin2zxapbnqjmwdjny2kz
mq7swt5pxdhhz6mmryz28n3ytgma83fb
18789
18790
http://82.158.226.4:18789?token=r5hzczwdpd2bin2zxapbnqjmwdjny2kz
https://openclaw.excalicode.org?token=mq7swt5pxdhhz6mmryz28n3ytgma83fb
```
# Openresty
# MySQL
```
root
ykz2WKZ@vke6rmk*req
端口 13306
```
# Redis
```
jgw5wpe!HVB@vem2wmp
端口 16379
```
# Gitea
```
数据库 gitea
数据库用户 gitea
数据库密码 ykz2WKZ@vke6rmk*req
HTTP 端口 3000
SSH 端口 222
```
# PostgreSQL
```
user_kJd5rr
uPN2gbSgWI5yb5
端口 15432
```
# sonarqube
```
http://82.158.226.4:19000
数据库名 sonarqube
数据库用户 sonarqube
数据库用户密码 8hIu5ys14x7mbT
端口 19000
登录用户
admin
WhrNNu*Lcd5&2h
```
---
# Sub-Store【域名】 # Sub-Store【域名】
@@ -129,19 +69,65 @@ services:
SUB_STORE_BACKEND_API_HOST: 127.0.0.1 SUB_STORE_BACKEND_API_HOST: 127.0.0.1
SUB_STORE_BACKEND_API_PORT: 3001 SUB_STORE_BACKEND_API_PORT: 3001
SUB_STORE_BACKEND_MERGE: true SUB_STORE_BACKEND_MERGE: true
SUB_STORE_FRONTEND_BACKEND_PATH: /PVM!xwm7hkz4hek2xjy SUB_STORE_FRONTEND_BACKEND_PATH: /AZmFbXAp9Tyhws
PORT: 9876 PORT: 9876
HOST: 127.0.0.1 HOST: 127.0.0.1
volumes: volumes:
- /opt/docker/data/sub-store:/opt/app/data - sub-store-data:/opt/app/data
volumes:
sub-store-data:
``` ```
在 Openresty 中反向代理 3001 申请证书并在 Openresty 中反向代理 3001
访问地址 访问地址
``` ```
https://sub-store.excalicode.org?api=https://sub-store.excalicode.org/PVM!xwm7hkz4hek2xjy https://sub-store.excalicode.org?api=https://sub-store.excalicode.org/AZmFbXAp9Tyhws
```
# OpenClaw【域名】
```
r5hzczwdpd2bin2zxapbnqjmwdjny2kz
mq7swt5pxdhhz6mmryz28n3ytgma83fb
18789
18790
http://82.158.226.4:18789?token=r5hzczwdpd2bin2zxapbnqjmwdjny2kz
https://openclaw.excalicode.org?token=mq7swt5pxdhhz6mmryz28n3ytgma83fb
```
# MySQL
```
root
ykz2WKZ@vke6rmk*req
13306
```
# Redis
```
jgw5wpe!HVB@vem2wmp
16379
```
# Gitea
```
数据库 gitea
数据库用户 gitea
数据库密码 ykz2WKZ@vke6rmk*req
HTTP 端口 3000
SSH 端口 222
``` ```
# s-ui # s-ui
@@ -63,3 +63,5 @@
5、建立客户跟进记录管理体系,支持对跟进情况的记录、查询、修改和删除。 5、建立客户跟进记录管理体系,支持对跟进情况的记录、查询、修改和删除。
6、建立自动化的预警机制,支持预警规则的自定义配置,支持查询、修改、删除预警规则,并能定时生成预警提醒,防范业务风险。 6、建立自动化的预警机制,支持预警规则的自定义配置,支持查询、修改、删除预警规则,并能定时生成预警提醒,防范业务风险。
帮我看下现在 spring ai 底层的重试机制是怎么样的?会重试多少次?我怎么看到过 30 多次的日志。
@@ -0,0 +1,43 @@
硬件:NVIDIA A800 80GB GPU30GB 系统盘 和 100GB 数据盘 (`/root/autodl-tmp`)。
> **19.5 TFLOPS** = 普通生产线能力
> **312 Tensor TFLOPS** = AI 专用流水线能力
模型:deepseek-ai/DeepSeek-R1-Distill-Qwen-32B
> Tensor type BF16
> Tensor type(张量类型)通常指 PyTorch 或 TensorFlow 等框架中,用于表示多维数组的数据对象。通俗理解模型内部数字是用什么“数据格式”来存的。
> 33B × 2 字节 ≈ 66GB
服务器启动日志
```
+-----------------------------------------------AutoDL-----------------------------------------------------+
目录说明:
╔═════════════════╦════════╦════╦═════════════════════════════════════════════════════════════════════════╗
║目录 ║名称 ║速度║说明 ║
╠═════════════════╬════════╬════╬═════════════════════════════════════════════════════════════════════════╣
║/ ║系 统 盘║一般║实例关机数据不会丢失,可存放代码等。会随保存镜像一起保存。 ║
║/root/autodl-tmp ║数 据 盘║ 快 ║实例关机数据不会丢失,可存放读写IO要求高的数据。但不会随保存镜像一起保存 ║
╚═════════════════╩════════╩════╩═════════════════════════════════════════════════════════════════════════╝
CPU 14 核心
内存:120 GB
GPU NVIDIA A800 80GB PCIe, 1
存储:
系 统 盘/ 1% 53M/30G
数 据 盘/root/autodl-tmp1% 12K/100G
+----------------------------------------------------------------------------------------------------------+
*注意:
1.系统盘较小请将大的数据存放于数据盘或文件存储中,重置系统时数据盘和文件存储中的数据不受影响
2.清理系统盘请参考:https://www.autodl.com/docs/qa1/
3.终端中长期执行命令请使用screen等工具开后台运行,确保程序不受SSH连接中断影响:https://www.autodl.com/docs/daemon/
```
显卡检测
```
root@autodl-container-c6d54aa471-4479d4d0:~# python -c "import torch; print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0))"
True
NVIDIA A800 80GB PCIe
```
@@ -0,0 +1,172 @@
# 第一步:准备环境与配置下载源
`DeepSeek-R1-Distill-Qwen-32B` 的模型权重(BF16/FP16精度)大约需要占用 **64GB 的磁盘空间****约 65GB 的显存**
**A800 80GB 显存完美支持该模型单卡运行**,但**系统盘(30GB)空间不足**,因此将模型下载到数据盘(`/root/autodl-tmp`)中。
通过国内镜像站下载,并**强制将缓存路径设置在数据盘**,防止系统盘撑爆导致实例死机。
在终端中依次执行以下命令:
```bash
# 1. 进入数据盘目录
cd /root/autodl-tmp
# 2. 必须:设置 Hugging Face 缓存目录到数据盘
export HF_HOME=/root/autodl-tmp/hf_cache
# 3. 设置 Hugging Face 国内镜像加速下载
export HF_ENDPOINT=https://hf-mirror.com
# 4. 安装 huggingface-cli 及加速传输依赖
pip install -U huggingface_hub hf_transfer
如果遇到风险
pip install -U huggingface_hub hf_transfer --break-system-packages
export HF_HUB_ENABLE_HF_TRANSFER=1
```
# 第二步:下载模型
**方式一**
使用 `huggingface-cli` 将模型直接下载到数据盘的指定文件夹中。下载大概需要十几到几十分钟(约 64 GB)。
```bash
hf download deepseek-ai/DeepSeek-R1-Distill-Qwen-32B --local-dir /root/autodl-tmp/DeepSeek-R1-32B
hf download deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B --local-dir /root/autodl-tmp/DeepSeek-R1-1.5B
hf download deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B --local-dir /root/autodl-tmp/DeepSeek-R1-Distill-Qwen-7B
```
**方式二**
```bash
python - <<'PY'
import os
from huggingface_hub import snapshot_download
os.environ["HF_ENDPOINT"] = "https://hf-mirror.com"
os.environ["HF_HOME"] = "/root/autodl-tmp/hf_cache"
os.environ["HF_HUB_ENABLE_HF_TRANSFER"] = "1"
print("⏳ 开始下载模型...")
path = snapshot_download(
repo_id="deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B",
local_dir="/root/autodl-tmp/DeepSeek-R1-1.5B",
)
print("✅ 下载完成,模型目录:", path)
PY
```
# 第三步:安装并启动 vLLM 推理框架
**1. 安装 vLLM**
```bash
pip install vllm
```
**2. 开启后台运行:**
使用 `screen` 创建一个叫 `vllm_server` 的后台窗口:
```bash
创建
screen -U -S vLLM
列表
screen -U -ls
重新进入
screen -U -r 89505.vllm_server
退出
screen -U -S 7394 -X quit
离开
Ctrl-a d
```
**3. 启动类似 OpenAI 的 API 服务:**
注意:我们将端口设为 `6006`,这是 AutoDL 官方支持对外暴露的默认端口
前台
```bash
python -m vllm.entrypoints.openai.api_server \
--model /root/autodl-tmp/DeepSeek-R1-Distill-Qwen-7B \
--served-model-name deepseek-r1 \
--tensor-parallel-size 1 \
--max-model-len 131072 \
--gpu-memory-utilization 0.95 \
--reasoning-parser deepseek_r1 \
--tool-call-parser qwen3_xml \
--enable-auto-tool-choice \
--port 6006
```
后台
```bash
deepseek-ai/DeepSeek-R1-Distill-Qwen-7B
screen -U -L -Logfile /root/vllm_server.log -dmS vllm_server bash -c 'python -m vllm.entrypoints.openai.api_server \
--model /root/autodl-tmp/DeepSeek-R1-32B \
--served-model-name deepseek-r1 \
--tensor-parallel-size 1 \
--max-model-len 8192 \
--gpu-memory-utilization 0.95 \
--port 6006'
screen -U -L -Logfile /root/vllm_server.log -dmS vllm_server bash -c 'python -m vllm.entrypoints.openai.api_server \
--model /root/autodl-tmp/DeepSeek-R1-1.5B \
--served-model-name deepseek-r1 \
--tensor-parallel-size 1 \
--max-model-len 131072 \
--gpu-memory-utilization 0.95 \
--port 6006'
screen -U -L -Logfile /root/vllm_server.log -dmS vllm_server bash -c 'python -m vllm.entrypoints.openai.api_server \
--model /root/autodl-tmp/DeepSeek-R1-Distill-Qwen-7B \
--served-model-name deepseek-r1 \
--tensor-parallel-size 1 \
--max-model-len 131072 \
--gpu-memory-utilization 0.95 \
--port 6006'
```
```
可以决定
--reasoning-parser deepseek_r1
```
**参数解释:**
- `--max-model-len 8192`:限制最大上下文为 8K token(因为模型本身 64GA800 剩约 15G 显存留给 KV Cache,8K 是比较安全且不会 OOM 的长度)。
- `--gpu-memory-utilization 0.95`:允许 vLLM 使用 95% 的显存。
- `--served-model-name`:客户端调用时填写的模型名称。
等待终端显示 `Uvicorn running on http://0.0.0.0:6006` 字样,即代表部署成功。
# 第四步:测试调用 (与 OpenAI API 完全兼容)
您可以在同一个实例新开一个终端,或者直接在当前终端输入以下命令进行测试:
```bash
curl http://localhost:6006/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-r1",
"messages":[
{"role": "system", "content": "你是一个有用的AI助手。"},
{"role": "user", "content": "请用Python写一个快速排序算法。"}
],
"max_tokens": 1024,
"temperature": 0.6
}'
```
@@ -0,0 +1,883 @@
## 安装命令
如何实现离线安装:
```
pip install vllm
pip download -d /tmp/vllm_pkgs vllm
```
```bash
root@autodl-container-c6d54aa471-4479d4d0:~# pip show vllm
Name: vllm
Version: 0.18.0
Summary: A high-throughput and memory-efficient inference and serving engine for LLMs
Home-page:
Author: vLLM Team
Author-email:
License:
Location: /root/miniconda3/lib/python3.12/site-packages
Requires: aiohttp, anthropic, blake3, cachetools, cbor2, cloudpickle, compressed-tensors, depyf, diskcache, einops, fastapi, filelock, flashinfer-python, gguf, ijson, lark, llguidance, lm-format-enforcer, mcp, mistral_common, model-hosting-container-standards, msgspec, ninja, numba, numpy, nvidia-cudnn-frontend, nvidia-cutlass-dsl, openai, openai-harmony, opencv-python-headless, opentelemetry-api, opentelemetry-exporter-otlp, opentelemetry-sdk, opentelemetry-semantic-conventions-ai, outlines_core, partial-json-parser, pillow, prometheus-fastapi-instrumentator, prometheus_client, protobuf, psutil, py-cpuinfo, pybase64, pydantic, python-json-logger, pyyaml, pyzmq, quack-kernels, regex, requests, sentencepiece, setproctitle, setuptools, six, tiktoken, tokenizers, torch, torchaudio, torchvision, tqdm, transformers, typing_extensions, watchfiles, xgrammar
Required-by:
```
一些建议:
```bash
conda create -n vllm python=3.12 -y
conda activate vllm
pip install vllm
```
## 安装日志
```
root@autodl-container-c6d54aa471-4479d4d0:~/autodl-tmp# pip install vllm
Looking in indexes: http://mirrors.aliyun.com/pypi/simple
Collecting vllm
Downloading http://mirrors.aliyun.com/pypi/packages/4f/e9/59cf9b8939b51e859d2166ac3336b353f52ec4f9ceda34228aae7b386840/vllm-0.18.0-cp38-abi3-manylinux_2_31_x86_64.whl (433.2 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 433.2/433.2 MB 7.0 MB/s eta 0:00:00
Collecting regex (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/9e/40/bb226f203caa22c1043c1ca79b36340156eca0f6a6742b46c3bb222a3a57/regex-2026.2.28-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (802 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 802.0/802.0 kB 13.3 MB/s eta 0:00:00
Collecting cachetools (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/06/f3/39cf3367b8107baa44f861dc802cbf16263c945b62d8265d36034fc07bea/cachetools-7.0.5-py3-none-any.whl (13 kB)
Requirement already satisfied: psutil in /root/miniconda3/lib/python3.12/site-packages (from vllm) (7.0.0)
Collecting sentencepiece (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/04/88/14f2f4a2b922d8b39be45bf63d79e6cd3a9b2f248b2fcb98a69b12af12f5/sentencepiece-0.2.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (1.4 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 11.1 MB/s eta 0:00:00
Requirement already satisfied: numpy in /root/miniconda3/lib/python3.12/site-packages (from vllm) (2.3.2)
Requirement already satisfied: requests>=2.26.0 in /root/miniconda3/lib/python3.12/site-packages (from vllm) (2.31.0)
Requirement already satisfied: tqdm in /root/miniconda3/lib/python3.12/site-packages (from vllm) (4.66.2)
Collecting blake3 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/5b/94/eafaa5cdddadc0c9c603a6a6d8339433475e1a9f60c8bb9c2eed2d8736b6/blake3-1.0.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (388 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 388.0/388.0 kB 30.7 MB/s eta 0:00:00
Collecting py-cpuinfo (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/e0/a9/023730ba63db1e494a271cb018dcd361bd2c917ba7004c3e49d5daf795a2/py_cpuinfo-9.0.0-py3-none-any.whl (22 kB)
Collecting transformers<5,>=4.56.0 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/03/b8/e484ef633af3887baeeb4b6ad12743363af7cce68ae51e938e00aaa0529d/transformers-4.57.6-py3-none-any.whl (12.0 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.0/12.0 MB 9.5 MB/s eta 0:00:00
Collecting tokenizers>=0.21.1 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/2e/76/932be4b50ef6ccedf9d3c6639b056a967a86258c6d9200643f01269211ca/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.3 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.3/3.3 MB 10.6 MB/s eta 0:00:00
Collecting protobuf!=6.30.*,!=6.31.*,!=6.32.*,!=6.33.0.*,!=6.33.1.*,!=6.33.2.*,!=6.33.3.*,!=6.33.4.*,>=5.29.6 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/53/1b/3b431694a4dc6d37b9f653f0c64b0a0d9ec074ee810710c0c3da21d67ba7/protobuf-7.34.1-cp310-abi3-manylinux2014_x86_64.whl (324 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 324.3/324.3 kB 32.1 MB/s eta 0:00:00
Collecting fastapi>=0.115.0 (from fastapi[standard]>=0.115.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/8f/ea/18f6d0457f9efb2fc6fa594857f92810cadb03024975726db6546b3d6fcf/fastapi-0.135.2-py3-none-any.whl (117 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 117.4/117.4 kB 31.5 MB/s eta 0:00:00
Collecting aiohttp>=3.13.3 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/86/f6/a62cbbf13f0ac80a70f71b1672feba90fdb21fd7abd8dbf25c0105fb6fa3/aiohttp-3.13.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (1.8 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.8/1.8 MB 11.9 MB/s eta 0:00:00
Collecting openai<2.25.0,>=1.99.1 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/c9/30/844dc675ee6902579b8eef01ed23917cc9319a1c9c0c14ec6e39340c96d0/openai-2.24.0-py3-none-any.whl (1.1 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.1/1.1 MB 6.8 MB/s eta 0:00:00
Collecting pydantic>=2.12.0 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl (463 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 463.6/463.6 kB 12.2 MB/s eta 0:00:00
Requirement already satisfied: prometheus_client>=0.18.0 in /root/miniconda3/lib/python3.12/site-packages (from vllm) (0.22.1)
Requirement already satisfied: pillow in /root/miniconda3/lib/python3.12/site-packages (from vllm) (11.3.0)
Collecting prometheus-fastapi-instrumentator>=7.0.0 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/27/72/0824c18f3bc75810f55dacc2dd933f6ec829771180245ae3cc976195dec0/prometheus_fastapi_instrumentator-7.1.0-py3-none-any.whl (19 kB)
Collecting tiktoken>=0.6.0 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/f4/90/3dae6cc5436137ebd38944d396b5849e167896fc2073da643a49f372dc4f/tiktoken-0.12.0-cp312-cp312-manylinux_2_28_x86_64.whl (1.2 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.2/1.2 MB 14.4 MB/s eta 0:00:00
Collecting lm-format-enforcer==0.11.3 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/a0/ef/11292bb0b85cf4c93447cab5a29f64576ed14d3ab4280e35ddd23486594a/lm_format_enforcer-0.11.3-py3-none-any.whl (45 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 45.4/45.4 kB 21.0 MB/s eta 0:00:00
Collecting llguidance<1.4.0,>=1.3.0 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/83/a8/1ff2bedb8f9acb46a2d2d603415d272bb622c142ea86f5b95445cc6e366c/llguidance-1.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.0 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.0/3.0 MB 11.0 MB/s eta 0:00:00
Collecting outlines_core==0.2.11 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/92/c7/a65d1fddf49830ebc41422294eacde35286d9f68994a8aa905cb14f5aade/outlines_core-0.2.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.3 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.3/2.3 MB 12.9 MB/s eta 0:00:00
Collecting diskcache==5.6.3 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/3f/27/4570e78fc0bf5ea0ca45eb1de3818a23787af9b390c0b0a0033a1b8236f9/diskcache-5.6.3-py3-none-any.whl (45 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 45.5/45.5 kB 16.4 MB/s eta 0:00:00
Requirement already satisfied: lark==1.2.2 in /root/miniconda3/lib/python3.12/site-packages (from vllm) (1.2.2)
Collecting xgrammar<1.0.0,>=0.1.32 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/69/62/65e664d861cdadf2d788c03dd8fe67f1faaa7bd4bd2317a2ab850aebee20/xgrammar-0.1.32-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (37.7 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 37.7/37.7 MB 11.5 MB/s eta 0:00:00
Requirement already satisfied: typing_extensions>=4.10 in /root/miniconda3/lib/python3.12/site-packages (from vllm) (4.14.1)
Requirement already satisfied: filelock>=3.16.1 in /root/miniconda3/lib/python3.12/site-packages (from vllm) (3.18.0)
Collecting partial-json-parser (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/42/32/658973117bf0fd82a24abbfb94fe73a5e86216e49342985e10acce54775a/partial_json_parser-0.2.1.1.post7-py3-none-any.whl (10 kB)
Requirement already satisfied: pyzmq>=25.0.0 in /root/miniconda3/lib/python3.12/site-packages (from vllm) (27.0.1)
Collecting msgspec (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/5c/a2/488517a43ccf5a4b6b6eca6dd4ede0bd82b043d1539dd6bb908a19f8efd3/msgspec-0.20.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (224 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 224.9/224.9 kB 44.8 MB/s eta 0:00:00
Collecting gguf>=0.17.0 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/5e/0c/e0f1eae7535a97476fb903f65301e35da2a66182b8161066b7eb312b2cb8/gguf-0.18.0-py3-none-any.whl (114 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 114.2/114.2 kB 45.5 MB/s eta 0:00:00
Collecting mistral_common>=1.10.0 (from mistral_common[image]>=1.10.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/87/c6/1429a0a3ab40f8530492b62b52eb792266c261b22ed62aa7f25d61d531ae/mistral_common-1.10.0-py3-none-any.whl (6.5 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6.5/6.5 MB 9.6 MB/s eta 0:00:00
Collecting opencv-python-headless>=4.13.0 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/4b/33/b5db29a6c00eb8f50708110d8d453747ca125c8b805bc437b289dbdcc057/opencv_python_headless-4.13.0.92-cp37-abi3-manylinux_2_28_x86_64.whl (60.4 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 60.4/60.4 MB 10.7 MB/s eta 0:00:00
Requirement already satisfied: pyyaml in /root/miniconda3/lib/python3.12/site-packages (from vllm) (6.0.2)
Requirement already satisfied: six>=1.16.0 in /root/miniconda3/lib/python3.12/site-packages (from vllm) (1.17.0)
Collecting setuptools<81.0.0,>=77.0.3 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/94/b8/f1f62a5e3c0ad2ff1d189590bfa4c46b4f3b6e49cef6f26c6ee4e575394d/setuptools-80.10.2-py3-none-any.whl (1.1 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.1/1.1 MB 14.2 MB/s eta 0:00:00
Collecting einops (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/2a/09/f8d8f8f31e4483c10a906437b4ce31bdf3d6d417b73fe33f1a8b59e34228/einops-0.8.2-py3-none-any.whl (65 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 65.6/65.6 kB 26.7 MB/s eta 0:00:00
Collecting compressed-tensors==0.13.0 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/0b/b5/61ac2563c62490922b603c09113a083fd74af3630ec3931e769484d6dcb5/compressed_tensors-0.13.0-py3-none-any.whl (192 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 192.6/192.6 kB 42.8 MB/s eta 0:00:00
Collecting depyf==0.20.0 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/cf/65/4df6936130b56e1429114e663e7c1576cf845f3aef1b2dd200c0a5d19dba/depyf-0.20.0-py3-none-any.whl (39 kB)
Collecting cloudpickle (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl (22 kB)
Collecting watchfiles (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/cf/68/5707da262a119fb06fbe214d82dd1fe4a6f4af32d2d14de368d0349eb52a/watchfiles-1.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (456 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 456.8/456.8 kB 40.0 MB/s eta 0:00:00
Requirement already satisfied: python-json-logger in /root/miniconda3/lib/python3.12/site-packages (from vllm) (3.3.0)
Collecting ninja (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (180 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 180.7/180.7 kB 39.5 MB/s eta 0:00:00
Collecting pybase64 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/62/f7/965b79ff391ad208b50e412b5d3205ccce372a2d27b7218ae86d5295b105/pybase64-1.4.3-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl (71 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 71.6/71.6 kB 36.8 MB/s eta 0:00:00
Collecting cbor2 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/db/9d/7ede2cc42f9bb4260492e7d29d2aab781eacbbcfb09d983de1e695077199/cbor2-5.9.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (288 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 288.2/288.2 kB 19.8 MB/s eta 0:00:00
Collecting ijson (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/6d/81/2fee58f9024a3449aee83edfa7167fb5ccd7e1af2557300e28531bb68e16/ijson-3.5.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (149 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 149.7/149.7 kB 28.8 MB/s eta 0:00:00
Collecting setproctitle (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/d0/99/71630546b9395b095f4082be41165d1078204d1696c2d9baade3de3202d0/setproctitle-1.3.7-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (32 kB)
Collecting openai-harmony>=0.0.3 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/25/3f/1a192b93bb47c6b44cd98ba8cc1d3d2a9308f1bb700c3017e6352da11bda/openai_harmony-0.0.8-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.0 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.0/3.0 MB 11.9 MB/s eta 0:00:00
Collecting anthropic>=0.71.0 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/63/5f/67db29c6e5d16c8c9c4652d3efb934d89cb750cad201539141781d8eae14/anthropic-0.86.0-py3-none-any.whl (469 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 469.4/469.4 kB 27.6 MB/s eta 0:00:00
Collecting model-hosting-container-standards<1.0.0,>=0.1.13 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/48/94/052452842d39c562237a70345c57ec213a9db22bd25bba998fd2b32d70a7/model_hosting_container_standards-0.1.14-py3-none-any.whl (121 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 121.4/121.4 kB 32.0 MB/s eta 0:00:00
Collecting mcp (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/fd/d9/eaa1f80170d2b7c5ba23f3b59f766f3a0bb41155fbc32a69adfa1adaaef9/mcp-1.26.0-py3-none-any.whl (233 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 233.6/233.6 kB 28.6 MB/s eta 0:00:00
Collecting opentelemetry-sdk>=1.27.0 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/2c/c5/6a852903d8bfac758c6dc6e9a68b015d3c33f2f1be5e9591e0f4b69c7e0a/opentelemetry_sdk-1.40.0-py3-none-any.whl (141 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 142.0/142.0 kB 32.3 MB/s eta 0:00:00
Collecting opentelemetry-api>=1.27.0 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/5f/bf/93795954016c522008da367da292adceed71cca6ee1717e1d64c83089099/opentelemetry_api-1.40.0-py3-none-any.whl (68 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 68.7/68.7 kB 32.4 MB/s eta 0:00:00
Collecting opentelemetry-exporter-otlp>=1.27.0 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/2d/fc/aea77c28d9f3ffef2fdafdc3f4a235aee4091d262ddabd25882f47ce5c5f/opentelemetry_exporter_otlp-1.40.0-py3-none-any.whl (7.0 kB)
Collecting opentelemetry-semantic-conventions-ai>=0.4.1 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/a7/18/35fec29ed6e49bcbbe629b790cc0deb5bb58da9caceee29b39b54d3d7f47/opentelemetry_semantic_conventions_ai-0.5.0-py3-none-any.whl (10.0 kB)
Collecting numba==0.61.2 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/9a/2d/e518df036feab381c23a624dac47f8445ac55686ec7f11083655eb707da3/numba-0.61.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (3.9 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.9/3.9 MB 10.1 MB/s eta 0:00:00
Collecting torch==2.10.0 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/b3/7a/abada41517ce0011775f0f4eacc79659bc9bc6c361e6bfe6f7052a6b9363/torch-2.10.0-3-cp312-cp312-manylinux_2_28_x86_64.whl (915.6 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 915.6/915.6 MB 4.6 MB/s eta 0:00:00
Collecting torchaudio==2.10.0 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/98/25/e55a30d7138f8fe56ed006df25b0a3c27681f0ec7bc9989e1778e6d559c3/torchaudio-2.10.0-cp312-cp312-manylinux_2_28_x86_64.whl (1.9 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.9/1.9 MB 14.1 MB/s eta 0:00:00
Collecting torchvision==0.25.0 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/68/2f/f24b039169db474e8688f649377de082a965fbf85daf4e46c44412f1d15a/torchvision-0.25.0-cp312-cp312-manylinux_2_28_x86_64.whl (8.1 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.1/8.1 MB 10.9 MB/s eta 0:00:00
Collecting flashinfer-python==0.6.6 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/e0/61/385d06755f3ab66333018285657adf0daf8a90a129448231fd09e315bd2e/flashinfer_python-0.6.6-py3-none-any.whl (7.8 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7.8/7.8 MB 11.1 MB/s eta 0:00:00
Collecting nvidia-cudnn-frontend<1.19.0,>=1.13.0 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/c6/52/08f98262e77b1cbcc834cc1a5db494d0661ea1dbdea58c2e2d51a57fdaca/nvidia_cudnn_frontend-1.18.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (2.2 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.2/2.2 MB 13.7 MB/s eta 0:00:00
Collecting nvidia-cutlass-dsl>=4.4.0.dev1 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/a9/03/678dab0383db1ddfc449da216220f40404189eb36eeed9d87a4fa4bdb0e6/nvidia_cutlass_dsl-4.4.2-py3-none-any.whl (10 kB)
Collecting quack-kernels>=0.2.7 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/45/e6/fb900aa5d6053069c3180382874520e7313362fa03994a034626906e7094/quack_kernels-0.3.5-py3-none-any.whl (195 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 195.7/195.7 kB 28.3 MB/s eta 0:00:00
Collecting loguru (from compressed-tensors==0.13.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl (61 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 61.6/61.6 kB 33.3 MB/s eta 0:00:00
Collecting astor (from depyf==0.20.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/c3/88/97eef84f48fa04fbd6750e62dcceafba6c63c81b7ac1420856c8dcc0a3f9/astor-0.8.1-py2.py3-none-any.whl (27 kB)
Collecting dill (from depyf==0.20.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl (120 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 120.0/120.0 kB 2.4 MB/s eta 0:00:00
Collecting apache-tvm-ffi!=0.1.8,!=0.1.8.post0,<0.2,>=0.1.6 (from flashinfer-python==0.6.6->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/70/ef/5402da5d37f5270fd88ea0348acca78dba9be8bdbf6c2bcae0935eb03ef1/apache_tvm_ffi-0.1.9-cp312-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (2.3 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.3/2.3 MB 10.0 MB/s eta 0:00:00
Requirement already satisfied: click in /root/miniconda3/lib/python3.12/site-packages (from flashinfer-python==0.6.6->vllm) (8.3.1)
Collecting nvidia-ml-py (from flashinfer-python==0.6.6->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/8a/24/fc256107d23597fa33d319505ce77160fa1a2349c096d01901ffc7cb7fc4/nvidia_ml_py-13.595.45-py3-none-any.whl (51 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 51.8/51.8 kB 23.7 MB/s eta 0:00:00
Collecting packaging>=24.2 (from flashinfer-python==0.6.6->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl (74 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 74.4/74.4 kB 32.2 MB/s eta 0:00:00
Collecting tabulate (from flashinfer-python==0.6.6->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl (39 kB)
Collecting interegular>=0.3.2 (from lm-format-enforcer==0.11.3->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/c4/01/72d6472f80651673716d1deda2a5bbb633e563ecf94f4479da5519d69d25/interegular-0.3.3-py37-none-any.whl (23 kB)
Collecting llvmlite<0.45,>=0.44.0dev0 (from numba==0.61.2->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/cb/da/8341fd3056419441286c8e26bf436923021005ece0bff5f41906476ae514/llvmlite-0.44.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (42.4 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 42.4/42.4 MB 9.8 MB/s eta 0:00:00
Collecting numpy (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/8c/3d/1e1db36cfd41f895d266b103df00ca5b3cbe965184df824dec5c08c6b803/numpy-2.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (16.5 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 16.5/16.5 MB 10.4 MB/s eta 0:00:00
Requirement already satisfied: sympy>=1.13.3 in /root/miniconda3/lib/python3.12/site-packages (from torch==2.10.0->vllm) (1.14.0)
Requirement already satisfied: networkx>=2.5.1 in /root/miniconda3/lib/python3.12/site-packages (from torch==2.10.0->vllm) (3.5)
Requirement already satisfied: jinja2 in /root/miniconda3/lib/python3.12/site-packages (from torch==2.10.0->vllm) (3.1.6)
Requirement already satisfied: fsspec>=0.8.5 in /root/miniconda3/lib/python3.12/site-packages (from torch==2.10.0->vllm) (2025.7.0)
Collecting cuda-bindings==12.9.4 (from torch==2.10.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/a9/c1/dabe88f52c3e3760d861401bb994df08f672ec893b8f7592dc91626adcf3/cuda_bindings-12.9.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (12.2 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.2/12.2 MB 10.3 MB/s eta 0:00:00
Requirement already satisfied: nvidia-cuda-nvrtc-cu12==12.8.93 in /root/miniconda3/lib/python3.12/site-packages (from torch==2.10.0->vllm) (12.8.93)
Requirement already satisfied: nvidia-cuda-runtime-cu12==12.8.90 in /root/miniconda3/lib/python3.12/site-packages (from torch==2.10.0->vllm) (12.8.90)
Requirement already satisfied: nvidia-cuda-cupti-cu12==12.8.90 in /root/miniconda3/lib/python3.12/site-packages (from torch==2.10.0->vllm) (12.8.90)
Requirement already satisfied: nvidia-cudnn-cu12==9.10.2.21 in /root/miniconda3/lib/python3.12/site-packages (from torch==2.10.0->vllm) (9.10.2.21)
Requirement already satisfied: nvidia-cublas-cu12==12.8.4.1 in /root/miniconda3/lib/python3.12/site-packages (from torch==2.10.0->vllm) (12.8.4.1)
Requirement already satisfied: nvidia-cufft-cu12==11.3.3.83 in /root/miniconda3/lib/python3.12/site-packages (from torch==2.10.0->vllm) (11.3.3.83)
Requirement already satisfied: nvidia-curand-cu12==10.3.9.90 in /root/miniconda3/lib/python3.12/site-packages (from torch==2.10.0->vllm) (10.3.9.90)
Requirement already satisfied: nvidia-cusolver-cu12==11.7.3.90 in /root/miniconda3/lib/python3.12/site-packages (from torch==2.10.0->vllm) (11.7.3.90)
Requirement already satisfied: nvidia-cusparse-cu12==12.5.8.93 in /root/miniconda3/lib/python3.12/site-packages (from torch==2.10.0->vllm) (12.5.8.93)
Requirement already satisfied: nvidia-cusparselt-cu12==0.7.1 in /root/miniconda3/lib/python3.12/site-packages (from torch==2.10.0->vllm) (0.7.1)
Collecting nvidia-nccl-cu12==2.27.5 (from torch==2.10.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/6e/89/f7a07dc961b60645dbbf42e80f2bc85ade7feb9a491b11a1e973aa00071f/nvidia_nccl_cu12-2.27.5-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (322.3 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 322.3/322.3 MB 7.1 MB/s eta 0:00:00
Collecting nvidia-nvshmem-cu12==3.4.5 (from torch==2.10.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/b5/09/6ea3ea725f82e1e76684f0708bbedd871fc96da89945adeba65c3835a64c/nvidia_nvshmem_cu12-3.4.5-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (139.1 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 139.1/139.1 MB 8.9 MB/s eta 0:00:00
Requirement already satisfied: nvidia-nvtx-cu12==12.8.90 in /root/miniconda3/lib/python3.12/site-packages (from torch==2.10.0->vllm) (12.8.90)
Requirement already satisfied: nvidia-nvjitlink-cu12==12.8.93 in /root/miniconda3/lib/python3.12/site-packages (from torch==2.10.0->vllm) (12.8.93)
Requirement already satisfied: nvidia-cufile-cu12==1.13.1.3 in /root/miniconda3/lib/python3.12/site-packages (from torch==2.10.0->vllm) (1.13.1.3)
Collecting triton==3.6.0 (from torch==2.10.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/ab/a8/cdf8b3e4c98132f965f88c2313a4b493266832ad47fb52f23d14d4f86bb5/triton-3.6.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (188.3 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 188.3/188.3 MB 8.1 MB/s eta 0:00:00
Collecting cuda-pathfinder~=1.1 (from cuda-bindings==12.9.4->torch==2.10.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/c0/66/7b2c3d23dac4bb9629b4d9702f1f796bd41c01142c2b47be6fcfdeaf4ee4/cuda_pathfinder-1.4.4-py3-none-any.whl (48 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 48.8/48.8 kB 18.4 MB/s eta 0:00:00
Collecting aiohappyeyeballs>=2.5.0 (from aiohttp>=3.13.3->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl (15 kB)
Collecting aiosignal>=1.4.0 (from aiohttp>=3.13.3->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl (7.5 kB)
Requirement already satisfied: attrs>=17.3.0 in /root/miniconda3/lib/python3.12/site-packages (from aiohttp>=3.13.3->vllm) (25.3.0)
Collecting frozenlist>=1.1.1 (from aiohttp>=3.13.3->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/6a/bd/d91c5e39f490a49df14320f4e8c80161cfcce09f1e2cde1edd16a551abb3/frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (242 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 242.4/242.4 kB 4.8 MB/s eta 0:00:00
Collecting multidict<7.0,>=4.5 (from aiohttp>=3.13.3->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/f3/8d/5e5be3ced1d12966fefb5c4ea3b2a5b480afcea36406559442c6e31d4a48/multidict-6.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (256 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 256.3/256.3 kB 14.4 MB/s eta 0:00:00
Collecting propcache>=0.2.0 (from aiohttp>=3.13.3->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/46/4b/3aae6835b8e5f44ea6a68348ad90f78134047b503765087be2f9912140ea/propcache-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (221 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 221.6/221.6 kB 17.2 MB/s eta 0:00:00
Collecting yarl<2.0,>=1.17.0 (from aiohttp>=3.13.3->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/66/3e/868e5c3364b6cee19ff3e1a122194fa4ce51def02c61023970442162859e/yarl-1.23.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (100 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100.1/100.1 kB 15.2 MB/s eta 0:00:00
Requirement already satisfied: anyio<5,>=3.5.0 in /root/miniconda3/lib/python3.12/site-packages (from anthropic>=0.71.0->vllm) (4.10.0)
Requirement already satisfied: distro<2,>=1.7.0 in /root/miniconda3/lib/python3.12/site-packages (from anthropic>=0.71.0->vllm) (1.9.0)
Collecting docstring-parser<1,>=0.15 (from anthropic>=0.71.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/55/e2/2537ebcff11c1ee1ff17d8d0b6f4db75873e3b0fb32c2d4a2ee31ecb310a/docstring_parser-0.17.0-py3-none-any.whl (36 kB)
Requirement already satisfied: httpx<1,>=0.25.0 in /root/miniconda3/lib/python3.12/site-packages (from anthropic>=0.71.0->vllm) (0.28.1)
Collecting jiter<1,>=0.4.0 (from anthropic>=0.71.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/f8/4c/09b93e30e984a187bc8aaa3510e1ec8dcbdcd71ca05d2f56aac0492453aa/jiter-0.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (360 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 360.7/360.7 kB 16.4 MB/s eta 0:00:00
Requirement already satisfied: sniffio in /root/miniconda3/lib/python3.12/site-packages (from anthropic>=0.71.0->vllm) (1.3.1)
Collecting starlette>=0.46.0 (from fastapi>=0.115.0->fastapi[standard]>=0.115.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/0b/c9/584bc9651441b4ba60cc4d557d8a547b5aff901af35bda3a4ee30c819b82/starlette-1.0.0-py3-none-any.whl (72 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 72.7/72.7 kB 15.4 MB/s eta 0:00:00
Collecting typing-inspection>=0.4.2 (from fastapi>=0.115.0->fastapi[standard]>=0.115.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl (14 kB)
Requirement already satisfied: annotated-doc>=0.0.2 in /root/miniconda3/lib/python3.12/site-packages (from fastapi>=0.115.0->fastapi[standard]>=0.115.0->vllm) (0.0.4)
Collecting fastapi-cli>=0.0.8 (from fastapi-cli[standard]>=0.0.8; extra == "standard"->fastapi[standard]>=0.115.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/c7/4b/68f9fe268e535d79c76910519530026a4f994ce07189ac0dded45c6af825/fastapi_cli-0.0.24-py3-none-any.whl (12 kB)
Collecting python-multipart>=0.0.18 (from fastapi[standard]>=0.115.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/1b/d0/397f9626e711ff749a95d96b7af99b9c566a9bb5129b8e4c10fc4d100304/python_multipart-0.0.22-py3-none-any.whl (24 kB)
Collecting email-validator>=2.0.0 (from fastapi[standard]>=0.115.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl (35 kB)
Collecting uvicorn>=0.12.0 (from uvicorn[standard]>=0.12.0; extra == "standard"->fastapi[standard]>=0.115.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/0a/89/f8827ccff89c1586027a105e5630ff6139a64da2515e24dafe860bd9ae4d/uvicorn-0.42.0-py3-none-any.whl (68 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 68.8/68.8 kB 16.4 MB/s eta 0:00:00
Collecting pydantic-settings>=2.0.0 (from fastapi[standard]>=0.115.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/00/4b/ccc026168948fec4f7555b9164c724cf4125eac006e176541483d2c959be/pydantic_settings-2.13.1-py3-none-any.whl (58 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 58.9/58.9 kB 18.5 MB/s eta 0:00:00
Collecting pydantic-extra-types>=2.0.0 (from fastapi[standard]>=0.115.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/17/c1/3226e6d7f5a4f736f38ac11a6fbb262d701889802595cdb0f53a885ac2e0/pydantic_extra_types-2.11.1-py3-none-any.whl (79 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 79.5/79.5 kB 25.0 MB/s eta 0:00:00
Requirement already satisfied: jsonschema>=4.21.1 in /root/miniconda3/lib/python3.12/site-packages (from mistral_common>=1.10.0->mistral_common[image]>=1.10.0->vllm) (4.25.0)
Collecting jmespath (from model-hosting-container-standards<1.0.0,>=0.1.13->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl (20 kB)
Requirement already satisfied: supervisor>=4.2.0 in /root/miniconda3/lib/python3.12/site-packages (from model-hosting-container-standards<1.0.0,>=0.1.13->vllm) (4.2.5)
Collecting nvidia-cutlass-dsl-libs-base==4.4.2 (from nvidia-cutlass-dsl>=4.4.0.dev1->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/56/98/e264964741d9cc9816625d9600d17a5249fd5cbd8c2d166fb0d0c34dfe5a/nvidia_cutlass_dsl_libs_base-4.4.2-cp312-cp312-manylinux_2_28_x86_64.whl (74.4 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 74.4/74.4 MB 8.7 MB/s eta 0:00:00
Collecting cuda-python>=12.8 (from nvidia-cutlass-dsl-libs-base==4.4.2->nvidia-cutlass-dsl>=4.4.0.dev1->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/4a/da/b4dbe129f941afe1c24a09ba53521b78875626763d96414798a74763282f/cuda_python-13.2.0-py3-none-any.whl (8.1 kB)
Collecting importlib-metadata<8.8.0,>=6.0 (from opentelemetry-api>=1.27.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl (27 kB)
Collecting opentelemetry-exporter-otlp-proto-grpc==1.40.0 (from opentelemetry-exporter-otlp>=1.27.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/96/6f/7ee0980afcbdcd2d40362da16f7f9796bd083bf7f0b8e038abfbc0300f5d/opentelemetry_exporter_otlp_proto_grpc-1.40.0-py3-none-any.whl (20 kB)
Collecting opentelemetry-exporter-otlp-proto-http==1.40.0 (from opentelemetry-exporter-otlp>=1.27.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/a0/3a/8865d6754e61c9fb170cdd530a124a53769ee5f740236064816eb0ca7301/opentelemetry_exporter_otlp_proto_http-1.40.0-py3-none-any.whl (19 kB)
Collecting googleapis-common-protos~=1.57 (from opentelemetry-exporter-otlp-proto-grpc==1.40.0->opentelemetry-exporter-otlp>=1.27.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/69/28/23eea8acd65972bbfe295ce3666b28ac510dfcb115fac089d3edb0feb00a/googleapis_common_protos-1.73.0-py3-none-any.whl (297 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 297.6/297.6 kB 15.8 MB/s eta 0:00:00
Requirement already satisfied: grpcio<2.0.0,>=1.63.2 in /root/miniconda3/lib/python3.12/site-packages (from opentelemetry-exporter-otlp-proto-grpc==1.40.0->opentelemetry-exporter-otlp>=1.27.0->vllm) (1.74.0)
Collecting opentelemetry-exporter-otlp-proto-common==1.40.0 (from opentelemetry-exporter-otlp-proto-grpc==1.40.0->opentelemetry-exporter-otlp>=1.27.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/8b/ca/8f122055c97a932311a3f640273f084e738008933503d0c2563cd5d591fc/opentelemetry_exporter_otlp_proto_common-1.40.0-py3-none-any.whl (18 kB)
Collecting opentelemetry-proto==1.40.0 (from opentelemetry-exporter-otlp-proto-grpc==1.40.0->opentelemetry-exporter-otlp>=1.27.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/b9/b2/189b2577dde745b15625b3214302605b1353436219d42b7912e77fa8dc24/opentelemetry_proto-1.40.0-py3-none-any.whl (72 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 72.1/72.1 kB 14.7 MB/s eta 0:00:00
Collecting protobuf!=6.30.*,!=6.31.*,!=6.32.*,!=6.33.0.*,!=6.33.1.*,!=6.33.2.*,!=6.33.3.*,!=6.33.4.*,>=5.29.6 (from vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/16/92/d1e32e3e0d894fe00b15ce28ad4944ab692713f2e7f0a99787405e43533a/protobuf-6.33.6-cp39-abi3-manylinux2014_x86_64.whl (323 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 323.4/323.4 kB 15.5 MB/s eta 0:00:00
Collecting opentelemetry-semantic-conventions==0.61b0 (from opentelemetry-sdk>=1.27.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/b2/37/cc6a55e448deaa9b27377d087da8615a3416d8ad523d5960b78dbeadd02a/opentelemetry_semantic_conventions-0.61b0-py3-none-any.whl (231 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 231.6/231.6 kB 16.4 MB/s eta 0:00:00
Collecting starlette>=0.46.0 (from fastapi>=0.115.0->fastapi[standard]>=0.115.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/81/0d/13d1d239a25cbfb19e740db83143e95c772a1fe10202dda4b76792b114dd/starlette-0.52.1-py3-none-any.whl (74 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 74.3/74.3 kB 16.1 MB/s eta 0:00:00
Collecting annotated-types>=0.6.0 (from pydantic>=2.12.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl (13 kB)
Collecting pydantic-core==2.41.5 (from pydantic>=2.12.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/0d/76/941cc9f73529988688a665a5c0ecff1112b3d95ab48f81db5f7606f522d3/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.1 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.1/2.1 MB 13.5 MB/s eta 0:00:00
Collecting torch-c-dlpack-ext (from quack-kernels>=0.2.7->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/e2/79/a914539b4785f3e44f891aa012a886edb8bc10fe081c440981c57543ce21/torch_c_dlpack_ext-0.1.5-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (897 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 897.8/897.8 kB 17.5 MB/s eta 0:00:00
Requirement already satisfied: charset-normalizer<4,>=2 in /root/miniconda3/lib/python3.12/site-packages (from requests>=2.26.0->vllm) (2.0.4)
Requirement already satisfied: idna<4,>=2.5 in /root/miniconda3/lib/python3.12/site-packages (from requests>=2.26.0->vllm) (3.7)
Requirement already satisfied: urllib3<3,>=1.21.1 in /root/miniconda3/lib/python3.12/site-packages (from requests>=2.26.0->vllm) (2.1.0)
Requirement already satisfied: certifi>=2017.4.17 in /root/miniconda3/lib/python3.12/site-packages (from requests>=2.26.0->vllm) (2024.2.2)
Requirement already satisfied: huggingface-hub<2.0,>=0.16.4 in /root/miniconda3/lib/python3.12/site-packages (from tokenizers>=0.21.1->vllm) (1.7.2)
Collecting huggingface-hub<2.0,>=0.16.4 (from tokenizers>=0.21.1->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/a8/af/48ac8483240de756d2438c380746e7130d1c6f75802ef22f3c6d49982787/huggingface_hub-0.36.2-py3-none-any.whl (566 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 566.4/566.4 kB 13.5 MB/s eta 0:00:00
Collecting safetensors>=0.4.3 (from transformers<5,>=4.56.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/a0/60/429e9b1cb3fc651937727befe258ea24122d9663e4d5709a48c9cbfceecb/safetensors-0.7.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (507 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 507.2/507.2 kB 32.9 MB/s eta 0:00:00
Collecting httpx-sse>=0.4 (from mcp->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/d2/fd/6668e5aec43ab844de6fc74927e155a3b37bf40d7c3790e49fc0406b6578/httpx_sse-0.4.3-py3-none-any.whl (9.0 kB)
Collecting pyjwt>=2.10.1 (from pyjwt[crypto]>=2.10.1->mcp->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/e5/7a/8dd906bd22e79e47397a61742927f6747fe93242ef86645ee9092e610244/pyjwt-2.12.1-py3-none-any.whl (29 kB)
Collecting sse-starlette>=1.6.1 (from mcp->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/78/e2/b8cff57a67dddf9a464d7e943218e031617fb3ddc133aeeb0602ff5f6c85/sse_starlette-3.3.3-py3-none-any.whl (14 kB)
Collecting dnspython>=2.0.0 (from email-validator>=2.0.0->fastapi[standard]>=0.115.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl (331 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 331.1/331.1 kB 33.9 MB/s eta 0:00:00
Requirement already satisfied: typer>=0.16.0 in /root/miniconda3/lib/python3.12/site-packages (from fastapi-cli>=0.0.8->fastapi-cli[standard]>=0.0.8; extra == "standard"->fastapi[standard]>=0.115.0->vllm) (0.24.1)
Collecting rich-toolkit>=0.14.8 (from fastapi-cli>=0.0.8->fastapi-cli[standard]>=0.0.8; extra == "standard"->fastapi[standard]>=0.115.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/fb/3c/c923619f6d2f5fafcc96fec0aaf9550a46cd5b6481f06e0c6b66a2a4fed0/rich_toolkit-0.19.7-py3-none-any.whl (32 kB)
Collecting fastapi-cloud-cli>=0.1.1 (from fastapi-cli[standard]>=0.0.8; extra == "standard"->fastapi[standard]>=0.115.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/40/cc/1ccca747f5609be27186ea8c9219449142f40e3eded2c6089bba6a6ecc82/fastapi_cloud_cli-0.15.0-py3-none-any.whl (32 kB)
Requirement already satisfied: httpcore==1.* in /root/miniconda3/lib/python3.12/site-packages (from httpx<1,>=0.25.0->anthropic>=0.71.0->vllm) (1.0.9)
Requirement already satisfied: h11>=0.16 in /root/miniconda3/lib/python3.12/site-packages (from httpcore==1.*->httpx<1,>=0.25.0->anthropic>=0.71.0->vllm) (0.16.0)
Requirement already satisfied: hf-xet<2.0.0,>=1.1.3 in /root/miniconda3/lib/python3.12/site-packages (from huggingface-hub<2.0,>=0.16.4->tokenizers>=0.21.1->vllm) (1.4.2)
Collecting zipp>=3.20 (from importlib-metadata<8.8.0,>=6.0->opentelemetry-api>=1.27.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl (10 kB)
Requirement already satisfied: MarkupSafe>=2.0 in /root/miniconda3/lib/python3.12/site-packages (from jinja2->torch==2.10.0->vllm) (3.0.2)
Requirement already satisfied: jsonschema-specifications>=2023.03.6 in /root/miniconda3/lib/python3.12/site-packages (from jsonschema>=4.21.1->mistral_common>=1.10.0->mistral_common[image]>=1.10.0->vllm) (2025.4.1)
Requirement already satisfied: referencing>=0.28.4 in /root/miniconda3/lib/python3.12/site-packages (from jsonschema>=4.21.1->mistral_common>=1.10.0->mistral_common[image]>=1.10.0->vllm) (0.36.2)
Requirement already satisfied: rpds-py>=0.7.1 in /root/miniconda3/lib/python3.12/site-packages (from jsonschema>=4.21.1->mistral_common>=1.10.0->mistral_common[image]>=1.10.0->vllm) (0.26.0)
Collecting pycountry>=23 (from pydantic-extra-types[pycountry]>=2.10.5->mistral_common>=1.10.0->mistral_common[image]>=1.10.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/9c/42/7703bd45b62fecd44cd7d3495423097e2f7d28bc2e99e7c1af68892ab157/pycountry-26.2.16-py3-none-any.whl (8.0 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.0/8.0 MB 10.6 MB/s eta 0:00:00
Collecting python-dotenv>=0.21.0 (from pydantic-settings>=2.0.0->fastapi[standard]>=0.115.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl (22 kB)
Requirement already satisfied: cryptography>=3.4.0 in /root/miniconda3/lib/python3.12/site-packages (from pyjwt[crypto]>=2.10.1->mcp->vllm) (42.0.5)
Requirement already satisfied: mpmath<1.4,>=1.1.0 in /root/miniconda3/lib/python3.12/site-packages (from sympy>=1.13.3->torch==2.10.0->vllm) (1.3.0)
Collecting httptools>=0.6.3 (from uvicorn[standard]>=0.12.0; extra == "standard"->fastapi[standard]>=0.115.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/84/a6/b3965e1e146ef5762870bbe76117876ceba51a201e18cc31f5703e454596/httptools-0.7.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (517 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 517.7/517.7 kB 43.0 MB/s eta 0:00:00
Collecting uvloop>=0.15.1 (from uvicorn[standard]>=0.12.0; extra == "standard"->fastapi[standard]>=0.115.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/5f/6f/e62b4dfc7ad6518e7eff2516f680d02a0f6eb62c0c212e152ca708a0085e/uvloop-0.22.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (4.4 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.4/4.4 MB 12.6 MB/s eta 0:00:00
Collecting websockets>=10.4 (from uvicorn[standard]>=0.12.0; extra == "standard"->fastapi[standard]>=0.115.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/18/29/71729b4671f21e1eaa5d6573031ab810ad2936c8175f03f97f3ff164c802/websockets-16.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (184 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 184.9/184.9 kB 22.0 MB/s eta 0:00:00
Requirement already satisfied: cffi>=1.12 in /root/miniconda3/lib/python3.12/site-packages (from cryptography>=3.4.0->pyjwt[crypto]>=2.10.1->mcp->vllm) (1.16.0)
INFO: pip is looking at multiple versions of cuda-python to determine which version is compatible with other requirements. This could take a while.
Collecting cuda-python>=12.8 (from nvidia-cutlass-dsl-libs-base==4.4.2->nvidia-cutlass-dsl>=4.4.0.dev1->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/cd/08/b5e3b9822662d72d540d830531e3ab6a7cabbda3dd56175696aabccfeb76/cuda_python-13.1.1-py3-none-any.whl (8.0 kB)
Downloading http://mirrors.aliyun.com/pypi/packages/3d/4d/876c2f87d34ccde0f11688f07e98a43cb3498cc115ee85fc7ae79711b7ae/cuda_python-13.1.0-py3-none-any.whl (7.6 kB)
Downloading http://mirrors.aliyun.com/pypi/packages/31/5f/beaa12a11b051027eec0b041df01c6690db4f02e3b2e8fadd5a0eeb4df52/cuda_python-13.0.3-py3-none-any.whl (7.6 kB)
Downloading http://mirrors.aliyun.com/pypi/packages/36/4d/d04772e5ba415aad4633796d636a3abbd8f779b438c3441d795e6bc9f172/cuda_python-13.0.2-py3-none-any.whl (7.6 kB)
Downloading http://mirrors.aliyun.com/pypi/packages/02/02/078f4cba58349faad5597306ca54bf0bf129f8c713b261e1def59468a505/cuda_python-13.0.1-py3-none-any.whl (7.6 kB)
Downloading http://mirrors.aliyun.com/pypi/packages/05/99/7df7b57a5eba85b25a76c9c247c88e79770b4902bce266dbf0fc58f21198/cuda_python-13.0.0-py3-none-any.whl (7.6 kB)
Downloading http://mirrors.aliyun.com/pypi/packages/57/69/4a79126959ad6f1653504122ee1eb22d089dd6272d3fa37694dcdeb78ba5/cuda_python-12.9.6-py3-none-any.whl (7.6 kB)
INFO: pip is still looking at multiple versions of cuda-python to determine which version is compatible with other requirements. This could take a while.
Downloading http://mirrors.aliyun.com/pypi/packages/0a/02/ce79a804a2d6ee7dc2d1637b75b7c3f01eb90a796915d4d3a1ac42e2d6e6/cuda_python-12.9.5-py3-none-any.whl (7.6 kB)
Downloading http://mirrors.aliyun.com/pypi/packages/af/f3/6b032a554019cfb3447e671798c1bd3e79b5f1af20d10253f56cea269ef2/cuda_python-12.9.4-py3-none-any.whl (7.6 kB)
Collecting rignore>=0.5.1 (from fastapi-cloud-cli>=0.1.1->fastapi-cli[standard]>=0.0.8; extra == "standard"->fastapi[standard]>=0.115.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/85/e5/7f99bd0cc9818a91d0e8b9acc65b792e35750e3bdccd15a7ee75e64efca4/rignore-0.7.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (959 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 959.8/959.8 kB 9.2 MB/s eta 0:00:00
Collecting sentry-sdk>=2.20.0 (from fastapi-cloud-cli>=0.1.1->fastapi-cli[standard]>=0.0.8; extra == "standard"->fastapi[standard]>=0.115.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/9a/66/20465097782d7e1e742d846407ea7262d338c6e876ddddad38ca8907b38f/sentry_sdk-2.55.0-py2.py3-none-any.whl (449 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 449.3/449.3 kB 16.4 MB/s eta 0:00:00
Collecting fastar>=0.8.0 (from fastapi-cloud-cli>=0.1.1->fastapi-cli[standard]>=0.0.8; extra == "standard"->fastapi[standard]>=0.115.0->vllm)
Downloading http://mirrors.aliyun.com/pypi/packages/41/df/d663214d35380b07a24a796c48d7d7d4dc3a28ec0756edbcb7e2a81dc572/fastar-0.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (819 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 819.0/819.0 kB 8.8 MB/s eta 0:00:00
Requirement already satisfied: rich>=13.7.1 in /root/miniconda3/lib/python3.12/site-packages (from rich-toolkit>=0.14.8->fastapi-cli>=0.0.8->fastapi-cli[standard]>=0.0.8; extra == "standard"->fastapi[standard]>=0.115.0->vllm) (14.3.3)
Requirement already satisfied: shellingham>=1.3.0 in /root/miniconda3/lib/python3.12/site-packages (from typer>=0.16.0->fastapi-cli>=0.0.8->fastapi-cli[standard]>=0.0.8; extra == "standard"->fastapi[standard]>=0.115.0->vllm) (1.5.4)
Requirement already satisfied: pycparser in /root/miniconda3/lib/python3.12/site-packages (from cffi>=1.12->cryptography>=3.4.0->pyjwt[crypto]>=2.10.1->mcp->vllm) (2.21)
Requirement already satisfied: markdown-it-py>=2.2.0 in /root/miniconda3/lib/python3.12/site-packages (from rich>=13.7.1->rich-toolkit>=0.14.8->fastapi-cli>=0.0.8->fastapi-cli[standard]>=0.0.8; extra == "standard"->fastapi[standard]>=0.115.0->vllm) (4.0.0)
Requirement already satisfied: pygments<3.0.0,>=2.13.0 in /root/miniconda3/lib/python3.12/site-packages (from rich>=13.7.1->rich-toolkit>=0.14.8->fastapi-cli>=0.0.8->fastapi-cli[standard]>=0.0.8; extra == "standard"->fastapi[standard]>=0.115.0->vllm) (2.19.2)
Requirement already satisfied: mdurl~=0.1 in /root/miniconda3/lib/python3.12/site-packages (from markdown-it-py>=2.2.0->rich>=13.7.1->rich-toolkit>=0.14.8->fastapi-cli>=0.0.8->fastapi-cli[standard]>=0.0.8; extra == "standard"->fastapi[standard]>=0.115.0->vllm) (0.1.2)
Installing collected packages: py-cpuinfo, nvidia-ml-py, zipp, websockets, uvloop, uvicorn, typing-inspection, triton, tabulate, setuptools, setproctitle, sentry-sdk, sentencepiece, safetensors, rignore, regex, python-multipart, python-dotenv, pyjwt, pydantic-core, pycountry, pybase64, protobuf, propcache, partial-json-parser, packaging, outlines_core, nvidia-nvshmem-cu12, nvidia-nccl-cu12, nvidia-cudnn-frontend, numpy, ninja, multidict, msgspec, loguru, llvmlite, llguidance, jmespath, jiter, interegular, ijson, httpx-sse, httptools, frozenlist, fastar, einops, docstring-parser, dnspython, diskcache, dill, cuda-pathfinder, cloudpickle, cbor2, cachetools, blake3, astor, apache-tvm-ffi, annotated-types, aiohappyeyeballs, yarl, watchfiles, tiktoken, starlette, pydantic, opentelemetry-proto, opencv-python-headless, numba, importlib-metadata, huggingface-hub, googleapis-common-protos, gguf, email-validator, depyf, cuda-bindings, aiosignal, torch, tokenizers, sse-starlette, rich-toolkit, pydantic-settings, pydantic-extra-types, prometheus-fastapi-instrumentator, opentelemetry-exporter-otlp-proto-common, opentelemetry-api, openai-harmony, openai, lm-format-enforcer, fastapi, cuda-python, anthropic, aiohttp, transformers, torchvision, torchaudio, torch-c-dlpack-ext, opentelemetry-semantic-conventions, nvidia-cutlass-dsl-libs-base, model-hosting-container-standards, mcp, fastapi-cloud-cli, fastapi-cli, xgrammar, opentelemetry-sdk, nvidia-cutlass-dsl, mistral_common, compressed-tensors, quack-kernels, opentelemetry-semantic-conventions-ai, opentelemetry-exporter-otlp-proto-http, opentelemetry-exporter-otlp-proto-grpc, flashinfer-python, opentelemetry-exporter-otlp, vllm
Attempting uninstall: triton
Found existing installation: triton 3.4.0
Uninstalling triton-3.4.0:
Successfully uninstalled triton-3.4.0
Attempting uninstall: setuptools
Found existing installation: setuptools 69.5.1
Uninstalling setuptools-69.5.1:
Successfully uninstalled setuptools-69.5.1
Attempting uninstall: protobuf
Found existing installation: protobuf 6.31.1
Uninstalling protobuf-6.31.1:
Successfully uninstalled protobuf-6.31.1
Attempting uninstall: packaging
Found existing installation: packaging 23.2
Uninstalling packaging-23.2:
Successfully uninstalled packaging-23.2
Attempting uninstall: nvidia-nccl-cu12
Found existing installation: nvidia-nccl-cu12 2.27.3
Uninstalling nvidia-nccl-cu12-2.27.3:
Successfully uninstalled nvidia-nccl-cu12-2.27.3
Attempting uninstall: numpy
Found existing installation: numpy 2.3.2
Uninstalling numpy-2.3.2:
Successfully uninstalled numpy-2.3.2
Attempting uninstall: huggingface-hub
Found existing installation: huggingface_hub 1.7.2
Uninstalling huggingface_hub-1.7.2:
Successfully uninstalled huggingface_hub-1.7.2
Attempting uninstall: torch
Found existing installation: torch 2.8.0+cu128
Uninstalling torch-2.8.0+cu128:
Successfully uninstalled torch-2.8.0+cu128
Attempting uninstall: torchvision
Found existing installation: torchvision 0.23.0+cu128
Uninstalling torchvision-0.23.0+cu128:
Successfully uninstalled torchvision-0.23.0+cu128
Successfully installed aiohappyeyeballs-2.6.1 aiohttp-3.13.3 aiosignal-1.4.0 annotated-types-0.7.0 anthropic-0.86.0 apache-tvm-ffi-0.1.9 astor-0.8.1 blake3-1.0.8 cachetools-7.0.5 cbor2-5.9.0 cloudpickle-3.1.2 compressed-tensors-0.13.0 cuda-bindings-12.9.4 cuda-pathfinder-1.4.4 cuda-python-12.9.4 depyf-0.20.0 dill-0.4.1 diskcache-5.6.3 dnspython-2.8.0 docstring-parser-0.17.0 einops-0.8.2 email-validator-2.3.0 fastapi-0.135.2 fastapi-cli-0.0.24 fastapi-cloud-cli-0.15.0 fastar-0.9.0 flashinfer-python-0.6.6 frozenlist-1.8.0 gguf-0.18.0 googleapis-common-protos-1.73.0 httptools-0.7.1 httpx-sse-0.4.3 huggingface-hub-0.36.2 ijson-3.5.0 importlib-metadata-8.7.1 interegular-0.3.3 jiter-0.13.0 jmespath-1.1.0 llguidance-1.3.0 llvmlite-0.44.0 lm-format-enforcer-0.11.3 loguru-0.7.3 mcp-1.26.0 mistral_common-1.10.0 model-hosting-container-standards-0.1.14 msgspec-0.20.0 multidict-6.7.1 ninja-1.13.0 numba-0.61.2 numpy-2.2.6 nvidia-cudnn-frontend-1.18.0 nvidia-cutlass-dsl-4.4.2 nvidia-cutlass-dsl-libs-base-4.4.2 nvidia-ml-py-13.595.45 nvidia-nccl-cu12-2.27.5 nvidia-nvshmem-cu12-3.4.5 openai-2.24.0 openai-harmony-0.0.8 opencv-python-headless-4.13.0.92 opentelemetry-api-1.40.0 opentelemetry-exporter-otlp-1.40.0 opentelemetry-exporter-otlp-proto-common-1.40.0 opentelemetry-exporter-otlp-proto-grpc-1.40.0 opentelemetry-exporter-otlp-proto-http-1.40.0 opentelemetry-proto-1.40.0 opentelemetry-sdk-1.40.0 opentelemetry-semantic-conventions-0.61b0 opentelemetry-semantic-conventions-ai-0.5.0 outlines_core-0.2.11 packaging-26.0 partial-json-parser-0.2.1.1.post7 prometheus-fastapi-instrumentator-7.1.0 propcache-0.4.1 protobuf-6.33.6 py-cpuinfo-9.0.0 pybase64-1.4.3 pycountry-26.2.16 pydantic-2.12.5 pydantic-core-2.41.5 pydantic-extra-types-2.11.1 pydantic-settings-2.13.1 pyjwt-2.12.1 python-dotenv-1.2.2 python-multipart-0.0.22 quack-kernels-0.3.5 regex-2026.2.28 rich-toolkit-0.19.7 rignore-0.7.6 safetensors-0.7.0 sentencepiece-0.2.1 sentry-sdk-2.55.0 setproctitle-1.3.7 setuptools-80.10.2 sse-starlette-3.3.3 starlette-0.52.1 tabulate-0.10.0 tiktoken-0.12.0 tokenizers-0.22.2 torch-2.10.0 torch-c-dlpack-ext-0.1.5 torchaudio-2.10.0 torchvision-0.25.0 transformers-4.57.6 triton-3.6.0 typing-inspection-0.4.2 uvicorn-0.42.0 uvloop-0.22.1 vllm-0.18.0 watchfiles-1.1.1 websockets-16.0 xgrammar-0.1.32 yarl-1.23.0 zipp-3.23.0
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
root@autodl-container-c6d54aa471-4479d4d0:~/autodl-tmp#
```
## 一、你最终安装的核心东西是什么?
你执行的是:
```bash
pip install vllm
```
最终成功安装了:
- **vllm 0.18.0**
它不是单独一个包,而是顺带安装了一大堆依赖,主要可以分成几类:
---
## 二、最核心的大件
这几个是体积最大、最关键的:
### 1. vLLM 本体
- **vllm-0.18.0**
这是高性能大模型推理框架本身,用来部署/推理 LLM。
---
### 2. PyTorch 整套
你安装/替换了:
- **torch 2.10.0**
- **torchvision 0.25.0**
- **torchaudio 2.10.0**
- **triton 3.6.0**
这说明 vLLM 把你原来环境里的 PyTorch 升级/替换成了它需要的版本。
日志里明确显示它卸载了原有版本:
- 卸载了 **torch 2.8.0+cu128**
- 卸载了 **torchvision 0.23.0+cu128**
- 卸载了 **triton 3.4.0**
也就是说,你现在的推理底座已经变成:
- **PyTorch 2.10.0**
- CUDA 12 相关依赖配套版本
---
### 3. CUDA / NVIDIA 相关高性能组件
新装或调整了这些:
- **nvidia-nccl-cu12 2.27.5**
- **nvidia-nvshmem-cu12 3.4.5**
- **nvidia-cudnn-frontend 1.18.0**
- **cuda-bindings 12.9.4**
- **cuda-python 12.9.4**
- **cuda-pathfinder 1.4.4**
- **nvidia-cutlass-dsl 4.4.2**
- **nvidia-cutlass-dsl-libs-base 4.4.2**
- **nvidia-ml-py 13.595.45**
这些主要作用:
- GPU 通信
- CUDA API 绑定
- 高性能 kernel
- 多卡推理支持
- NVIDIA 底层算子优化
其中:
- **NCCL**:多卡通信关键组件
- **NVSHMEM**:高性能 GPU 间共享内存通信
- **CUTLASS DSL**NVIDIA 高性能 GEMM/算子支持
- **CUDA Python / Bindings**:让 Python 能直接调用 CUDA 能力
---
### 4. vLLM 专用高性能推理加速组件
这几个也很关键:
- **flashinfer-python 0.6.6**
- **quack-kernels 0.3.5**
- **torch-c-dlpack-ext 0.1.5**
- **compressed-tensors 0.13.0**
- **depyf 0.20.0**
- **apache-tvm-ffi 0.1.9**
作用大概是:
- 加速 attention / decoding
- 优化张量操作
- 支持压缩权重
- 支持更底层高性能 kernel
- 一些编译/调度/FFI 能力
---
## 三、模型生态相关依赖
这些是为了支持 HuggingFace 模型、tokenizer、权重格式等:
- **transformers 4.57.6**
- **tokenizers 0.22.2**
- **huggingface-hub 0.36.2**
- **safetensors 0.7.0**
- **sentencepiece 0.2.1**
- **tiktoken 0.12.0**
- **gguf 0.18.0**
- **mistral_common 1.10.0**
- **openai-harmony 0.0.8**
### 它们分别干嘛:
- **transformers**:加载 HuggingFace 模型
- **tokenizers / sentencepiece / tiktoken**:分词器
- **huggingface-hub**:从 HF 下载模型
- **safetensors**:加载 safetensors 权重
- **gguf**:支持 GGUF 格式模型
- **mistral_common**Mistral 模型相关支持
---
## 四、API 服务相关依赖
vLLM 很常见的用法是启动 OpenAI 兼容服务,所以安装了 Web/API 框架:
- **fastapi 0.135.2**
- **starlette 0.52.1**
- **uvicorn 0.42.0**
- **uvloop 0.22.1**
- **httptools 0.7.1**
- **websockets 16.0**
- **watchfiles 1.1.1**
- **python-multipart 0.0.22**
- **email-validator 2.3.0**
- **fastapi-cli 0.0.24**
- **fastapi-cloud-cli 0.15.0**
- **prometheus-fastapi-instrumentator 7.1.0**
作用:
- 启动 HTTP 服务
- 提供 OpenAI 风格 API
- 处理 websocket / multipart
- 自动监控接口指标
- 热更新/文件监控
也就是说,你现在环境已经具备了直接跑:
```bash
vllm serve ...
```
或者类似 OpenAI API 服务的能力。
---
## 五、OpenAI / Anthropic / MCP 相关客户端
你还安装了:
- **openai 2.24.0**
- **anthropic 0.86.0**
- **mcp 1.26.0**
- **httpx-sse 0.4.3**
- **sse-starlette 3.3.3**
- **pyjwt 2.12.1**
这部分主要是为了:
- 兼容 OpenAI 接口风格
- 兼容 Anthropic 风格
- 支持 MCPModel Context Protocol)相关功能
- 支持 SSE 流式输出
- 认证/鉴权
---
## 六、约束解码 / 结构化输出相关
这些是 vLLM 比较新的一类能力,支持 JSON schema、语法约束解码等:
- **lm-format-enforcer 0.11.3**
- **llguidance 1.3.0**
- **outlines_core 0.2.11**
- **xgrammar 0.1.32**
- **partial-json-parser 0.2.1.1.post7**
- **interegular 0.3.3**
作用:
- 强制模型输出符合 JSON/语法规则
- 结构化生成
- grammar-guided decoding
- 部分 JSON 流式解析
如果你要做“模型输出必须是 JSON”这种功能,这些包就是相关支持。
---
## 七、监控 / 可观测性相关
安装了 OpenTelemetry 一整套:
- **opentelemetry-api 1.40.0**
- **opentelemetry-sdk 1.40.0**
- **opentelemetry-exporter-otlp 1.40.0**
- **opentelemetry-exporter-otlp-proto-common 1.40.0**
- **opentelemetry-exporter-otlp-proto-grpc 1.40.0**
- **opentelemetry-exporter-otlp-proto-http 1.40.0**
- **opentelemetry-proto 1.40.0**
- **opentelemetry-semantic-conventions 0.61b0**
- **opentelemetry-semantic-conventions-ai 0.5.0**
- **googleapis-common-protos 1.73.0**
- **protobuf 6.33.6**
作用:
- 打点
- tracing
- metrics
- 将监控数据发给 OTLP 后端
如果你部署线上服务,这部分是有用的。
---
## 八、数值计算 / 编译优化相关
- **numba 0.61.2**
- **llvmlite 0.44.0**
- **numpy 2.2.6**
- **einops 0.8.2**
- **cloudpickle 3.1.2**
- **msgspec 0.20.0**
- **ijson 3.5.0**
- **cbor2 5.9.0**
- **blake3 1.0.8**
这些属于:
- 数值计算
- JIT/LLVM 编译支持
- 数据序列化/反序列化
- 哈希
- JSON 流式解析
---
## 九、图像/多模态相关
你还装了:
- **opencv-python-headless 4.13.0.92**
- **pillow** 已经存在
- **torchvision**
- **mistral_common[image]** 相关依赖
这说明 vLLM 这版不只是纯文本,也带了一些多模态/图像处理支持。
---
## 十、一些工具类依赖
比如:
- **regex**
- **cachetools**
- **diskcache**
- **py-cpuinfo**
- **ninja**
- **setproctitle**
- **pybase64**
- **loguru**
- **tabulate**
- **packaging 26.0**
- **setuptools 80.10.2**
- **importlib-metadata 8.7.1**
- **zipp 3.23.0**
- **dnspython 2.8.0**
- **python-dotenv 1.2.2**
- **docstring-parser 0.17.0**
- **jmespath 1.1.0**
- **rignore 0.7.6**
- **sentry-sdk 2.55.0**
- **fastar 0.9.0**
这些一般是:
- 构建工具
- 日志
- 配置管理
- 缓存
- 监控
- 辅助解析
---
## 十一、这次安装替换了你环境里的哪些已有包?
从日志里能明确看到,以下包被替换了:
### 被卸载并重装/降级/升级的
- **triton**3.4.0 → 3.6.0
- **setuptools**69.5.1 → 80.10.2
- **protobuf**6.31.1 → 6.33.6
- **packaging**23.2 → 26.0
- **nvidia-nccl-cu12**2.27.3 → 2.27.5
- **numpy**2.3.2 → 2.2.6
- **huggingface-hub**1.7.2 → 0.36.2
- **torch**2.8.0+cu128 → 2.10.0
- **torchvision**0.23.0+cu128 → 0.25.0
### 这里要特别注意两点:
#### 1huggingface-hub 被“降版本”了
从:
- 1.7.2 → 0.36.2
这通常是因为 `transformers/tokenizers/vllm` 当前依赖链要求 `<1.0` 风格版本。
#### 2numpy 被换成了 2.2.6
原来是 2.3.2,现在是 2.2.6。
这是依赖兼容性导致的,不算异常。
---
## 十二、按功能给你一个简版总结
你这次安装,本质上装了:
### 1. vLLM 主程序
- vllm
### 2. 大模型推理底座
- torch / torchvision / torchaudio / triton
### 3. GPU 高性能依赖
- NCCL / NVSHMEM / CUDA bindings / CUTLASS / flashinfer / quack kernels
### 4. HuggingFace 模型生态
- transformers / tokenizers / huggingface-hub / sentencepiece / safetensors / tiktoken
### 5. Web 服务框架
- fastapi / uvicorn / starlette / websockets
### 6. 结构化输出与语法约束
- lm-format-enforcer / llguidance / xgrammar / outlines_core
### 7. 监控与可观测性
- prometheus / opentelemetry 全家桶
### 8. 多模态支持
- opencv-python-headless / torchvision / mistral_common
---
## 十三、占空间最大的几个包
从日志看,比较大的有:
- **torch-2.10.0**915.6 MB
- **vllm-0.18.0**433.2 MB
- **nvidia-nccl-cu12**322.3 MB
- **triton-3.6.0**188.3 MB
- **nvidia-nvshmem-cu12**139.1 MB
- **nvidia-cutlass-dsl-libs-base**74.4 MB
- **opencv-python-headless**60.4 MB
- **llvmlite**42.4 MB
- **xgrammar**37.7 MB
所以这次安装是很重的一次安装,不是一个轻量包。
---
## 十四、最终结论
一句话总结:
**你安装的不只是 vLLM 本身,而是一整套“LLM 推理服务运行环境”**,包括:
- vLLM 本体
- PyTorch 2.10 + Triton
- CUDA/NVIDIA 高性能推理组件
- HuggingFace 模型加载生态
- FastAPI/uvicorn 服务框架
- OpenAI 兼容 API 支持
- 结构化输出/语法约束生成
- 监控和可观测性组件
- 一部分多模态支持
同时它还**替换了你环境中原有的 torch、torchvision、triton、numpy、protobuf、huggingface-hub 等包**。
---
如果你愿意,我还可以进一步帮你做两件事里的任意一种:
1. **把这份日志整理成“安装包清单表格”**(包名 / 版本 / 作用)
2. **帮你判断这个 vllm 环境是否和你当前 CUDA、显卡、驱动兼容**
@@ -0,0 +1,730 @@
```
(APIServer pid=17207) INFO 03-24 13:28:31 [api_server.py:580] Starting vLLM server on http://0.0.0.0:6006
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:37] Available routes are:
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /openapi.json, Methods: HEAD, GET
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /docs, Methods: HEAD, GET
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /docs/oauth2-redirect, Methods: HEAD, GET
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /redoc, Methods: HEAD, GET
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /tokenize, Methods: POST
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /detokenize, Methods: POST
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /load, Methods: GET
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /version, Methods: GET
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /health, Methods: GET
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /metrics, Methods: GET
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /v1/models, Methods: GET
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /ping, Methods: GET
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /ping, Methods: POST
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /invocations, Methods: POST
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /v1/chat/completions, Methods: POST
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /v1/responses, Methods: POST
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /v1/responses/{response_id}, Methods: GET
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /v1/responses/{response_id}/cancel, Methods: POST
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /v1/completions, Methods: POST
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /v1/messages, Methods: POST
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /v1/messages/count_tokens, Methods: POST
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /inference/v1/generate, Methods: POST
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /scale_elastic_ep, Methods: POST
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /is_scaling_elastic_ep, Methods: POST
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /v1/chat/completions/render, Methods: POST
(APIServer pid=17207) INFO 03-24 13:28:31 [launcher.py:46] Route: /v1/completions/render, Methods: POST
(APIServer pid=17207) INFO: Started server process [17207]
(APIServer pid=17207) INFO: Waiting for application startup.
(APIServer pid=17207) INFO: Application startup complete.
```
# 一、最前面的基础信息
## 1)版本和模型路径
```bash
version 0.18.0
model /root/autodl-tmp/DeepSeek-R1-32B
```
表示:
- 当前 vLLM 版本:`0.18.0`
- 加载的模型目录:`/root/autodl-tmp/DeepSeek-R1-32B`
这是最基础的确认信息。
---
## 2)非默认启动参数
```bash
non-default args: {
'port': 6006,
'model': '/root/autodl-tmp/DeepSeek-R1-32B',
'max_model_len': 8192,
'served_model_name': ['deepseek-r1'],
'gpu_memory_utilization': 0.95
}
```
这里列的是你手动指定、不同于默认值的参数。
你的关键参数含义:
- `port: 6006`
服务监听端口是 6006
- `model: /root/autodl-tmp/DeepSeek-R1-32B`
模型目录
- `max_model_len: 8192`
最大上下文长度 8192 token
- `served_model_name: deepseek-r1`
API 层暴露给客户端的模型名
- `gpu_memory_utilization: 0.95`
vLLM 最多使用 95% GPU 显存来做模型和缓存分配
---
# 二、模型识别与调度信息
## 3)模型架构识别
```bash
Resolved architecture: Qwen2ForCausalLM
```
说明 vLLM 识别出这个模型底层架构是:
- `Qwen2ForCausalLM`
虽然你目录叫 DeepSeek-R1-32B,但很多 DeepSeek 模型底层是兼容 Qwen 架构的,所以这是正常的。
---
## 4)最大长度设置
```bash
Using max model len 8192
```
表示最终采用的最大序列长度是 8192。
这个值会直接影响:
- KV Cache 占用
- 最大并发
- 显存使用
---
## 5Chunked Prefill
```bash
Chunked prefill is enabled with max_num_batched_tokens=8192.
```
说明启用了 **分块预填充(chunked prefill**
作用:
- 输入 prompt 很长时,不是一次性全部 prefill,而是按块处理
- 能改善吞吐和显存使用
- 对长上下文模型很有帮助
---
## 6)异步调度
```bash
Asynchronous scheduling is enabled.
```
表示启用了 **异步调度器**
作用:
- 更好地调度多个请求
- 通常提升吞吐
- 对服务化部署更友好
---
# 三、Engine 初始化配置
这段很重要:
```bash
Initializing a V1 LLM engine (v0.18.0) with config: ...
```
这是整个推理引擎的详细配置总表。里面关键信息包括:
---
## 7dtype
```bash
dtype=torch.bfloat16
```
模型以 `bfloat16` 精度运行。
说明:
- 显存比 fp32 小很多
- 通常速度更快
- 需要 GPU 支持 bf16
---
## 8)并行配置
```bash
tensor_parallel_size=1
pipeline_parallel_size=1
data_parallel_size=1
```
表示当前都是单卡/单副本:
- 张量并行 TP = 1
- 流水线并行 PP = 1
- 数据并行 DP = 1
也就是:**你现在实际上是单卡部署**。
---
## 9)前缀缓存
```bash
enable_prefix_caching=True
```
表示启用了 **prefix caching(前缀缓存)**
作用:
- 如果多个请求共享相同前缀 prompt
- 可以复用前缀计算结果
- 节省时间,提高吞吐
---
## 10)编译配置
```bash
compilation_config=...
backend='inductor'
cudagraph_mode=FULL_AND_PIECEWISE
```
说明 vLLM 启用了编译优化和 CUDA Graph:
- `torch.compile`
- `inductor`
- CUDA Graph
这会提高推理性能,但启动时会多花一些时间做 warmup 和 graph capture。
---
# 四、分布式与 rank 信息
## 11world size / rank
```bash
world_size=1 rank=0 local_rank=0 ... backend=nccl
```
说明:
- 总进程数:1
- 当前 rank0
- 本地 rank0
- 通信后端:NCCL
虽然你只有单卡,但 vLLM 内部还是走统一的分布式初始化逻辑,这是正常的。
---
## 12)并行角色分配
```bash
rank 0 in world size 1 is assigned as DP rank 0, PP rank 0, PCP rank 0, TP rank 0
```
表示当前唯一这个进程兼任所有角色。
---
# 五、模型加载阶段
## 13)开始加载模型
```bash
Starting to load model /root/autodl-tmp/DeepSeek-R1-32B...
```
开始读取模型权重。
---
## 14Attention 后端
```bash
Using FLASH_ATTN attention backend ...
Using FlashAttention version 2
```
说明 vLLM 最终选用了:
- `FLASH_ATTN`
- 版本 `FlashAttention v2`
这是高性能 attention 实现,通常是比较理想的情况。
候选后端里还有:
- FLASHINFER
- TRITON_ATTN
- FLEX_ATTENTION
但最终选择了 FlashAttention。
---
## 15checkpoint shard 加载进度
```bash
Loading safetensors checkpoint shards: ...
```
表示模型权重是分片存储的,一共 `8` 个 shard。
日志里看到:
- 0/8
- 1/8
- …
- 8/8
说明模型权重成功全部加载完成。
---
## 16)权重加载耗时
```bash
Loading weights took 13.38 seconds
```
纯粹“读权重文件并装入”的时间是 13.38 秒。
---
## 17)模型加载显存占用
```bash
Model loading took 61.06 GiB memory and 14.101032 seconds
```
这是一个非常关键的信息:
- 模型加载后占用了 `61.06 GiB` 显存
- 总耗时约 `14.1 秒`
这能帮助你判断:
- 模型本体有多大
- 剩余显存还能留多少给 KV Cache 和 CUDA Graph
---
# 六、编译和缓存信息
## 18torch.compile 缓存目录
```bash
Using cache directory: /root/.cache/vllm/torch_compile_cache/...
```
说明 vLLM 使用这个目录缓存 `torch.compile` 的编译结果。
好处:
- 下次重启如果配置没变,可能直接复用缓存
- 启动速度更快
---
## 19)编译耗时
```bash
Dynamo bytecode transform time: 4.52 s
torch.compile took 7.13 s in total
```
表示:
- Dynamo 变换用了 4.52 秒
- 整体 compile 用了 7.13 秒
---
## 20)直接从缓存加载编译图
```bash
Directly load the compiled graph(s) ... from the cache
Directly load AOT compilation from path ...
```
说明你这次并不是全量重新编译,而是 **命中了历史缓存**
所以启动会快很多。
---
# 七、warmup 和 profiling
## 21)初始 profiling / warmup
```bash
Initial profiling/warmup run took 2.69 s
```
表示模型做了一次预热运行:
- 激活算子
- 建立执行图
- 为后面正式推理做准备
---
# 八、KV Cache 相关信息
这部分是服务性能、并发能力最关键的。
## 22KV cache block override
```bash
Overriding num_gpu_blocks=0 with num_gpu_blocks_override=512
```
说明最终 GPU KV Cache block 数被设为 `512`
这个值决定了可缓存多少 token。
---
## 23CUDA graph 显存估计
```bash
Estimated CUDA graph memory: 0.93 GiB total
```
表示 CUDA graph 本身大概占用 `0.93 GiB` 显存。
---
## 24)可用于 KV cache 的显存
```bash
Available KV cache memory: 11.89 GiB
```
这是很关键的一行:
- 模型权重 + 编译 + graph 占完之后
- 剩下给 KV Cache 的显存是 `11.89 GiB`
---
## 25GPU KV cache size
```bash
GPU KV cache size: 48,704 tokens
```
表示 GPU 上最多可缓存约:
- `48,704 token`
这是总 token 容量,不是单请求。
---
## 26)最大并发估算
```bash
Maximum concurrency for 8,192 tokens per request: 5.95x
```
意思是:
- 如果每个请求都占满 `8192 token`
- 理论上最多支持接近 `5.95` 个这样的请求同时驻留
也就是大约 **5~6 个满长请求并发**
这是一个“理论上限估计”,实际情况还会受生成长度、调度、碎片等影响。
---
# 九、CUDA Graph 捕获
## 27)捕获过程
```bash
Capturing CUDA graphs (mixed prefill-decode, PIECEWISE): ...
Capturing CUDA graphs (decode, FULL): ...
```
表示 vLLM 正在为不同 batch size / 场景捕获 CUDA Graph。
作用:
- 降低 kernel launch 开销
- 提升推理速度
- 尤其对稳定 batch 的在线推理很有用
---
## 28)捕获结果
```bash
Graph capturing finished in 13 secs, took 0.93 GiB
CUDA graph pool memory: 0.93 GiB (actual), 0.93 GiB (estimated)
```
说明:
- Graph capture 总共耗时 13 秒
- 占显存 0.93 GiB
- 实测和预估几乎一致
这是正常且比较理想的结果。
---
## 29Engine 初始化总耗时
```bash
init engine (profile, create kv cache, warmup model) took 25.79 seconds
```
表示引擎最终初始化总耗时约:
- `25.79 秒`
包括:
- profiling
- 创建 KV cache
- warmup
---
# 十、API 服务层信息
## 30)支持的任务
```bash
Supported tasks: ['generate']
```
说明当前模型/服务支持的任务是:
- `generate`
也就是文本生成类任务。
---
## 31generation_config 覆盖提醒
```bash
Default vLLM sampling parameters have been overridden by the model's `generation_config.json`: {'temperature': 0.6, 'top_p': 0.95}
```
表示模型目录里的 `generation_config.json` 覆盖了 vLLM 默认采样参数。
当前默认采样变成:
- `temperature = 0.6`
- `top_p = 0.95`
如果你不想让模型自带配置生效,可以加:
```bash
--generation-config vllm
```
---
## 32chat template 格式检测
```bash
Detected the chat template content format to be 'string'
```
说明 vLLM 检测到聊天模板内容格式是 `string`
一般不用管,除非你自定义 chat template。
---
## 33)服务启动地址
```bash
Starting vLLM server on http://0.0.0.0:6006
```
表示:
- 监听所有网卡:`0.0.0.0`
- 端口:`6006`
如果你本机访问,就是:
```bash
http://127.0.0.1:6006
```
如果外部访问,要换成宿主机 IP。
---
# 十一、可用接口列表
日志中列出了所有路由。最常用的是:
## OpenAI 兼容接口
- `/v1/chat/completions`
- `/v1/completions`
- `/v1/models`
## 其他接口
- `/health`:健康检查
- `/metrics`:监控指标
- `/version`:版本信息
- `/tokenize`:分词
- `/detokenize`:反分词
---
# 十二、Uvicorn/FastAPI 启动完成
最后几行:
```bash
Started server process [70536]
Waiting for application startup.
Application startup complete.
```
这表示:
- API server 进程已经启动
- 应用初始化完成
- 服务已经可以接收请求
也就是说:**你的 vLLM 已经成功启动完成了。**
---
# 十三、这份日志里最值得关注的几个核心指标
如果你以后只想快速判断服务状态,重点看这几项:
---
## 1)模型是否识别成功
```bash
Resolved architecture: Qwen2ForCausalLM
```
---
## 2)模型是否加载成功
```bash
Loading weights took 13.38 seconds
Model loading took 61.06 GiB memory
```
---
## 3KV Cache 有多少
```bash
Available KV cache memory: 11.89 GiB
GPU KV cache size: 48,704 tokens
```
---
## 4)理论最大并发
```bash
32
Maximum concurrency for 8,192 tokens per request: 5.95x
1.5
Maximum concurrency for 8,192 tokens per request: 318.54x
1.5 128k
Maximum concurrency for 131,072 tokens per request: 19.91x
```
---
## 5)服务是否真正启动
```bash
Starting vLLM server on http://0.0.0.0:6006
Application startup complete.
```
---
# 十四、根据你的日志,可以总结成一句话
你的这次启动结果是:
- vLLM 版本:`0.18.0`
- 模型:`DeepSeek-R1-32B`
- 底层架构:`Qwen2ForCausalLM`
- 精度:`bfloat16`
- 单卡部署
- 模型权重占用显存:`61.06 GiB`
- 可用 KV Cache 显存:`11.89 GiB`
- KV Cache 总容量:`48,704 tokens`
- 在 `8192` 上下文长度下理论并发约:`5.95`
- 服务监听地址:`http://0.0.0.0:6006`
- OpenAI 兼容接口可用:`/v1/chat/completions`
---
# 十五、你可以马上这样测试服务
比如用 curl
```bash
curl http://127.0.0.1:6006/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-r1",
"messages": [
{"role": "user", "content": "你好,介绍一下你自己"}
],
"temperature": 0.6,
"top_p": 0.95,
"max_tokens": 128
}'
```
```
Value error, User-specified max_model_len (200000) is greater than the derived max_model_len (max_position_embeddings=131072.0 or model_max_length=None in model's config.json
```
@@ -0,0 +1,29 @@
# 1. Hugging Face 上的这些文件是什么?
**👉 通俗比喻:这位天才大厨的“记忆、秘方和大脑说明书”**
如果你点开 `DeepSeek-R1-Distill-Qwen-7B` 的网页,你会看到很多文件。这些文件加在一起,就是一个已经培训好的“数字大脑”(也就是模型本身)。
主要分为三类文件:
- **`.safetensors` 文件(大厨的烹饪经验/肌肉记忆)**:这是模型体积最大、最重要的文件,专业名词叫“权重(Weights)”。你可以把它理解为大厨脑子里记住的成千上万种调料的比例。它是 DeepSeek 团队花了海量数据和算力“训练”出来的精华。
- **`config.json`(大脑的生理结构/图纸)**:告诉电脑这个模型有几层神经网络、多大尺寸。就像是说明大厨的大脑神经元是怎么连接的。
- **`tokenizer.json` 等(翻译官/点菜单)**:AI 是不懂人类语言的,它只懂数字。Tokenizer 的作用就是把你打字的中文/英文,翻译成 AI 能看懂的数字编号(专业叫 Token)。就像餐厅前台的翻译,把你点的“宫保鸡丁”翻译成后厨看得懂的“菜品代码 1045”。
# 2. PyTorch 是什么?
**👉 通俗比喻:打造这间厨房的基础设施(锅碗瓢盆、水电气)**
PyTorch 是由 MetaFacebook)开发的一个**深度学习基础框架**。
- **在 AI 界的作用**:AI 模型的计算全是极其复杂的矩阵数学题。如果没有 PyTorch,程序员需要自己从零开始写底层的数学公式,还要教电脑怎么控制显卡(GPU)去算。PyTorch 直接提供了一套“造物主工具箱”。
- **回到比喻**:PyTorch 就像是厨房里的燃气灶、平底锅、水电系统和物理定律。不管你是要做中餐(DeepSeek模型)、西餐(ChatGPT)还是烤肉(画图模型),你都得依赖这些基础工具才能把大厨的“秘方(模型文件)”变成一盘真正的菜。
# 3. vLLM 是什么?
**👉 通俗比喻:一套极其高效的“麦当劳流水线管理系统”**
vLLM 是一个专门用来**加速大语言模型运行(推理)的引擎**。
- **为什么需要它?** 如果你只用 PyTorch 提供的基础锅碗瓢盆,大厨也能做菜,但他一次只能给一个客人做,做完一单再做下一单(速度慢,效率低)。而现实中,如果要把模型放到网上给成千上万人用,服务器会卡死。
- **vLLM 的作用**:vLLM 就像引入了一套极致的流水线管理系统。它聪明地统筹安排:客人 A 和客人 B 都点了汉堡,它就让大厨一次性烤两块肉;它还能高效管理后厨的桌面空间(显存),不让食材堆得乱七八糟(这是 vLLM 的核心技术 PagedAttention)。用了 vLLM,大模型生成文字的速度会成倍飙升,能同时接待的客人也多得多。
@@ -0,0 +1,47 @@
# 1. 核心命名规则解析
- **数字B (如 397B, 27B)**:代表模型的**总参数量**(Billion,十亿)。
- **-A+数字B (如 -A17B)**:代表模型的**激活参数量**Active Parameters)。只要带这个后缀,说明它采用了 **MoE(混合专家)架构**。推理时只有部分专家网络被激活,从而在保持极高模型能力的同时大幅降低显存和计算压力。
- **-Base**:代表**基础预训练模型**,没有经过人类指令微调(Instruct Tuning),适合开发者用来做二次微调。如果没有带 `-Base`,则默认是经过指令微调的对话模型(Instruct / Chat)。
- **-FP8 / -GPTQ-Int4**:代表模型的**量化版本**。用来压缩模型体积、降低显存占用并加速推理。
# 2. Qwen3.5 系列模型全景分类表
| 模型系列 | 完整模型名称 | 架构类型 | 总参数量 | 激活参数量 | 版本类型 | 精度 / 量化格式 | 适用场景 / 硬件要求 |
| :-------------- | :---------------------------- | :--- | :----- | :---- | :--- | :------------- | :----------------------------- |
| **超大规模 (MoE)** | `Qwen3.5-397B-A17B` | MoE | 约 403B | 17B | 指令微调 | BF16/FP16 (默认) | 极致性能,需超大型计算集群 |
| | `Qwen3.5-397B-A17B-FP8` | MoE | 约 403B | 17B | 指令微调 | FP8 | 极致性能,适合 H100 等支持 FP8 的集群 |
| | `Qwen3.5-397B-A17B-GPTQ-Int4` | MoE | 约 403B | 17B | 指令微调 | INT4 (GPTQ) | 大幅节省显存,适合多卡高端服务器 |
| **大规模 (MoE)** | `Qwen3.5-122B-A10B` | MoE | 约 125B | 10B | 指令微调 | BF16/FP16 (默认) | 顶尖多模态能力,企业级服务器 |
| | `Qwen3.5-122B-A10B-FP8` | MoE | 约 125B | 10B | 指令微调 | FP8 | 性能与效率的平衡,企业级部署 |
| | `Qwen3.5-122B-A10B-GPTQ-Int4` | MoE | 约 125B | 10B | 指令微调 | INT4 (GPTQ) | 适合双卡或四卡 24G/40G 显存设备部署 |
| **中大规模 (MoE)** | `Qwen3.5-35B-A3B` | MoE | 约 36B | 3B | 指令微调 | BF16/FP16 (默认) | 极高性价比,适合单卡高端 GPU (如 A100) |
| | `Qwen3.5-35B-A3B-Base` | MoE | 约 36B | 3B | 基础模型 | BF16/FP16 (默认) | 适合开发者进行垂直行业数据的二次微调 |
| | `Qwen3.5-35B-A3B-FP8` | MoE | 约 36B | 3B | 指令微调 | FP8 | 单卡高效推理 |
| | `Qwen3.5-35B-A3B-GPTQ-Int4` | MoE | 约 36B | 3B | 指令微调 | INT4 (GPTQ) | 消费级显卡(如 RTX 4090)可轻松运行 |
| **中型 (Dense)** | `Qwen3.5-27B` | 稠密 | 约 28B | 27B | 指令微调 | BF16/FP16 (默认) | 强大的稠密模型,常规服务器单卡部署 |
| | `Qwen3.5-27B-FP8` | 稠密 | 约 28B | 27B | 指令微调 | FP8 | 吞吐量更高的推理部署 |
| | `Qwen3.5-27B-GPTQ-Int4` | 稠密 | 约 28B | 27B | 指令微调 | INT4 (GPTQ) | 24G 消费级显卡(如 RTX 3090/4090)流畅运行 |
| **中小型 (Dense)** | `Qwen3.5-9B` | 稠密 | 约 10B | 9B | 指令微调 | BF16/FP16 (默认) | 优秀的泛用尺寸,适合一般消费级 GPU |
| | `Qwen3.5-9B-Base` | 稠密 | 约 10B | 9B | 基础模型 | BF16/FP16 (默认) | 适合中小企业/个人开发者微调 |
| **小型 (Dense)** | `Qwen3.5-4B` | 稠密 | 约 5B | 4B | 指令微调 | BF16/FP16 (默认) | 适合移动端、边缘设备或低配显卡运行 |
| | `Qwen3.5-4B-Base` | 稠密 | 约 5B | 4B | 基础模型 | BF16/FP16 (默认) | 轻量级微调使用 |
| **微型 (Dense)** | `Qwen3.5-2B` | 稠密 | 约 2B | 2B | 指令微调 | BF16/FP16 (默认) | 手机端侧、IoT 边缘计算设备部署 |
| | `Qwen3.5-2B-Base` | 稠密 | 约 2B | 2B | 基础模型 | BF16/FP16 (默认) | 端侧设备能力定制微调 |
| **极微型 (Dense)** | `Qwen3.5-0.8B` | 稠密 | 约 0.9B | 0.8B | 指令微调 | BF16/FP16 (默认) | 极限轻量化环境(如老旧手机、树莓派等) |
| | `Qwen3.5-0.8B-Base` | 稠密 | 约 0.9B | 0.8B | 基础模型 | BF16/FP16 (默认) | 极限轻量化微调 |
# 3. 三大核心维度的差异总结
1. **架构差异(MoE vs 稠密模型):**
- **MoE397B, 122B, 35B**:以 `397B-A17B` 为例,模型总参数虽高达近 4000 亿,但处理一张图片或一段文字时,实际工作的参数只有 170 亿(A17B)。这种架构能让模型拥有海量的知识库,同时推理速度极快,是当前大模型最前沿的设计。
- **稠密/Dense27B, 9B, 4B, 2B, 0.8B**:传统架构,每次推理时所有的参数都会参与计算。例如 27B 模型,每次计算都要拉起 270 亿参数。
2. **版本差异(Instruct对话版 vs Base基座版):**
- **无后缀(如 Qwen3.5-9B**:开箱即用,经过了人类偏好对齐,擅长听懂指令、回答问题、描述图片等,适合**直接用于应用开发**。
- **Base(如 Qwen3.5-9B-Base**:只是学会了海量文本和图像的规律,但还不具备良好的“一问一答”对话能力,适合**算法工程师拿来做 SFT(监督微调)**。
3. **量化差异(默认 vs FP8 vs INT4):**
- **默认版本**:通常是 BF16(16位浮点数),精度最高,但显存占用极大(例如 122B 模型需要约 250GB+ 显存才能跑起来)。
- **FP8**:8位浮点数量化,精度损失极小,显存减半,但在最新的英伟达显卡(如 Hopper 架构的 H100、Ada 架构的 RTX 4090)上能获得原生硬件加速。
- **GPTQ-Int4**:4位整数极限压缩,显存占用仅为默认版本的 1/4 左右。让普通玩家也能在一两张消费级显卡上跑起 35B 甚至 122B 的庞然大物。
@@ -0,0 +1,216 @@
使用 vLLM 启动时
```bash
screen -U -L -Logfile /root/vllm_server.log -dmS vllm_server bash -c 'python -m vllm.entrypoints.openai.api_server \
--model /root/autodl-tmp/DeepSeek-R1-Distill-Qwen-7B \
--served-model-name deepseek-r1 \
--tensor-parallel-size 1 \
--max-model-len 131072 \
--gpu-memory-utilization 0.95 \
--port 6006'
```
此参数可以决定对话返回时在 reasoning 中。
```
--reasoning-parser deepseek_r1
```
```json
{
"id": "chatcmpl-a76d0e60ddd6e6cc",
"object": "chat.completion",
"created": 1774488794,
"model": "deepseek-r1",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "\n\n以下是使用Python实现的快速排序算法的完整代码:\n\n```python\ndef quicksort(arr):\n if len(arr) <= 1:\n return arr\n pivot = arr[0]\n left = []\n right = []\n for num in arr[1:]:\n if num <= pivot:\n ",
"refusal": null,
"annotations": null,
"audio": null,
"function_call": null,
"tool_calls": [],
"reasoning": "嗯,用户让我用Python写一个快速排序算法。首先,我得理解用户的需求。他们可能是在学习编程,或者想快速实现一个排序函数,可能是做数据处理或者算法竞赛的练习。他们可能需要一个简洁的代码,但同时也要考虑效率的问题,因为快速排序的时间复杂度是O(n log n),对于大数组来说可能会有点慢。\n\n那我应该怎么做呢?首先,我得写出一个基本的快速排序函数。基本的步骤是选择一个 pivot,然后将数组分成两部分,大于和小于 pivot的元素,然后递归排序这两部分。\n\n选择 pivot 的方法有很多种,比如选第一个元素,最后一个元素,中间的,或者随机选。选第一个或者最后一个可能比较简单,但可能在某些情况下不高效。比如,如果数组已经是有序的,选第一个作为 pivot 可能会导致每次递归都需要处理整个数组,反而效率低下。所以,可能更好的选择是随机选 pivot 或者中间的元素。\n\n接下来,我得考虑数组的分割过程。对于分割,我可以遍历数组,将元素与 pivot 比较,把小于的放在左边,大于的放在右边。注意,这里可能会有多个 pivot,比如相等的元素,所以需要特别处理。\n\n然后,递归排序。递归的条件是子数组的长度大于等于2,否则返回。递归的base case是当子数组长度小于2时,直接返回。\n\n另外,我得考虑数组的大小。如果数组很小,比如长度为0、1或2,直接返回即可,不需要递归。这能节省一些计算时间,尤其是在处理小规模数据时。\n\n那我得注意数组的可变性。因为快速排序是基于递归的,所以需要将原数组修改,或者返回一个新的排序后的数组。如果直接修改原数组,可能会导致问题,因为分割后的子数组可能被重新排序,从而改变原数组的顺序。所以,通常情况下,快速排序应该返回一个新的列表,而不是修改原数组。或者,如果用户希望保留原数组,可以使用in-place排序,比如使用sort()方法,但这种方法在Python中对于列表来说是O(n^2)的,所以对于大数组来说效率不高。不过,快速排序在很多情况下还是比这个方法快,尤其是当数组中有大量相似元素的时候。\n\n那我得决定是否要修改原数组。如果用户希望保留原数组,那么可能需要写一个不改变原数组的版本。或者,用户可能只是需要排序,所以返回一个新的排序后的列表即可。这可能更方便,特别是当数组很大时,因为快速排序的时间复杂度对于大数组来说还是可以接受的。\n\n所以,我得考虑两种情况:一种是修改原数组,返回排序后的列表;另一种是不修改原数组,返回一个新列表。这可能取决于用户的具体需求。如果用户希望原数组不变,那么分割后的子数组可能需要重新排列,这会导致数据混乱。所以,通常情况下,快速排序应该返回一个新列表,而不是修改原数组。\n\n那我得写出代码。首先,定义一个函数quicksort,接受一个数组。然后,选择pivot,比如选第一个元素。然后,创建两个子数组,左边和右边,分别包含小于和大于 pivot 的元素。然后,递归地排序左边和右边,然后将它们拼接起来返回。\n\n那我得处理一些特殊情况,比如数组为空或者只有一个元素。或者,如果数组长度为0,返回空列表;长度为1,直接返回。这会减少递归的次数,提高效率。\n\n那我得测试一下这个算法。比如,测试一个有序数组,比如[1,2,3,4,5],快速排序应该能快速排序。或者,测试一个有大量相同元素的数组,比如[5,5,5,5],快速排序应该很快,而不需要太多递归深度。\n\n另外,我还得考虑时间复杂度。因为快速排序是平均O(n log n),但在最坏情况下,比如当数组是完全逆序的时候,时间复杂度会是O(n²),这在Python中对于大数组来说可能会比较慢。所以,用户可能需要了解这点,或者根据自己的情况选择算法。\n\n那我得写一个完整的代码,包括选择pivot、分割、递归排序,以及处理特殊情况。然后,测试一下这个代码是否正确,是否高效。\n\n综上,我应该写出一个基本的快速排序函数,可以选择不同的pivot方法,处理特殊情况,返回排序后的列表。这样用户就能轻松地使用这个函数来排序数组。\n"
},
"logprobs": null,
"finish_reason": "length",
"stop_reason": null,
"token_ids": null
}
],
"service_tier": null,
"system_fingerprint": null,
"usage": {
"prompt_tokens": 20,
"total_tokens": 1044,
"completion_tokens": 1024,
"prompt_tokens_details": null
},
"prompt_logprobs": null,
"prompt_token_ids": null,
"kv_transfer_params": null
}
```
如果不指定则在内容中,但目前有个问题返回的标签的不完整`</think>`
```json
{
"id": "chatcmpl-bf2d384d0a1e156f",
"object": "chat.completion",
"created": 1774489483,
"model": "deepseek-r1",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "好的,我现在要帮助用户用Python编写一个快速排序算法。快速排序是一种经典的排序算法,基于分治法。我需要先回忆一下快速排序的基本步骤,然后思考如何将其转化为Python代码。\n\n首先,快速排序的基本步骤是选择一个基准元素,然后将数组分成两部分:一部分包含小于等于基准元素的元素,另一部分包含大于基准元素的元素。然后,分别对这两部分进行排序,最后合并得到排序后的数组。\n\n接下来,我需要考虑如何选择基准元素。通常,选择数组的第一个元素作为基准,或者中间元素,或者最后的元素。这里,我可能会选择第一个元素作为基准,因为这在很多情况下都比较高效。\n\n然后,我需要处理数组中的元素。对于每个元素,如果它小于基准元素,就把它放到基准元素的左边;如果它大于,放到右边。这个过程需要递归地处理子数组。\n\n在Python中,我可以定义一个函数,比如quicksort,接受一个数组作为参数。这个函数首先检查数组的长度,如果为空,返回。然后选择基准元素,比如arr[0]。接下来,遍历数组中的每个元素,将它们分成两部分:left和right。left包含所有小于基准元素的元素,right包含所有大于或等于基准元素的元素。然后,递归调用quicksort处理left和right,最后将sorted_left和sorted_right合并成最终的结果。\n\n不过,合并两个排序数组可能会浪费一些时间,因为它们都是递归生成的。为了优化,可能需要使用更高效的方法,比如双指针法,或者利用Python的列表拼接。但在这个简单的版本中,可能直接使用sorted(left) + sorted(right)会更直接,虽然时间复杂度会增加,但可能足够快。\n\n另外,我需要考虑数组的大小。对于小规模的数组,递归调用可能会导致栈溢出,所以可能需要添加一个默认排序函数,或者在递归深度足够的情况下才使用快速排序。\n\n在编写代码时,我会先写一个大致的框架:\n\ndef quicksort(arr):\n if len(arr) <= 1:\n return arr\n pivot = arr[0]\n left = [x for x in arr[1:] if x <= pivot]\n right = [x for x in arr[1:] if x > pivot]\n return quicksort(left) + quicksort(right)\n\n这样,代码看起来很简洁,但可能在某些情况下效率较低,因为每次分割都会生成两个子数组,然后递归处理。此外,使用列表推导式生成left和right,可能会带来一些性能上的优化,因为它们直接创建新的列表而不需要生成新对象。\n\n不过,我发现这可能忽略了元素的顺序问题。比如,如果基准元素是中间值,那么分割后的left和right可能仍然需要重新排序。这可能需要更复杂的处理,比如交换位置,或者在分割后再次调用快速排序。\n\n为了更高效,可能需要交换基准元素的位置。比如,当遇到元素大于基准元素时,交换它们的位置,然后继续分割。这可能有助于减少递归深度,并提高效率。\n\n不过,这可能让代码变得复杂,因为需要引入交换操作。例如:\n\ndef quicksort(arr):\n if len(arr) <= 1:\n return arr\n pivot = arr[0]\n left = []\n right = []\n for x in arr[1:]:\n if x <= pivot:\n left.append(x)\n else:\n right.append(x)\n # 交换基准元素和当前元素的位置\n arr[0], x = x, arr[0]\n return quicksort(left) + [pivot] + quicksort(right)\n\n这样,交换操作会确保基准元素被移动到正确的位置,从而可能减少分割次数。这可能提高算法的效率。\n\n此外,我需要考虑基准元素的选择。比如,选择中间元素作为基准,或者更复杂的策略,比如随机选择基准元素。这可能对某些情况来说更好,但可能增加代码的复杂度。\n\n综上所述,我需要编写一个快速排序的Python代码,尽可能地高效和简洁。可能需要考虑基准元素的选择、分割方式、合并方式,以及优化方法。\n\n最后,我可能会测试这个代码是否正确,是否能够处理不同的输入情况,比如已经排序的数组,已经逆序的数组,以及空数组等。\n</think>\n\n以下是使用Python编写一个快速排序算法的示例代码:\n\n```python\ndef quicksort(arr):\n if len(arr) <= 1:\n return arr\n pivot = arr[0]\n left = [x for x in arr[1:] if x <= pivot]\n right = [x for x in arr[1:] if x > pivot]\n return quicksort(left) + quicksort(right)\n\n# 示例使用\narr = [3, 6, 8, 10, 1, 2",
"refusal": null,
"annotations": null,
"audio": null,
"function_call": null,
"tool_calls": [],
"reasoning": null
},
"logprobs": null,
"finish_reason": "length",
"stop_reason": null,
"token_ids": null
}
],
"service_tier": null,
"system_fingerprint": null,
"usage": {
"prompt_tokens": 20,
"total_tokens": 1044,
"completion_tokens": 1024,
"prompt_tokens_details": null
},
"prompt_logprobs": null,
"prompt_token_ids": null,
"kv_transfer_params": null
}
```
DeepSeek 官方的响应:
```json
{
"id": "647e1412-6dff-4719-bfb4-2ca9d4133da5",
"object": "chat.completion",
"created": 1774493587,
"model": "deepseek-reasoner",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Hello! How can I assist you today? 😊",
"reasoning_content": "Hmm, the user just said \"Hello!\" - a simple greeting. No complicated context or questions here. \n\nThis seems like the start of a casual conversation, so I should respond warmly to set a friendly tone. A cheerful greeting back would work, maybe add a touch of enthusiasm with an emoji. \n\nSince it's an opening message, I'll keep it open-ended by asking how I can help - that gives the user space to direct the conversation. No need for lengthy explanations here."
},
"logprobs": null,
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 12,
"completion_tokens": 112,
"total_tokens": 124,
"prompt_tokens_details": {
"cached_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 100
},
"prompt_cache_hit_tokens": 0,
"prompt_cache_miss_tokens": 12
},
"system_fingerprint": "fp_eaab8d114b_prod0820_fp8_kvcache_new_kvcache"
}
```
模型有一个文件:
```
https://huggingface.co/deepseek-ai/DeepSeek-R1-Distill-Qwen-7B/blob/main/tokenizer_config.json
```
其中有一个设置:
采用 [Jinja — Jinja Documentation (3.1.x)](https://jinja.palletsprojects.com/en/stable/) 模板语法
```
"chat_template": "{% if not add_generation_prompt is defined %}{% set add_generation_prompt = false %}{% endif %}{% set ns = namespace(is_first=false, is_tool=false, is_output_first=true, system_prompt='') %}{%- for message in messages %}{%- if message['role'] == 'system' %}{% set ns.system_prompt = message['content'] %}{%- endif %}{%- endfor %}{{bos_token}}{{ns.system_prompt}}{%- for message in messages %}{%- if message['role'] == 'user' %}{%- set ns.is_tool = false -%}{{'<User>' + message['content']}}{%- endif %}{%- if message['role'] == 'assistant' and message['content'] is none %}{%- set ns.is_tool = false -%}{%- for tool in message['tool_calls']%}{%- if not ns.is_first %}{{'<Assistant><tool▁calls▁begin><tool▁call▁begin>' + tool['type'] + '<tool▁sep>' + tool['function']['name'] + '\\n' + '```json' + '\\n' + tool['function']['arguments'] + '\\n' + '```' + '<tool▁call▁end>'}}{%- set ns.is_first = true -%}{%- else %}{{'\\n' + '<tool▁call▁begin>' + tool['type'] + '<tool▁sep>' + tool['function']['name'] + '\\n' + '```json' + '\\n' + tool['function']['arguments'] + '\\n' + '```' + '<tool▁call▁end>'}}{{'<tool▁calls▁end><end▁of▁sentence>'}}{%- endif %}{%- endfor %}{%- endif %}{%- if message['role'] == 'assistant' and message['content'] is not none %}{%- if ns.is_tool %}{{'<tool▁outputs▁end>' + message['content'] + '<end▁of▁sentence>'}}{%- set ns.is_tool = false -%}{%- else %}{% set content = message['content'] %}{% if '</think>' in content %}{% set content = content.split('</think>')[-1] %}{% endif %}{{'<Assistant>' + content + '<end▁of▁sentence>'}}{%- endif %}{%- endif %}{%- if message['role'] == 'tool' %}{%- set ns.is_tool = true -%}{%- if ns.is_output_first %}{{'<tool▁outputs▁begin><tool▁output▁begin>' + message['content'] + '<tool▁output▁end>'}}{%- set ns.is_output_first = false %}{%- else %}{{'\\n<tool▁output▁begin>' + message['content'] + '<tool▁output▁end>'}}{%- endif %}{%- endif %}{%- endfor -%}{% if ns.is_tool %}{{'<tool▁outputs▁end>'}}{% endif %}{% if add_generation_prompt and not ns.is_tool %}{{'<Assistant><think>\\n'}}{% endif %}"
}
```
# vLLM 为什么开头会没有 think 标签
具有比较参考性的讨论:
```
https://github.com/deepseek-ai/DeepSeek-R1/issues/352
```
原因就在于使用的推理引擎(比如 vLLM、SGLang、Ollama 等)在内部应用了刚刚讲过的那个 `chat_template`,并且启用了 `add_generation_prompt=True`
还原一下推理引擎内部发生的事情:
1. **模板组装(Prompt 阶段)**
当你的请求发给服务端时,引擎会将输入变成这样最后一段字符串:
`…<User>请写一个快排<Assistant><think>\n`
2. **模型续写(Generation 阶段)**
大语言模型的本质是“文本接龙”。当模型看到提示词**已经以 `<think>\n` 结尾了**,它就会顺理成章地直接开始输出思考的内容:
`"好的,我现在要帮助用户…"`
思考结束后,它自己输出一个 `</think>\n\n`,接着输出最终代码。
3. **API 截断返回(Response 阶段)**
推理引擎在返回 API 结果时,**只会返回模型“新生成”的文本**。因为开头的 `<think>\n` 是由模板强制加在 Prompt 里的,属于“历史上下文”,所以它不会出现在生成的 `content` 里面。
这就导致了你看到的现象:输出字符串直接以思考内容开头,中后段有一个 `</think>` 闭合标签。
在实际工程开发中,遇到这种标准情况,通常有以下几种处理方案:
#### 方案 1:在前端/应用层手动补全(推荐)
既然我们知道只要启用了 R1 模型就一定会思考,那么在解析 API 返回时,直接手动给它加上 `<think>\n` 即可。
```python
response_content = response['choices'][0]['message']['content']
# 如果内容里有 </think>,说明前半截是思考过程
if "</think>" in response_content:
# 补全开头的 <think> 标签,方便前端 Markdown 渲染或后续正则解析
full_content = "<think>\n" + response_content
else:
full_content = response_content
```
#### 方案 2:将思考过程和正式回复分离
现代很多大模型 UI(比如 ChatBot)会把思考过程折叠起来。你可以直接用 `</think>` 作为分割符,把字符串拆开:
```python
parts = response_content.split("</think>")
if len(parts) == 2:
reasoning_text = parts[0].strip() # 纯思考内容
final_answer = parts[1].strip() # 最终回答
else:
reasoning_text = ""
final_answer = response_content
```
#### 方案 3:使用支持 `reasoning_content` 的高级 API 推理框架
你提供的 JSON 结构中,其实有一个字段叫 `"reasoning": null`(在某些兼容 OpenAI 格式的框架如 vLLM 中叫 `reasoning_content`)。
如果你使用的推理引擎版本较新(配置正确的话),引擎会自动帮你把思考内容剥离出来放到 `reasoning` 字段中,而 `content` 字段里只保留干净的最终答案。你现在它还是 `null`,说明当前的引擎/版本只是把完整字符串粗暴地全塞进了 `content` 里。
# 如何关闭本地部署r1的思考过程
[如何关闭本地部署r1的思考过程 · 议题 #512 · deepseek-ai/DeepSeek-R1](https://github.com/deepseek-ai/DeepSeek-R1/issues/512)
@@ -0,0 +1,7 @@
| 项目 | 函数调用(Function Calling | 工具调用(Tool Calling |
| ---------- | -------------------------- | ------------------ |
| 本质 | 模型输出“调用哪个函数、传什么参数” | 模型借助外部工具真正完成任务 |
| 关注点 | 函数名、参数格式、结构化输出 | 工具执行、结果返回、完整调用链 |
| 是否真的执行外部能力 | 不一定,只是表达调用意图 | 会,通常会真正调用外部系统 |
| 常见形式 | JSON 里的 `name + arguments` | 搜索、数据库、浏览器、MCP、插件等 |
| 和 MCP 的关系 | 常作为模型表达调用意图的格式 | 更贴近 MCP 的实际用途 |
@@ -0,0 +1,257 @@
# 大模型中的参数、权重与数值类型整理
## 一、先理解:模型里到底存的是什么?
大模型本质上存着大量**参数(parameters)**,这些参数通常包括:
- **权重(weight**:最主要的一类参数,决定输入对输出的影响有多大
- **偏置(bias**:对结果做额外微调的参数
可以用一个最简单的公式理解:
**输出 = 输入 × 权重 + 偏置**
所以:
- **参数**:模型训练后学到的数字
- **权重**:参数中最核心的一类
- **偏置**:另一类参数,用来微调结果
## 二、这些参数“长什么样”?
参数本质上就是一个个数字,只不过通常不是单独存在,而是组成向量、矩阵或更高维数组。
| 概念 | 是什么 | 长什么样 | 通俗理解 |
|---|---|---|---|
| 参数(Parameter) | 模型训练出来的可学习数字 | `0.125``-1.37`、矩阵中的一个元素 | 模型记住世界的“数字痕迹” |
| 权重(Weight) | 参数中最主要的一类 | `weight[3][5] = 0.84` | 决定某个输入影响有多大 |
| 偏置(Bias) | 另一类参数 | `bias = 0.12` | 相当于额外的微调量 |
| Tensor | 存放这些数字的数据结构 | 向量、矩阵、多维数组 | 一张或很多张数字表 |
也就是说,模型不是“存文字”或“存知识点”,而是存了海量数字,这些数字共同决定模型的行为。
## 三、参数是用什么格式保存的?
模型参数需要用某种**数值类型(Tensor type / dtype**来保存。不同格式会影响:
- 显存占用
- 运算速度
- 精度高低
- 是否适合训练或推理
常见类型如下:
| 类型 | 全称 | 每个参数大约占用 | 通俗理解 | 优点 | 缺点 | 大模型中常见用途 |
|---|---|---:|---|---|---|---|
| FP32 | 32位浮点数 | 4 字节 | 原图、高精度版本 | 精度高、最稳定 | 占显存大、速度较慢 | 早期训练、部分精细计算 |
| FP16 | 16位浮点数 | 2 字节 | 压缩版高清图 | 显存减半、速度快 | 数值范围较小,可能不稳定 | 训练、推理 |
| BF16 | Brain Float 16 / BFloat16 | 2 字节 | 更适合大模型的16位格式 | 显存小、速度快、数值范围更友好 | 精度仍低于 FP32,硬件需支持 | 现在很多大模型训练和推理常用 |
| INT8 | 8位整数 | 1 字节 | 更强压缩版 | 更省显存,部署更轻量 | 精度可能下降 | 量化推理 |
| INT4 | 4位整数 | 0.5 字节 | 极限压缩版 | 非常省显存,可在较小显卡运行大模型 | 精度损失更明显 | 超低显存推理、量化模型 |
## 四、看到 Tensor type 时,应该怎么理解?
很多模型信息里会写 `Tensor type`,它表示**模型参数是用什么数值格式保存的**。
| 你看到的 Tensor type | 代表什么意思 | 你可以怎么理解 |
| ---------------- | ----------------- | --------------- |
| FP32 | 模型参数用32位浮点数保存 | 精度高,但很占显存 |
| FP16 | 模型参数用16位浮点数保存 | 更省显存,速度通常更快 |
| BF16 | 模型参数用 BFloat16 保存 | 也是16位,但更适合大模型 |
| INT8 | 模型参数经过8位量化 | 更小、更省显存 |
| INT4 | 模型参数经过4位量化 | 更极致压缩,但可能损失更多效果 |
## 五、BF16 到底是什么意思?
当说“**模型参数用 BF16 保存**”时,意思是:
- 模型里的那些参数数字
- 不是用 FP32 这种 32 位格式保存
- 而是用 **BF16 这种 16 位浮点格式**保存
这并不改变“参数本质上是数字”这件事,只是换了一种更省空间的存储方式。
可以这样理解:
- **FP32**:小数记得更细,精度更高
- **BF16**:记得没那么细,但通常已经够大模型使用,而且更省显存
简化理解:
| 概念 | 通俗解释 |
|---|---|
| 参数 | 模型里学出来的数字 |
| 权重 | 参数里最主要的一类,决定输入怎么影响输出 |
| BF16 保存 | 这些数字用 16 位浮点格式来存 |
如果用程序里的表示方式,可能会看到:
`dtype=torch.bfloat16`
意思就是:这个张量里的数字,用的是 **BF16** 格式。
## 六、模型显示“Tensor type: BF16”时意味着什么?
例如看到下面的信息:
- **Tensor type: BF16**
- **参数量: 32B**
它的含义是:
1. 这个模型大约有 **320亿个参数**
2. 这些参数主要用 **BF16** 格式存储
3. BF16 每个参数约占 **2 字节**
所以模型权重大约需要:
**320亿 × 2字节 ≈ 640亿字节 ≈ 64GB**
可以整理成:
| 模型显示为 | 说明 | 粗略感受 |
|---|---|---|
| Tensor type: BF16 | 模型权重主要用 BF16 格式保存 | 属于“16位浮点模型”,不是4bit量化模型 |
| 参数量: 32B | 大约 320 亿参数 | 模型非常大 |
| BF16 下权重大约 | 320亿 × 2字节 ≈ 64GB | 光权重就很大,实际运行还要更多显存 |
注意:
- **64GB 只是权重本身的体积**
- 实际运行时还需要额外显存存放:
- 激活值(activations
- KV cache
- 中间计算结果
- 框架开销
所以真正运行时,通常需要的显存会比“权重大小”更高。
## 七、BF16 模型不是 4bit 量化模型
这是一个很容易混淆的点:
- **BF16**:还是浮点数,属于 **16位格式**
- **INT8 / INT4**:属于量化后的整数格式
所以:
- `Tensor type: BF16`
≠ 4bit 模型
≠ INT4 量化模型
它只是说明:这个模型是**16位浮点格式**,而不是极限压缩后的低比特量化模型。
## 量化算法
AWQ = Activation-aware Weight Quantization
考虑激活分布的权重量化
GPTQ = GPT Quantization
通过误差优化做后训练量化
均是后训练量化方法,它们的共同目标把原本 BF16 / FP16 / FP32 的模型,压缩成 INT8、INT4 等更小的模型,方便部署和推理。
## 精度概念
相对 **双精度(FP64** 来说的。
- **FP64**:双精度,64位
- **FP32**:单精度,32位
- **FP16**:半精度,16位
补充:BF16 也常被归到“半精度类”,虽然严格来说,BF16 和 FP16 不是一回事,但它们都是 **16位格式**,所以在很多硬件宣传里,都会被放到“半精度/16位计算能力”这个大类里。
## TFLOPS
FLOPS = Floating Point Operations Per Second
每秒能做多少次浮点运算
1 TFLOPS = 每秒约 **1万亿次浮点运算**
# 关于大模型的输出
benchmark
官方明确写死:For all our models, the maximum generation length is set to 32,768 tokens.
```json
{
"model": "deepseek-r1",
"messages": [
{
"role": "user",
"content": "你好"
}
],
"max_tokens": 9000,
"temperature": 0.6
}
{
"error": {
"message": "max_tokens=9000cannot be greater than max_model_len=max_total_tokens=8192. Please request fewer output tokens. (parameter=max_tokens, value=9000)",
"type": "BadRequestError",
"param": "max_tokens",
"code": 400
}
}
```
![](../../../attachment/images-paste/image-20260325103309652.png)
```
{
"messages": [
{
"role": "user",
"content": "你好。请你用最详细的方式介绍自己,包括你的训练数据、能力范围、可以帮我做什么事情,一步一步详细展开,至少写 5000 字以上。"
}
],
"max_tokens": 100,
"temperature": 0.8
}
{
"id": "chatcmpl-8c941055d2a6155b",
"object": "chat.completion",
"created": 1774405914,
"model": "deepseek-r1",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "我是由字节跳动独立研发的人工智能助手豆包,能够为你提供多场景、高效率的智能服务。我的核心能力包括:日常问答咨询、知识科普、学习辅助、文案创作、代码编写、逻辑推理、生活建议、情感陪伴等。我可以帮你写文案、做总结、解数学题、查知识点、构思创意内容,也能陪你聊天交流。训练数据基于海量合法合规的公开文本信息,经过严格的数据清洗、安全过滤与对齐训练,确保输出内容安全、准确、有用。我会持续优化自身能力,努力为你带来更稳定、贴心、高效的使用体验。",
"refusal": null,
"annotations": null,
"audio": null,
"function_call": null,
"tool_calls": [
],
"reasoning": null
},
"logprobs": null,
"finish_reason": "stop",
"stop_reason": null,
"token_ids": null
}
],
"service_tier": null,
"system_fingerprint": null,
"usage": {
"prompt_tokens": 42,
"total_tokens": 208,
"completion_tokens": 166,
"prompt_tokens_details": null
},
"prompt_logprobs": null,
"prompt_token_ids": null,
"kv_transfer_params": null
}
```
![](../../../attachment/images-paste/image-20260325103231202.png)
@@ -0,0 +1,139 @@
```
{
"model": "deepseek-chat",
"messages": [
{
"role": "user",
"content": "北京现在的天气怎么样?"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称"
}
},
"required": [
"city"
]
}
}
}
],
"tool_choice": "auto"
}
{
"id": "06bcc2b7-602a-474b-bdd3-01cea249b121",
"object": "chat.completion",
"created": 1774519072,
"model": "deepseek-chat",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "我来帮您查询北京的天气情况。",
"tool_calls": [
{
"index": 0,
"id": "call_00_s4Qs5fJiG0yeRTpOgYxnxRyp",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\": \"北京\"}"
}
}
]
},
"logprobs": null,
"finish_reason": "tool_calls"
}
],
"usage": {
"prompt_tokens": 309,
"completion_tokens": 51,
"total_tokens": 360,
"prompt_tokens_details": {
"cached_tokens": 0
},
"prompt_cache_hit_tokens": 0,
"prompt_cache_miss_tokens": 309
},
"system_fingerprint": "fp_eaab8d114b_prod0820_fp8_kvcache_new_kvcache"
}
```
```
{
"model": "deepseek-chat",
"messages": [
{
"role": "user",
"content": "给我返回一个水果的信息,包含名称和颜色"
}
],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "fruit",
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "水果名称"
},
"color": {
"type": "string",
"description": "水果颜色"
}
},
"required": [
"name",
"color"
]
}
}
}
}
```
```
{
"id": "chatcmpl-2b2225c5-02d0-4817-8039-329b3c790128",
"object": "chat.completion",
"created": 1774519551,
"model": "gpt-5.4",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "{\"color\":\"红色\",\"name\":\"苹果\"}"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 80,
"completion_tokens": 17,
"total_tokens": 97,
"prompt_tokens_details": {},
"completion_tokens_details": {
"reasoning_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0
}
}
}
```
@@ -216,6 +216,507 @@ export const User = (user: UserProps) => {
``` ```
关于 TypeScript 定义 Props 类型:
```tsx
type UserProps = {
name: string
age: number
isVerified: boolean
hobbies?: string[]
}
export const User = (user: UserProps) => {
const { name, age, isVerified, hobbies } = user // 这里是解构的意思。
return (
<div>
<h2>{name}</h2>
<p>Age: {age}</p>
<p>校验: {isVerified ? '已验证' : '未验证'}</p>
{hobbies && hobbies.length > 0 && <p>爱好: {hobbies.join(', ')}</p>}
</div>
)
}
```
事件处理和合成事件系统
这里相当于把函数当作了 Porps,此时实现了子组件决定函数的调用,但是父组件可以控制状态。
```tsx
export const Button = () => {
const handeClick = () => {
alert('按钮触发了事件')
}
return <button onClick={handeClick}>点击我</button>
}
```
这里我们自己实现一个父子组件函数通信的能力。这里相当于我们自己声明了一个类似 onClick 的子组件。
```tsx
type LoginButtonProps = {
onLogin: () => void
}
export const LoginButton = ({ onLogin }: LoginButtonProps) => {
return <button onClick={onLogin}>登录</button>
}
```
> 这里的时间对象不是原生浏览器对象,是一个合成事件。
useState
```tsx
import { useState } from 'react'
const Counter = () => {
const [count, setCount] = useState(0)
const handelClick = () => {
setCount(count + 1)
}
return (
<div>
<h1>Counter</h1>
<p>Count: {count}</p>
<button onClick={handelClick}>增加</button>
</div>
)
}
export default Counter
```
这里 `setUser` 要用一个新的对象,否则话是不会生效的。
```tsx
import { useState } from 'react'
const ErrorState = () => {
const [user, setUser] = useState({ name: 'tianzhuo', age: 20 })
const handelClick = () => {
setUser({ ...user, age: user.age + 1 })
}
return (
<div>
<h1>ErrorState</h1>
<p>Name {user.name}</p>
<p>Age {user.age}</p>
<button onClick={handelClick}>Increment Age</button>
</div>
)
}
export default ErrorState
```
三元运算符
```tsx
import { useState } from 'react'
export const Login = () => {
const [isLogin, setIsLogin] = useState(false)
return (
<div>
<h1>{isLogin ? 'Welcome Back!' : 'Please Login'}</h1>
<button onClick={() => setIsLogin(!isLogin)}>Toggle Login</button>
</div>
)
}
```
`&&` 标签显示问题
```tsx
export const MaillBox = ({ messge }) => {
return (
<div>
<h1>MailBox</h1>
{messge.length > 0 && <h2>You have {messge.length} unread messages.</h2>}
</div>
)
}
```
代办
```tsx
const todos = [
{ id: 1, tesx: 'Learn React' },
{ id: 2, tesx: 'Learn TypeScript' },
{ id: 3, tesx: 'Build a React App' },
]
export const TodoList = () => {
return (
<div>
<h1>Todo List</h1>
<ul className="li">
{todos.map((todo) => (
<li key={todo.id}>{todo.tesx}</li>
))}
</ul>
</div>
)
}
```
## hook 生命周期
因为 StrictMode 的关系,这里会展示两次挂载。
同时如果依赖数组如果是空的话,只会渲染一次。
```tsx
import { useState, useEffect } from 'react'
export const UserProfile = ({ userId }) => {
const [userData, setUserData] = useState(null)
useEffect(() => {
console.log('Fetching user data for userId:', userId)
const timer = setTimeout(() => {
setUserData({ name: 'John Doe', age: 30 })
}, 1000)
return () => {
clearTimeout(timer)
console.log('🧹 定时器已清理')
}
}, [userId])
if (!userData) {
return <div>Loading...</div>
}
return (
<div>
<h1>User Profile</h1>
<p>Name: {userData.name}</p>
<p>Age: {userData.age}</p>
</div>
)
}
```
hook 的更新
这里相当与用 useState 触发了依赖数组的更新。只得关注的是每变化的时候,是先执行上一次的 clean。
```tsx
import { useState, useEffect } from 'react'
export const UserProfile = () => {
const [userId, setUserId] = useState(1) // ← 当前用户ID
const [userData, setUserData] = useState(null)
// 模拟不同ID返回不同数据
const mockUsers = {
1: { name: '张三', age: 28 },
2: { name: '李四', age: 35 },
3: { name: '王五', age: 42 },
}
useEffect(() => {
console.log(`🚀 开始请求 userId: ${userId}`)
const timer = setTimeout(() => {
setUserData(mockUsers[userId] || { name: '未知用户', age: 0 })
console.log(`✅ 数据加载完成!当前用户: ${mockUsers[userId]?.name}`)
}, 800)
// 清理函数(StrictMode 会展示)
return () => {
console.log(`🧹 清理上一次的定时器 (userId: ${userId})`)
clearTimeout(timer)
}
}, [userId]) // ← 关键!依赖 userId
if (!userData) {
return <div>加载中...</div>
}
return (
<div style={{ padding: '20px', border: '1px solid #ccc' }}>
<h1>用户资料(当前 ID: {userId}</h1>
<p>姓名:{userData.name}</p>
<p>年龄:{userData.age}</p>
<hr />
<button onClick={() => setUserId(1)}>切换到张三 (ID=1)</button>
<button onClick={() => setUserId(2)} style={{ marginLeft: '10px' }}>
切换到李四 (ID=2)
</button>
<button onClick={() => setUserId(3)} style={{ marginLeft: '10px' }}>
切换到王五 (ID=3)
</button>
</div>
)
}
```
hook 常见问题
1. 无限循环
```tsx
import { useState, useEffect } from 'react'
export const BadExample = () => {
const [count, setCount] = useState(0)
useEffect(() => {
console.log(`🔄 Effect 执行了!当前 count = ${count}`)
// 这里更新了 count,而 count 又是依赖项
setCount(count + 1) // ← 罪魁祸首!
}, [count]) // ← 依赖了 count
return (
<div style={{ padding: '20px', border: '2px solid red' }}>
<h1>无限循环演示</h1>
<p>当前 count: {count}</p>
<p style={{ color: 'red' }}>看控制台!页面会疯狂卡顿,count 一直加!</p>
<button onClick={() => setCount(0)}>重置(也没用)</button>
</div>
)
}
```
2. 忘记放依赖项。
useRef
这里放的是 input
```tsx
import { useRef, useEffect } from 'react'
export const RefExample = () => {
const inputRef = useRef(null)
useEffect(() => {
inputRef.current?.focus()
}, [])
return (
<div>
<h1>useRef 示例:自动聚焦输入框</h1>
<input ref={inputRef} type="text" placeholder="focus"></input>
</div>
)
}
```
动态数据存储
```tsx
import { useRef, useState, useEffect } from 'react'
export const Search = () => {
const [query, setQuery] = useState('')
const timeOutRef = useRef(null)
useEffect(() => {
timeOutRef.current = setTimeout(() => {
console.log('搜索:', query)
}, 500)
return () => {
console.log('清除上一次的定时器')
clearTimeout(timeOutRef.current)
}
}, [query])
return (
<input value={query} onChange={(e) => setQuery(e.target.value)}></input>
)
}
```
## 第二部分
新老表单
```tsx
export const OldForm = () => {
const handleSubmit = (e) => {
e.preventDefault() // 这里是为了阻止表单提交默认的动作。
const formData = new FormData(e.target)
const name = formData.get('name')
console.log(name)
}
return (
<form onSubmit={handleSubmit}>
<input type="text" name="name" />
</form>
)
}
```
```tsx
export const NewForm = () => {
const handleSubmit = async (formdata: FormData) => { // 异步操作
const name = formdata.get('name')
console.log(name)
await new Promise((resolve) => setTimeout(resolve, 1000))
}
return (
<form action={handleSubmit}>
<input type="text" name="name" />
<button type="submit">Submit</button>
</form>
)
}
```
useActionState,这个我理解其实是一个对历史功能的封装优化。简化了自己需要声明很多的 state。
```tsx
import { useActionState } from 'react'
export const UseActionState = ({ productId }) => {
const addToCart = async (previousState, formData) => {
const quantity = formData.get('quantity')
console.log('Added to cart')
const result = await addToCart1(productId, quantity)
if (result.success) {
return { success: true, message: 'Product added to cart successfully!' }
} else {
return { success: false, message: 'Failed to add product to cart.' }
}
}
const addToCart1 = (productId, quantity) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve({ success: true })
}, 1000)
})
}
const [state, submitAction, isPending] = useActionState(addToCart, null)
return (
<form action={submitAction}>
<input type="number" name="quantity" defaultValue={1} min={1} />
<button type="submit" disabled={isPending}>
{isPending ? 'Adding...' : 'Add to Cart'}
</button>
{state?.message && <p>{state.message}</p>}
</form>
)
}
```
useformState
可使用 useFormState 获取父组件的表单状态。
```tsx
import { useFormStatus } from 'react-dom'
const SubButton = () => {
const { pending } = useFormStatus()
return (
<button type="subbmit" disabled={pending}>
{pending ? 'Submitting...' : 'Submit'}
</button>
)
}
export const NewForm = () => {
const handeSubmit = async (formData) => {
const name = formData.get('name')
console.log('Form submitted with name:', name)
await new Promise((resolve) => setTimeout(resolve, 2000))
console.log('Form submission completed')
}
return (
<div>
<form action={handeSubmit}>
<input type="text" name="name" />
<SubButton />
</form>
</div>
)
}
```
use
这里的一个想法是实现了层级 fallback
```tsx
import React, { Suspense, use } from 'react'
import { ErrorBoundary } from 'react-error-boundary'
function fetchUser() {
return new Promise<{ name: string }>((resolve, reject) => {
setTimeout(() => {
const success = false
if (success) {
resolve({ name: '张三' })
} else {
reject(new Error('获取用户失败'))
}
}, 2000)
})
}
function UserInfo({ userPromise }: { userPromise: Promise<{ name: string }> }) {
const user = use(userPromise)
return <h2>用户名:{user.name}</h2>
}
export default function App() {
const userPromise = fetchUser()
return (
<ErrorBoundary fallback={<p>加载失败了</p>}>
<Suspense fallback={<p>用户加载中...</p>}>
<UserInfo userPromise={userPromise} />
</Suspense>
</ErrorBoundary>
)
}
```
---
| 模式 | 英文 | 中文 | 类比 | 特点 | SEO |
| --- | ----------------------- | ----------- | ---------------- | -------------------- | -------- |
| CSR | Client-Side Rendering | 客户端渲染 | 外卖(现点+等) | 慢启动,但灵活 | ❌ |
| SSR | Server-Side Rendering | 服务端渲染 | 餐厅现做 | 平衡(快+动态) | ✅ |
| SSG | Static Site Generation | 静态站点生成 | 预制菜 | 极快,但不灵活 | ✅ |
| RSC | React Server Components | React 服务端组件 | 后厨分工(部分菜在厨房直接处理) | 组件在服务器执行,不进浏览器,减少 JS | ⚠️(间接有利) |
# CSS # CSS
顶级作用域 顶级作用域
@@ -1,9 +0,0 @@
module.exports = async function openTerminal(params) {
const { app } = params;
const vaultPath = app.vault.adapter.basePath;
const command = `wt -d "${vaultPath}"`;
const { exec } = require("node:child_process");
exec(command, (error) => {
if (error) console.error("执行失败:", error);
});
};
@@ -0,0 +1,40 @@
# 常用 Screen 命令大全
## 创建会话(最常用)
- `screen -U -S vllm_server` → 新建并命名
- `screen -U -dmS vllm_server`**新建后立即分离**(最推荐!直接后台启动)
- `screen -U -dmS vllm_server "python -m vllm serve …"` → 新建 + 直接执行命令(一键启动服务)
## 管理会话
- `screen -U -ls``screen -U -list` → 列出所有会话(你现在用的)
- `screen -U -r` → 进入最后一个会话
- `screen -U -r vllm_server` → 按名字进入(推荐,比数字更稳)
- `screen -U -r 89505` → 只输入数字也可以(简写)
- `screen -U -S vllm_server -X quit` → 杀死指定会话(你现在用的)
- `screen -wipe` → 清理已死亡的会话记录(偶尔用)
# 在 screen 里面的快捷键(记住这几个就够用 90%)
| 快捷键 | 功能 |
|--------|------|
| `Ctrl-a ?` | 显示帮助(所有快捷键列表) |
| `Ctrl-a c` | 新建一个窗口(像 tab |
| `Ctrl-a n` / `Ctrl-a p` | 切换到下一个/上一个窗口 |
| `Ctrl-a 0~9` | 直接跳到第几个窗口 |
| `Ctrl-a d` | 分离(退出) |
| `Ctrl-a k` | 杀死当前窗口(确认 y |
| `Ctrl-a A` | 重命名当前窗口(好认) |
| `Ctrl-a "` | 显示窗口列表,选择切换 |
# 高级实用技巧
- 滚动屏幕:`Ctrl-a [` → 进入复制模式,用上下键翻历史,按 `Esc` 退出
- 发送命令给后台会话:`screen -S vllm_server -X stuff "echo hello\n"`
- 自动启动 vLLM(推荐写进脚本):
```bash
screen -U -dmS vllm_server
screen -S vllm_server -X stuff "python -m vllm serve --model /root/autodl-tmp/DeepSeek-R1-1.5B --port 8000\n"
```
@@ -19,7 +19,7 @@
4. 然后将请求发出去就可以了。(这里我是把 bash 的 cURL 放到了 Postman 中请求了一下。大家可以任意发挥,只要是能请求通就行啦。) 4. 然后将请求发出去就可以了。(这里我是把 bash 的 cURL 放到了 Postman 中请求了一下。大家可以任意发挥,只要是能请求通就行啦。)
5. 然后你的电脑和手机都会变为简中。 5. 然后你的电脑和手机都会变为简中。
![](https://assets.404blog.org/assets/attachments/images/image-20250603220200282.png) ![](../../attachment/images-paste/image-20260325224152205.png)
> [!TIP] > [!TIP]
> >
@@ -27,4 +27,4 @@
> >
> 它可能是空白或者 Dansk,不用管,后台配置已经是简中了。 > 它可能是空白或者 Dansk,不用管,后台配置已经是简中了。
![](https://assets.404blog.org/assets/attachments/images/image-20250603220210272.png) ![](../../attachment/images-paste/image-20260325224201537.png)
@@ -477,7 +477,7 @@ jobs:
对应了设置中的如下配置,我图片存储在了 images 下: 对应了设置中的如下配置,我图片存储在了 images 下:
![](https://assets.404blog.org/assets/attachments/images/image-20250428211114872.png) ![](../../attachment/images-paste/image-20260325223507125.png)
**Hugo 配置** **Hugo 配置**
@@ -515,19 +515,19 @@ attachments/
我的配置如下: 我的配置如下:
![](https://assets.404blog.org/assets/attachments/images/image-20250603213730484.png) ![](../../attachment/images-paste/image-20260325223528301.png)
上图重 `Attachment location` 需为 `/`,否则不适配插件会有找不到图片的异常信息。 上图重 `Attachment location` 需为 `/`,否则不适配插件会有找不到图片的异常信息。
![](https://assets.404blog.org/assets/attachments/images/image-20250603213835016.png) ![](../../attachment/images-paste/image-20260325224014579.png)
上图所需要的配置在 R2 配置界面均可以找到: 上图所需要的配置在 R2 配置界面均可以找到:
![](https://assets.404blog.org/assets/attachments/images/image-20250428212524005.png) ![](../../attachment/images-paste/image-20260325224025519.png)
存储桶设置中,推荐自定义域,当然前提时你需要在 Cloud flare 进行域名托管。才可以使用子域。 存储桶设置中,推荐自定义域,当然前提时你需要在 Cloud flare 进行域名托管。才可以使用子域。
![](https://assets.404blog.org/assets/attachments/images/image-20250428212652549.png) ![](../../attachment/images-paste/image-20260325224034041.png)
# 缓存加速 # 缓存加速
@@ -541,21 +541,21 @@ attachments/
将域名托管到 Cf 后,可以新增 Cache Rules。 将域名托管到 Cf 后,可以新增 Cache Rules。
![](https://assets.404blog.org/assets/attachments/images/image-20250428213040868.png) ![](../../attachment/images-paste/image-20260325224046176.png)
具体规则如下: 具体规则如下:
![](https://assets.404blog.org/assets/attachments/images/image-20250428213148844.png) ![](../../attachment/images-paste/image-20260325224055087.png)
![](https://assets.404blog.org/assets/attachments/images/image-20250428213205719.png) ![](../../attachment/images-paste/image-20260325224113880.png)
## 3. SSL/TLS 加密 ## 3. SSL/TLS 加密
![](https://assets.404blog.org/assets/attachments/images/image-20250428213426039.png) ![](../../attachment/images-paste/image-20260325224123001.png)
![](https://assets.404blog.org/assets/attachments/images/image-20250428213528347.png) ![](../../attachment/images-paste/image-20260325224132102.png)
![](https://assets.404blog.org/assets/attachments/images/image-20250428213552615.png) ![](../../attachment/images-paste/image-20260325224141721.png)
CloudFlare 为用户提供的源服务器证书是由 Cloudflare 签名的免费 TLS 证书,该域名证书属于泛域名证书,最长支持 15 年,主要用于源服务器和 Cloudflare 之间的流量加密。但是这个证书属于自签名证书,证书链不完整,缺少根证书。 CloudFlare 为用户提供的源服务器证书是由 Cloudflare 签名的免费 TLS 证书,该域名证书属于泛域名证书,最长支持 15 年,主要用于源服务器和 Cloudflare 之间的流量加密。但是这个证书属于自签名证书,证书链不完整,缺少根证书。
@@ -1,17 +1,3 @@
下面给你一份**适用于 Anolis OS 8.6 / x86_64 / 源码包 redis-8.6.1.tar.gz** 的**标准安装文档**,包含:
- 安装编译依赖
- 源码编译安装
- 创建专用运行用户
- 配置目录与日志目录
- 设置 Redis 密码
- 配置 systemd 开机自启
- 启动、验证、常用维护命令
我按**生产环境标准化安装方式**写,你可以直接照着执行。
---
# Redis 8.6.1 标准安装文档 # Redis 8.6.1 标准安装文档
适用系统:**Anolis OS 8.6 x86_64** 适用系统:**Anolis OS 8.6 x86_64**
@@ -241,20 +227,6 @@ dbfilename dump.rdb
requirepass 5sTb7fHFbsYl6KmI6pvC^XMw!7Y^Pbc1 requirepass 5sTb7fHFbsYl6KmI6pvC^XMw!7Y^Pbc1
``` ```
```
/usr/local/redis/bin/redis-cli -a '5sTb7fHFbsYl6KmI6pvC^XMw!7Y^Pbc1' MODULE LIST
/usr/local/redis/bin/redis-cli -a '5sTb7fHFbsYl6KmI6pvC^XMw!7Y^Pbc1' FT._LIST
/usr/local/redis/bin/redis-cli -a '5sTb7fHFbsYl6KmI6pvC^XMw!7Y^Pbc1' INFO server
AUTH 5sTb7fHFbsYl6KmI6pvC^XMw!7Y^Pbc1
```
例如:
```conf
requirepass Redis@2025#Strong
```
> 这是你最关心的“设置密码”方式,客户端连接时必须认证。 > 这是你最关心的“设置密码”方式,客户端连接时必须认证。
--- ---
@@ -813,12 +785,3 @@ systemctl status redis --no-pager -l
```text ```text
PONG PONG
``` ```
---
如果你愿意,我还可以继续给你补两份内容之一:
1. **一份可直接执行的自动化安装脚本 install_redis_8.6.1.sh**
2. **一份更严格的生产环境配置版(限制 IP、ACL 用户、systemd 安全加固、日志轮转)**
如果你要,我可以直接继续输出。
@@ -8,6 +8,8 @@
基于 vLLM 推理引擎部署 DeepSeek-R1-Distill-Qwen-32B 基于 vLLM 推理引擎部署 DeepSeek-R1-Distill-Qwen-32B
推荐:Qwen3.5-35B-A3B、Qwen3.5-35B-A3B-FP8
> 32K tokens32768 约 2.4 万字中文) > 32K tokens32768 约 2.4 万字中文)
> 使用 vLLM 框架,注意需开启工具调用相关配置。 > 使用 vLLM 框架,注意需开启工具调用相关配置。
@@ -34,7 +36,7 @@ Function Calling / Tool Call / Tool Calling
> 调用工具:客户端发起 call tool,带上符合 schema 的参数 > 调用工具:客户端发起 call tool,带上符合 schema 的参数
> 返回结果:服务器返回结构化结果(文本/数据/错误),客户端再交给模型继续推理 > 返回结果:服务器返回结构化结果(文本/数据/错误),客户端再交给模型继续推理
**ReAct**: Synergizing Reasoning and Acting in Language Models **ReAct**: Synergizing Reasoning(推理) and Acting(行动) in Language Models
> Question: 用户问题 > Question: 用户问题
> >
@@ -47,6 +49,36 @@ Function Calling / Tool Call / Tool Calling
> >
> Final Answer: 最终结果 > Final Answer: 最终结果
Thought(思考) → Action(行动) → Observation(观察) → Thought → … → Final Answer
- 用户:北京今天天气?
- Thought:需要实时天气,我没有实时数据,调用天气API
- Actionget_weather("北京")
- Observation:北京晴天,1525℃
- Thought:信息足够,直接回答
- Answer:北京今天晴天,15–25℃,适合户外活动
例如在 Dify 中:
```
用户问题
Dify Agent 接收
选择策略 (Function Calling / ReAct)
连接 MCP 服务器
发现可用工具列表
根据用户问题选择工具
调用工具获取结果
返回给模型生成回答
```
**RAGFlow**(开源的 RAG 工程化平台 / 系统)Python TypeScript **RAGFlow**(开源的 RAG 工程化平台 / 系统)Python TypeScript
本质是 RAGRetrieval-Augmented Generation)检索增强生成 本质是 RAGRetrieval-Augmented Generation)检索增强生成
@@ -96,3 +128,13 @@ DeepSeek-R1-Distill-Qwen-32B 工具调用。
后期 Tool 多了,我们是否提供 MCP 注册中心。 后期 Tool 多了,我们是否提供 MCP 注册中心。
DeepSeek-R1-Distill-Qwen-32B 工具调用。 DeepSeek-R1-Distill-Qwen-32B 工具调用。
---
- **可以商用**
- **可以二次开发**
- **可以作为企业应用开发平台使用**
- 但如果你要:
- 搭建**多租户服务**
- 或修改/去掉其前端品牌标识
- 那就**需要向官方购买商业授权**。
@@ -0,0 +1,41 @@
`x-csrf-token` 是 Spring Security CSRF 防护机制 的一部分,用于防止跨站请求伪造(CSRF)攻击。后端接口需要通过请求头接收前端携带的 CSRF token,以验证请求的合法性。
其中 IBSCsrfTokenRepository 管理 CSRF token,本质是一个 `UUID.randomUUID().toString()` 随机字符串。
登录成功后,`SecurityConfig.writeLoginSuccessResult()SecurityConfig.java:482` 会将 token 存入 session。
前端获取 Token,前端有两套机制,取决于环境:
```
生产环境(cdn-web 模板):页面通过 Thymeleaf 模板将 token 渲染到 HTML meta 标签中
<meta name="_csrf" th:content="${_csrf.token}">
<meta name="_csrf_header" th:content="${_csrf.headerName}">
前端通过 getCsrfHeaderFromMeta() 读取这两个 meta 标签,动态设置请求头。
非生产环境(IBS-web):通过调用 /admin/getCurrentUser 接口获取 token 并缓存在 window.XTOKEN 中。
```
后端 Filter 链验证 Token RequestReplaceFilter
```
response.setHeader("Access-Control-Allow-Headers", "content-type,x-requested-with,Authorization, x-request-with,x-ui-request,lang,x-csrf-token,csrf-token");
```
```
// CSRF
String[] ignorePathes = {"/v1/**", "/v2/**", "/v1.0/**", "/analyzer/**", "/puppet/**", "/api/**",
"/sso/**", "/ssoapi/**", "/dss/prohibit/**", "/dss/v1/log/subscribe/callback", "/portal/**",
"/param/config/**", "/bboss/**", "/sync/BBOSS/**", "/download/exportFile", "/action", "/actionpm",
"/action/cms", "/action/cdn/statistics", "/action/enterprise/domains","/action/enterprise/productId/domains",
"/action/js", "/content/delivery/**", "/information/**","/testAction","/api/v2/**",
"/home/page/help/Doc/**", "/home/page/security/**", "/query/cmcc/party/**", "/query/enterprise/domain/info", "/v2.0/log/template/**"};
http.csrf().ignoringAntMatchers(ignorePathes)
.csrfTokenRepository(new IBSCsrfTokenRepository(Arrays.asList(ignorePathes)));
```
如果请求路径在 ignorePathes 列表中(如 /v1/, /api/, /action, /actionpm 等),loadToken 返回硬编码的 "1111111111",此时:
请求带 X-CSRF-TOKEN: 1111111111 → 可以通过
请求带 X-CSRF-TOKEN: 任意UUID → 失败
@@ -10,6 +10,90 @@ Add/Fix/Mod JiraID BYMC 说明
## 需求开发 ## 需求开发
```json
{
"企业月流量": {
"华为平面": "1",
"中兴平面": "2",
"HCDN": "3",
"自研2.0": "8",
"自研RTMP": "5",
"合作服务商1": "10",
"合作服务商2": "11"
},
"试商用客户峰值带宽": {
"华为平面": "1",
"中兴平面": "2",
"HCDN": "3",
"自研2.0": "4",
"合作服务商1": "6",
"合作服务商2": "7"
},
"非系统分发域名日峰值": {
"华为": "1",
"中兴": "2",
"HCDN": "3",
"自研2.0": "8",
"合作服务商1": "10",
"合作服务商2": "11"
}
}
```
# 用例评审 # 用例评审
# 冒烟自测 # 冒烟自测
企业名称:ECName1773900714
订购:PRODUCTID1773900830
网页加速
融合2平面
DevReq1773900714B.komect.com
DevReq1773900714A.komect.com
---
企业名称:ECName1773900498
订购:PRODUCTID1773900678
网页加速
融合1平面
DevReq1773900498B.komect.com
DevReq1773900498A.komect.com
---
企业名称:ECName1773972775
订购:PRODUCTID1773972906
网页加速
合作服务商1
devreq1773972775b.komect.com
devreq1773972775a.komect.com
---
企业名称:ECName1773973012
订购:PRODUCTID1773973126
网页加速
合作服务商2
devreq1773973012b.komect.com
devreq1773973012a.komect.com

Some files were not shown because too many files have changed in this diff Show More