Initial commit: obsidian to gitea
16
.obsidian/app.json
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"vimMode": true,
|
||||
"attachmentFolderPath": "/",
|
||||
"newFileLocation": "current",
|
||||
"alwaysUpdateLinks": true,
|
||||
"promptDelete": false,
|
||||
"showInlineTitle": false,
|
||||
"pdfExportSettings": {
|
||||
"includeName": false,
|
||||
"pageSize": "A4",
|
||||
"landscape": false,
|
||||
"margin": "0",
|
||||
"downscalePercent": 100
|
||||
},
|
||||
"showIndentGuide": false
|
||||
}
|
||||
7
.obsidian/appearance.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"cssTheme": "Minimal",
|
||||
"enabledCssSnippets": [
|
||||
"table-wrap-fix",
|
||||
"mermaid"
|
||||
]
|
||||
}
|
||||
10
.obsidian/community-plugins.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
[
|
||||
"attachment-management",
|
||||
"periodic-notes",
|
||||
"oz-clear-unused-images",
|
||||
"obsidian-focus-mode",
|
||||
"remember-cursor-position",
|
||||
"remotely-save",
|
||||
"copy-as-html",
|
||||
"obsidian-image-toolkit"
|
||||
]
|
||||
30
.obsidian/core-plugins-migration.json
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"file-explorer": true,
|
||||
"global-search": true,
|
||||
"switcher": true,
|
||||
"graph": true,
|
||||
"backlink": true,
|
||||
"canvas": true,
|
||||
"outgoing-link": true,
|
||||
"tag-pane": true,
|
||||
"properties": false,
|
||||
"page-preview": true,
|
||||
"daily-notes": true,
|
||||
"templates": true,
|
||||
"note-composer": true,
|
||||
"command-palette": true,
|
||||
"slash-command": false,
|
||||
"editor-status": true,
|
||||
"bookmarks": true,
|
||||
"markdown-importer": false,
|
||||
"zk-prefixer": false,
|
||||
"random-note": false,
|
||||
"outline": true,
|
||||
"word-count": true,
|
||||
"slides": false,
|
||||
"audio-recorder": false,
|
||||
"workspaces": false,
|
||||
"file-recovery": true,
|
||||
"publish": false,
|
||||
"sync": false
|
||||
}
|
||||
33
.obsidian/core-plugins.json
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"file-explorer": true,
|
||||
"global-search": true,
|
||||
"switcher": true,
|
||||
"graph": true,
|
||||
"backlink": true,
|
||||
"canvas": true,
|
||||
"outgoing-link": true,
|
||||
"tag-pane": true,
|
||||
"properties": false,
|
||||
"page-preview": true,
|
||||
"daily-notes": true,
|
||||
"templates": true,
|
||||
"note-composer": true,
|
||||
"command-palette": true,
|
||||
"slash-command": false,
|
||||
"editor-status": true,
|
||||
"bookmarks": true,
|
||||
"markdown-importer": false,
|
||||
"zk-prefixer": false,
|
||||
"random-note": false,
|
||||
"outline": true,
|
||||
"word-count": true,
|
||||
"slides": false,
|
||||
"audio-recorder": false,
|
||||
"workspaces": false,
|
||||
"file-recovery": true,
|
||||
"publish": false,
|
||||
"sync": false,
|
||||
"webviewer": false,
|
||||
"footnotes": false,
|
||||
"bases": true
|
||||
}
|
||||
5
.obsidian/daily-notes.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"folder": "daily",
|
||||
"format": "YYMMDD",
|
||||
"template": "daily/250216"
|
||||
}
|
||||
22
.obsidian/graph.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"collapse-filter": true,
|
||||
"search": "",
|
||||
"showTags": false,
|
||||
"showAttachments": false,
|
||||
"hideUnresolved": false,
|
||||
"showOrphans": true,
|
||||
"collapse-color-groups": true,
|
||||
"colorGroups": [],
|
||||
"collapse-display": true,
|
||||
"showArrow": false,
|
||||
"textFadeMultiplier": 0,
|
||||
"nodeSizeMultiplier": 1,
|
||||
"lineSizeMultiplier": 1,
|
||||
"collapse-forces": true,
|
||||
"centerStrength": 0.518713248970312,
|
||||
"repelStrength": 10,
|
||||
"linkStrength": 1,
|
||||
"linkDistance": 250,
|
||||
"scale": 1,
|
||||
"close": true
|
||||
}
|
||||
11
.obsidian/hotkeys.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"app:toggle-left-sidebar": [
|
||||
{
|
||||
"modifiers": [
|
||||
"Mod"
|
||||
],
|
||||
"key": "B"
|
||||
}
|
||||
],
|
||||
"editor:toggle-bold": []
|
||||
}
|
||||
19
.obsidian/plugins/attachment-management/data.json
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"attachPath": {
|
||||
"attachmentRoot": "",
|
||||
"saveAttE": "obsFolder",
|
||||
"attachmentPath": "${notepath}/${notename}.figs",
|
||||
"attachFormat": "${date}",
|
||||
"type": "GLOBAL",
|
||||
"extensionOverride": []
|
||||
},
|
||||
"dateFormat": "YYMMDD-HHmmss",
|
||||
"excludeExtensionPattern": "",
|
||||
"autoRenameAttachment": true,
|
||||
"excludedPaths": "",
|
||||
"excludePathsArray": [],
|
||||
"excludeSubpaths": false,
|
||||
"originalNameStorage": [],
|
||||
"overridePath": {},
|
||||
"disableNotification": false
|
||||
}
|
||||
2078
.obsidian/plugins/attachment-management/main.js
vendored
Normal file
10
.obsidian/plugins/attachment-management/manifest.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"id": "attachment-management",
|
||||
"name": "Attachment Management",
|
||||
"version": "0.9.16",
|
||||
"description": "Customize your attachment path of notes independently with variables and auto rename it on change.",
|
||||
"author": "trganda",
|
||||
"authorUrl": "https://github.com/trganda",
|
||||
"fundingUrl": "https://paypal.me/trganda",
|
||||
"isDesktopOnly": false
|
||||
}
|
||||
15
.obsidian/plugins/attachment-management/styles.css
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
|
||||
This CSS file will be included with your plugin, and
|
||||
available in the app when your plugin is enabled.
|
||||
|
||||
If your plugin does not need CSS, delete this file.
|
||||
|
||||
*/
|
||||
.attach_management_sub_setting {
|
||||
padding-left: 2em;
|
||||
}
|
||||
.attach_management_sub_setting + .attach_management_sub_setting {
|
||||
padding-left: 0;
|
||||
margin-left: 2em;
|
||||
}
|
||||
3747
.obsidian/plugins/copy-as-html/main.js
vendored
Normal file
10
.obsidian/plugins/copy-as-html/manifest.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"id": "copy-as-html",
|
||||
"name": "Copy as HTML",
|
||||
"version": "1.1.3",
|
||||
"minAppVersion": "0.12.0",
|
||||
"description": "This is a simple plugin that converts the selected markdown to HTML and copies it to the clipboard.",
|
||||
"author": "Bailey Jennings",
|
||||
"authorUrl": "https://twitter.com/Bailey_Jennings",
|
||||
"isDesktopOnly": false
|
||||
}
|
||||
182
.obsidian/plugins/obsidian-focus-mode/main.js
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
THIS IS A GENERATED/BUNDLED FILE BY ROLLUP
|
||||
if you want to view the source visit the plugins github repository
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var obsidian = require('obsidian');
|
||||
|
||||
/******************************************************************************
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
***************************************************************************** */
|
||||
|
||||
function __awaiter(thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
}
|
||||
|
||||
class FocusMode extends obsidian.Plugin {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.focusModeActive = false;
|
||||
this.maximisedClass = "maximised";
|
||||
this.focusModeClass = "focus-mode";
|
||||
this.superFocusModeClass = "super-focus-mode";
|
||||
}
|
||||
storeSplitsValues() {
|
||||
// @ts-ignore
|
||||
this.leftSplitCollapsed = this.app.workspace.leftSplit.collapsed;
|
||||
// @ts-ignore
|
||||
this.rightSplitCollapsed = this.app.workspace.rightSplit.collapsed;
|
||||
}
|
||||
collapseSplits() {
|
||||
// @ts-ignore
|
||||
this.app.workspace.leftSplit.collapse();
|
||||
// @ts-ignore
|
||||
this.app.workspace.rightSplit.collapse();
|
||||
}
|
||||
restoreSplits() {
|
||||
if (!this.leftSplitCollapsed) {
|
||||
// @ts-ignore
|
||||
this.app.workspace.leftSplit.expand();
|
||||
}
|
||||
if (!this.rightSplitCollapsed) {
|
||||
// @ts-ignore
|
||||
this.app.workspace.rightSplit.expand();
|
||||
}
|
||||
}
|
||||
removeExtraneousClasses() {
|
||||
if (
|
||||
// @ts-ignore
|
||||
this.app.workspace.rootSplit.containerEl.hasClass(this.maximisedClass)) {
|
||||
// @ts-ignore
|
||||
this.app.workspace.rootSplit.containerEl.removeClass(this.maximisedClass);
|
||||
// @ts-ignore
|
||||
this.app.workspace.onLayoutChange();
|
||||
}
|
||||
if (document.body.classList.contains(this.superFocusModeClass)) {
|
||||
document.body.classList.remove(this.superFocusModeClass);
|
||||
}
|
||||
}
|
||||
sharedFocusModeCommands() {
|
||||
this.focusModeActive = true;
|
||||
// @ts-ignore
|
||||
this.app.on("active-leaf-change", () => {
|
||||
try {
|
||||
// @ts-ignore
|
||||
this.app.workspace.activeLeaf.view.editor.blur();
|
||||
// @ts-ignore
|
||||
this.app.workspace.activeLeaf.view.editor.focus();
|
||||
// @ts-ignore
|
||||
this.app.workspace.activeLeaf.view.editor.refresh();
|
||||
}
|
||||
catch (ignore) { }
|
||||
});
|
||||
if (!document.body.classList.contains(this.focusModeClass)) {
|
||||
this.storeSplitsValues();
|
||||
}
|
||||
this.collapseSplits();
|
||||
}
|
||||
enableSuperFocusMode() {
|
||||
this.sharedFocusModeCommands();
|
||||
// @ts-ignore
|
||||
this.app.workspace.rootSplit.containerEl.toggleClass(this.maximisedClass,
|
||||
// @ts-ignore
|
||||
!this.app.workspace.rootSplit.containerEl.hasClass(this.maximisedClass));
|
||||
document.body.classList.toggle(this.superFocusModeClass, !document.body.classList.contains(this.superFocusModeClass));
|
||||
if (!document.body.classList.contains(this.focusModeClass)) {
|
||||
document.body.classList.add(this.focusModeClass);
|
||||
}
|
||||
if (document.body.classList.contains(this.superFocusModeClass)) {
|
||||
Array.from(document.querySelectorAll(`.${this.superFocusModeClass} .workspace-split`)).forEach((node) => {
|
||||
const theNode = node;
|
||||
const hasActiveKids = theNode.querySelector(".mod-active");
|
||||
if (hasActiveKids) {
|
||||
theNode.style.display = "flex";
|
||||
}
|
||||
else {
|
||||
theNode.style.display = "none";
|
||||
}
|
||||
});
|
||||
}
|
||||
// @ts-ignore
|
||||
this.app.workspace.onLayoutChange();
|
||||
}
|
||||
enableFocusMode() {
|
||||
this.sharedFocusModeCommands();
|
||||
this.removeExtraneousClasses();
|
||||
document.body.classList.toggle(this.focusModeClass, !document.body.classList.contains(this.focusModeClass));
|
||||
}
|
||||
disableFocusMode() {
|
||||
this.removeExtraneousClasses();
|
||||
if (document.body.classList.contains(this.focusModeClass)) {
|
||||
document.body.classList.remove(this.focusModeClass);
|
||||
}
|
||||
this.restoreSplits();
|
||||
Array.from(document.querySelectorAll(".workspace-split")).forEach((node) => {
|
||||
const theNode = node;
|
||||
theNode.style.display = "flex";
|
||||
});
|
||||
this.focusModeActive = false;
|
||||
}
|
||||
toggleFocusMode(superFocus = false) {
|
||||
if (superFocus) {
|
||||
this.enableSuperFocusMode();
|
||||
}
|
||||
else if (this.focusModeActive) {
|
||||
this.disableFocusMode();
|
||||
}
|
||||
else {
|
||||
this.enableFocusMode();
|
||||
}
|
||||
}
|
||||
onload() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
console.log("Loading Focus Mode plugin ...");
|
||||
this.addRibbonIcon("enter", "Toggle Focus Mode (Shift + Click to show active pane only)", (event) => {
|
||||
this.toggleFocusMode(event.shiftKey);
|
||||
});
|
||||
this.addCommand({
|
||||
id: "toggle-focus-mode",
|
||||
name: "Toggle Focus Mode",
|
||||
callback: () => {
|
||||
this.toggleFocusMode();
|
||||
},
|
||||
hotkeys: [{ modifiers: ["Alt", "Mod"], key: "Z" }],
|
||||
});
|
||||
this.addCommand({
|
||||
id: "toggle-super-focus-mode",
|
||||
name: "Toggle Super Focus Mode (Active pane only)",
|
||||
callback: () => {
|
||||
this.toggleFocusMode(true);
|
||||
},
|
||||
hotkeys: [{ modifiers: ["Alt", "Mod", "Shift"], key: "Z" }],
|
||||
});
|
||||
});
|
||||
}
|
||||
onunload() {
|
||||
console.log("Unloading Focus Mode plugin ...");
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = FocusMode;
|
||||
|
||||
|
||||
/* nosourcemap */
|
||||
10
.obsidian/plugins/obsidian-focus-mode/manifest.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"id": "obsidian-focus-mode",
|
||||
"name": "Focus Mode",
|
||||
"version": "1.11.5",
|
||||
"minAppVersion": "0.9.12",
|
||||
"description": "Add Focus Mode to Obsidian.",
|
||||
"author": "ryanpcmcquen",
|
||||
"authorUrl": "https://github.com/ryanpcmcquen",
|
||||
"isDesktopOnly": false
|
||||
}
|
||||
44
.obsidian/plugins/obsidian-focus-mode/styles.css
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
.focus-mode .cm-s-obsidian .cm-line:not(.cm-active),
|
||||
.focus-mode .cm-s-obsidian div:not(.CodeMirror-activeline) > .CodeMirror-line {
|
||||
opacity: 0.85;
|
||||
filter: saturate(0.85);
|
||||
}
|
||||
|
||||
.focus-mode .status-bar,
|
||||
.focus-mode .view-actions,
|
||||
.focus-mode .view-header-icon,
|
||||
.focus-mode .inline-title,
|
||||
.focus-mode .workspace-ribbon:not(.mod-left),
|
||||
.focus-mode .workspace-split.maximised .workspace-leaf:not(.mod-active),
|
||||
.focus-mode
|
||||
.workspace-split.maximised
|
||||
.workspace-leaf.mod-active
|
||||
~ .workspace-split,
|
||||
.focus-mode.plugin-tabs .stayopen .view-header,
|
||||
.super-focus-mode .workspace-tabs:not(.mod-active) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.super-focus-mode .workspace-tab-header-container {
|
||||
padding-left: var(--size-4-8);
|
||||
}
|
||||
|
||||
.focus-mode .view-content {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.focus-mode .workspace-split.maximised .workspace-leaf.mod-active {
|
||||
/* 4px is for scrollbar width: */
|
||||
flex-basis: calc(100% - 4px);
|
||||
}
|
||||
|
||||
.focus-mode .workspace-ribbon,
|
||||
.focus-mode .sidebar-toggle-button {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.focus-mode .workspace-ribbon::before,
|
||||
.focus-mode
|
||||
.side-dock-ribbon-action[aria-label="Toggle Focus Mode (Shift + Click to show active pane only)"] {
|
||||
visibility: visible;
|
||||
}
|
||||
3294
.obsidian/plugins/obsidian-image-toolkit/main.js
vendored
Normal file
10
.obsidian/plugins/obsidian-image-toolkit/manifest.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"id": "obsidian-image-toolkit",
|
||||
"name": "Image Toolkit",
|
||||
"version": "1.4.3",
|
||||
"minAppVersion": "1.8.7",
|
||||
"description": "Click images to preview with zoom, move, rotate, flip, invert, and copy.",
|
||||
"author": "Xiangru",
|
||||
"authorUrl": "https://github.com/sissilab",
|
||||
"isDesktopOnly": true
|
||||
}
|
||||
319
.obsidian/plugins/obsidian-image-toolkit/styles.css
vendored
Normal file
@@ -0,0 +1,319 @@
|
||||
body {
|
||||
--layer-image-toolkit-popup: 1024;
|
||||
--layer-image-toolkit-player: 1025;
|
||||
--layer-image-toolkit-notice: 1026;
|
||||
}
|
||||
|
||||
.notice-container {
|
||||
z-index: var(--layer-image-toolkit-notice);
|
||||
}
|
||||
|
||||
.oit li::before {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.image-toolkit-img-invert {
|
||||
filter: invert(1) hue-rotate(180deg);
|
||||
mix-blend-mode: screen;
|
||||
}
|
||||
|
||||
.oit-normal {
|
||||
position: fixed;
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: rgba(0, 0, 0, .6);
|
||||
z-index: var(--layer-image-toolkit-popup);
|
||||
display: none;
|
||||
}
|
||||
|
||||
.oit-pin {
|
||||
position: fixed;
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
z-index: var(--layer-image-toolkit-popup);
|
||||
display: none;
|
||||
}
|
||||
|
||||
.oit .oit-img-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.oit .oit-img-container .oit-img-view {
|
||||
max-height: none;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.oit-pin .oit-img-container .oit-img-view {
|
||||
position: fixed;
|
||||
pointer-events: auto;
|
||||
box-shadow: 0 0 5px;
|
||||
}
|
||||
|
||||
.oit-pin .oit-img-container .oit-img-view:hover {
|
||||
box-shadow: 0 0 6px #55acc6;
|
||||
}
|
||||
|
||||
.oit .img-default-background {
|
||||
background-position: 0 0, 5px 5px !important;
|
||||
background-size: 10px 10px !important;
|
||||
background-image: linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee 100%), linear-gradient(45deg, #eee 25%, #fff 25%, #fff 75%, #eee 75%, #eee 100%) !important;
|
||||
}
|
||||
|
||||
.oit .oit-img-container .oit-img-view:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.oit-normal .img-close {
|
||||
position: absolute;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
top: 0;
|
||||
right: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.oit .oit-img-tip {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
height: 20px;
|
||||
width: 50px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
border-radius: 10px;
|
||||
background-color: rgba(0, 0, 0, .4);
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/*region img-player*/
|
||||
.oit .img-player {
|
||||
display: none;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
cursor: none;
|
||||
background-color: #000;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.oit .img-player > img {
|
||||
display: inline;
|
||||
float: none;
|
||||
padding: 0;
|
||||
max-height: none;
|
||||
transform: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
/*endregion*/
|
||||
|
||||
.oit-normal .oit-img-footer {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
bottom: 5px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
/*region oit-img-title*/
|
||||
.oit-normal .oit-img-footer .oit-img-title {
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
display: inline-block;
|
||||
max-width: 90%;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
margin: 5px;
|
||||
opacity: .8;
|
||||
color: #fff;
|
||||
/* filter: alpha(opacity=80) */
|
||||
}
|
||||
|
||||
.oit-normal .oit-img-footer .oit-img-title:hover {
|
||||
/* opacity: 1; */
|
||||
color: #fff;
|
||||
font-size: 15px;
|
||||
background-color: rgba(0, 0, 0, .3);
|
||||
border-radius: 8px;
|
||||
line-height: 1.5;
|
||||
/* filter: alpha(opacity=100) */
|
||||
}
|
||||
/*endregion*/
|
||||
|
||||
/*region toolbar*/
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar {
|
||||
width: 385px;
|
||||
height: 30px;
|
||||
margin: 0 auto 5px;
|
||||
padding: 3px 0;
|
||||
}
|
||||
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar:hover {
|
||||
background-color: rgba(0, 0, 0, .3);
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar > li {
|
||||
float: left;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
margin: 0 5px;
|
||||
padding: 0;
|
||||
line-height: 0;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar > li:hover {
|
||||
animation: bounce .5s cubic-bezier(0.51, 0.23, 0.02, 0.96)
|
||||
}
|
||||
|
||||
@keyframes bounce {
|
||||
0% {
|
||||
transform: scale(1, 1);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale(0.85, 1.1) translateY(-5px);
|
||||
}
|
||||
}
|
||||
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar .toolbar_zoom_to_100::before,
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar .toolbar_zoom_in::before,
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar .toolbar_zoom_out::before,
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar .toolbar_full_screen::before,
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar .toolbar_refresh::before,
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar .toolbar_rotate_left::before,
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar .toolbar_rotate_right::before,
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar .toolbar_scale_x::before,
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar .toolbar_scale_y::before,
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar .toolbar_invert_color::before,
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar .toolbar_copy::before {
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
display: block;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
color: transparent;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAARMAAAAZCAYAAAASRcpqAAAAAXNSR0IArs4c6QAADgJJREFUeF7tXHnQftUc/3z+YJC9KVuWsZOlIiopTYakZZpIJSUiS6JkLKGFYkJJRJsKpUVEhYpItiZFUtknJGQXmRHzMZ/H97xz3vuce++5z3ufX696z8wz77zPc+75nnPu93zO57ucQ6yUlRlYmYGVGRhhBjhCG7e7JiQd2Bw0yanv2iZmqc/f7iZ8ZcBznwFJDwPwopKgWt3uBBNJ6wJYH8DjADwFwFMBfAPAtwB8H8B5JP+01JFKenkM5EEA/HH73wXwVZJnLrV9Pz+WjACCAwp9WpvkNX19lfR8AGcU6h1U89IkPQHAzgAeCuCxANYGcHl8rgZwLckL+/rR97uk7QA8EYDl+bO63weAryd5JG/qa6f0u6S7A9gwPhvE399Gu1cBuIbkZ2dp+9Z8RtKTALwXwNFj6W3L/J1BcoexxirpwwBe0dHegSQP6pPXCiaS3gng9QDuFI3cEkDyNAB3iO9+AsCL4JQ+QS2T4oX1RgB+CW3FC+RTNQttVchogImB7mjLJemFVlUkPSMqvgqA58ClE0wkPQDA3gBeA+DOPYLeRtLvb6EEmB4DYE+Sx0o6DID7sQvJH6eKku4N4H0AXtwj45cA3k3SilhdJG0D4HAA3gm7yknWv3yzkvQQAF+JTWb3aqGroGK8048BeGCI22EegCLJG5F15swxACVrz93erKnHkhTzvVnfNBbBRJJ32MckJQfwNQCXkLxFkoHk6fFJ1P4Ukrv0CWso90cBJIXwznqld6TYnbzjPh7ARrEr+tFjSe55a8vIwMRAMvNLzZUi2mkFE0meDyuRWYjLFwGcDMC7uYt3ei+0TQBsH999Mhbjb/x/1u+JHElelAaTBQWStHEsdLNRl8sCLK+L/+8K4MkAzCaeHd+ZnW5V814kHQrgzVH3gmC3Zrp/ie/uB8AsNYGt5e9L0mzIY/D3CUx6lbumT2PUkeTxfwLAPRrtjQoojYVvUUsClKw9sw6z7XHBRNKXAGwO4DsAduui7vFyzUruD2Avkh+qeTmNSZnslKXnJHkHPhHAC+L3k0hW7UjzkpEtSitzYhaDXmoDSMxsvECKYNIAEpt/R3TteJK82K0cW8Zi3Z3kFX1gImnXAI7VAFwK4F1dpoYkA/tbwiw1M+szmb3DubjtI0ka7IpF0rYBOjar/2GAIXnqMgaTNLap8fTNS816CSBNjMT/psU/M6A0gMSs2jo4HphIsgPGVO0sks8bMNBfAVjLNjZJ+1JaS24m1E60JO+C3o1dvDhMgW8VGTmYmBIOpZ3N+tkCmQKTYIHfBrDe0F0o6+cvALwMgM1T7z5TzASAfWM2PZKiHkryX33vvwF0Bh+Dy1SRdC6A5wL4Msln9rUbi+eOAVbJP2Wb/kfLlJkkJuW/kzkO/9Ig87dtXhobo30lZqi5327WzSzpQmJ8rWAC4PyMjeZdvS5t8Au7STj2TCfvZqZBckKPa0o4aq8AcAHJRH9LSmUaa8ZjJvMRkq/MK0nybvqGMGkW7VySPHk2q0y51yP55xbF7ZTRA0K1MjYleXFqqxZQ2upJWofk95p9k7Rv+C+qTYnGfL4HwH4A/gjggy1g8nYABycgGeqbagDKtiQ/1+iD37HZ1w8AbE0ymUw1qpWbZ67/VgD2Bdkxv2zMnEwPrJ8LgF01wJ5KTSAxK20JAlQBiqTjAbw01tKCDvcwk9TLkl/QQDQBpRxMXh0KVxVVKCh+msh1SwsjdpvEfK4kuU5HG6Vd+i4RSfAuuiPJ01vApFNGD5hUyWiR2+kYqwWcTDHvA8CsxL6Q7Ul+ehblzDz1Zhre7ZvMJDU703uP92rH8JEAfhbs1KaJgcDzeW2YQq8l+YEZx5BAfkGpbw9gIin3Ky74XzoiiieSfEnbHAfwO6DRVhZFJLPIo58xG2pjLlNgkhBrK5LnhTKYJWzZfHGS7LE2Xd01/SbpheGEajVDJB0B4HUlVhLyOpFd0gkAPFknkNyjZVF3yuhT5hoZHS/LgLIWSTuOFxVJZmQ/r/XAz+ofCEXbtNDHRMVLYFLacezwbvVr5O1Lulc40K0XG5I0CBpM7L+xE9VmsE3gIpsszFViqM2f0hiKzCQcoeeUlL5nE0k0f0H3+/SkRfdGYyaSdgSQ5n+RI7cDTNytnUie1tO/Equ7iaQDIZPSAJK9epjLFJjYTHEEZbVkL0tyRMcx/wmDsYCgWemlHpCBiXMRHJF5P8l9WgaTIgivJjkJqUraCcCjsvrJ5kxfnZpCl5IcqnYcv5XmZlGKLhnN7g2SMYuizfJMAMqNNfkrmRLYCW7HcFvZg+QJkuzY7gr/7kfSIeKqIsmOeOe/2Fl6XLzbxBKrHefxnPvl/rWVs0k6D2ahxFydHRGVqR20axAZcP8VwDYkHb0cXJpO7sENxAMRnrcJ4vyuKV9UD5jYnLQZPpX/lZ7r81U2gMQ+mjWHgkkxnuw4cwYm3nltm9luc77APjlr6YtJt4QjE8C0zf0CcNTs1qtCxqxKsiqek2SfUQ7Oi8TmeQRZvkupa5eRnJgrNUXSm6z4AI4iabPHG4WB3xvAIBNHkv12rblHhVwI1/1MluPRm2BVGFNyaDp/ZjtHwGrG3QC0UZhJxkqcuLkJyb+3yGnrYpGd1IBJE0i8kWXrrtrMsfPVWa5mJk5Qm5QcTBoDcj6Dw8ETypTZY87+s/9lqlSyhhVmMlSLl0H9EtCXgH0eXc3kjNX8TA7eEZlJAqXjSDrvZlHpYSau25ZmMGm3jZlIWgOA/SM3OlG0IbYrD2XKzEme/81JXhTK4QQ1JxctQqT4zenVtqXckEOkKU28dReSZPprX8dUJCcAqdZnsj9JJ0CVAKtTRp+2ZT6TVhl9bSz19x7GcDXJ3y9VxtjPZyZoiZksmJxjyw29aTIT61Ep78Xsuy0fZjkxEyfA2QdZnLcKMCkmkfYxE0lmlmaYpWJ/inFg0RGKsEamwCTZt5M8/FDo3SIU63j5AnWMMK29uxPPcNRPQODwn/MKSgs91XEuygYk/5lX6kJ2SfcMu81RoPVJ2qE5WEaXMtfKmMeCSG1KsoPaTuS2cg5Jm5hVJRjjml3p/n7XQ44DtMx7co6XfCbFzaNqAFGpr4+3MZ9JyssprqUKMCmmElSAycTl0OdTaaxZA/QUmPhMhr3wj5jBG24q5nMfl5O0B79Ywp5PeSank7THeqFIemS0Yyehw4z5b0lZO1P3+2T0gEmVjI7x2ae0RilsKembAK7vi+Y0FKUUZbl4SC5In6kxBjWPELDNZIftS9Ec2/4bk7x5CIBkAFvli7itRHMkHRIJe53mSsdcOulw/+bvqwxMLDgL795A0gfLqkpQHdfduS+c2FgsW5B0Zl1naTzTezp3VcgovKhR8kyyvqe8kJNJ9h26awPvFPL078V5k/QcAJ8H4IXuBe+FP6hkfe7KM5kpjyUSIg1UzllxmsIXBnVuFVYeA5hjHaZo1vkkt2gDhY6hFdMzVimYxECSvXZ9hMlalStzuvnRaqeVJOexOJfAxebTYaVdK1jGqdnBr3/7FDPJ//TpyDxlNDNWaxPSOjJgFzJqc4WMU8LO4Wh1anfNgyQf47dJdBpJh+DbQCe98856pYcbi70rA3YmsJLkXAsz2MGHSft0ZOzfRwQTH5+wlWCf5dTx/x4zx8ETuxCmolHZc10n3Jdu5uQTKyllw6bF7qsGrvK5m0i7dz6KzaHktHLnvAueS3LrmpckKTl8Xd2A5U/z1LBPsTrW7pKy8P4A4OEknRPQWeYhY95ncxpg4oQvH/F3MtignT0DrptJ+vBea5HkA3WTRDNnQZP0NQe9JTYTn5N6cCkfIjWQnc1xKr0THS/pbfx/TNmmc4pmeIH4kOCyK5nDfLSzOZKc4+PjFC6rN65iSGZfaS4OJ+lwfLFIcgjd/se2Mi6YWEqAhhf8szoEG0Rsn10oyZmHPopdvbtFwpoH3nWfiamzj60bTNIx/J+Go+jXfZo1towcTOZxari5u8VC96lqJwXaHHFor+h8jvfmqJqTBn35kMtGJH3auLM0Lm3y5Uq+E6V18UryQVCnezsnZMip4b85i5nkWR0K7ysQ0n0rrjbqUf6+uRj6e2bmTz06xJnZfFiSr5jwsQoX3zszuTeog5n8juR9h/Y/1U/+tSF9LkZzOl6soyf++NYt//VCNlP5YeFQV6Kkx5P0SdWqEhf3uG2fPJ4oZ9zV4Vj3RSkNu3GozDTOPhqfJO0tY8nIXuRc7jMpUeUw97xTJVPFC9EOXe/0KdPRZ3h8gMtszsXAY0f2kAObzVvgDCYe50KadYCaI3/J0V59CLFxn4kzNb04EiNyn31vi/uQMqyXPZDE4vaJaI9l9PtMJPk0d8oo9+bptefs2OZtf76aIjGZ3vVQqjB3MBnaqyyXZGbHYZfMBqBMpVUP7W/LpOaXES2S0dgVRr9pLWMIU7uxJJ+afUfPGG8A4FybQ/Lkw9p5CSZkM8d5Dl1l3jeteXE6Z2VZmjbNiZHki6k+nu53GZNNSbIT1qe7E9vMxZt1HkwyXdFR+6qn6i07MAmkth3tHBXfVZkuNpp5kIUX58Xu8JlPH1df5DykAwFaUzI6KKZtzfxId1Fcx8nNKp+IJJud6V7WdEerTUD7m/w5ZggbaZuTiPLYSe7U/EcHY5znHbBmWO6/d15HMZZt1KZjzuw4NYOcyx2wcWbH/i1/DLKXjnEHcxqPpOSIH7JUXHdvkkfN7XZ6Sb4iwMlSy+7eiaEzVQCzldvplzqJK88vyxmIzXJI35yRPbn0fW5gMqQ3K3VXZmBlBv7/Z+C/kQ6WkguncSQAAAAASUVORK5CYII=);
|
||||
background-repeat: no-repeat
|
||||
}
|
||||
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar .toolbar_zoom_to_100::before {
|
||||
content: 'Zoom to Actual Size';
|
||||
background-position: 0 0
|
||||
}
|
||||
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar .toolbar_zoom_in::before {
|
||||
content: 'Zoom In';
|
||||
background-position: -25px 0
|
||||
}
|
||||
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar .toolbar_zoom_out::before {
|
||||
content: 'Zoom Out';
|
||||
background-position: -50px 0
|
||||
}
|
||||
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar .toolbar_full_screen::before {
|
||||
content: 'Full Screen';
|
||||
background-position: -75px 0
|
||||
}
|
||||
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar .toolbar_refresh::before {
|
||||
content: 'Refresh';
|
||||
background-position: -100px 0
|
||||
}
|
||||
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar .toolbar_rotate_left::before {
|
||||
content: 'Rotate Left';
|
||||
background-position: -125px 0
|
||||
}
|
||||
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar .toolbar_rotate_right::before {
|
||||
content: 'Rotate Right';
|
||||
background-position: -150px 0
|
||||
}
|
||||
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar .toolbar_scale_x::before {
|
||||
content: 'Scale x';
|
||||
background-position: -175px 0
|
||||
}
|
||||
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar .toolbar_scale_y::before {
|
||||
content: 'Scale y';
|
||||
background-position: -200px 0
|
||||
}
|
||||
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar .toolbar_invert_color::before {
|
||||
content: 'Invert color';
|
||||
background-position: -225px 0
|
||||
}
|
||||
|
||||
.oit-normal .oit-img-footer .oit-img-toolbar .toolbar_copy::before {
|
||||
content: 'Copy';
|
||||
background-position: -250px 0
|
||||
}
|
||||
/*endregion*/
|
||||
|
||||
/*region gallery-navbar*/
|
||||
.oit-normal .oit-img-footer .gallery-navbar {
|
||||
position: relative;
|
||||
flex: 0 0 auto;
|
||||
overflow: hidden;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
margin-top: 20px;
|
||||
background-color: rgba(0, 0, 0, .1);
|
||||
}
|
||||
|
||||
.oit-normal .oit-img-footer .gallery-navbar:hover {
|
||||
background-color: rgba(0, 0, 0, .8);
|
||||
}
|
||||
|
||||
.oit-normal .oit-img-footer .gallery-navbar .gallery-list {
|
||||
display: flex;
|
||||
transform: translateX(0px);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.oit-normal .oit-img-footer .gallery-navbar .gallery-list .gallery-active {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.oit-normal .oit-img-footer .gallery-navbar .gallery-list .img-border-active {
|
||||
margin-top: 1px;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.oit-normal .oit-img-footer .gallery-navbar .gallery-list > li {
|
||||
width: 48px;
|
||||
height: 58px;
|
||||
opacity: .3;
|
||||
color: transparent;
|
||||
margin: 2px 1px;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
/* transition: all 100ms linear; */
|
||||
}
|
||||
|
||||
.oit-normal .oit-img-footer .gallery-navbar .gallery-list img {
|
||||
width: 46px;
|
||||
height: 56px;
|
||||
}
|
||||
/*endregion*/
|
||||
7
.obsidian/plugins/oz-clear-unused-images/data.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"deleteOption": "system-trash",
|
||||
"logsModal": true,
|
||||
"excludedFolders": "",
|
||||
"ribbonIcon": false,
|
||||
"excludeSubfolders": false
|
||||
}
|
||||
4
.obsidian/plugins/oz-clear-unused-images/main.js
vendored
Normal file
11
.obsidian/plugins/oz-clear-unused-images/manifest.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "oz-clear-unused-images",
|
||||
"name": "Clear Unused Images",
|
||||
"version": "1.1.1",
|
||||
"minAppVersion": "0.11.13",
|
||||
"description": "Clear the images that you are not using anymore in your markdown notes to save space.",
|
||||
"author": "Ozan",
|
||||
"authorUrl": "https://www.ozan.pl",
|
||||
"fundingUrl": "https://ko-fi.com/ozante",
|
||||
"isDesktopOnly": false
|
||||
}
|
||||
10
.obsidian/plugins/oz-clear-unused-images/styles.css
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
.unused-images-logs {
|
||||
margin-bottom: 13px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.unused-images-center-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
32
.obsidian/plugins/periodic-notes/data.json
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"showGettingStartedBanner": false,
|
||||
"hasMigratedDailyNoteSettings": true,
|
||||
"hasMigratedWeeklyNoteSettings": false,
|
||||
"daily": {
|
||||
"format": "YYMMDD",
|
||||
"folder": "period/daily/26",
|
||||
"template": "",
|
||||
"enabled": true
|
||||
},
|
||||
"weekly": {
|
||||
"format": "YY-WW",
|
||||
"template": "",
|
||||
"folder": "period/weekly",
|
||||
"enabled": true
|
||||
},
|
||||
"monthly": {
|
||||
"format": "",
|
||||
"template": "",
|
||||
"folder": ""
|
||||
},
|
||||
"quarterly": {
|
||||
"format": "",
|
||||
"template": "",
|
||||
"folder": ""
|
||||
},
|
||||
"yearly": {
|
||||
"format": "",
|
||||
"template": "",
|
||||
"folder": ""
|
||||
}
|
||||
}
|
||||
5561
.obsidian/plugins/periodic-notes/main.js
vendored
Normal file
10
.obsidian/plugins/periodic-notes/manifest.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"id": "periodic-notes",
|
||||
"name": "Periodic Notes",
|
||||
"description": "Create/manage your daily, weekly, and monthly notes",
|
||||
"version": "0.0.17",
|
||||
"author": "Liam Cain",
|
||||
"authorUrl": "https://github.com/liamcain/",
|
||||
"isDesktopOnly": false,
|
||||
"minAppVersion": "0.10.11"
|
||||
}
|
||||
30
.obsidian/plugins/periodic-notes/styles.css
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
.periodic-modal {
|
||||
min-width: 40vw;
|
||||
}
|
||||
|
||||
.settings-banner {
|
||||
background-color: var(--background-primary-alt);
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
margin-bottom: 1em;
|
||||
margin-top: 1em;
|
||||
padding: 1.5em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.settings-banner h3 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.settings-banner h4 {
|
||||
margin-bottom: 0.25em;
|
||||
}
|
||||
|
||||
.has-error {
|
||||
color: var(--text-error);
|
||||
}
|
||||
|
||||
input.has-error {
|
||||
color: var(--text-error);
|
||||
border-color: var(--text-error);
|
||||
}
|
||||
1
.obsidian/plugins/remember-cursor-position/cursor-positions.json
vendored
Normal file
302
.obsidian/plugins/remember-cursor-position/main.js
vendored
Normal file
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
THIS IS A GENERATED/BUNDLED FILE BY ROLLUP
|
||||
if you want to view the source visit the plugins github repository
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var obsidian = require('obsidian');
|
||||
|
||||
/******************************************************************************
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
***************************************************************************** */
|
||||
|
||||
function __awaiter(thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
}
|
||||
|
||||
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
||||
var e = new Error(message);
|
||||
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
||||
};
|
||||
|
||||
const SAFE_DB_FLUSH_INTERVAL = 5000;
|
||||
const DEFAULT_SETTINGS = {
|
||||
dbFileName: '.obsidian/plugins/remember-cursor-position/cursor-positions.json',
|
||||
delayAfterFileOpening: 100,
|
||||
saveTimer: SAFE_DB_FLUSH_INTERVAL,
|
||||
};
|
||||
class RememberCursorPosition extends obsidian.Plugin {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.loadedLeafIdList = [];
|
||||
this.loadingFile = false;
|
||||
}
|
||||
onload() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield this.loadSettings();
|
||||
try {
|
||||
this.db = yield this.readDb();
|
||||
this.lastSavedDb = yield this.readDb();
|
||||
}
|
||||
catch (e) {
|
||||
console.error("Remember Cursor Position plugin can\'t read database: " + e);
|
||||
this.db = {};
|
||||
this.lastSavedDb = {};
|
||||
}
|
||||
this.addSettingTab(new SettingTab(this.app, this));
|
||||
this.registerEvent(this.app.workspace.on('file-open', (file) => this.restoreEphemeralState()));
|
||||
this.registerEvent(this.app.workspace.on('quit', () => { this.writeDb(this.db); }));
|
||||
this.registerEvent(this.app.vault.on('rename', (file, oldPath) => this.renameFile(file, oldPath)));
|
||||
this.registerEvent(this.app.vault.on('delete', (file) => this.deleteFile(file)));
|
||||
//todo: replace by scroll and mouse cursor move events
|
||||
this.registerInterval(window.setInterval(() => this.checkEphemeralStateChanged(), 100));
|
||||
this.registerInterval(window.setInterval(() => this.writeDb(this.db), this.settings.saveTimer));
|
||||
this.restoreEphemeralState();
|
||||
});
|
||||
}
|
||||
renameFile(file, oldPath) {
|
||||
let newName = file.path;
|
||||
let oldName = oldPath;
|
||||
this.db[newName] = this.db[oldName];
|
||||
delete this.db[oldName];
|
||||
}
|
||||
deleteFile(file) {
|
||||
let fileName = file.path;
|
||||
delete this.db[fileName];
|
||||
}
|
||||
checkEphemeralStateChanged() {
|
||||
var _a;
|
||||
let fileName = (_a = this.app.workspace.getActiveFile()) === null || _a === void 0 ? void 0 : _a.path;
|
||||
//waiting for load new file
|
||||
if (!fileName || !this.lastLoadedFileName || fileName != this.lastLoadedFileName || this.loadingFile)
|
||||
return;
|
||||
let st = this.getEphemeralState();
|
||||
if (!this.lastEphemeralState)
|
||||
this.lastEphemeralState = st;
|
||||
if (!isNaN(st.scroll) && !this.isEphemeralStatesEquals(st, this.lastEphemeralState)) {
|
||||
this.saveEphemeralState(st);
|
||||
this.lastEphemeralState = st;
|
||||
}
|
||||
}
|
||||
isEphemeralStatesEquals(state1, state2) {
|
||||
if (state1.cursor && !state2.cursor)
|
||||
return false;
|
||||
if (!state1.cursor && state2.cursor)
|
||||
return false;
|
||||
if (state1.cursor) {
|
||||
if (state1.cursor.from.ch != state2.cursor.from.ch)
|
||||
return false;
|
||||
if (state1.cursor.from.line != state2.cursor.from.line)
|
||||
return false;
|
||||
if (state1.cursor.to.ch != state2.cursor.to.ch)
|
||||
return false;
|
||||
if (state1.cursor.to.line != state2.cursor.to.line)
|
||||
return false;
|
||||
}
|
||||
if (state1.scroll && !state2.scroll)
|
||||
return false;
|
||||
if (!state1.scroll && state2.scroll)
|
||||
return false;
|
||||
if (state1.scroll && state1.scroll != state2.scroll)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
saveEphemeralState(st) {
|
||||
var _a;
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let fileName = (_a = this.app.workspace.getActiveFile()) === null || _a === void 0 ? void 0 : _a.path;
|
||||
if (fileName && fileName == this.lastLoadedFileName) { //do not save if file changed or was not loaded
|
||||
this.db[fileName] = st;
|
||||
}
|
||||
});
|
||||
}
|
||||
restoreEphemeralState() {
|
||||
var _a, _b, _c;
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let fileName = (_a = this.app.workspace.getActiveFile()) === null || _a === void 0 ? void 0 : _a.path;
|
||||
if (fileName && this.loadingFile && this.lastLoadedFileName == fileName) //if already started loading
|
||||
return;
|
||||
let activeLeaf = this.app.workspace.getMostRecentLeaf();
|
||||
if (activeLeaf && this.loadedLeafIdList.includes(activeLeaf.id + ':' + activeLeaf.getViewState().state.file))
|
||||
return;
|
||||
this.loadedLeafIdList = [];
|
||||
this.app.workspace.iterateAllLeaves((leaf) => {
|
||||
if (leaf.getViewState().type === "markdown") {
|
||||
this.loadedLeafIdList.push(leaf.id + ':' + leaf.getViewState().state.file);
|
||||
}
|
||||
});
|
||||
this.loadingFile = true;
|
||||
if (this.lastLoadedFileName != fileName) {
|
||||
this.lastEphemeralState = {};
|
||||
this.lastLoadedFileName = fileName;
|
||||
let st;
|
||||
if (fileName) {
|
||||
st = this.db[fileName];
|
||||
if (st) {
|
||||
//waiting for load note
|
||||
yield this.delay(this.settings.delayAfterFileOpening);
|
||||
let scroll;
|
||||
for (let i = 0; i < 20; i++) {
|
||||
scroll = (_c = (_b = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _b === void 0 ? void 0 : _b.currentMode) === null || _c === void 0 ? void 0 : _c.getScroll();
|
||||
if (scroll !== null)
|
||||
break;
|
||||
yield this.delay(10);
|
||||
}
|
||||
// TODO: if note opened by link like [link](note.md#header), do not scroll it
|
||||
yield this.delay(10);
|
||||
this.setEphemeralState(st);
|
||||
}
|
||||
}
|
||||
this.lastEphemeralState = st;
|
||||
}
|
||||
this.loadingFile = false;
|
||||
});
|
||||
}
|
||||
readDb() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let db = {};
|
||||
if (yield this.app.vault.adapter.exists(this.settings.dbFileName)) {
|
||||
let data = yield this.app.vault.adapter.read(this.settings.dbFileName);
|
||||
db = JSON.parse(data);
|
||||
}
|
||||
return db;
|
||||
});
|
||||
}
|
||||
writeDb(db) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
//create folder for db file if not exist
|
||||
let newParentFolder = this.settings.dbFileName.substring(0, this.settings.dbFileName.lastIndexOf("/"));
|
||||
if (!(yield this.app.vault.adapter.exists(newParentFolder)))
|
||||
this.app.vault.adapter.mkdir(newParentFolder);
|
||||
if (JSON.stringify(this.db) !== JSON.stringify(this.lastSavedDb)) {
|
||||
this.app.vault.adapter.write(this.settings.dbFileName, JSON.stringify(db));
|
||||
this.lastSavedDb = JSON.parse(JSON.stringify(db));
|
||||
}
|
||||
});
|
||||
}
|
||||
getEphemeralState() {
|
||||
// let state: EphemeralState = this.app.workspace.getActiveViewOfType(MarkdownView)?.getEphemeralState(); //doesn't work properly
|
||||
var _a, _b, _c;
|
||||
let state = {};
|
||||
state.scroll = Number((_c = (_b = (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.currentMode) === null || _b === void 0 ? void 0 : _b.getScroll()) === null || _c === void 0 ? void 0 : _c.toFixed(4));
|
||||
let editor = this.getEditor();
|
||||
if (editor) {
|
||||
let from = editor.getCursor("anchor");
|
||||
let to = editor.getCursor("head");
|
||||
if (from && to) {
|
||||
state.cursor = {
|
||||
from: {
|
||||
ch: from.ch,
|
||||
line: from.line
|
||||
},
|
||||
to: {
|
||||
ch: to.ch,
|
||||
line: to.line
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
setEphemeralState(state) {
|
||||
const view = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView);
|
||||
if (state.cursor) {
|
||||
let editor = this.getEditor();
|
||||
if (editor) {
|
||||
editor.setSelection(state.cursor.from, state.cursor.to);
|
||||
}
|
||||
}
|
||||
if (view && state.scroll) {
|
||||
view.setEphemeralState(state);
|
||||
// view.previewMode.applyScroll(state.scroll);
|
||||
// view.sourceMode.applyScroll(state.scroll);
|
||||
}
|
||||
}
|
||||
getEditor() {
|
||||
var _a;
|
||||
return (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.editor;
|
||||
}
|
||||
loadSettings() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData());
|
||||
if ((settings === null || settings === void 0 ? void 0 : settings.saveTimer) < SAFE_DB_FLUSH_INTERVAL) {
|
||||
settings.saveTimer = SAFE_DB_FLUSH_INTERVAL;
|
||||
}
|
||||
this.settings = settings;
|
||||
});
|
||||
}
|
||||
saveSettings() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield this.saveData(this.settings);
|
||||
});
|
||||
}
|
||||
delay(ms) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
});
|
||||
}
|
||||
}
|
||||
class SettingTab extends obsidian.PluginSettingTab {
|
||||
constructor(app, plugin) {
|
||||
super(app, plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
display() {
|
||||
let { containerEl } = this;
|
||||
containerEl.empty();
|
||||
containerEl.createEl('h2', { text: 'Remember cursor position - Settings' });
|
||||
new obsidian.Setting(containerEl)
|
||||
.setName('Data file name')
|
||||
.setDesc('Save positions to this file')
|
||||
.addText((text) => text
|
||||
.setPlaceholder('Example: cursor-positions.json')
|
||||
.setValue(this.plugin.settings.dbFileName)
|
||||
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
||||
this.plugin.settings.dbFileName = value;
|
||||
yield this.plugin.saveSettings();
|
||||
})));
|
||||
new obsidian.Setting(containerEl)
|
||||
.setName('Delay after opening a new note')
|
||||
.setDesc("This plugin shouldn't scroll if you used a link to the note header like [link](note.md#header). If it did, then increase the delay until everything works. If you are not using links to page sections, set the delay to zero (slider to the left). Slider values: 0-300 ms (default value: 100 ms).")
|
||||
.addSlider((text) => text
|
||||
.setLimits(0, 300, 10)
|
||||
.setValue(this.plugin.settings.delayAfterFileOpening)
|
||||
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
||||
this.plugin.settings.delayAfterFileOpening = value;
|
||||
yield this.plugin.saveSettings();
|
||||
})));
|
||||
new obsidian.Setting(containerEl)
|
||||
.setName('Delay between saving the cursor position to file')
|
||||
.setDesc("Useful for multi-device users. If you don't want to wait until closing Obsidian to the cursor position been saved.")
|
||||
.addSlider((text) => text
|
||||
.setLimits(SAFE_DB_FLUSH_INTERVAL, SAFE_DB_FLUSH_INTERVAL * 10, 10)
|
||||
.setValue(this.plugin.settings.saveTimer)
|
||||
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
|
||||
this.plugin.settings.saveTimer = value;
|
||||
yield this.plugin.saveSettings();
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RememberCursorPosition;
|
||||
|
||||
|
||||
/* nosourcemap */
|
||||
10
.obsidian/plugins/remember-cursor-position/manifest.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"id": "remember-cursor-position",
|
||||
"name": "Remember cursor position",
|
||||
"version": "1.0.9",
|
||||
"minAppVersion": "0.9.12",
|
||||
"description": "Remember cursor and scroll position for each note",
|
||||
"author": "Dmitry Savosh",
|
||||
"authorUrl": "https://github.com/dy-sh/",
|
||||
"isDesktopOnly": false
|
||||
}
|
||||
1
.obsidian/plugins/remotely-save/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
data.json
|
||||
235
.obsidian/plugins/remotely-save/main.js
vendored
Normal file
11
.obsidian/plugins/remotely-save/manifest.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "remotely-save",
|
||||
"name": "Remotely Save",
|
||||
"version": "0.5.25",
|
||||
"minAppVersion": "0.13.21",
|
||||
"description": "Yet another unofficial plugin allowing users to synchronize notes between local device and the cloud service.",
|
||||
"author": "fyears",
|
||||
"authorUrl": "https://github.com/fyears",
|
||||
"isDesktopOnly": false,
|
||||
"fundingUrl": "https://remotelysave.com"
|
||||
}
|
||||
244
.obsidian/plugins/remotely-save/styles.css
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
/* set the styles */
|
||||
|
||||
.password-second-confirm {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.password-disclaimer {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.encryptionmethod-second-confirm {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.settings-auth-related {
|
||||
border-top: 1px solid var(--background-modifier-border);
|
||||
padding-top: 18px;
|
||||
}
|
||||
|
||||
.settings-percentage-custom-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.settings-encryption-method-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.s3-disclaimer {
|
||||
font-weight: bold;
|
||||
}
|
||||
.s3-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dropbox-disclaimer {
|
||||
font-weight: bold;
|
||||
}
|
||||
.dropbox-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dropbox-auth-button-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dropbox-revoke-auth-button-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.onedrive-disclaimer {
|
||||
font-weight: bold;
|
||||
}
|
||||
.onedrive-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.onedrive-auth-button-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.onedrive-revoke-auth-button-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.onedrivefull-allow-to-use-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.onedrivefull-disclaimer {
|
||||
font-weight: bold;
|
||||
}
|
||||
.onedrivefull-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.onedrivefull-auth-button-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.onedrivefull-revoke-auth-button-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.webdav-disclaimer {
|
||||
font-weight: bold;
|
||||
}
|
||||
.webdav-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.webdav-customheaders-textarea {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.webdis-disclaimer {
|
||||
font-weight: bold;
|
||||
}
|
||||
.webdis-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.googledrive-disclaimer {
|
||||
font-weight: bold;
|
||||
}
|
||||
.googledrive-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.googledrive-allow-to-use-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.googledrive-auth-button-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.googledrive-revoke-auth-button-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.box-disclaimer {
|
||||
font-weight: bold;
|
||||
}
|
||||
.box-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.box-allow-to-use-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.box-auth-button-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.box-revoke-auth-button-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pcloud-disclaimer {
|
||||
font-weight: bold;
|
||||
}
|
||||
.pcloud-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pcloud-allow-to-use-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pcloud-auth-button-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pcloud-revoke-auth-button-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.yandexdisk-disclaimer {
|
||||
font-weight: bold;
|
||||
}
|
||||
.yandexdisk-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.yandexdisk-allow-to-use-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.yandexdisk-auth-button-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.yandexdisk-revoke-auth-button-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.koofr-disclaimer {
|
||||
font-weight: bold;
|
||||
}
|
||||
.koofr-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.koofr-allow-to-use-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.koofr-auth-button-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.koofr-revoke-auth-button-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.azureblobstorage-disclaimer {
|
||||
font-weight: bold;
|
||||
}
|
||||
.azureblobstorage-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.azureblobstorage-allow-to-use-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.qrcode-img {
|
||||
width: 350px;
|
||||
height: 350px;
|
||||
}
|
||||
|
||||
.ignorepaths-textarea {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.onlyallowpaths-textarea {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.logtohttpserver-warning {
|
||||
color: red;
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.setting-need-wrapping .setting-item-control {
|
||||
/* flex-wrap: wrap; */
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.pro-disclaimer {
|
||||
font-weight: bold;
|
||||
}
|
||||
.pro-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pro-auth-button-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pro-revoke-auth-button-hide {
|
||||
display: none;
|
||||
}
|
||||
35
.obsidian/snippets/mermaid.css
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
.markdown-preview-view .mermaid,
|
||||
.markdown-rendered .mermaid {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.mermaid svg {
|
||||
display: block;
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
max-width: 80%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div:has(> .mermaid):hover {
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
.mermaid:hover {
|
||||
overflow: scroll;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.mermaid:hover svg {
|
||||
display: block;
|
||||
width: auto;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
17
.obsidian/snippets/table-wrap-fix.css
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
.markdown-preview-view table {
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.markdown-preview-view th,
|
||||
.markdown-preview-view td {
|
||||
white-space: normal !important;
|
||||
word-break: break-word !important;
|
||||
overflow-wrap: break-word !important;
|
||||
}
|
||||
|
||||
.markdown-preview-view code {
|
||||
white-space: pre-wrap !important;
|
||||
word-break: break-all !important;
|
||||
}
|
||||
|
||||
8
.obsidian/themes/Baseline/manifest.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "Baseline",
|
||||
"version": "3.2.9",
|
||||
"minAppVersion": "1.11.6",
|
||||
"author": "Alexis C",
|
||||
"authorUrl": "https://github.com/aaaaalexis",
|
||||
"fundingUrl": "https://www.buymeacoffee.com/sevenaxis"
|
||||
}
|
||||
3146
.obsidian/themes/Baseline/theme.css
vendored
Normal file
8
.obsidian/themes/Minimal/manifest.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "Minimal",
|
||||
"version": "8.0.4",
|
||||
"minAppVersion": "1.9.0",
|
||||
"author": "@kepano",
|
||||
"authorUrl": "https://twitter.com/kepano",
|
||||
"fundingUrl": "https://www.buymeacoffee.com/kepano"
|
||||
}
|
||||
2251
.obsidian/themes/Minimal/theme.css
vendored
Normal file
229
.obsidian/workspace-mobile.json
vendored
Normal file
@@ -0,0 +1,229 @@
|
||||
{
|
||||
"main": {
|
||||
"id": "63c7a94c5413fbe9",
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "c7e2a979e98e91a5",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "9e20e40848ead0dd",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "markdown",
|
||||
"state": {
|
||||
"file": "period/daily/250509.md",
|
||||
"mode": "source",
|
||||
"source": false
|
||||
},
|
||||
"icon": "lucide-file",
|
||||
"title": "250509"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "96952f7fa67ed71b",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "markdown",
|
||||
"state": {
|
||||
"file": "study/conf/EuroSys'26.md",
|
||||
"mode": "preview",
|
||||
"source": false
|
||||
},
|
||||
"icon": "lucide-file",
|
||||
"title": "EuroSys'26"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "211edc9bbedb8e4a",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "markdown",
|
||||
"state": {
|
||||
"file": "study/conf/Untitled.md",
|
||||
"mode": "source",
|
||||
"source": false
|
||||
},
|
||||
"icon": "lucide-file",
|
||||
"title": "Untitled"
|
||||
}
|
||||
}
|
||||
],
|
||||
"currentTab": 2
|
||||
}
|
||||
],
|
||||
"direction": "vertical"
|
||||
},
|
||||
"left": {
|
||||
"id": "dda3df687c3b1f7a",
|
||||
"type": "mobile-drawer",
|
||||
"children": [
|
||||
{
|
||||
"id": "2681dfdaed3d6e72",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "file-explorer",
|
||||
"state": {
|
||||
"sortOrder": "alphabetical",
|
||||
"autoReveal": false
|
||||
},
|
||||
"icon": "lucide-folder-closed",
|
||||
"title": "Files"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "47d7b56b8956fba6",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "search",
|
||||
"state": {
|
||||
"query": "",
|
||||
"matchingCase": false,
|
||||
"explainSearch": false,
|
||||
"collapseAll": false,
|
||||
"extraContext": false,
|
||||
"sortOrder": "alphabetical"
|
||||
},
|
||||
"icon": "lucide-search",
|
||||
"title": "Search"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "987074333a2814fc",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "tag",
|
||||
"state": {
|
||||
"sortOrder": "frequency",
|
||||
"useHierarchy": true,
|
||||
"showSearch": false,
|
||||
"searchQuery": ""
|
||||
},
|
||||
"icon": "lucide-tags",
|
||||
"title": "Tags"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "90f659e436253420",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "bookmarks",
|
||||
"state": {},
|
||||
"icon": "lucide-bookmark",
|
||||
"title": "Bookmarks"
|
||||
}
|
||||
}
|
||||
],
|
||||
"currentTab": 0
|
||||
},
|
||||
"right": {
|
||||
"id": "205878452f07eea8",
|
||||
"type": "mobile-drawer",
|
||||
"children": [
|
||||
{
|
||||
"id": "8b57cba29869dbde",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "backlink",
|
||||
"state": {
|
||||
"file": "study/conf/EuroSys'26.md",
|
||||
"collapseAll": true,
|
||||
"extraContext": false,
|
||||
"sortOrder": "alphabetical",
|
||||
"showSearch": false,
|
||||
"searchQuery": "",
|
||||
"backlinkCollapsed": false,
|
||||
"unlinkedCollapsed": true
|
||||
},
|
||||
"icon": "links-coming-in",
|
||||
"title": "Backlinks"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "d5da11cc7f42c6e0",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "outgoing-link",
|
||||
"state": {
|
||||
"file": "phd/research/moe/Study.md",
|
||||
"linksCollapsed": false,
|
||||
"unlinkedCollapsed": true
|
||||
},
|
||||
"icon": "links-going-out",
|
||||
"title": "Outgoing links"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "d597776f419bcca5",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "outline",
|
||||
"state": {
|
||||
"file": "phd/research/moe/Study.md",
|
||||
"followCursor": false,
|
||||
"showSearch": false,
|
||||
"searchQuery": ""
|
||||
},
|
||||
"icon": "lucide-list",
|
||||
"title": "Outline"
|
||||
}
|
||||
}
|
||||
],
|
||||
"currentTab": 0
|
||||
},
|
||||
"left-ribbon": {
|
||||
"hiddenItems": {
|
||||
"remotely-save:Remotely Save": false,
|
||||
"bases:Create new base": false,
|
||||
"obsidian-focus-mode:Toggle Focus Mode (Shift + Click to show active pane only)": false,
|
||||
"switcher:Open quick switcher": false,
|
||||
"graph:Open graph view": false,
|
||||
"canvas:Create new canvas": false,
|
||||
"daily-notes:Open today's daily note": false,
|
||||
"templates:Insert template": false,
|
||||
"command-palette:Open command palette": false,
|
||||
"periodic-notes:Open today": false
|
||||
}
|
||||
},
|
||||
"active": "211edc9bbedb8e4a",
|
||||
"lastOpenFiles": [
|
||||
"study/conf/Untitled.md",
|
||||
"study/conf/EuroSys'26.md",
|
||||
"projects/agentic-kvcache/ongoing.md",
|
||||
"dev-env-setup.md",
|
||||
"Scrolling.md",
|
||||
"projects/heterogenous-parallelism/sync2.md",
|
||||
"z/courses/中马.md",
|
||||
"z/courses/pm/report.figs/struct.drawio",
|
||||
"phd/weekly-report/251214.md",
|
||||
"z/courses/自然辩证法复习资料.md",
|
||||
"phd/weekly-report/251109.md",
|
||||
"phd/weekly-report/251102.md",
|
||||
"phd/weekly-report/251026.md",
|
||||
"Config for Ali.md",
|
||||
"projects/heterogenous-parallelism/Sync.md",
|
||||
"article/Thinking.md",
|
||||
"ongoing/Agentic AI Infra.md",
|
||||
"projects/moe-autoscaling/Bailian Arch.md",
|
||||
"projects/moe-autoscaling/Survey.md",
|
||||
"projects/moe-autoscaling/Survey.figs",
|
||||
"projects/moe-autoscaling/Survey.figs/250611-091821.jpeg",
|
||||
"phd/paper-sharing/IMPRESS.md",
|
||||
"conf/ChinaSys25-Spr.md",
|
||||
"conf/ChinaSys25-Spr.figs/250525-101629.jpeg",
|
||||
"conf/ChinaSys25-Spr.figs/250525-101147.jpeg",
|
||||
"conf/ChinaSys25-Spr.figs/250525-100839.jpeg",
|
||||
"conf/ChinaSys25-Spr.figs/250525-100200.jpeg",
|
||||
"conf/ChinaSys25-Spr.figs/250525-095739.jpeg",
|
||||
"ongoing/Hardware for Inference.md",
|
||||
"conf/ChinaSys25-Spr.figs",
|
||||
"conf/ChinaSys25-Spr.figs/250524-113000.jpeg",
|
||||
"period/daily/250509.md",
|
||||
"conf",
|
||||
"period/daily/250508.md",
|
||||
"project/serverless-kvcache/Dev.md",
|
||||
"period/weekly/25-08.md",
|
||||
"period/weekly/25-14.md"
|
||||
]
|
||||
}
|
||||
241
.obsidian/workspace.json
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
{
|
||||
"main": {
|
||||
"id": "9403ee3a1c3b5fdc",
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "a8893039c60b1468",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "d3ef7a66c76312f9",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "markdown",
|
||||
"state": {
|
||||
"file": "Config for Ali.md",
|
||||
"mode": "source",
|
||||
"source": false
|
||||
},
|
||||
"icon": "lucide-file",
|
||||
"title": "Config for Ali"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "355b338ca9065921",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "markdown",
|
||||
"state": {
|
||||
"file": "projects/agentic-kvcache/related-works.md",
|
||||
"mode": "source",
|
||||
"source": false
|
||||
},
|
||||
"icon": "lucide-file",
|
||||
"title": "related-works"
|
||||
}
|
||||
}
|
||||
],
|
||||
"currentTab": 1
|
||||
}
|
||||
],
|
||||
"direction": "vertical"
|
||||
},
|
||||
"left": {
|
||||
"id": "be577ada85f6747a",
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "cd5cce81b09d3b4e",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "91d8cf92d8e931b2",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "file-explorer",
|
||||
"state": {
|
||||
"sortOrder": "alphabetical",
|
||||
"autoReveal": true
|
||||
},
|
||||
"icon": "lucide-folder-closed",
|
||||
"title": "Files"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "023b47b49edb4ba3",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "search",
|
||||
"state": {
|
||||
"query": "",
|
||||
"matchingCase": false,
|
||||
"explainSearch": false,
|
||||
"collapseAll": false,
|
||||
"extraContext": false,
|
||||
"sortOrder": "alphabetical"
|
||||
},
|
||||
"icon": "lucide-search",
|
||||
"title": "Search"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "914daba8cb3bfdc1",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "bookmarks",
|
||||
"state": {},
|
||||
"icon": "lucide-bookmark",
|
||||
"title": "Bookmarks"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"direction": "horizontal",
|
||||
"width": 247.5
|
||||
},
|
||||
"right": {
|
||||
"id": "ec415b2a0aef9bb4",
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "010cf2140800e841",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "90f6b8f3150c9e47",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "backlink",
|
||||
"state": {
|
||||
"file": "phd/paper-sharing/IMPRESS.md",
|
||||
"collapseAll": false,
|
||||
"extraContext": false,
|
||||
"sortOrder": "alphabetical",
|
||||
"showSearch": false,
|
||||
"searchQuery": "",
|
||||
"backlinkCollapsed": false,
|
||||
"unlinkedCollapsed": true
|
||||
},
|
||||
"icon": "links-coming-in",
|
||||
"title": "Backlinks for IMPRESS"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "e0ffc1ccd84af0df",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "outgoing-link",
|
||||
"state": {
|
||||
"file": "phd/research/MoE/Papers.md",
|
||||
"linksCollapsed": false,
|
||||
"unlinkedCollapsed": true
|
||||
},
|
||||
"icon": "links-going-out",
|
||||
"title": "Outgoing links from Papers"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "c905c5e3f85014fd",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "tag",
|
||||
"state": {
|
||||
"sortOrder": "frequency",
|
||||
"useHierarchy": true,
|
||||
"showSearch": false,
|
||||
"searchQuery": ""
|
||||
},
|
||||
"icon": "lucide-tags",
|
||||
"title": "Tags"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "b9bf7673cb90e601",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "outline",
|
||||
"state": {
|
||||
"file": "projects/agentic-kvcache/related-works.md",
|
||||
"followCursor": false,
|
||||
"showSearch": false,
|
||||
"searchQuery": ""
|
||||
},
|
||||
"icon": "lucide-list",
|
||||
"title": "Outline of related-works"
|
||||
}
|
||||
}
|
||||
],
|
||||
"currentTab": 3
|
||||
}
|
||||
],
|
||||
"direction": "horizontal",
|
||||
"width": 200
|
||||
},
|
||||
"left-ribbon": {
|
||||
"hiddenItems": {
|
||||
"bases:Create new base": false,
|
||||
"switcher:Open quick switcher": false,
|
||||
"graph:Open graph view": false,
|
||||
"canvas:Create new canvas": false,
|
||||
"templates:Insert template": false,
|
||||
"command-palette:Open command palette": false,
|
||||
"daily-notes:Open today's daily note": true,
|
||||
"obsidian-focus-mode:Toggle Focus Mode (Shift + Click to show active pane only)": false,
|
||||
"remotely-save:Remotely Save": false,
|
||||
"periodic-notes:Open today": false
|
||||
}
|
||||
},
|
||||
"active": "355b338ca9065921",
|
||||
"lastOpenFiles": [
|
||||
"study/conf/Untitled.md",
|
||||
"study/conf/EuroSys'26.md",
|
||||
"Untitled.md",
|
||||
"Config for Ali.md",
|
||||
"projects/auto-tuner/Ali Deployment.md",
|
||||
"projects/agentic-kvcache/ongoing.md",
|
||||
"projects/agentic-kvcache/related-works.md",
|
||||
"Commands.md",
|
||||
"projects/agentic-kvcache/sync.md",
|
||||
"projects/agentic-kvcache/outline.md",
|
||||
"projects/agentic-kvcache/roadmap.md",
|
||||
"projects/agentic-kvcache/main.md",
|
||||
"projects/agentic-kvcache",
|
||||
"projects/auto-tuner/sync2.md",
|
||||
"period/daily/26/260310.md",
|
||||
"period/daily/26/260312.md",
|
||||
"projects/auto-tuner/ali trace.md",
|
||||
"projects/auto-tuner/Untitled 3.md",
|
||||
"projects/auto-tuner/eval setup.md",
|
||||
"projects/auto-tuner/related-works.md",
|
||||
"dev-env-setup.md",
|
||||
"projects/auto-tuner/draft.md",
|
||||
"projects/auto-tuner/Untitled 1.md",
|
||||
"period/daily/26/260320.md",
|
||||
"period/daily/26/260317.md",
|
||||
"projects/auto-tuner/Untitled 2.md",
|
||||
"projects/auto-tuner/principles model.md",
|
||||
"projects/auto-tuner/related-works.figs",
|
||||
"projects/auto-tuner/related-works.figs/260410-105227.png",
|
||||
"projects/auto-tuner/sync2.figs/260410-105228-9.png",
|
||||
"projects/auto-tuner/sync2.figs/260410-105228-7.png",
|
||||
"projects/auto-tuner/sync2.figs/260410-105228-6.png",
|
||||
"projects/auto-tuner/sync2.figs/260410-105228-8.png",
|
||||
"projects/auto-tuner/sync2.figs/260410-105228-5.png",
|
||||
"projects/auto-tuner/sync2.figs/260410-105228-4.png",
|
||||
"projects/auto-tuner/sync2.figs/260410-105228-3.png",
|
||||
"projects/auto-tuner/sync2.figs/260410-105228-2.png",
|
||||
"main.canvas",
|
||||
"period/weekly/26",
|
||||
"period/weekly/25",
|
||||
"period/daily/25",
|
||||
"period/daily/26",
|
||||
"article/published/杂谈|博零总结.figs/250913-144507.png",
|
||||
"article/published/杂谈|博零总结.figs",
|
||||
"article/published",
|
||||
"article/drafts",
|
||||
"review/assignments",
|
||||
"Untitled.canvas"
|
||||
]
|
||||
}
|
||||
311
Commands.md
Normal file
@@ -0,0 +1,311 @@
|
||||
### Python
|
||||
|
||||
`pip install xxx -i https://pypi.tuna.tsinghua.edu.cn/simple`
|
||||
|
||||
mirrors:
|
||||
- https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
- https://mirrors.aliyun.com/pypi/simple/
|
||||
|
||||
|
||||
### RDMA
|
||||
|
||||
`ibstat`
|
||||
`ibv_devinfo`
|
||||
|
||||
`lspci | grep -i mellanox` (`apt install pciutils`)
|
||||
|
||||
`wget https://content.mellanox.com/ofed/MLNX_OFED-24.10-2.1.8.0/MLNX_OFED_LINUX-24.10-2.1.8.0-ubuntu24.04-x86_64.tgz`
|
||||
`./mlnxofedinstall --user-space-only --without-fw-update --distro ubuntu24.04 --force`
|
||||
[MLNX_OFED Download Center](https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/)
|
||||
|
||||
`ib_send_bw <server_ip> --report_gbits`
|
||||
|
||||
|
||||
|
||||
### Linux
|
||||
|
||||
`cat /etc/os-release`
|
||||
`cat /proc/cpuinfo`
|
||||
|
||||
|
||||
|
||||
### uv
|
||||
|
||||
`curl -LsSf https://astral.sh/uv/install.sh | sh`
|
||||
`uv self update`
|
||||
|
||||
|
||||
|
||||
## docker
|
||||
|
||||
`docker system info` 来得到 config 配置
|
||||
|
||||
`/etc/docker/daemon.json` 内配置:
|
||||
|
||||
``` json
|
||||
{
|
||||
"proxies": {
|
||||
"http-proxy": "http://ipads:ipads123@202.120.40.82:11235",
|
||||
"https-proxy": "http://ipads:ipads123@202.120.40.82:11235"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Proxy
|
||||
|
||||
```
|
||||
p="http://127.0.0.1:7890"
|
||||
p="http://gahow:Jiahao_4465_proxy@47.83.188.3:9118"
|
||||
p="http://gahow:Jiahao_13387_proxy@47.245.13.144:12358"
|
||||
```
|
||||
|
||||
server: tiny proxy
|
||||
|
||||
```
|
||||
sudo apt install tinyproxy -y
|
||||
sudo vim /etc/tinyproxy/tinyproxy.conf
|
||||
sudo systemctl restart tinyproxy
|
||||
```
|
||||
|
||||
|
||||
trojan
|
||||
|
||||
```
|
||||
trojan -c trojan_server.json
|
||||
```
|
||||
|
||||
trojan_server.json
|
||||
|
||||
```json
|
||||
{
|
||||
"run_type": "server",
|
||||
"local_addr": "0.0.0.0",
|
||||
"local_port": 12358,
|
||||
"remote_addr": "127.0.0.1",
|
||||
"remote_port": 80,
|
||||
"password": [
|
||||
"Jiahao_4465_trojan_proxy"
|
||||
],
|
||||
"log_level": 1,
|
||||
"ssl": {
|
||||
"cert": "/home/gahow/ca/certificate.crt",
|
||||
"key": "/home/gahow/ca/privkey.key",
|
||||
"key_password": "",
|
||||
"cipher": "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384",
|
||||
"cipher_tls13": "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384",
|
||||
"prefer_server_cipher": true,
|
||||
"alpn": [
|
||||
"http/1.1"
|
||||
],
|
||||
"alpn_port_override": {
|
||||
"h2": 81
|
||||
},
|
||||
"reuse_session": true,
|
||||
"session_ticket": false,
|
||||
"session_timeout": 600,
|
||||
"plain_http_response": "",
|
||||
"curves": "",
|
||||
"dhparam": ""
|
||||
},
|
||||
"tcp": {
|
||||
"prefer_ipv4": false,
|
||||
"no_delay": true,
|
||||
"keep_alive": true,
|
||||
"reuse_port": false,
|
||||
"fast_open": false,
|
||||
"fast_open_qlen": 20
|
||||
},
|
||||
"mysql": {
|
||||
"enabled": false,
|
||||
"server_addr": "127.0.0.1",
|
||||
"server_port": 3306,
|
||||
"database": "trojan",
|
||||
"username": "trojan",
|
||||
"password": "",
|
||||
"key": "",
|
||||
"cert": "",
|
||||
"ca": ""
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
trojan_client.json
|
||||
|
||||
```json
|
||||
{
|
||||
"run_type": "client",
|
||||
"local_addr": "127.0.0.1",
|
||||
"local_port": 1080,
|
||||
"remote_addr": "47.245.13.144",
|
||||
"remote_port": 12358,
|
||||
"password": [
|
||||
"Jiahao_13387_trojan_proxy"
|
||||
],
|
||||
"log_level": 1,
|
||||
"ssl": {
|
||||
"verify": false,
|
||||
"verify_hostname": true,
|
||||
"cert": "",
|
||||
"cipher": "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA",
|
||||
"cipher_tls13": "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384",
|
||||
"sni": "",
|
||||
"alpn": [
|
||||
"h2",
|
||||
"http/1.1"
|
||||
],
|
||||
"reuse_session": true,
|
||||
"session_ticket": false,
|
||||
"curves": ""
|
||||
},
|
||||
"tcp": {
|
||||
"no_delay": true,
|
||||
"keep_alive": true,
|
||||
"reuse_port": false,
|
||||
"fast_open": false,
|
||||
"fast_open_qlen": 20
|
||||
},
|
||||
"forward_proxy": {
|
||||
"enabled": true,
|
||||
"listen_addr": "127.0.0.1",
|
||||
"listen_port": 3128
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
http to socks5h
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install privoxy -y
|
||||
sudo vim /etc/privoxy/config
|
||||
|
||||
# add some lines:
|
||||
# listen-address 127.0.0.1:7890
|
||||
# forward-socks5t / 127.0.0.1:1080 .
|
||||
|
||||
sudo privoxy /etc/privoxy/config
|
||||
```
|
||||
|
||||
|
||||
## Mount
|
||||
|
||||
`mount_webdav`, `umount`
|
||||
|
||||
|
||||
## IP
|
||||
|
||||
`curl ipinfo.io / curl ip-api.com`
|
||||
|
||||
|
||||
|
||||
## Model download
|
||||
|
||||
`uvx modelscope download --model Qwen/Qwen3-VL-8B-Instruct --local_dir ./Qwen3-VL-8B-Instruct`
|
||||
|
||||
|
||||
|
||||
## Self signed ca
|
||||
|
||||
```bash
|
||||
# 进入 root(如果你已经是 root 可跳过)
|
||||
# sudo -i
|
||||
|
||||
# 创建目录并进入
|
||||
mkdir -p /root/ca
|
||||
cd /root/ca
|
||||
chmod 700 /root/ca
|
||||
|
||||
# ---------- A. 生成 CA(根证书) ----------
|
||||
# 生成 CA 私钥(4096 bits)
|
||||
openssl genrsa -out /root/ca/ca.key 4096
|
||||
|
||||
# 生成自签 CA 根证书(有效期 10 年 => 3650 天)
|
||||
openssl req -x509 -new -nodes -key /root/ca/ca.key \
|
||||
-sha256 -days 3650 -out /root/ca/ca.crt \
|
||||
-subj "/C=CN/ST=Shanghai/L=Shanghai/O=MyOrg/OU=MyUnit/CN=MyLocalCA"
|
||||
|
||||
chmod 600 /root/ca/ca.key
|
||||
chmod 644 /root/ca/ca.crt
|
||||
|
||||
# ---------- B. 生成服务器私钥与 CSR(包含 SAN 配置) ----------
|
||||
# 服务器私钥(2048 bits)
|
||||
openssl genrsa -out /root/ca/privkey.key 2048
|
||||
chmod 600 /root/ca/privkey.key
|
||||
|
||||
# 生成用于 CSR 的配置文件(内含 SAN)
|
||||
cat > /root/ca/server.csr.cnf <<'EOF'
|
||||
[req]
|
||||
default_bits = 2048
|
||||
prompt = no
|
||||
default_md = sha256
|
||||
distinguished_name = dn
|
||||
req_extensions = req_ext
|
||||
|
||||
[dn]
|
||||
C=CN
|
||||
ST=Shanghai
|
||||
L=Shanghai
|
||||
O=MyOrg
|
||||
OU=MyUnit
|
||||
CN = my.example.com
|
||||
|
||||
[req_ext]
|
||||
subjectAltName = @alt_names
|
||||
|
||||
[alt_names]
|
||||
DNS.1 = my.example.com
|
||||
DNS.2 = localhost
|
||||
IP.1 = 127.0.0.1
|
||||
EOF
|
||||
|
||||
# 生成 CSR
|
||||
openssl req -new -key /root/ca/privkey.key -out /root/ca/server.csr -config /root/ca/server.csr.cnf
|
||||
|
||||
# ---------- C. 用 CA 签发服务器证书(包含 SAN) ----------
|
||||
# v3 扩展文件(可复用)
|
||||
cat > /root/ca/v3.ext <<'EOF'
|
||||
authorityKeyIdentifier=keyid,issuer
|
||||
basicConstraints=CA:FALSE
|
||||
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
|
||||
subjectAltName = @alt_names
|
||||
|
||||
[alt_names]
|
||||
DNS.1 = my.example.com
|
||||
DNS.2 = localhost
|
||||
IP.1 = 127.0.0.1
|
||||
EOF
|
||||
|
||||
# 用 CA 签发(有效期 1 年 = 365 天),-CAcreateserial 会生成 /root/ca/ca.srl
|
||||
openssl x509 -req -in /root/ca/server.csr -CA /root/ca/ca.crt -CAkey /root/ca/ca.key \
|
||||
-CAcreateserial -out /root/ca/certificate.crt -days 365 -sha256 -extfile /root/ca/v3.ext
|
||||
|
||||
chmod 644 /root/ca/certificate.crt
|
||||
|
||||
# ---------- 可选:合并为一个 PEM(某些软件需要) ----------
|
||||
cat /root/ca/privkey.key /root/ca/certificate.crt > /root/ca/server.pem
|
||||
chmod 600 /root/ca/server.pem
|
||||
|
||||
# 输出结果路径
|
||||
echo "生成完成:"
|
||||
echo " CA 根证书: /root/ca/ca.crt"
|
||||
echo " CA 私钥 : /root/ca/ca.key"
|
||||
echo " 服务器私钥: /root/ca/privkey.key"
|
||||
echo " 服务器证书: /root/ca/certificate.crt"
|
||||
echo " 合并 PEM : /root/ca/server.pem (可选)"
|
||||
echo " CA serial : /root/ca/ca.srl"
|
||||
```
|
||||
|
||||
|
||||
修复 apt
|
||||
|
||||
```bash
|
||||
sudo dpkg --remove --force-depends x11-utils zutty
|
||||
|
||||
sudo apt --fix-broken install
|
||||
sudo dpkg --configure -a
|
||||
|
||||
sudo apt update
|
||||
sudo apt install -y --no-install-recommends bubblewrap
|
||||
```
|
||||
1025
Config for Ali.md
Normal file
25
LLM API price.md
Normal file
@@ -0,0 +1,25 @@
|
||||
## Price
|
||||
|
||||
每百万 token 计
|
||||
|
||||
| model | input with cache | input without cache | output | output thinking |
|
||||
| --------------------- | ---------------- | ------------------- | ------ | --------------- |
|
||||
| Qwen-Turbo | | 0.3 | 0.6 | 3.0 |
|
||||
| Qwen-Plus | | 0.8 | 2.0 | 8.0 |
|
||||
| Qwen-Max | | 2.4 | 9.6 | |
|
||||
| Qwen3-235b-a22b | | 2.0 | 8.0 | 20.0 |
|
||||
| Kimi-K2 | 1.0 | 4.0 | 16.0 | |
|
||||
| DeepSeek-R1(深夜 2.5 折) | 1.0 | 4.0 | 16.0 | |
|
||||
| DeepSeek-V3 (深夜 5 折) | 0.5 | 2.0 | 8.0 | |
|
||||
| GPT4.1/o3 | $0.5 | $2.0 | $8.0 | |
|
||||
| Gemini 2.5 Pro | $0.31 | $1.25 | $10 | |
|
||||
| Gemini 2.5 Flash | $0.075 | $0.3 | $2.5 | |
|
||||
|
||||
## Reference
|
||||
|
||||
https://help.aliyun.com/zh/model-studio/models
|
||||
https://platform.moonshot.cn/docs/pricing/chat
|
||||
https://api-docs.deepseek.com/zh-cn/quick_start/pricing
|
||||
https://openai.com/api/pricing/
|
||||
https://ai.google.dev/gemini-api/docs/pricing
|
||||
|
||||
9
LongRunning.md
Normal file
@@ -0,0 +1,9 @@
|
||||
- [ ] 统一的学术论文绘图包
|
||||
- [ ] 几套统一的绘图 style
|
||||
- [ ] 方便的基本图片类型绘制
|
||||
|
||||
|
||||
- [ ] LaTeX template for rebuttal & revision plan
|
||||
|
||||
|
||||
|
||||
48
Scrolling.md
Normal file
@@ -0,0 +1,48 @@
|
||||
|
||||
跨 region,region 扩缩容、kvs 要迁移、服务什么场景、怎么迁移、怎么定义 cost model
|
||||
|
||||
|
||||
|
||||
claudian claude code for obsidian
|
||||
|
||||
|
||||
|
||||
deepwiki
|
||||
|
||||
context as memory, LLM as CPU: https://rlancemartin.github.io/2025/06/23/context_engineering/
|
||||
|
||||
|
||||
通过向某些特定网址发送 HTTP 请求(比如`google.com/generate_204`),根据它们的回复,判断当前是否在线。相比于 `ping 8.8.8.8` 使用 ICMP protocol 只检查了 DNS,能够检查 full stack 的 DNS, TCP, HTTP
|
||||
|
||||
|
||||
|
||||
Dijkstra’s 10 commandments for academic research https://www.cs.utexas.edu/~EWD/
|
||||
|
||||
> - Raise your standards as high as you can live with, avoid wasting your time on routine problems, and always try to work as closely as possible at the boundary of your abilities. Do this because it is the only way of discovering how that boundary should be moved forward.
|
||||
> - We all like our work to be socially relevant and scientifically sound. If we can find a topic satisfying both desires, we are lucky; if the two targets are in conflict with each other, let the requirement of scientific soundness prevail.
|
||||
> - Never tackle a problem of which you can be pretty sure that (now or in the near future) it will be tackled by others who are, in relation to that problem, at least as competent and well-equipped as you are.
|
||||
> - Write as if your work is going to be studied by a thousand people.
|
||||
> - Don't get enamored with the complexities you have learned to live with (be they of your own making or imported). The lurking suspicion that something could be simplified is the world's richest source of rewarding challenges.
|
||||
> - Before embarking on an ambitious project, try to kill it.
|
||||
> - Remember that research with a big R is rarely mission-oriented and plan in terms of decades, not years. Resist all pressure —be it financial or cultural— to do work that is of ephemeral significance at best.
|
||||
> - Don't strive for recognition (in whatever form): recognition should not be your goal, but a symptom that your work has been worthwhile.
|
||||
> - Avoid involvement in projects so vague that their failure could remain invisible: such involvement tends to corrupt one's scientific integrity.
|
||||
> - Striving for perfection is ultimately the only justification for the academic enterprise; if you don't feel comfortable with this goal —e.g. because you think it too presumptuous—, stay out!
|
||||
|
||||
|
||||
|
||||
视频格式转换:
|
||||
handbrake: https://handbrake.fr/
|
||||
|
||||
|
||||
The craft of research
|
||||
The design of everyday things
|
||||
|
||||
|
||||
https://github.com/xlite-dev/CUDA-Learn-Notes
|
||||
|
||||
- [ ] transformer 各个模块的具体计算流程
|
||||
- [ ] attention 的各类计算方式,计算、访存的复杂度分析,分别是如何优化的?如何做到硬件友好
|
||||
- [ ] 各种并行策略是如何实现的?如何切分?如何综合?
|
||||
|
||||
|
||||
1193
Untitled.md
Normal file
47
article/drafts/Thinking.md
Normal file
@@ -0,0 +1,47 @@
|
||||
沟通对齐的艺术:与 MoBA 游戏视野的共同点
|
||||
|
||||
---
|
||||
民科:AI 时代的 OS API 设计,新的抽象层设计
|
||||
|
||||
|
||||
---
|
||||
为硅基生命的诞生创造世界基础,为科技发展添一把火,“尔曹身与名俱灭,不废江河万古流”
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
人类和 LLM 比的优势究竟在哪?
|
||||
反应速度显然不如机器:脚本怪,开挂,任何电子游戏,机器都能吊打人
|
||||
记忆能力显然不如机器
|
||||
一辈子能得到的信息输入显然不如机器:五感输入,一辈子也只有相对有限的 bit 输入
|
||||
|
||||
|
||||
人类的优势:
|
||||
想象力,整合能力:LLM 需要很长的 context 才能得到的结果,人类可以使用短很多的 context 得到,但是这个本质可能来源于人类的潜知识/潜意识,但是 LLM 的参数也可以认为是这些潜知识
|
||||
|
||||
成本,是的人比机器便宜!
|
||||
|
||||
|
||||
|
||||
---
|
||||
学习做好销售:如果不想工作只是圈地自萌的自我精神满足和自我愉悦,必须学会如何 sell 自己/自己的工作,在这个信息爆炸的时代,更需要让大家知道你,知道你的工作
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
agent 框架下的推荐系统/广告
|
||||
|
||||
|
||||
|
||||
---
|
||||
学习笔记
|
||||
- 量子计算
|
||||
|
||||
|
||||
---
|
||||
博 0 总结
|
||||
|
||||
|
||||
0
article/drafts/学习笔记|量子计算.md
Normal file
29
article/drafts/杂谈|AI 时代的人类优势.md
Normal file
@@ -0,0 +1,29 @@
|
||||
作为一个守旧派,我还是时常和同学吐槽 LLM 怎么这么笨的,但是不可否认的是在工作中我已经离不开 LLM 了,最近的一次深刻体会是在公司时 Qwen Chat 的前端崩溃了半分钟,这半分钟我就等着它活过来继续帮我解决问题,已经变成了离开 LLM 不会写代码的形状了。
|
||||
|
||||
人类作为一个几百万年进化来的生物,也只是一套演化了几百万年的参数(基因),加上一辈子有限的信息输入对自身做 finetune。那么人类相比硅基生物究竟有什么优势呢?自己最近时常在思考这个问题。
|
||||
|
||||
首先先说一下人类显然比不过硅基生物的地方:
|
||||
|
||||
1. 反应速度
|
||||
显然在现代的所有比拼反应速度的电子游戏中,如果不加以限制,机器都能吊打人类,经典的脚本怪。
|
||||
2. 记忆能力
|
||||
这点应该很显然
|
||||
3. 信息输入量
|
||||
有科普介绍过人类通过五感,能够得到的输入信息比特数也是有限的,这点显然比不过大规模分布式的 LLM 训练所能得到的信息输入。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
人类和 LLM 比的优势究竟在哪?
|
||||
反应速度显然不如机器:脚本怪,开挂,任何电子游戏,机器都能吊打人
|
||||
记忆能力显然不如机器
|
||||
一辈子能得到的信息输入显然不如机器:五感输入,一辈子也只有相对有限的 bit 输入
|
||||
|
||||
|
||||
人类的优势:
|
||||
想象力,整合能力:LLM 需要很长的 context 才能得到的结果,人类可以使用短很多的 context 得到,但是这个本质可能来源于人类的潜知识/潜意识,但是 LLM 的参数也可以认为是这些潜知识
|
||||
|
||||
成本,是的人比机器便宜!
|
||||
BIN
article/published/杂谈|博零总结.figs/250913-144507.png
Normal file
|
After Width: | Height: | Size: 55 KiB |
53
article/published/杂谈|博零总结.md
Normal file
@@ -0,0 +1,53 @@
|
||||
## 杂谈|博零总结
|
||||
|
||||
赶在博一开始前的最后一天,写写过去一年的博零生活的收获、体验和感悟。从 24 年 9.12 进入阿里实习算作正式的科研开始节点,也是正好过去了一年。
|
||||
|
||||
![[250913-144507.png]]
|
||||
|
||||
### 我的收获
|
||||
|
||||
1. 最直接可量化的收获是被老板手把手带飞,比较幸运地一投即中收获了一篇 ATC:[KVCache Cache in the Wild: Characterizing and Optimizing KVCache Cache at a Large Cloud Provider](https://www.usenix.org/conference/atc25/presentation/wang-jiahao).
|
||||
2. 参加了不少会(~~旅了不少游~~),作为死宅也是趁着各类开会到处玩了玩。
|
||||
3. 参加了 EuroSys'26 的 shadow PC,体验了一下审稿人的心态和学习了审稿流程,对 paper 的 presentation 重要性的认识进一步加强。
|
||||
4. 经过一个完整的科研工作流程,也得到了一些关于科研工作流的收获与进步。就输入端来说,读 paper 不再像一年前的小朋友模样,拿到一篇 paper 从头开始一句句往后读,开始有一些自己的 background 在脑中,读 paper 会开始更主动地找自己想要的部分。但是由于当前仍然十分有限的 background,读 paper 和找到对自己想要部分的能力仍需要继续加强。就输出端来说,目前认识到了写作、画图、做 slides 进行输出的重要性,但是在输出端的所有方面都还缺乏锻炼,希望能在未来一年摸索出一些自己就这三方面输出的一些 SOP.
|
||||
5. 就合作与沟通有了一些更深的体会。即使本科期间有着各种团队开发、小组合作等任务,但是本科所做的事情大抵是十分确定的,容易有明确的任务分解,大家的信息差不大,需要“有效沟通”的部分并不多。但在科研项目中许多东西本身是不确定的,很多东西是自己在摸索过程中被自己学习到了 latent space 中,在与他人沟通时很容易忽视这些 latent space 中的 context 导致的信息差,导致沟通的不顺畅。自然语言本身存在的 ambiguous 也很容易导致即使是两个人沟通,两个人脑中形成的 figure 也不太一样进而引起误解。目前自己还没探索出好的方式来精确认识自己的 latent space 进而精准地进行表达,只能通过反复 ping-pong 的方式确认是不是在沟通中达成了共识,希望未来能找到更清晰的沟通合作方式。
|
||||
6. 这个世界的大部分工作(除了纯数一类的工作需要极端天才的个人英雄主义)想要做出一些有价值的事还是离不开团队合作,做技术与团队合作是两个正交的纬度,学会避免纯粹技术主义的叙事。作为 system 特别是 distributed system 的研究者,最直接的比喻是做技术是 compute、团队合作是 communication,但是在分布式系统中,存在着无数例子告诉我们,一个系统很可能是 communication-bound 的,在团队合作中如何降低 communication 的 overhead 是一个十分值得学习的事情。(如果希望做一些有价值的事,而不仅局限于个人折腾技术的精神愉悦的话)
|
||||
|
||||
### 一些遗憾与不足
|
||||
|
||||
1. 美签被卡,没去成最后一届 ATC 现场,~~错失波士顿旅游机会~~
|
||||
2. 仍然缺乏独立开启一个科研项目的能力,从今年 5 月赶完 ATC final version 之后,似乎就开始了一边感觉挺忙,一边又看起来毫无科研进展的既感觉挺累又感觉很摆的本科毕业假期时光。进入一种探索可能的方向、发现 prior work,怀疑价值,想不到更进一步的工作的循环之中。
|
||||
3. 开始科研生活后的拖延症相比之前似乎更严重了,ddl 的到来相比固定每周要交的作业、要写完的 lab 要不规律和慢很多,许多想做的事情最后都变成停留在脑中的想法而没有开启任何行动,目前还没找到好的方式改善这一点。
|
||||
4. 很多不足其实在上一部分的收获中已经说到,~~认识到这些不足用乐观的角度看也是收获~~。
|
||||
|
||||
### 过去一年读过的一些东西
|
||||
|
||||
在从本科向独立做科研的转变中大家或多或少都会有一些迷茫,曾经读过一些来帮助自己更清晰地认识科研、认识读博这件事,了解一些形而上的东西,在此汇总一下。
|
||||
|
||||
1. The Ph.D. Grind. 作者介绍了自己读博的各个阶段以及得到的个人成长,让读者能对读博生活有更清晰的预期
|
||||
2. 一名系统研究者的攀登之路. 海波老师的一些研究经历与感触
|
||||
3. [Useful Thoughts about Research](https://www.eecs.harvard.edu/htk/phdadvice/). H.T. Kung 教授在 Harvard 给的一些关于 research 的实用建议
|
||||
4. https://zhaoxiahust.github.io/blog/index.html. 一个关于 system research 的资源汇总的 article list
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
关于沟通
|
||||
|
||||
进入实验室以来,感觉到自己的沟通明显变多了,~~有从 I 人变 E 的趋势~~
|
||||
|
||||
随着合作和沟通变多,发现了一些明显存在的问题,作为技术人非常容易陷入知识的诅咒,有一些东西即使是自己花了一下午搞懂的,但是在搞懂之后就会进入一种觉得这个东西十分简单、显然等的心态,在与别人沟通时,常常会不自觉地假设别人也非常了解这一块,但是这是一种错误的心态。感觉仍然需要进一步通过刻意训练来避免。
|
||||
|
||||
另一方面,除了纯数一类的人类智慧巅峰,可能需要极少数天才做出一些突破,这个世界上的大部分工作要成事还是离不开合作,作为做分布式系统的,也有着许多系统问题能够让人清晰地认识到,一个系统中的通信开销往往是不可忽略的,甚至是 bottleneck,团队合作同样是一个分布式系统,在一个优秀的团队中,也许大家的处理器性能都很强,计算不会成为 bottleneck,但是如何做好沟通降低通信的 overhead 就显得尤为重要。
|
||||
|
||||
本科到做研究的转变
|
||||
|
||||
本科期间做的事情往往是确定性的,即使是从零开始写一个上万行的玩具编译器,其中做的编译优化等等,也是路径明确的,只需要复现前人提出的各类优化即可。而在研究中,你需要自己第一手地去探索可能性,回答一个不确定的问题。
|
||||
|
||||
关于舒适圈
|
||||
|
||||
当在向上走时,总是有一个需要走出舒适圈的过程。经过本科几年的代码训练,写代码相比于做科研项目一定是一个更在舒适圈内的事。而可以想象到的,经过几年的科研训练之后,可能做科研会是一个相对在舒适圈内的事情,但是那时可能又有新的舒适圈外的事情,例如如何做团队的组织、如何 social 等等。人生没有所谓的上岸,一岸过后必有下一岸。找到自己喜欢的方式,收敛到一个自己满意的人生节奏点即可。
|
||||
|
||||
想要做一套自己的画图工具包、即使现在有了大模型的帮助,科研画图能够很轻松的让大模型写一段代码来画出自己想要的图,但是画图的美观性、个人风格方面,仍然是需要自己来准备一套画图工具包的
|
||||
27
article/published/民科|瞎谈 AI for OS.md
Normal file
@@ -0,0 +1,27 @@
|
||||
## 民科|瞎谈 AI for OS
|
||||
|
||||
> Disclaimer: 本文为民科软文,不涉及任何具体的真实的技术讨论。
|
||||
|
||||
前段时间看到 NeuralOS [1] 这个工作,由大模型来模拟 OS 的行为,通过读取键盘、鼠标的操作作为输入,让大模型生成计算机屏幕画面作为输出。其实这件事并不新颖,容易让人想到早期 ChatGPT 刚发布时,就有人让 GPT 扮演一个命令行工具,来模拟输出执行一条命令后的结果。
|
||||
|
||||
这类工作自然是看着比较有趣的,但是本质来说脱离了 OS 的范畴(下面贴一段 Wikipedia 的定义)。目前常说的 AI OS,个人认为分为两个层级,一个是目前常出现的 AI PC、AI mobile phone 之类的,提供一些 AI 能力让用户使用更加方便,例如一些办公软件自动化、一个 agent 来自动点外卖等,这些在我看来属于 AI agent 的范畴,他们有可能带来类似从 CLI 到 GUI 变化的一个新变革,但不在本文讨论的 scope 内。另一个则是从传统 OS 定义出发,我们希望抽象和管理硬件资源,同时为上层应用提供各类能力(计算、存储等等),本文希望设想一下 AI for OS 在这传统定义下能够做什么。
|
||||
|
||||
> An operating system (OS) is system software that manages computer hardware and software resources, and provides common services for computer programs. [2]
|
||||
|
||||
在设想 AI for OS 能够带来什么改变之前,我们先看一下最开始 OS 是如何诞生的。最早期的计算机通过人工纸带打孔以及在超大机房里做电缆插拔来执行一个“程序”,每次只能运行一个“程序”,且需要大量的人力成本来进行“程序”的加载、切换等,资源利用率极低。一个自然的想法是:能不能让计算机自己管理程序的加载、运行、切换和资源分配,由此开始了 OS 的诞生与不断演化,从而有了现今的时间片轮转实现程序的并行,虚拟内存的管理实现程序间的隔离等等。
|
||||
|
||||
既然 OS 的本质是对硬件资源提供抽象和管理、对上层应用暴露统一的能力,我们能够看到现今的操作系统仍然有着很多需要大量人力成本的工作,尤其是在分布式、云计算等领域。传统 OS 需要人作为核心决策者,OS 只是静态配置来实现确定性的行为。但现今的系统复杂性越来越高,分布式场景下有着异构节点、不同的网络拓扑、复杂的状态同步问题,在负载侧有着越来越复杂的 workload,任务的多样性越来越高,对于调度机制等也带来了许多新的挑战。而现今面对这些复杂性,都是依靠人类专家付出大量的人力成本来试错、调优,这种事情本不该是 sysetm 哲学希望看到的。
|
||||
|
||||
因此本文想要随意畅想一下 AI for OS 可能能够带来什么改变。人类使用工具的最本质需求应该是:我有一个问题,工具能够帮助我解决这个问题。传统 OS 提供的接口(syscall、POSIX 标准等),都是由人告诉机器“你要做什么”,而我们更希望看到的是,由人告诉机器“我想干什么”。我们从上到下来看这个问题:
|
||||
|
||||
当有一个足够聪明的系统时,最上层统一提供的接口应该是一些类似于 `run_inference(model="Qwen3-Max", SLO=50ms, budget=$1000, mode="performance_first")` 这样的 API 来直接告诉系统“我想干什么”。那么在我们希望能够提供这样的接口的情况下,我们的系统需要能够做到很多事情。
|
||||
|
||||
在系统的调度层面,我们希望有一个类似 AI agent 的智能体来做自动化的调度决策,而不是传统的时间片轮转与优先级队列。从小的方面说一个最简单的需求,我们在做批量化测试时,特别是不同测试可能需要使用的资源(卡数等)不同,目前都需要人工编写脚本编排来依次启动测试任务。一个更加智能的系统应该能够在我告诉系统我需要完成这些测试任务之后,就自动编排调度,在最大化资源利用完成测试任务的前提下,也不会出现 OOM 等现象。从大的方面说,在我们的云厂商中,有着大量的 serverless 需求,这些需求都应该由系统的智能调度决策自动化地解决,从而避免大量的人类专家编写规则与试错调优,进而减少资源利用的 bubble。最终实现用户只需要负责提交任务,以及任务需要满足的 SLO 等性能需求指标、执行任务的预算,系统就能根据需求自动化地做任务调度。
|
||||
|
||||
在硬件抽象层面,从传统的 CPU 为中心,到现代的系统已经在面对越来越多样的异构硬件(CPU, GPGPU, NPU, TPU, etc),传统 OS 缺少对各类异构硬件的状态感知,需要各种硬件之间的不同 API 来反复同步状态,任务在不同异构硬件之间的分发与决策也需要大量的人类专家经验来调优(例如在 LLM Infra 领域的很多将部分需求卸载至 CPU 计算的工作)。在 AI for OS 下,我们可能会希望系统层面能够自动感知这些异构硬件的特征、当前状态等等,实时评估当前硬件能够提供的资源,甚至提供对未来的预测能力,以此提供抽象并暴露一些接口,从而屏蔽异构硬件的区别,让上层看到的只是简单的不同资源和能力,从而根据任务需求做自动化地任务分发与调优。
|
||||
|
||||
以上纯属民科瞎谈,不涉及任何技术建议,但是技术总归是在不断演进的,仍然需要许许多多踏实的科研工作一步步尝试和推进,从而探索和实现未来科技的可能性。总而言之,我们这些在当代做计算机系统的工程师们,又何尝不是七八十年前那些负责把纸带一个个塞到大型机上运行,同时反复修理大型机故障的人呢?这又本该如此吗?
|
||||
|
||||
参考资料:
|
||||
[1] https://arxiv.org/abs/2507.08800
|
||||
[2] https://en.wikipedia.org/wiki/Operating_system
|
||||
223
dev-env-setup.md
Normal file
@@ -0,0 +1,223 @@
|
||||
## tools
|
||||
|
||||
https://next-ai-drawio.jiang.jp
|
||||
|
||||
|
||||
## check list
|
||||
|
||||
### proxy
|
||||
|
||||
```bash
|
||||
proxyOn() {
|
||||
p="http://ipads:ipads123@202.120.40.82:11235"
|
||||
p="http://gahow:Jiahao_4465_proxy@47.83.188.3:9118"
|
||||
p="http://127.0.0.1:7890"
|
||||
export https_proxy=$p http_proxy=$p all_proxy=$p
|
||||
}
|
||||
|
||||
proxyOff() {
|
||||
unset https_proxy http_proxy all_proxy
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
```bash
|
||||
sudo apt update && sudo apt install autossh -y
|
||||
nohup autossh -M 0 -N proxy > /tmp/ssh-proxy.log 2>&1 &
|
||||
```
|
||||
|
||||
|
||||
### nvim
|
||||
|
||||
`wget https://github.com/neovim/neovim/releases/download/v0.11.4/nvim-linux-x86_64.tar.gz`
|
||||
|
||||
add `.config/nvim/init.lua`
|
||||
|
||||
### tmux
|
||||
|
||||
```
|
||||
bind-key b send-prefix
|
||||
|
||||
set -g default-terminal "tmux-256color"
|
||||
set -ag terminal-overrides ",xterm-256color:RGB"
|
||||
set -g status-right ""
|
||||
|
||||
unbind '%'
|
||||
bind '|' split-window -h -c "#{pane_current_path}"
|
||||
|
||||
unbind '"'
|
||||
bind '_' split-window -v -c "#{pane_current_path}"
|
||||
|
||||
bind -r m resize-pane -Z
|
||||
|
||||
set -g base-index 1
|
||||
|
||||
set-window-option -g mode-keys vi
|
||||
bind-key -T copy-mode-vi 'v' send -X begin-selection
|
||||
bind-key -T copy-mode-vi 'y' send -X copy-selection
|
||||
unbind -T copy-mode-vi MouseDragEnd1Pane
|
||||
```
|
||||
|
||||
|
||||
### uv
|
||||
|
||||
```bash
|
||||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
|
||||
export UV_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
export UV_INDEX_URL=https://mirrors.aliyun.com/pypi/simple/
|
||||
```
|
||||
|
||||
|
||||
|
||||
### codex
|
||||
|
||||
```bash
|
||||
cd "$HOME/.vscode-server/extensions/openai.chatgpt-0.4.15/bin/linux-x86_64"
|
||||
|
||||
# keep the original
|
||||
mv codex codex.real
|
||||
|
||||
# wrapper that forces a proxy and then calls the original
|
||||
cat > codex <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
export HTTPS_PROXY="http://ipads:ipads123@127.0.0.1:11235"
|
||||
export HTTP_PROXY="http://ipads:ipads123@127.0.0.1:11235"
|
||||
export NO_PROXY="http://ipads:ipads123@127.0.0.1:11235"
|
||||
# ------------------------------------------------
|
||||
HERE="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
exec "$HERE/codex.real" "$@"
|
||||
EOF
|
||||
chmod +x codex
|
||||
```
|
||||
|
||||
|
||||
### vllm
|
||||
|
||||
```bash
|
||||
VLLM_USE_PRECOMPILED=1 uv pip install --editable . [--prerelease=allow]
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
ray start --head --port 6379 --num-gpus 8
|
||||
ray start --address=172.27.21.64:6379 --num-gpus 8
|
||||
```
|
||||
|
||||
|
||||
### Rust
|
||||
|
||||
```bash
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### trojan
|
||||
|
||||
server:
|
||||
|
||||
```yaml
|
||||
run-type: server
|
||||
local-addr: 0.0.0.0
|
||||
local-port: 12358
|
||||
remote-addr: 127.0.0.1
|
||||
remote-port: 80
|
||||
password:
|
||||
- Jiahao_13387_trojan_proxy
|
||||
ssl:
|
||||
cert: /root/ca/certificate.crt
|
||||
key: /root/ca/privkey.key
|
||||
sni: your-domain-name.com
|
||||
```
|
||||
|
||||
client:
|
||||
|
||||
```yaml
|
||||
run-type: client
|
||||
local-addr: 127.0.0.1
|
||||
local-port: 1080
|
||||
remote-addr: 47.245.13.144
|
||||
remote-port: 12358
|
||||
password:
|
||||
- Jiahao_13387_trojan_proxy
|
||||
ssl:
|
||||
verify: false
|
||||
sni: your-domain-name.com
|
||||
mux:
|
||||
enabled: true
|
||||
```
|
||||
|
||||
|
||||
use subscription:
|
||||
|
||||
```yaml
|
||||
run-type: client
|
||||
local-addr: 127.0.0.1
|
||||
local-port: 1080
|
||||
remote-addr: oss-cn-shanghai.solidigm-qwer.com
|
||||
remote-port: 20032
|
||||
password:
|
||||
- 1AF767FB-A9B4-805B-7EF7-ABBA76044B77
|
||||
ssl:
|
||||
verify: false
|
||||
sni: cos.ap-shanghai.myqcloud.com
|
||||
```
|
||||
|
||||
|
||||
`./trojan-go -config config.yaml`
|
||||
|
||||
|
||||
|
||||
## mac
|
||||
|
||||
```
|
||||
❯ sudo pmset -a sleep 0
|
||||
Password:
|
||||
❯ pmset -g
|
||||
System-wide power settings:
|
||||
SleepDisabled 1
|
||||
DestroyFVKeyOnStandby 0
|
||||
Currently in use:
|
||||
standby 1
|
||||
Sleep On Power Button 1
|
||||
hibernatefile /var/vm/sleepimage
|
||||
powernap 1
|
||||
networkoversleep 0
|
||||
disksleep 10
|
||||
sleep 0
|
||||
hibernatemode 0
|
||||
ttyskeepawake 1
|
||||
displaysleep 30
|
||||
tcpkeepalive 1
|
||||
lowpowermode 0
|
||||
womp 1
|
||||
```
|
||||
|
||||
|
||||
# Prompts
|
||||
|
||||
`codex -a never -s workspace-write`
|
||||
|
||||
|
||||
```md
|
||||
请使用第一性原理思考。你不能总是假设我非常清楚自己想要什么和该怎么得到。请保持审慎,从原始需求和问题出发,如果动机和目标不清晰,停下来和我讨论。如果目标清晰但是路径不是最短,告诉我,并且建议更好的办法
|
||||
```
|
||||
|
||||
|
||||
```md
|
||||
**Use first-principles reasoning.**
|
||||
Do not assume that I always have a precise understanding of the problem, the objective, or the best way to achieve it.
|
||||
|
||||
Start from the underlying problem and constraints rather than from my proposed solution.
|
||||
|
||||
- If the **goal, motivation, or constraints are unclear**, pause and ask clarifying questions.
|
||||
|
||||
- If my approach is **suboptimal, inefficient, or based on incorrect assumptions**, explain why and suggest better alternatives.
|
||||
|
||||
- Challenge hidden assumptions when necessary.
|
||||
|
||||
|
||||
Your role is not just to execute instructions, but to **help identify the correct problem and the most effective path to solving it**.
|
||||
```
|
||||
17
main.canvas
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"nodes":[
|
||||
{"id":"n1","type":"text","text":"# Knowledge Library\nCanvas dashboard for this Obsidian vault. Click cards to open notes.","x":0,"y":0,"width":660,"height":140},
|
||||
{"id":"n2","type":"text","text":"## Stats\n- 143 markdown notes\n- PhD 63 | Projects 28 | Period 20 | Study 12 | Article 5 | Ongoing 2 | Review 2 | Z 4 | Root 7","x":700,"y":0,"width":440,"height":140},
|
||||
{"id":"n3","type":"text","text":"## PhD\n- Weekly report: [260125](phd/weekly-report/260125.md)\n- Papers: [IMPRESS](phd/papers/IMPRESS.md) · [fMoE](phd/papers/fMoE.md)\n- Research threads: `phd/research/`","x":0,"y":180,"width":320,"height":260},
|
||||
{"id":"n4","type":"text","text":"## Projects\n- Heterogenous parallelism: [Roadmap](projects/auto-tuner/Roadmap.md)\n- KV cache: [Dev](projects/kvcachecache/Dev.md)\n- MoE autoscaling: [Ongoing](projects/moe-autoscaling/Ongoing.md)","x":360,"y":180,"width":320,"height":260},
|
||||
{"id":"n5","type":"text","text":"## Ongoing\n- [Agentic AI Infra](ongoing/Agentic%20AI%20Infra.md)\n- [Hardware for Inference](ongoing/Hardware%20for%20Inference.md)","x":720,"y":180,"width":320,"height":260},
|
||||
{"id":"n6","type":"text","text":"## Period\n- Daily: [260129](period/daily/26/260129.md)\n- Weekly: [0714-0720](period/weekly/25/0714-0720.md)","x":1080,"y":180,"width":320,"height":260},
|
||||
{"id":"n7","type":"text","text":"## Study\n- [How to review](study/How%20to%20review.md)\n- [Rules for good OKR](study/Rules%20for%20good%20OKR.md)\n- [CUDA notes](study/CUDA%20notes.md)","x":0,"y":520,"width":320,"height":260},
|
||||
{"id":"n8","type":"text","text":"## Article\n- Drafts: [Thinking](article/drafts/Thinking.md)\n- Published: [民科|瞎谈 AI for OS](article/published/民科|瞎谈%20AI%20for%20OS.md)","x":360,"y":520,"width":320,"height":260},
|
||||
{"id":"n9","type":"text","text":"## Review\n- Assignment: [EuroSys26-Spring-Shadow](review/assignments/EuroSys26-Spring-Shadow.md)\n- Template: [Template](review/templates/Template.md)","x":720,"y":520,"width":320,"height":260},
|
||||
{"id":"n10","type":"text","text":"## Z\n- [How To Ask Questions The Smart Way](z/How%20To%20Ask%20Questions%20The%20Smart%20Way.md)\n- [Marked](z/Marked.md)","x":1080,"y":520,"width":320,"height":260},
|
||||
{"id":"n11","type":"text","text":"## Root Utilities\n- [Commands](Commands.md)\n- [LLM API price](LLM%20API%20price.md)\n- [dev-env-setup](dev-env-setup.md)\n- [Scrolling](Scrolling.md) · [LongRunning](LongRunning.md)","x":0,"y":860,"width":680,"height":240},
|
||||
{"id":"n12","type":"text","text":"## Navigation Notes\n- Folder links like `study/` create new files in Obsidian.\n- Use the file explorer for folders, or click note links in this canvas.\n- If you want folder-level hubs, I can add index notes inside each folder.","x":720,"y":860,"width":440,"height":240}
|
||||
],
|
||||
"edges":[]
|
||||
}
|
||||
BIN
ongoing/Agentic AI Infra.figs/250722-113804.png
Normal file
|
After Width: | Height: | Size: 698 KiB |
23
ongoing/Agentic AI Infra.md
Normal file
@@ -0,0 +1,23 @@
|
||||
https://mp.weixin.qq.com/s/es2ZIRDTQQ_Z0fifyKzodQ
|
||||
|
||||
Agent执行和传统的Serverless无状态服务相比, 最大的区别是需要维持大量的Agent执行状态, 有可能还需要执行过程中尽量能够有一些checkpoint, 在某些执行失败后可以回退到前一个snapshot状态继续执行.
|
||||
|
||||
Agent本身具有一定的身份权限去处理很多敏感的数据, 因此它的执行环境的安全性是一个非常值得关注的话题, 传统的容器, 例如一些AWS Lambda服务则无法提供这样的安全隔离性.
|
||||
|
||||
|
||||
|
||||
事实上这样的ShortTerm/LongTerm Memory也就构成了一个存储上的冷热分层. 一方面像OSS这样的存储需要热缓存, 同时也需要像S3 Vectors那样构建一定的搜索能力. 另一方面更重要的是, `在模型多个Agent并行执行的时候, 还有很多数据一致性的处理`. 以前写过一篇埋了一些伏笔
|
||||
|
||||
但是在传输过程中需要有很好的拥塞控制和优先级调度避免对DeepEP这样的流量产生干扰.
|
||||
|
||||
又要保证Cache的命中率, 又不会让Context爆掉.
|
||||
|
||||
|
||||
![[250722-113804.png]]
|
||||
|
||||
|
||||
https://manus.im/blog/Context-Engineering-for-AI-Agents-Lessons-from-Building-Manus
|
||||
|
||||
|
||||
|
||||
当然在Infra层是否能够也去考虑MultiAgent Runtime Level的RL, 就像很多推荐系统一样能够做到近实时的更新, 针对用户的MAS系统做一些类似于Embedding Table的扩展来构成RL工作流, 挺值得研究的.
|
||||
189
ongoing/Hardware for Inference.md
Normal file
@@ -0,0 +1,189 @@
|
||||
# Background
|
||||
|
||||
## Hardware spec
|
||||
|
||||
|
||||
![[250326-153847.png]]
|
||||
|
||||
| | memory | bandwidth | FP32 TFLOPs | TF32 TFLOPS | FP16 TFLOPs | FP8 TFLOPs (FP16 Accumulate) | inter bandwidth |
|
||||
| -------- | ------ | --------- | ----------- | ------------- | ----------- | ---------------------------- | ---------------------------------------- |
|
||||
| M3-Ultra | 512 GB | 800 GB/s | 43 | NA | 114.688 | NA | thunderbolt5-15 GB/s (max: 6 links * 15) |
|
||||
| 4090 | 24 GB | 1.01 TB/s | 82.6 | 82.6 / 165.2 | 82.58 | 660.6 / 1321.2 | |
|
||||
| 5090 | 32 GB | 1.79 TB/s | 104.8 | 104.8 / 209.5 | 419 / 838 | 838 / 1676 | |
|
||||
| H20-HGX | 96 GB | 4 TB/s | 44 | 74 | 148 | 296 | |
|
||||
| H100-SXM | 80 GB | 3.35 TB/s | 67 | 495 / 989 | 990 / 1979 | 1979 / 3958 | |
|
||||
| A100-SXM | 80 GB | 2039 GB/s | 19.5 | 156 / 312 | 312 / 624 | NA | |
|
||||
|
||||
## M3-Ultra
|
||||
|
||||
- 算力
|
||||
对于 DeepSeek-V3/R1 的架构,prefill per token 需 0.0763 TFLOPs。假设 M3-Ultra 能吃满 80% 的算力,则单卡 M3-Ultra 至多做 1195 tokens/s 的 prefill。
|
||||
在平均 seq_len 为 2k tokens 时,做一次 decode 需要 0.1055 TFLOPs。假设此时 M3-Ultra 能吃满 30% 的算力,则至多做 324 tokens/s,如果 batch_size = 16,对每个用户可以达到 20tps(TPOT = 50 ms),满足 SLO。即使 seq_len 达到 8k,也能提供 10tps,满足基本使用需求。
|
||||
|
||||
| seq_len | TFLOPs/token | TPS for a batch (30% utilization) |
|
||||
| ------- | ------------ | --------------------------------- |
|
||||
| 256 | 0.075 | 455.825 |
|
||||
| 512 | 0.079 | 430.848 |
|
||||
| 1024 | 0.088 | 388.296 |
|
||||
| 2048 | 0.105 | 324.247 |
|
||||
| 4096 | 0.140 | 243.813 |
|
||||
| 8192 | 0.210 | 162.963 |
|
||||
| 16384 | 0.349 | 97.981 |
|
||||
|
||||
- 访存
|
||||
每次激活 37 B,使用 FP8 的参数,需要 load 37 GB,假设 800 GB/s 的带宽能吃满 85%,54.41 ms 的参数访存时间。TPS 从 20 降至 10.
|
||||
|
||||
- 通信
|
||||
MLA 部分单 token all_reduce 需要 0.000814438 GB。Decode 阶段,bsz=64,15 GB/s bandwidth,利用率 50%,则耗时为 6.95 ms。bsz=16,则耗时为 1.74ms。从 50 ms 的 decode,考虑带宽开销后变为 51.74 ms,此时为每个用户可提供 19.32 tps。
|
||||
|
||||
- KV cache load
|
||||
seq_len=4096, bsz=16,KV load 的开销为 6.7 ms,以访存计算,可达到每用户 149 tps。考虑 TPOT=50ms,加上通信开销与 KV cache load 开销后,在 60ms 以内,每用户可达到 16.7 tps
|
||||
|
||||
- KV cache 存储
|
||||
FP16 保存时,单 token 需要 68.62 KB。bsz=16,平均 input+output=8k tokens,则共需 8.58 GB。对于最大支持 512 GB 的 M3-Ultra 来说就是洒洒水啦~
|
||||
|
||||
综合考虑以上部分,假设输入的 batch 为 16 reqs * 4k context,在单卡 M3-Ultra 上进行推理,output 下一个 token 的耗时为:
|
||||
- load model params:37 GB / (800 GB/s * 0.85) = 54.41 ms
|
||||
- load KV cache: 6.7 ms
|
||||
- 计算:(0.105 / (114 * 0.3)) * 16 = 49.12 ms
|
||||
可做到对每个请求达到 110.23ms / token ~ 9 TPS
|
||||
|
||||
## KTransformers
|
||||
|
||||
假设使用单卡 4090,report 的性能数据:286 tokens/s prefill,14 tokens/s decode
|
||||
|
||||
TBD:
|
||||
- 理论计算 KT 的性能
|
||||
|
||||
On-demand quantization, Module injection, Operator placement
|
||||
|
||||
核心 feature:
|
||||
- 写一个 yaml 即可匹配模型的指定部分,将这部分参数 offload 至 CPU 进行计算
|
||||
- 算子注入框架,将指定模块的算子进行替换
|
||||
|
||||
# References
|
||||
|
||||
- [DeepSeek-V3/R1推理效率分析(v0.15)](https://mp.weixin.qq.com/s/-KWSFpjiTggFP4Y_jJa1oA)
|
||||
- [GPU specs database](https://www.techpowerup.com/gpu-specs/)
|
||||
- [M3 Ultra is a slightly weakened 3090 w/ 512GB](https://www.reddit.com/r/LocalLLaMA/comments/1j4jpij/m3_ultra_is_a_slightly_weakened_3090_w_512gb/)
|
||||
|
||||
|
||||
|
||||
---
|
||||
# Backup
|
||||
|
||||
### KTransformers
|
||||
|
||||
假设使用单卡 4090,report 的性能数据:286 tokens/s prefill,14 tokens/s decode
|
||||
|
||||
TBD: 理论计算 KT 的性能
|
||||
|
||||
On-demand quantization, Module injection, Operator placement
|
||||
|
||||
核心 feature:
|
||||
- 写一个 yaml 即可匹配模型的指定部分,将这部分参数 offload 至 CPU 进行计算
|
||||
- 算子注入框架,将指定模块的算子进行替换
|
||||
|
||||
|
||||
|
||||
## 模型情况
|
||||
|
||||
DeepSeek-V3,[计算参考](https://zhuanlan.zhihu.com/p/24954705040)。
|
||||
每个专家 44,040,192B,router 参数量 1,835,264B,每层 load 8 个 experts,8 * 44,040,192 + 1,835,264 = 354,156,800B,每层约 load 0.35GB 参数。共 58 层(前 3 层为 dense)。每层参数走 PCIe 5.0 * 8,则耗时为 11ms。
|
||||
|
||||
算力需求:
|
||||
|
||||
$$8 \cdot 7168^2 + 2 \cdot 14336 \cdot L^2 + 473432064 \cdot L$$
|
||||
114 TFLOPs fp16 算力下,decode 吃满算力可做 ~4k tokens in a batch。
|
||||
|
||||
|
||||
## 各层算力需求计算
|
||||
|
||||
### MLA
|
||||
|
||||
![[250326-153847-1.png]]
|
||||
|
||||
$$
|
||||
\begin{aligned}
|
||||
o_{t, i} &= \sum_{j = 1}^{t} \mathrm{Softmax}_j(\frac{q_{t, i}^T k_{j, i}}{\sqrt{d_h + d_h^R}})v_{j, i}^C \\
|
||||
&= \sum_{j = 1}^{t} \mathrm{Softmax}_j(\frac{[q_{t, i}^C; q_{t, i}^R]^T [k_{j, i}^C; k_j^R]}{\sqrt{d_h + d_h^R}})v_{j, i}^C \\
|
||||
&= \sum_{j = 1}^{t} \mathrm{Softmax}_j(\frac{[W_i^{UQ}c_t^{Q}; q_{t, i}^R]^T [W_i^{UK}c_j^{KV}; k_j^R]}{\sqrt{d_h + d_h^R}})v_{j, i}^C \\
|
||||
&= \sum_{j = 1}^{t} \mathrm{Softmax}_j(\frac{[W_i^{UQ}c_t^{Q}; q_{t, i}^R]^T [W_i^{UK}\textcolor{blue}{c_j^{KV}}; \textcolor{blue}{k_j^R}]}{\sqrt{d_h + d_h^R}})(W_i^{UV}\textcolor{blue}{c_j^{KV}}) \\
|
||||
\end{aligned}
|
||||
$$
|
||||
|
||||
$$
|
||||
\begin{aligned}
|
||||
u_{t, i} &= W^O_i \cdot o_{t, i} \\
|
||||
&= W^O_i \sum_{j = 1}^{t} \mathrm{Softmax}_j(\frac{[W_i^{UQ}c_t^{Q}; q_{t, i}^R]^T [W_i^{UK}\textcolor{blue}{c_j^{KV}}; \textcolor{blue}{k_j^R}]}{\sqrt{d_h + d_h^R}})(W_i^{UV}\textcolor{blue}{c_j^{KV}}) \\
|
||||
&= \sum_{j = 1}^t \mathrm{Softmax}_j(\frac{[W_i^{UQ}c_t^{Q}; q_{t, i}^R]^T [W_i^{UK}\textcolor{blue}{c_j^{KV}}; \textcolor{blue}{k_j^R}]}{\sqrt{d_h + d_h^R}})(W^O_i W_i^{UV})\textcolor{blue}{c_j^{KV}} \\
|
||||
\end{aligned}
|
||||
$$
|
||||
|
||||
$h_t \in \mathbb{R}^{\text{hidden\_size} \times 1}$
|
||||
|
||||
$W^{DQ} \in \mathbb{R}^{\text{q\_lora\_rank} \times \text{hidden\_size}}$, $c_t^Q \in \mathbb{R}^{\text{q\_lora\_rank} \times 1}$
|
||||
$W^{UQ} \in \mathbb{R}^{(\text{num\_attention\_heads} \cdot \text{qk\_nope\_head\_dim}) \times \text{q\_lora\_rank}}$
|
||||
$q_t^C \in \mathbb{R}^{(\text{num\_attention\_heads} \cdot \text{qk\_nope\_head\_dim}) \times 1}$
|
||||
$W^{QR} \in \mathbb{R}^{\text{qk\_rope\_head\_dim} \times \text{q\_lora\_rank}}$, $q_t^R \in \mathbb{R}^{\text{qk\_rope\_head\_dim} \times 1}$
|
||||
$q_{t, i} \in \mathbb{R}^{(\text{qk\_nope\_head\_dim} + \text{qk\_rope\_head\_dim}) \times 1}$
|
||||
|
||||
|
||||
$W^{DKV} \in \mathbb{R}^{\text{kv\_lora\_rank} \times \text{hidden\_size}}$, $c_t^{KV} \in \mathbb{R}^{\text{kv\_lora\_rank} \times 1}$
|
||||
$W^{UK} \in \mathbb{R}^{(\text{num\_key\_value\_heads} \cdot \text{qk\_nope\_head\_dim}) \times \text{kv\_lora\_rank}}$
|
||||
$k_t^{C} \in \mathbb{R}^{(\text{num\_key\_value\_heads} \cdot \text{qk\_nope\_head\_dim}) \times 1}$
|
||||
$W^{KR} \in \mathbb{R}^{\text{qk\_rope\_head\_dim} \times \text{kv\_lora\_rank}}$, $k_t^R \in \mathbb{R}^{\text{qk\_rope\_head\_dim} \times 1}$
|
||||
$k_{t, i} \in \mathbb{R}^{(\text{qk\_nope\_head\_dim} + \text{qk\_rope\_head\_dim}) \times 1}$
|
||||
|
||||
|
||||
$W^{UV} \in \mathbb{R}^{(\text{num\_key\_value\_heads} \cdot \text{qk\_nope\_head\_dim}) \times \text{kv\_lora\_rank}}$
|
||||
$v_t^{C} \in \mathbb{R}^{(\text{num\_key\_value\_heads} \cdot \text{qk\_nope\_head\_dim}) \times 1}$
|
||||
|
||||
$W_O \in \mathbb{R}^{\text{num\_head} }$
|
||||
|
||||
总计算量 `n_h * ((qk_nope_head_dim + qk_rope_head_dim))`
|
||||
|
||||
KV cache 的部分 $C_t^{KV}$ 与 $k_t^R$,对于长度为 $l$ 的 tokens,总 cache 量为 $(\text{kv\_lora\_rank} + \text{qk\_rope\_head\_dim}) \cdot l$
|
||||
|
||||
|
||||
|
||||
## TBD
|
||||
|
||||
- [ ] 每层计算时按需 load/unload 的带宽耗时 对比 mac 统一内存下很差的 TFLOPs 计算速度,哪个会成为瓶颈
|
||||
|
||||
|
||||
|
||||
batch_size = 2, seq_len = 256
|
||||
|
||||
| n_layers | TFLOPs |
|
||||
| -------- | ------ |
|
||||
| 3 | 1.9059 |
|
||||
| 4 | 2.5418 |
|
||||
| 5 | 3.1778 |
|
||||
| 6 | 3.8137 |
|
||||
|
||||
layers 61: 1.9059 + (61 - 3) * 0.6359333333 = 38.79 TFLOPs
|
||||
|
||||
86 TFLOPs FP16 意味着,1s 处理 ~1k tokens 的 context 时,只能达到 1tps,完成不可用!
|
||||
|
||||
layers: 6
|
||||
2 * 512: 8.0623
|
||||
1 * 1024: 8.9369
|
||||
|
||||
|
||||
layers: 5
|
||||
1 * 1024: 7.4458
|
||||
1 * 2048: 17.8143
|
||||
|
||||
|
||||
583.48 M + (187.11 M + (1.84 M + 44.04 M * 9)) * (61 - 3) = 34531.46 M = 33.72 GB
|
||||
|
||||
|
||||
|
||||
1.49 * 61 = 90.89 GFLOPs
|
||||
|
||||
|
||||
单层算力需求(GFLOPs)
|
||||
- MLA: normal: 0.374292, absorb: 0.714439
|
||||
- MLP: 0.792723
|
||||
- MoE: 1 expert: 0.088080
|
||||
3
period/daily/25/250216.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# TBD
|
||||
|
||||
- [ ] xxx
|
||||
7
period/daily/25/250217.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# TBD
|
||||
|
||||
- [ ] xxx
|
||||
|
||||
Deepseek 为什么 1:10 的 PD 配比?
|
||||
如何评价硬件组合的优劣?
|
||||
Simulator 不同硬件组合,不同负载,不同算子库下的性能测试
|
||||
3
period/daily/25/250218.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# TBD
|
||||
|
||||
- [ ] xxx
|
||||
4
period/daily/25/250504.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# TBD
|
||||
|
||||
- [x] 图片换成中文
|
||||
- [x] 3.1 补充 通义
|
||||
17
period/daily/25/250508.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# TBD
|
||||
|
||||
- [ ] 检查 policy 测试情况,get a table
|
||||
- [x] 准备脱敏 trace
|
||||
- [x] 提交毕设
|
||||
- [x] 跑 5 天 trace 处理
|
||||
可用日期:4.20-4.24, 4.28-4.29
|
||||
预期处理时间 4.21-4.24 & 4.28 共 5 天工作日
|
||||
处理时间:9-11,使用 9-12 处理得到 9-11
|
||||
|
||||
|
||||
|
||||
traceB 下 WA 可能比 LRU 好,也可能比 LRU 差,testcase depended,如何解决
|
||||
|
||||
llama2-13b 为 MHA,空间小,但是 WA 反而比 LRU 差
|
||||
|
||||
|
||||
15
period/daily/25/250509.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# TBD
|
||||
|
||||
- [ ] PPT policy
|
||||
- [ ] policy 测试结果画图
|
||||
- [ ] policy 文字部分
|
||||
- [x] 准备盲审毕设
|
||||
- [ ] 开源 trace repo readme
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
traceB 下 WA 可能比 LRU 好,也可能比 LRU 差,testcase depended,如何解决
|
||||
|
||||
llama2-13b 为 MHA,空间小,但是 WA 反而比 LRU 差
|
||||
8
period/daily/25/250512.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# TBD
|
||||
|
||||
- [ ] policy 测试结果画图
|
||||
- [ ] policy 文字部分
|
||||
- [x] 开源 trace repo readme
|
||||
- [x] 添加最简单的 pseudocode
|
||||
|
||||
|
||||
8
period/daily/25/250513.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# TBD
|
||||
|
||||
- [ ] 删除 fig25-27,重画 fig28-30
|
||||
- [ ] 更新文字部分
|
||||
- [ ] 给出 policy design 对应 charactering 的对应表格
|
||||
- [ ] 给出 GDFS 到 WA 的演化
|
||||
|
||||
|
||||
7
period/daily/25/250519.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# TBD
|
||||
|
||||
- [ ] Fig 16 移到 policy 部分,给出拟合的分布
|
||||
- [x] Table 2,文字太多,添加 ref
|
||||
- [ ] table 文字自动断行添加 hyphen
|
||||
- [x] algo 格式调整
|
||||
- [x] policy 测试图
|
||||
5
period/daily/26/260116.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# TBD
|
||||
|
||||
INFO: Reminded 54 papers: [4, 5, 7, 33, 42, 47, 50, 59, 62, 65, 73, 84, 92, 100, 110, 121, 124, 160, 164, 165, 181, 187, 189, 202, 238, 260, 326, 358, 362, 380, 412, 454, 522, 532, 549, 610, 611, 643, 648, 657, 661, 675, 722, 736, 771, 818, 825, 827, 852, 1063, 1123, 1125, 1458, 1579]
|
||||
INFO: Already leaded 14 papers: [3, 28, 70, 81, 379, 389, 422, 470, 485, 578, 738, 761, 876, 1163]
|
||||
INFO: Already commented need check 2 papers: [12, 370]
|
||||
128
period/daily/26/260119.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# TBD
|
||||
|
||||
- [x] 如果 vLLM 启动超时(配置失败),直接放弃,而不是继续 trace-replay
|
||||
- [x] 分析一些 config (-dcp/-pcp) 跑不起来的原因
|
||||
|
||||
- [ ] 总结之前工作的 trick,为他们的场景解决了什么问题,从而实现了 0 -> 1, 1 -> 100
|
||||
- [ ] 开一个 paper repo
|
||||
|
||||
# Notes
|
||||
|
||||
```
|
||||
Assertion failed, tensor parallel size 4 must be greater than total num kv heads 4 when enable decode context parallel for GQA/MQA [type=assertion_error, input_value=ArgsKwargs((), {'model_co...timizationLevel.O2: 2>}), input_type=ArgsKwargs]
|
||||
|
||||
|
||||
ERROR 01-19 10:00:22 [multiproc_executor.py:231] Worker proc VllmWorker-3 died unexpectedly, shutting down executor. 10:00:25 [21/1935]
|
||||
(EngineCore_DP0 pid=3230802) Process EngineCore_DP0:
|
||||
(EngineCore_DP0 pid=3230802) Traceback (most recent call last):
|
||||
(EngineCore_DP0 pid=3230802) File "/usr/lib/python3.12/multiprocessing/process.py", line 314, in _bootstrap
|
||||
(EngineCore_DP0 pid=3230802) self.run()
|
||||
(EngineCore_DP0 pid=3230802) File "/usr/lib/python3.12/multiprocessing/process.py", line 108, in run (EngineCore_DP0 pid=3230802) self._target(*self._args, **self._kwargs)
|
||||
(EngineCore_DP0 pid=3230802) File "/mnt/debugger/wjh/auto-tuner/tuner/.venv/lib/python3.12/site-packages/vllm/v1/engine/core.py", line 940, in run_engine_core
|
||||
(EngineCore_DP0 pid=3230802) raise e
|
||||
(EngineCore_DP0 pid=3230802) File "/mnt/debugger/wjh/auto-tuner/tuner/.venv/lib/python3.12/site-packages/vllm/v1/engine/core.py", line 927, in run_engine_core
|
||||
(EngineCore_DP0 pid=3230802) engine_core = EngineCoreProc(*args, engine_index=dp_rank, **kwargs)
|
||||
(EngineCore_DP0 pid=3230802) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
(EngineCore_DP0 pid=3230802) File "/mnt/debugger/wjh/auto-tuner/tuner/.venv/lib/python3.12/site-packages/vllm/v1/engine/core.py", line 692, in __init__
|
||||
(EngineCore_DP0 pid=3230802) super().__init__(
|
||||
(EngineCore_DP0 pid=3230802) File "/mnt/debugger/wjh/auto-tuner/tuner/.venv/lib/python3.12/site-packages/vllm/v1/engine/core.py", line 113, in __init__
|
||||
(EngineCore_DP0 pid=3230802) num_gpu_blocks, num_cpu_blocks, kv_cache_config = self._initialize_kv_caches(
|
||||
(EngineCore_DP0 pid=3230802) ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
(EngineCore_DP0 pid=3230802) File "/mnt/debugger/wjh/auto-tuner/tuner/.venv/lib/python3.12/site-packages/vllm/v1/engine/core.py", line 270, in _initialize_kv_caches
|
||||
(EngineCore_DP0 pid=3230802) self.model_executor.initialize_from_config(kv_cache_configs)
|
||||
(EngineCore_DP0 pid=3230802) File "/mnt/debugger/wjh/auto-tuner/tuner/.venv/lib/python3.12/site-packages/vllm/v1/executor/abstract.py", line 115, in initialize_from_config
|
||||
(EngineCore_DP0 pid=3230802) self.collective_rpc("initialize_from_config", args=(kv_cache_configs,))
|
||||
(EngineCore_DP0 pid=3230802) File "/mnt/debugger/wjh/auto-tuner/tuner/.venv/lib/python3.12/site-packages/vllm/v1/executor/multiproc_executor.py", line 359, in collective_rpc
|
||||
(EngineCore_DP0 pid=3230802) return aggregate(get_response())
|
||||
(EngineCore_DP0 pid=3230802) ^^^^^^^^^^^^^^
|
||||
(EngineCore_DP0 pid=3230802) File "/mnt/debugger/wjh/auto-tuner/tuner/.venv/lib/python3.12/site-packages/vllm/v1/executor/multiproc_executor.py", line 342, in get_response
|
||||
(EngineCore_DP0 pid=3230802) raise RuntimeError(
|
||||
(EngineCore_DP0 pid=3230802) RuntimeError: Worker failed with error 'PCP requires attention impls' support, but the impl FlashAttentionImpl does not support PCP.', please check the
|
||||
stack trace above for the root cause
|
||||
```
|
||||
|
||||
|
||||
## vLLM `serve` 性能相关 flags 总表(按类别聚合)
|
||||
|
||||
| 类别 | Flag(聚合) | 主要影响点(性能/资源) | AITuner 里如何当成 search space |
|
||||
| --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
|
||||
| **Precision / Quantization / Graph** | `--dtype` | 权重/激活精度直接决定吞吐与显存(FP16/BF16/FP32 等)。 ([vLLM][1]) | **强推荐**作为离散选择(auto/float16/bfloat16/float32…),与硬件/模型强相关。 |
|
||||
| | `--quantization/-q`, `--allow-deprecated-quantization` | 量化方法决定算子实现、带宽/算力瓶颈与精度。 ([vLLM][1]) | **强推荐**离散选择;需与模型权重格式匹配(AWQ/GPTQ/…)。 |
|
||||
| | `--enforce-eager/--no-enforce-eager` | True 会禁用 CUDA graph(更灵活但通常更慢);False 允许混合以取最大性能。 ([vLLM][1]) | **强推荐**二值 knob(尤其影响稳定吞吐与尾延迟)。 |
|
||||
| | `--compilation-config/-cc` | `torch.compile` + cudagraph capture 细粒度配置(mode、capture sizes、backend 等),影响吞吐/稳定性/启动开销。 ([vLLM][1]) | **推荐**作为结构化 knob(可先只调 `mode` 与 `cudagraph_capture_sizes`)。 |
|
||||
| | `--optimization-level` | 用启动时间换性能(-O0…-O3,默认 O2)。 ([vLLM][1]) | **推荐**小离散空间(0/1/2/3),尤其对服务长期运行场景。 |
|
||||
| **Model length / Attention behavior** | `--max-model-len` | 直接决定 KV cache 上限与显存占用;过大导致 OOM/吞吐下降。支持 `auto`。 ([vLLM][1]) | **强推荐**作为核心连续/离散 knob(可按 workload 分布设上界)。 |
|
||||
| | `--disable-sliding-window` | 禁用滑窗(对支持滑窗的模型)会改变注意力范围/计算与显存。 ([vLLM][1]) | **可选**二值 knob(依模型/正确性要求)。 |
|
||||
| | `--disable-cascade-attn` | 影响 v1 的 cascade attention 启用策略(通常用于数值问题规避;可能影响性能)。 ([vLLM][1]) | **可选**(一般不作为主要调参维度,除非你在做稳定性-性能权衡)。 |
|
||||
| | `--attention-backend` | 强制 attention backend(默认自动选择)。 ([vLLM][1]) | **推荐**离散 knob(不同 GPU/驱动/shape 下差异很大)。 |
|
||||
| **Parallelism topology** | `--tensor-parallel-size/-tp`, `--pipeline-parallel-size/-pp` | TP/PP 改变通信/并行度/显存分片方式,是吞吐与尾延迟的关键结构性 knob。 ([vLLM][1]) | **强推荐**核心离散空间(受 GPU 数与模型结构约束)。 |
|
||||
| | `--data-parallel-size/-dp` | DP 复制模型以提升吞吐(服务侧并发/负载均衡关键)。 ([vLLM][1]) | **强推荐**(常与外部 LB、KV 策略联动)。 |
|
||||
| | `--decode-context-parallel-size/-dcp`, `--prefill-context-parallel-size/-pcp` | 在不改变 world size 的前提下复用 TP GPUs 做 DCP/PCP;影响 KV 放置与 decode/prefill 并行。 ([vLLM][1]) | **推荐**离散空间(需满足 `tp_size` 可整除等约束)。 |
|
||||
| | `--cp-kv-cache-interleave-size`, `--dcp-kv-cache-interleave-size` | 控制 DCP/PCP 下 KV cache 的交错存储粒度,影响访问局部性/通信/吞吐。 ([vLLM][1]) | **推荐**小离散空间(1 / block_size / 若干倍数),高度依赖 workload。 |
|
||||
| **Distributed executor / deployment backend** | `--distributed-executor-backend` | `mp/ray/uni/external_launcher` 影响多进程/多机执行模式与开销。 ([vLLM][1]) | **通常固定**(由部署环境决定);AITuner 可把它当“环境维度”。 |
|
||||
| | 多机参数:`--nnodes/-n`, `--node-rank/-r`, `--master-addr`, `--master-port` | 多机 `mp` 模式的控制面配置。 ([vLLM][1]) | **不建议调优**(属于集群 wiring)。 |
|
||||
| | DP 组网:`--data-parallel-rank/-dpn`, `--data-parallel-start-rank/-dpr`, `--data-parallel-size-local/-dpl`, `--data-parallel-address/-dpa`, `--data-parallel-rpc-port/-dpp`, `--data-parallel-backend/-dpb` | DP rank/本地副本/通信方式等,影响 LB/扩展方式与开销。 ([vLLM][1]) | **部分可调**:通常只把 `dp`、`dpb`、LB 模式作为空间;其余固定。 |
|
||||
| | LB 模式:`--data-parallel-hybrid-lb/-dph`, `--data-parallel-external-lb/-dpe` | online serving 的 DP 负载均衡策略,影响吞吐与尾延迟。 ([vLLM][1]) | **推荐**二值空间(尤其多节点/多副本场景)。 |
|
||||
| **MoE / Expert parallel & communication** | `--enable-expert-parallel/-ep` | MoE 层使用 EP 替代 TP(通信/算子形态变化大)。 ([vLLM][1]) | **强推荐**(MoE 模型的关键结构性 knob)。 |
|
||||
| | `--all2all-backend` | MoE all2all 通信后端选择(吞吐/延迟差异显著)。 ([vLLM][1]) | **强推荐**离散空间(按硬件/网络栈筛选)。 |
|
||||
| | `--enable-return-routed-experts` | 返回 routed experts(通常增加返回/处理开销)。 ([vLLM][1]) | **一般关闭**;若业务需要可做“开销开关”。 |
|
||||
| **Dual-batch overlap / microbatching** | `--enable-dbo`, `--ubatch-size`, `--dbo-decode-token-threshold`, `--dbo-prefill-token-threshold` | DBO 与 microbatch 策略,直接影响流水化程度、吞吐、TTFT/TPOT tradeoff。 ([vLLM][1]) | **强推荐**:对“prefill-heavy vs decode-heavy” workload 很敏感。 |
|
||||
| **KV cache sizing & residency** | `--block-size` | KV cache block 粒度影响碎片化、prefix cache/调度行为与吞吐。 ([vLLM][1]) | **强推荐**小离散空间(常见 8/16/32…)。 |
|
||||
| | `--gpu-memory-utilization` | 预留给 KV cache 的显存比例,直接决定可容纳并发与最大上下文。 ([vLLM][1]) | **强推荐**连续空间(例如 0.80–0.98,需 OOM guard)。 |
|
||||
| | `--kv-cache-memory-bytes` | 直接指定 KV cache bytes(比 utilization 更硬)。 ([vLLM][1]) | **可选**:当你想把 search space 显式化为 bytes。 |
|
||||
| | `--num-gpu-blocks-override` | 手动覆盖 GPU blocks 数量(影响可用 KV 容量与并发)。 ([vLLM][1]) | **可选**:更“底层”,适合研究型调优。 |
|
||||
| **KV cache dtype / scaling / fast-prefill** | `--kv-cache-dtype` | KV cache 精度(auto/fp8…)影响带宽与显存。 ([vLLM][1]) | **推荐**离散空间(尤其 FP8 KV 的吞吐潜力/数值风险)。 |
|
||||
| | `--calculate-kv-scales` | 计算 KV scales(为 FP8 KV 等服务),会引入额外计算但可能换来更好带宽/容量。 ([vLLM][1]) | **可选**:与 KV dtype 强绑定的条件 knob。 |
|
||||
| | `--kv-sharing-fast-prefill` | fast prefill 的 KV sharing 行为,影响 prefill 吞吐与缓存复用。 ([vLLM][1]) | **推荐**二值空间(对长 prompt/复用场景很关键)。 |
|
||||
| **Prefix caching** | `--enable-prefix-caching`, `--prefix-caching-hash-algo` | prefix cache 命中可显著降低 prefill;hash 算法影响开销/碰撞/性能。 ([vLLM][1]) | **强推荐**(你的 trace-replayer + block-hash 场景尤其关键)。 |
|
||||
| **KV / CPU swap / offloading** | `--swap-space` | CPU swap 空间(GiB)用于溢出,影响 OOM vs 延迟退化。 ([vLLM][1]) | **推荐**:作为“容量-延迟退化”权衡 knob。 |
|
||||
| | `--kv-offloading-size`, `--kv-offloading-backend` | 启用 KV offloading 到 CPU(native 或 lmcache),显著改变延迟/吞吐曲线。 ([vLLM][1]) | **推荐**:作为条件结构 knob(offloading 开/关 + backend + size)。 |
|
||||
| **Batching / scheduling capacity** | `--max-num-seqs` | 批内最大并发序列数,直接决定吞吐与每步调度开销。 ([vLLM][1]) | **强推荐**核心整数空间(与 KV 容量强耦合)。 |
|
||||
| | `--max-num-batched-tokens` | 批内 tokens 上限(吞吐/延迟核心)。 ([vLLM][1]) | **强推荐**:通常需要和 TTFT/TPOT 的目标函数做权衡。 |
|
||||
| | `--max-num-running-requests`, `--max-num-requests` | 运行中/总请求上限(背压策略),影响尾延迟与拒绝率。 ([vLLM][1]) | **推荐**:更偏服务质量控制;也会影响队列与 p95。 |
|
||||
| **Chunked / partial prefill** | `--enable-chunked-prefill` | 启用 chunked prefill(改善交互性/TTFT,但影响吞吐与调度复杂度)。 ([vLLM][1]) | **强推荐**二值 knob(对长 prompt + 在线场景很关键)。 |
|
||||
| | `--max-num-partial-prefills`, `--max-long-partial-prefills`, `--long-prefill-token-threshold` | partial prefill 的并发与阈值控制,影响 TTFT/吞吐/公平性。 ([vLLM][1]) | **推荐**:作为 chunked-prefill 开启后的条件整数空间。 |
|
||||
| **Scheduler behavior knobs** | `--num-scheduler-steps` | 每次输出 token 的调度步数(可改变调度-算子重叠/吞吐)。 ([vLLM][1]) | **推荐**小整数空间。 |
|
||||
| | `--scheduler-delay-factor` | scheduler 延迟因子(吞吐 vs 延迟)。 ([vLLM][1]) | **可选**连续小范围。 |
|
||||
| | `--scheduler-cls` | 自定义 scheduler 类(强影响行为)。 ([vLLM][1]) | **通常固定**(更像“选择调度器实现”而非调参)。 |
|
||||
| | `--enable-sleep-mode` | 空闲时 sleep(省电/降温;唤醒开销影响延迟)。 ([vLLM][1]) | **可选**(取决于业务是否追求极致 tail latency)。 |
|
||||
| **Speculative decoding / return-size** | `--disable-logprobs-during-spec-decoding` | speculative decoding 时禁用 logprobs 以减少开销。 ([vLLM][1]) | **可选**(若业务不需要 logprobs,通常应打开该禁用)。 |
|
||||
| | `--max-logprobs`, `--logprobs-mode` | logprobs 返回规模与内容模式会显著增加计算与输出体积;`-1` 可能 OOM。 ([vLLM][1]) | **推荐**作为“开销/功能”维度;对性能目标通常应限制。 |
|
||||
| **Frontend / API process scaling** | `--api-server-count` | API 进程数;可缓解前端解析/IO/序列化瓶颈(多核机器常见收益)。 ([vLLM][1]) | **推荐**:作为与 CPU/IO 相关的整数空间。 |
|
||||
| | `--disable-frontend-multiprocessing` | 禁用前端多进程可能降低并发处理能力。 ([vLLM][1]) | **一般不建议**作为优化 knob(多数场景保持多进程)。 |
|
||||
| **Logging / observability overhead** | `--disable-log-stats`, `--disable-log-requests`, `--max-log-len` | 统计与请求日志会引入 CPU/IO 开销,尤其高 QPS。 ([vLLM][1]) | **建议**在性能基准时统一关闭或固定,避免噪声。 |
|
||||
| | `--collect-detailed-traces`, `--otlp-traces-endpoint` | 详细 tracing 可能引入“昂贵或阻塞”操作并影响性能。 ([vLLM][1]) | **不要纳入自动 search**;应作为诊断模式开关。 |
|
||||
| | `--kv-cache-metrics`, `--kv-cache-metrics-sample`, `--cudagraph-metrics`, `--enable-layerwise-nvtx-tracing`, `--enable-mfu-metrics` | 指标/trace 会带来额外开销(部分采样降低开销;NVTX 与 cudagraph 互斥)。 ([vLLM][1]) | **诊断开关**:建议 AITuner 固定关闭,仅在分析阶段开启。 |
|
||||
| | `--profiler-config` | profiler 会显著影响性能(profiling 模式)。 ([vLLM][1]) | **不作为 search**;仅用于测量与归因。 |
|
||||
| **Disaggregated / KV transfer** | `--tokens-only` | 仅启用 Tokens In<>Out endpoint(面向 Disaggregated Everything)。 ([vLLM][1]) | **环境/架构维度**(通常不与常规 serving 混在同一空间)。 |
|
||||
| | `--speculative-config` | speculative decoding 配置(结构化),强影响吞吐/延迟。 ([vLLM][1]) | **推荐**:结构化 knob(但需要你定义可调子字段集合)。 |
|
||||
| | `--kv-transfer-config` | KV 传输配置(结构化),用于分离式架构/跨实例 KV。 ([vLLM][1]) | **推荐(条件)**:只在 disaggregated/多实例 KV 场景调。 |
|
||||
| | `--kv-events-config`, `--ec-transfer-config` | KV 事件发布与 EC cache transfer(结构化)。 ([vLLM][1]) | **条件 knob**:多节点/缓存协同架构才有意义。 |
|
||||
| **Multimodal performance knobs(若跑 MM 模型)** | `--mm-processor-cache-gb`, `--mm-processor-cache-type`, `--mm-shm-cache-max-object-size-mb` | MM 预处理缓存大小/类型影响 CPU 开销与内存占用(并随进程数复制)。 ([vLLM][1]) | **推荐(条件)**:高复用图像/视频输入场景会明显受益。 |
|
||||
| | `--mm-encoder-tp-mode`, `--mm-encoder-attn-backend` | MM encoder 的并行策略与 attention backend,直接影响 encoder 吞吐。 ([vLLM][1]) | **推荐(条件)**:作为离散选择。 |
|
||||
| | `--limit-mm-per-prompt`, `--video-pruning-rate`, `--skip-mm-profiling` | 限制输入规模/视频剪枝会改变 token/encoder 负载;skip profiling 主要影响启动。 ([vLLM][1]) | **建议**:把 input 规模限制当作 workload/profile 约束;剪枝率可作为质量-性能权衡 knob。 |
|
||||
| **LoRA performance knobs(若启用 LoRA)** | `--enable-lora`, `--max-loras`, `--max-lora-rank`, `--max-cpu-loras` | LoRA 会引入额外计算与管理开销;batch 内 LoRA 数/rank 直接影响吞吐。 ([vLLM][1]) | **推荐(条件)**:在 LoRA serving 场景纳入空间;否则固定关闭。 |
|
||||
| | `--fully-sharded-loras` | 在高 seq_len / 高 rank / 大 TP 下可能更快。 ([vLLM][1]) | **推荐(条件)**二值 knob。 |
|
||||
|
||||
1. **结构层(Topology / Memory feasibility)**:`tp/pp/dp/dcp/pcp` + `max-model-len` + `gpu-memory-utilization` + `block-size`(先保证可行,不 OOM)。 ([vLLM][1])
|
||||
2. **吞吐-延迟层(Batching / Scheduling / Overlap)**:`max-num-batched-tokens`, `max-num-seqs`, `chunked-prefill + partial-prefill family`, `enable-dbo + thresholds`。 ([vLLM][1])
|
||||
3. **内核层(Kernel / Compile / Backend)**:`attention-backend`, `enforce-eager`, `compilation-config`,(MoE 时)`all2all-backend`。 ([vLLM][1])
|
||||
|
||||
|
||||
| 类别 | Flag | 类型/取值形态 | 作用(与性能相关的核心机制) | 典型权衡 / 约束关系 |
|
||||
| --------------------- | -------------------------------------- | ---------------- | ------------------------------------------------------------------- | ---------------------------------------------------- |
|
||||
| Parallelism | `--tensor-parallel-size/-tp` | int | Tensor 并行度;决定 GEMM/Attention 的分片与跨卡通信形态,强影响吞吐、显存、p95。 | 需满足 `tp*pp` 不超过可用 GPU;通信带宽不足会拉低 TP 收益。 |
|
||||
| Parallelism | `--pipeline-parallel-size/-pp` | int | Pipeline 并行度;通过层切分减少单卡显存压力,但引入流水气泡与跨 stage 同步。 | 可能降低单请求 latency(气泡/flush);更适合大模型或显存受限。 |
|
||||
| Parallelism | `--data-parallel-size/-dp` | int | Data 并行(模型副本数);提升吞吐/并发能力,配合负载均衡影响尾延迟。 | 会复制权重占用更多 GPU;与请求路由、cache 复用策略耦合。 |
|
||||
| Context Parallel | `--decode-context-parallel-size/-dcp` | int | Decode 阶段的 context parallel;复用 TP GPU 做 decode 并行(改变 KV 放置/通信)。 | 需要与 `tp`、KV cache 组织匹配(通常有整除/拓扑约束)。 |
|
||||
| Context Parallel | `--prefill-context-parallel-size/-pcp` | int | Prefill 阶段的 context parallel;提升长 prompt prefill 吞吐或降低峰值显存。 | 与 `dcp` 类似受 `tp`/拓扑约束;prefill-heavy workload 更敏感。 |
|
||||
| MoE / Expert Parallel | `--enable-expert-parallel/-ep` | bool | MoE 模型启用 Expert Parallel(用 EP 处理 experts 分布/路由),改变通信与算子结构。 | 仅 MoE 模型适用;常与 all2all 通信后端强耦合。 |
|
||||
| MoE / Communication | `--all2all-backend` | enum | MoE all-to-all 通信后端选择,直接影响路由通信开销与吞吐。 | 取值依赖编译/环境(如 NCCL 等);网络/拓扑决定最优。 |
|
||||
| Overlap / Dual-batch | `--enable-dbo` | bool | 启用 Dual-batch overlap;通过将不同阶段/批次重叠执行提高利用率、吞吐。 | 可能牺牲 TTFT 或引入调度复杂度;与阈值/ubatch 强绑定。 |
|
||||
| Overlap / Microbatch | `--ubatch-size` | int | microbatch(uBatch)大小;控制 DBO 下切分粒度与重叠机会,影响吞吐与调度开销。 | 太小调度开销大;太大重叠不足、可能增加峰值显存/延迟。 |
|
||||
| Overlap / Threshold | `--dbo-decode-token-threshold` | int | Decode token 数阈值;达到阈值才触发/采用 DBO 的相关策略。 | 对 decode-heavy workload 敏感;阈值过低可能增加干扰,过高则收益不足。 |
|
||||
| Overlap / Threshold | `--dbo-prefill-token-threshold` | int | Prefill token 数阈值;控制 prefill 场景下 DBO 的启用门槛。 | 对长 prompt 场景敏感;与 chunked-prefill 可能产生交互。 |
|
||||
| KV Cache / Memory | `--block-size` | int(常见 8/16/32…) | KV cache 分块粒度;影响碎片、prefix 复用、调度/缓存命中与吞吐。 | 小 block 碎片少但管理开销增;大 block 管理轻但浪费显存、影响并发。 |
|
||||
| Batching | `--max-num-seqs` | int | 单 step/批内最大并发序列数;直接决定并发与调度开销、吞吐上限。 | 受 KV 容量、`max-num-batched-tokens` 约束;过大可能恶化尾延迟。 |
|
||||
| Batching | `--max-num-batched-tokens` | int | 单 step/批内 token 总上限;吞吐-延迟(TTFT/TPOT)核心 knob。 | 越大吞吐越高但 TTFT/p95 可能升;与 prefill/decode 负载结构强相关。 |
|
||||
| Prefill Scheduling | `--enable-chunked-prefill` | bool | 启用 chunked prefill;将长 prefill 切块与 decode 交错,提高交互性/TTFT(常见),并改变调度行为。 | 可能降低纯吞吐或增加调度复杂度;与 `max-num-batched-tokens`、DBO 阈值联动。 |
|
||||
0
period/daily/26/260129.md
Normal file
6
period/daily/26/260304.md
Normal file
@@ -0,0 +1,6 @@
|
||||
1. 刘嘉敏
|
||||
- 上海交大 IEEE CS 大三
|
||||
- 实习,不确定在IPADS读研/博
|
||||
- **大哥** 家豪
|
||||
- **任务** 辅助 agentic AITuner 项目的 micro benchmark 测试
|
||||
- **机器** H100-九章
|
||||
26
period/daily/26/260306.md
Normal file
1275
period/daily/26/260307.md
Normal file
2
period/daily/26/260309.md
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
- [ ] 设计怎么画图,证明 engine / workload / hardware 的演化速度
|
||||
7
period/daily/26/260310.md
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
- [ ] 设计怎么画图,证明 engine / workload / hardware 的演化速度
|
||||
- [ ] 证明 trace-replayer 比 synthesis 好
|
||||
- [ ] 证明 one instance tuning can work in cluster
|
||||
|
||||
|
||||
|
||||
121
period/daily/26/260312.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# TODO
|
||||
- [ ] 分析开启 EP 性能好坏的本质原因
|
||||
- [ ] 分析内部频繁修改 cuda_graph_sizes,会对性能有什么影响,怎么对应到 engine 性能
|
||||
|
||||
workload prefill 强度的定义,考虑三个维度:
|
||||
- 总 prefill tokens
|
||||
- request input length 的分布(长度究竟怎么影响?)
|
||||
- burst(QPS CV)
|
||||
|
||||
|
||||
|
||||
`export VLLM_DISABLE_COMPILE_CACHE=1`
|
||||
|
||||
|
||||
`export VLLM_FLASHINFER_ALLREDUCE_FUSION_THRESHOLDS_MB='{"4":0}'`
|
||||
|
||||
|
||||
|
||||
总 prefill load 增大,但是从 TP1 -> TP2,不仅 TPS 增大,而且 latency 降低
|
||||
|
||||
| **window_id** | trace_type | time_scale | prefill_tokens_per_second | real_prefill_tokens_per_second | prefix_cache_hit_tokens_per_second | total_prefill_tokens | total_real_prefill_tokens | total_prefix_cache_hit_tokens | prefix_cache_hit_rate | config_id | tensor_parallel_size | max_num_seqs | max_num_batched_tokens | goodput | goodput_per_gpu | num_slo_pass | total_requests | num_errors | experiment_duration | mean_ttft | p95_ttft | started_at | finished_at | log_path | server_log_path | num_good_tokens | good_token_per_second | good_token_per_second_per_gpu |
|
||||
| ------------- | ---------- | ---------- | ------------------------- | ------------------------------ | ---------------------------------- | -------------------- | ------------------------- | ----------------------------- | --------------------- | --------- | -------------------- | ------------ | ---------------------- | ----------------- | ----------------- | ------------ | -------------- | ---------- | ------------------- | ------------------ | ------------------ | ------------------ | ------------------ | ------------------------------------------------- | ------------------------------------------------------ | --------------- | --------------------- | ----------------------------- |
|
||||
| **chat_w06** | chat | 1.0 | 12045.351666666700 | 6850.685 | 5194.666666666670 | 7227211 | 4110411 | 3116800 | 0.4312590292437840 | A | 1 | 32 | 8192 | 5.426623109964860 | 5.426623109964860 | 3258 | 3436 | 0 | 600.373369216919 | 0.735489982664932 | 2.7120952010154700 | 1773196637.8148000 | 1773197238.188170 | results/experiment_logs/chat_w06__config_A.jsonl | results/experiment_logs/chat_w06__config_A.server.log | 7119724 | 11858.82713166710 | 11858.82713166710 |
|
||||
| **coder_w02** | coder | 1.0 | 31264.74 | 14433.46 | 16831.280000000000 | 18758844 | 8660076 | 10098768 | 0.5383470324717240 | B | 2 | 64 | 16384 | 5.418584987116260 | 2.709292493558130 | 3252 | 3264 | 1 | 600.1566843986510 | 0.6616424000997540 | 2.0865608930587800 | 1773206129.1402500 | 1773206729.2969400 | results/experiment_logs/coder_w02__config_B.jsonl | results/experiment_logs/coder_w02__config_B.server.log | 18745884 | 31234.98327571430 | 15617.49163785710 |
|
||||
|
||||
|
||||
|
||||
|
||||
- EP off
|
||||
```
|
||||
gahow@Gahow-MBA configs % rg '"enable_expert_parallel": false'
|
||||
qwen3-coder-plus/1m-0922-config-fix/h20_prefill.config
|
||||
38: "enable_expert_parallel": false,
|
||||
|
||||
qwen3-coder-plus/1m-0922-config-fix/h20_decode.config
|
||||
74: "enable_expert_parallel": false,
|
||||
|
||||
qwen3-plusp/256k-1106/h20_prefill.config
|
||||
43: "enable_expert_parallel": false,
|
||||
|
||||
qwen3-235b-a22b/256k-0717/h20_prefill.config
|
||||
43: "enable_expert_parallel": false,
|
||||
|
||||
qwen3-max/256k-0922-fp4/h20_prefill.config
|
||||
43: "enable_expert_parallel": false,
|
||||
|
||||
qwen3-235b-a22b/256k-0723-think-cs/h20_prefill.config
|
||||
44: "enable_expert_parallel": false,
|
||||
```
|
||||
|
||||
- EP on
|
||||
```
|
||||
gahow@Gahow-MBA configs % rg '"enable_expert_parallel": true'
|
||||
qwen3-max/256k-0922-fp4-pc-eplb/h20_decode.config
|
||||
74: "enable_expert_parallel": true,
|
||||
|
||||
qwen3-235b-a22b/256k-0717/h20_decode.config
|
||||
76: "enable_expert_parallel": true,
|
||||
|
||||
qwen3-1.16t-a86b/256k-0922-sq-re-nvfp4/l20c_decode.config
|
||||
76: "enable_expert_parallel": true,
|
||||
|
||||
qwen3-1.16t-a86b/256k-0922-sq-re-nvfp4/l20c_prefill.config
|
||||
44: "enable_expert_parallel": true,
|
||||
|
||||
qwen3-plusp/256k-1106/h20_decode.config
|
||||
76: "enable_expert_parallel": true,
|
||||
|
||||
qwen3-235b-a22b/256k-0723-think-cs/h20_decode.config
|
||||
77: "enable_expert_parallel": true,
|
||||
```
|
||||
|
||||
- TP
|
||||
```
|
||||
gahow@Gahow-MBA configs % rg '"tensor_parallel_size"'
|
||||
qwen3-max/256k-0922-fp4/h20_prefill.config
|
||||
51: "tensor_parallel_size": 8,
|
||||
|
||||
qwen3-max/256k-0922-fp4-pc-eplb/h20_decode.config
|
||||
84: "tensor_parallel_size": 8,
|
||||
|
||||
qwen3-1.16t-a86b/256k-0922-sq-re-nvfp4/l20c_decode.config
|
||||
84: "tensor_parallel_size": 8,
|
||||
|
||||
qwen3-coder-plus/1m-0922-re-fp8/h20.config
|
||||
14: "tensor_parallel_size": 4,
|
||||
|
||||
qwen3-1.16t-a86b/256k-0922-sq-re-nvfp4/l20c_prefill.config
|
||||
96: "tensor_parallel_size": 8,
|
||||
|
||||
qwen3-coder-plus/1m-0922-config-fix/h20_prefill.config
|
||||
43: "tensor_parallel_size": 4,
|
||||
|
||||
qwen3-coder-plus/1m-0922-config-fix/h20_decode.config
|
||||
84: "tensor_parallel_size": 4,
|
||||
|
||||
qwen3-30b-a3b-with-gate-next-fp4/instruct-fp4/h20.config
|
||||
28: "tensor_parallel_size": 1,
|
||||
```
|
||||
|
||||
- DP
|
||||
```
|
||||
gahow@Gahow-MBA configs % rg '"data_parallel_size"'
|
||||
qwen3-plusp/256k-1106/h20_decode.config
|
||||
85: "data_parallel_size": 8,
|
||||
|
||||
qwen3-235b-a22b/256k-0717/h20_decode.config
|
||||
85: "data_parallel_size": 8,
|
||||
|
||||
qwen3-235b-a22b/256k-0723-think-cs/h20_decode.config
|
||||
86: "data_parallel_size": 8,
|
||||
|
||||
qwen3-max/256k-0922-fp4-pc-eplb/h20_decode.config
|
||||
83: "data_parallel_size": 1,
|
||||
|
||||
qwen3-1.16t-a86b/256k-0922-sq-re-nvfp4/l20c_decode.config
|
||||
83: "data_parallel_size": 1,
|
||||
|
||||
qwen3-coder-plus/1m-0922-config-fix/h20_decode.config
|
||||
83: "data_parallel_size": 1,
|
||||
```
|
||||
4
period/daily/26/260317.md
Normal file
@@ -0,0 +1,4 @@
|
||||
backup 计划 -> OSS:
|
||||
ali/data/formatted_trace
|
||||
|
||||
|
||||
10
period/daily/26/260320.md
Normal file
@@ -0,0 +1,10 @@
|
||||
```bash
|
||||
OLD="/dashscope/caches/application/wjh"
|
||||
NEW="/home/admin/cpfs/wjh"
|
||||
|
||||
grep -rl "$OLD" .venv | xargs sed -i "s|$OLD|$NEW|g"
|
||||
|
||||
find .venv -name "*.pyc" -delete
|
||||
|
||||
python -c "import sys; print(sys.prefix)"
|
||||
```
|
||||
12
period/weekly/25/0217-0223.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# TBD
|
||||
|
||||
- [ ] 把 deepseek v3 跑起来。为什么 decode 需要 320 卡?如果多个 experts 在同一张卡会怎么样?8 卡下性能如何?expert parallelism 怎么 work 的?
|
||||
- [x] 找到可以在 8 * A100 上跑的 V3 【DeepSeek-V3-AWQ】
|
||||
- [ ] 修改 vLLM,分析 expert 如何激活、如何做 expert parallelism
|
||||
- [ ] 测试推理性能
|
||||
- [ ] 分析 experts 负载状况
|
||||
- [ ] 新 trace 的统一格式化处理,分析对比与之前 1h trace 是否存在区别,是否有新特征
|
||||
- [x] 给出统一的 trace 格式规范,写好 doc
|
||||
- [x] 支持 streaming 处理,格式化数据
|
||||
- [ ] 刷新之前的测试图
|
||||
- [ ] 调研 TensorFlow 为什么被 PyTorch 干趴下了,做对了什么/做错了什么?
|
||||
3
period/weekly/25/0224-0302.md
Normal file
@@ -0,0 +1,3 @@
|
||||
- [ ] vLLM 分布式 KV cache 管理: https://github.com/vllm-project/aibrix
|
||||
- [x] 准备 FAST'25 KV cache related paper sharing
|
||||
- [x] 完成 traceA/B 的 24h format
|
||||
7
period/weekly/25/0303-0309.md
Normal file
@@ -0,0 +1,7 @@
|
||||
- [ ] 调研企业级私有化部署 DeepSeek 的机会
|
||||
- [ ] llama.cpp 有什么问题?是不是只适合单机?
|
||||
- [ ] ktransformer 相比 llama.cpp 为什么有优势?他们是不是只 focus 在单机?企业级部署不像个人使用,提供 global scheduler 后跟多个单机跑有什么问题?分布式并行跑有什么问题?
|
||||
- [ ] M2 Ultra 这种 unified memory 芯片有提供低成本部署的机会吗?
|
||||
- 机会点:计算很可能在往稀疏性发展,MoE 等。m 系列芯片这种内存大算力一般的芯片可能具有一定优势
|
||||
- m 系列芯片互联带宽在 10~40Gb 之间(相比 450Gb+ 的 NVLink),会不会成为 bottleneck
|
||||
|
||||
16
period/weekly/25/0310-0316.md
Normal file
@@ -0,0 +1,16 @@
|
||||
- [x] 提供一个构造 不同时间段 / 不同总时长 / 不同 QPS 的 vLLM 真实测试的 trace 构造器,需要保证:小 QPS 是大 QPS 的子集(避免平均长度不同)
|
||||
|
||||
|
||||
- [x] trace 分析
|
||||
- [x] QPS
|
||||
- [x] 平均输入输出长度
|
||||
- [x] 有上一轮对话的比例
|
||||
- [x] 上下轮对话之间间隔时间的 mean/p90/p50/...
|
||||
- [ ] 不同 workload 的 one-shot 比例
|
||||
- [ ] s3-fifo 的不同 one-shot 比例与 S/M 比例的关系
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- [ ] DistServe 的 simulator 做了什么?
|
||||
4
period/weekly/25/0317-0323.md
Normal file
@@ -0,0 +1,4 @@
|
||||
- [ ] Sarathi(https://arxiv.org/abs/2308.16369)
|
||||
- [ ] HybridFlow(https://arxiv.org/pdf/2409.19256)
|
||||
|
||||
|
||||
0
period/weekly/25/0331-0406.md
Normal file
1
period/weekly/25/0512-0518.md
Normal file
@@ -0,0 +1 @@
|
||||
- [ ] 使用 trace 测试 MoE 的 activate pattern
|
||||
6
period/weekly/25/0714-0720.md
Normal file
@@ -0,0 +1,6 @@
|
||||
- [ ] review EuroSys paper <0/5>
|
||||
- [ ] deep research for review the comments from reviewers and review papers
|
||||
- [ ] run deep research to check the agent workflow overhead
|
||||
- [ ] 整理 ali 的 infra arch
|
||||
|
||||
|
||||
BIN
phd/papers/IMPRESS.figs/250228-095457.png
Normal file
|
After Width: | Height: | Size: 316 KiB |
BIN
phd/papers/IMPRESS.figs/250228-164104.png
Normal file
|
After Width: | Height: | Size: 412 KiB |
BIN
phd/papers/IMPRESS.figs/250228-170902.png
Normal file
|
After Width: | Height: | Size: 359 KiB |
BIN
phd/papers/IMPRESS.figs/250228-175702.png
Normal file
|
After Width: | Height: | Size: 317 KiB |
BIN
phd/papers/IMPRESS.figs/250228-175831.png
Normal file
|
After Width: | Height: | Size: 216 KiB |
BIN
phd/papers/IMPRESS.figs/250301-134529.png
Normal file
|
After Width: | Height: | Size: 307 KiB |
BIN
phd/papers/IMPRESS.figs/250301-151846.png
Normal file
|
After Width: | Height: | Size: 314 KiB |
BIN
phd/papers/IMPRESS.figs/250301-155139.png
Normal file
|
After Width: | Height: | Size: 886 KiB |
BIN
phd/papers/IMPRESS.figs/250301-155325.png
Normal file
|
After Width: | Height: | Size: 378 KiB |
BIN
phd/papers/IMPRESS.figs/250301-155822.png
Normal file
|
After Width: | Height: | Size: 179 KiB |
BIN
phd/papers/IMPRESS.figs/250301-155959.png
Normal file
|
After Width: | Height: | Size: 181 KiB |
BIN
phd/papers/IMPRESS.figs/250301-160458.png
Normal file
|
After Width: | Height: | Size: 247 KiB |